[
  {
    "path": ".gitattributes",
    "content": "###############################################################################\n# Set default behavior to automatically normalize line endings.\n###############################################################################\n* text=auto\n\n*.c linguist-language=C\n*.h linguist-language=C\n\n###############################################################################\n# Set default behavior for command prompt diff.\n#\n# This is need for earlier builds of msysgit that does not have it on by\n# default for csharp files.\n# Note: This is only used by command line\n###############################################################################\n#*.cs     diff=csharp\n\n###############################################################################\n# Set the merge driver for project and solution files\n#\n# Merging from the command prompt will add diff markers to the files if there\n# are conflicts (Merging from VS is not affected by the settings below, in VS\n# the diff markers are never inserted). Diff markers may cause the following \n# file extensions to fail to load in VS. An alternative would be to treat\n# these files as binary and thus will always conflict and require user\n# intervention with every merge. To do so, just uncomment the entries below\n###############################################################################\n#*.sln       merge=binary\n#*.csproj    merge=binary\n#*.vbproj    merge=binary\n#*.vcxproj   merge=binary\n#*.vcproj    merge=binary\n#*.dbproj    merge=binary\n#*.fsproj    merge=binary\n#*.lsproj    merge=binary\n#*.wixproj   merge=binary\n#*.modelproj merge=binary\n#*.sqlproj   merge=binary\n#*.wwaproj   merge=binary\n\n###############################################################################\n# behavior for image files\n#\n# image files are treated as binary by default.\n###############################################################################\n#*.jpg   binary\n#*.png   binary\n#*.gif   binary\n\n###############################################################################\n# diff behavior for common document formats\n# \n# Convert binary document formats to text before diffing them. This feature\n# is only available from the command line. Turn it on by uncommenting the \n# entries below.\n###############################################################################\n#*.doc   diff=astextplain\n#*.DOC   diff=astextplain\n#*.docx  diff=astextplain\n#*.DOCX  diff=astextplain\n#*.dot   diff=astextplain\n#*.DOT   diff=astextplain\n#*.pdf   diff=astextplain\n#*.PDF   diff=astextplain\n#*.rtf   diff=astextplain\n#*.RTF   diff=astextplain\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "content": "---\nname: Bug report\nabout: Create a report for driver defects or malfunctions\ntitle: ''\nlabels: bug\nassignees: ''\n\n---\n\n**Pre-report checks**\n\n- [ ] Have you checked (use search) [Azure DevOps Board](https://ligstd.visualstudio.com/Apple%20PTP%20Trackpad/_workitems/recentlyupdated) and Github issues for known bugs and plans?\n\n**Describe the bug**\nA clear and concise description of what the bug is.\n\n**To Reproduce**\nSteps to reproduce the behavior:\n\n**Expected behavior**\nA clear and concise description of what you expected to happen.\n\n**Traces**\nIf applicable, add WPP traces to help explain your problem.\n\n**Environment**\nAdd your device model, driver type (USB or SPI) and OS version here.\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.md",
    "content": "---\nname: Feature request\nabout: Suggest an idea for this project\ntitle: ''\nlabels: enhancement\nassignees: ''\n\n---\n\n**Pre-report checks**\n- [ ] Have you checked (use search) [Azure DevOps Board](https://ligstd.visualstudio.com/Apple%20PTP%20Trackpad/_workitems/recentlyupdated) and Github issues for known bugs and plans?\n\n**Is your feature request related to a problem? Please describe.**\nA clear and concise description of what the problem is. Ex. I'm always frustrated when [...]\n\n**Describe the solution you'd like**\nA clear and concise description of what you want to happen.\n\n**Describe alternatives you've considered**\nA clear and concise description of any alternative solutions or features you've considered.\n\n**Additional context**\nAdd any other context or screenshots about the feature request here.\n"
  },
  {
    "path": ".github/workflows/github-issue-sync.yml",
    "content": "# Synchronizes Github issue to Azure DevOps Board\n\nname: EngSys-ProjectManagement-GithubIssueOnewaySync\n\non:\n  issues:\n    types:\n      [opened, edited, deleted, closed, reopened, labeled, unlabeled, assigned]\n\njobs:\n  alert:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: danhellem/github-actions-issue-to-work-item@master\n        env:\n          ado_token: \"${{ secrets.ADO_PERSONAL_ACCESS_TOKEN }}\"\n          github_token: \"${{ secrets.GH_PERSONAL_ACCESS_TOKEN }}\"\n          ado_organization: \"ligstd\"\n          ado_project: \"Apple PTP Trackpad\"\n          ado_area_path: \"Apple PTP Trackpad\"\n          ado_iteration_path: \"Apple PTP Trackpad\\\\Github Triage\"\n          ado_wit: \"User Story\"\n          ado_new_state: \"New\"\n          ado_active_state: \"Active\"\n          ado_close_state: \"Closed\"\n          ado_bypassrules: true\n          log_level: 100\n"
  },
  {
    "path": ".gitignore",
    "content": "## Ignore Visual Studio temporary files, build results, and\n## files generated by popular Visual Studio add-ons.\n\n# User-specific files\n*.suo\n*.user\n*.userosscache\n*.sln.docstates\n\n# User-specific files (MonoDevelop/Xamarin Studio)\n*.userprefs\n\n# Build results\n[Dd]ebug/\n[Dd]ebugPublic/\n[Rr]elease/\n[Rr]eleases/\n[Xx]64/\n[Xx]86/\n[Bb]uild/\nbld/\n[Bb]in/\n[Oo]bj/\nintermediate/\n\n# Visual Studio 2015 cache/options directory\n.vs/\n# Uncomment if you have tasks that create the project's static files in wwwroot\n#wwwroot/\n\n# MSTest test Results\n[Tt]est[Rr]esult*/\n[Bb]uild[Ll]og.*\n\n# NUNIT\n*.VisualState.xml\nTestResult.xml\n\n# Build Results of an ATL Project\n[Dd]ebugPS/\n[Rr]eleasePS/\ndlldata.c\n\n# DNX\nproject.lock.json\nartifacts/\n\n*_i.c\n*_p.c\n*_i.h\n*.ilk\n*.meta\n*.obj\n*.pch\n*.pdb\n*.pgc\n*.pgd\n*.rsp\n*.sbr\n*.tlb\n*.tli\n*.tlh\n*.tmp\n*.tmp_proj\n*.log\n*.vspscc\n*.vssscc\n.builds\n*.pidb\n*.svclog\n*.scc\n\n# Chutzpah Test files\n_Chutzpah*\n\n# Visual C++ cache files\nipch/\n*.aps\n*.ncb\n*.opendb\n*.opensdf\n*.sdf\n*.cachefile\n*.VC.db\n\n# Visual Studio profiler\n*.psess\n*.vsp\n*.vspx\n*.sap\n\n# TFS 2012 Local Workspace\n$tf/\n\n# Guidance Automation Toolkit\n*.gpState\n\n# ReSharper is a .NET coding add-in\n_ReSharper*/\n*.[Rr]e[Ss]harper\n*.DotSettings.user\n\n# JustCode is a .NET coding add-in\n.JustCode\n\n# TeamCity is a build add-in\n_TeamCity*\n\n# DotCover is a Code Coverage Tool\n*.dotCover\n\n# NCrunch\n_NCrunch_*\n.*crunch*.local.xml\nnCrunchTemp_*\n\n# MightyMoose\n*.mm.*\nAutoTest.Net/\n\n# Web workbench (sass)\n.sass-cache/\n\n# Installshield output folder\n[Ee]xpress/\n\n# DocProject is a documentation generator add-in\nDocProject/buildhelp/\nDocProject/Help/*.HxT\nDocProject/Help/*.HxC\nDocProject/Help/*.hhc\nDocProject/Help/*.hhk\nDocProject/Help/*.hhp\nDocProject/Help/Html2\nDocProject/Help/html\n\n# Click-Once directory\npublish/\n\n# Publish Web Output\n*.[Pp]ublish.xml\n*.azurePubxml\n\n# TODO: Un-comment the next line if you do not want to checkin\n# your web deploy settings because they may include unencrypted\n# passwords\n#*.pubxml\n*.publishproj\n\n# NuGet Packages\n*.nupkg\n# The packages folder can be ignored because of Package Restore\n**/packages/*\n# except build/, which is used as an MSBuild target.\n!**/packages/build/\n# Uncomment if necessary however generally it will be regenerated when needed\n#!**/packages/repositories.config\n# NuGet v3's project.json files produces more ignoreable files\n*.nuget.props\n*.nuget.targets\n\n# Microsoft Azure Build Output\ncsx/\n*.build.csdef\n\n# Microsoft Azure Emulator\necf/\nrcf/\n\n# Windows Store app package directory\nAppPackages/\nBundleArtifacts/\n\n# Visual Studio cache files\n# files ending in .cache can be ignored\n*.[Cc]ache\n# but keep track of directories ending in .cache\n!*.[Cc]ache/\n\n# Others\nClientBin/\n[Ss]tyle[Cc]op.*\n~$*\n*~\n*.dbmdl\n*.dbproj.schemaview\n*.pfx\n*.publishsettings\nnode_modules/\norleans.codegen.cs\n\n# RIA/Silverlight projects\nGenerated_Code/\n\n# Backup & report files from converting an old project file\n# to a newer Visual Studio version. Backup files are not needed,\n# because we have git ;-)\n_UpgradeReport_Files/\nBackup*/\nUpgradeLog*.XML\nUpgradeLog*.htm\n\n# SQL Server files\n*.mdf\n*.ldf\n\n# Business Intelligence projects\n*.rdl.data\n*.bim.layout\n*.bim_*.settings\n\n# Microsoft Fakes\nFakesAssemblies/\n\n# GhostDoc plugin setting file\n*.GhostDoc.xml\n\n# Node.js Tools for Visual Studio\n.ntvs_analysis.dat\n\n# Visual Studio 6 build log\n*.plg\n\n# Visual Studio 6 workspace options file\n*.opt\n\n# Visual Studio LightSwitch build output\n**/*.HTMLClient/GeneratedArtifacts\n**/*.DesktopClient/GeneratedArtifacts\n**/*.DesktopClient/ModelManifest.xml\n**/*.Server/GeneratedArtifacts\n**/*.Server/ModelManifest.xml\n_Pvt_Extensions\n\n# LightSwitch generated files\nGeneratedArtifacts/\nModelManifest.xml\n\n# Paket dependency manager\n.paket/paket.exe\n\n# FAKE - F# Make\n.fake/\n/external\n"
  },
  {
    "path": "AmtPtpDevice.Settings.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio 15\nVisualStudioVersion = 15.0.26730.12\nMinimumVisualStudioVersion = 10.0.40219.1\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"src\", \"src\", \"{12BD4199-3AFB-4418-ACFB-873717B99C8F}\"\nEndProject\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"AmtPtpDevice.Settings\", \"src\\AmtPtpDevice.Settings\\AmtPtpDevice.Settings.csproj\", \"{8FF9D2F4-EC60-4AAE-865D-F11D1B4DEC2F}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|ARM = Debug|ARM\n\t\tDebug|x64 = Debug|x64\n\t\tDebug|x86 = Debug|x86\n\t\tRelease|ARM = Release|ARM\n\t\tRelease|x64 = Release|x64\n\t\tRelease|x86 = Release|x86\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{8FF9D2F4-EC60-4AAE-865D-F11D1B4DEC2F}.Debug|ARM.ActiveCfg = Debug|ARM\n\t\t{8FF9D2F4-EC60-4AAE-865D-F11D1B4DEC2F}.Debug|ARM.Build.0 = Debug|ARM\n\t\t{8FF9D2F4-EC60-4AAE-865D-F11D1B4DEC2F}.Debug|ARM.Deploy.0 = Debug|ARM\n\t\t{8FF9D2F4-EC60-4AAE-865D-F11D1B4DEC2F}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{8FF9D2F4-EC60-4AAE-865D-F11D1B4DEC2F}.Debug|x64.Build.0 = Debug|x64\n\t\t{8FF9D2F4-EC60-4AAE-865D-F11D1B4DEC2F}.Debug|x64.Deploy.0 = Debug|x64\n\t\t{8FF9D2F4-EC60-4AAE-865D-F11D1B4DEC2F}.Debug|x86.ActiveCfg = Debug|x86\n\t\t{8FF9D2F4-EC60-4AAE-865D-F11D1B4DEC2F}.Debug|x86.Build.0 = Debug|x86\n\t\t{8FF9D2F4-EC60-4AAE-865D-F11D1B4DEC2F}.Debug|x86.Deploy.0 = Debug|x86\n\t\t{8FF9D2F4-EC60-4AAE-865D-F11D1B4DEC2F}.Release|ARM.ActiveCfg = Release|ARM\n\t\t{8FF9D2F4-EC60-4AAE-865D-F11D1B4DEC2F}.Release|ARM.Build.0 = Release|ARM\n\t\t{8FF9D2F4-EC60-4AAE-865D-F11D1B4DEC2F}.Release|ARM.Deploy.0 = Release|ARM\n\t\t{8FF9D2F4-EC60-4AAE-865D-F11D1B4DEC2F}.Release|x64.ActiveCfg = Release|x64\n\t\t{8FF9D2F4-EC60-4AAE-865D-F11D1B4DEC2F}.Release|x64.Build.0 = Release|x64\n\t\t{8FF9D2F4-EC60-4AAE-865D-F11D1B4DEC2F}.Release|x64.Deploy.0 = Release|x64\n\t\t{8FF9D2F4-EC60-4AAE-865D-F11D1B4DEC2F}.Release|x86.ActiveCfg = Release|x86\n\t\t{8FF9D2F4-EC60-4AAE-865D-F11D1B4DEC2F}.Release|x86.Build.0 = Release|x86\n\t\t{8FF9D2F4-EC60-4AAE-865D-F11D1B4DEC2F}.Release|x86.Deploy.0 = Release|x86\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\n\tGlobalSection(NestedProjects) = preSolution\n\t\t{8FF9D2F4-EC60-4AAE-865D-F11D1B4DEC2F} = {12BD4199-3AFB-4418-ACFB-873717B99C8F}\n\tEndGlobalSection\n\tGlobalSection(ExtensibilityGlobals) = postSolution\n\t\tSolutionGuid = {5FFBB604-8825-4E20-B999-77FF3E00602B}\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "AmtPtpDriver.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio Version 16\nVisualStudioVersion = 16.0.29102.190\nMinimumVisualStudioVersion = 10.0.40219.1\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"src\", \"src\", \"{2557B86E-6ED8-495A-B9A5-BF80CD5C4DAC}\"\nEndProject\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"contrib\", \"contrib\", \"{1C0E2F63-A3D6-4B44-BDC7-22F6E31EA9F2}\"\n\tProjectSection(SolutionItems) = preProject\n\t\tApp Interface.md = App Interface.md\n\t\tLICENSE-GPL.md = LICENSE-GPL.md\n\t\tLICENSE-MIT.md = LICENSE-MIT.md\n\t\tLICENSE.md = LICENSE.md\n\t\tREADME.md = README.md\n\tEndProjectSection\nEndProject\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"AmtPtpDeviceUsbUm\", \"src\\AmtPtpDeviceUsbUm\\MagicTrackpad2PtpDevice.vcxproj\", \"{87EFA31B-25EB-4944-A30A-300171BFFF57}\"\nEndProject\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"AmtPtpDeviceSpiKm\", \"src\\AmtPtpDeviceSpiKm\\AmtPtpDeviceSpiKm.vcxproj\", \"{FC08B706-5661-47FA-A840-053B06125750}\"\nEndProject\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"AmtPtpDeviceUsbKm\", \"src\\AmtPtpDeviceUsbKm\\AmtPtpDeviceUsbKm.vcxproj\", \"{AB3E45E7-C524-47C1-9677-728BA2A19344}\"\nEndProject\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"AmtPtpDeviceUniversalPkg\", \"src\\AmtPtpDeviceUniversalPkg\\AmtPtpDeviceUniversalPkg.vcxproj\", \"{7AB0A246-AA1C-433B-9E16-88956C51A565}\"\nEndProject\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"AmtPtpHidFilter\", \"src\\AmtPtpHidFilter\\AmtPtpHidFilter.vcxproj\", \"{EE63C42B-F401-4F55-ADBB-14C16BD3B18C}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|ARM64 = Debug|ARM64\n\t\tDebug|x64 = Debug|x64\n\t\tRelease|ARM64 = Release|ARM64\n\t\tRelease|x64 = Release|x64\n\t\tReleaseSigned|ARM64 = ReleaseSigned|ARM64\n\t\tReleaseSigned|x64 = ReleaseSigned|x64\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{87EFA31B-25EB-4944-A30A-300171BFFF57}.Debug|ARM64.ActiveCfg = Debug|ARM64\n\t\t{87EFA31B-25EB-4944-A30A-300171BFFF57}.Debug|ARM64.Build.0 = Debug|ARM64\n\t\t{87EFA31B-25EB-4944-A30A-300171BFFF57}.Debug|ARM64.Deploy.0 = Debug|ARM64\n\t\t{87EFA31B-25EB-4944-A30A-300171BFFF57}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{87EFA31B-25EB-4944-A30A-300171BFFF57}.Debug|x64.Build.0 = Debug|x64\n\t\t{87EFA31B-25EB-4944-A30A-300171BFFF57}.Debug|x64.Deploy.0 = Debug|x64\n\t\t{87EFA31B-25EB-4944-A30A-300171BFFF57}.Release|ARM64.ActiveCfg = Release|ARM64\n\t\t{87EFA31B-25EB-4944-A30A-300171BFFF57}.Release|ARM64.Build.0 = Release|ARM64\n\t\t{87EFA31B-25EB-4944-A30A-300171BFFF57}.Release|ARM64.Deploy.0 = Release|ARM64\n\t\t{87EFA31B-25EB-4944-A30A-300171BFFF57}.Release|x64.ActiveCfg = Release|x64\n\t\t{87EFA31B-25EB-4944-A30A-300171BFFF57}.Release|x64.Build.0 = Release|x64\n\t\t{87EFA31B-25EB-4944-A30A-300171BFFF57}.Release|x64.Deploy.0 = Release|x64\n\t\t{87EFA31B-25EB-4944-A30A-300171BFFF57}.ReleaseSigned|ARM64.ActiveCfg = ReleaseSigned|ARM64\n\t\t{87EFA31B-25EB-4944-A30A-300171BFFF57}.ReleaseSigned|ARM64.Build.0 = ReleaseSigned|ARM64\n\t\t{87EFA31B-25EB-4944-A30A-300171BFFF57}.ReleaseSigned|ARM64.Deploy.0 = ReleaseSigned|ARM64\n\t\t{87EFA31B-25EB-4944-A30A-300171BFFF57}.ReleaseSigned|x64.ActiveCfg = ReleaseSigned|x64\n\t\t{87EFA31B-25EB-4944-A30A-300171BFFF57}.ReleaseSigned|x64.Build.0 = ReleaseSigned|x64\n\t\t{87EFA31B-25EB-4944-A30A-300171BFFF57}.ReleaseSigned|x64.Deploy.0 = ReleaseSigned|x64\n\t\t{FC08B706-5661-47FA-A840-053B06125750}.Debug|ARM64.ActiveCfg = Debug|ARM64\n\t\t{FC08B706-5661-47FA-A840-053B06125750}.Debug|ARM64.Build.0 = Debug|ARM64\n\t\t{FC08B706-5661-47FA-A840-053B06125750}.Debug|ARM64.Deploy.0 = Debug|ARM64\n\t\t{FC08B706-5661-47FA-A840-053B06125750}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{FC08B706-5661-47FA-A840-053B06125750}.Debug|x64.Build.0 = Debug|x64\n\t\t{FC08B706-5661-47FA-A840-053B06125750}.Debug|x64.Deploy.0 = Debug|x64\n\t\t{FC08B706-5661-47FA-A840-053B06125750}.Release|ARM64.ActiveCfg = Release|ARM64\n\t\t{FC08B706-5661-47FA-A840-053B06125750}.Release|ARM64.Build.0 = Release|ARM64\n\t\t{FC08B706-5661-47FA-A840-053B06125750}.Release|ARM64.Deploy.0 = Release|ARM64\n\t\t{FC08B706-5661-47FA-A840-053B06125750}.Release|x64.ActiveCfg = Release|x64\n\t\t{FC08B706-5661-47FA-A840-053B06125750}.Release|x64.Build.0 = Release|x64\n\t\t{FC08B706-5661-47FA-A840-053B06125750}.Release|x64.Deploy.0 = Release|x64\n\t\t{FC08B706-5661-47FA-A840-053B06125750}.ReleaseSigned|ARM64.ActiveCfg = ReleaseSigned|ARM64\n\t\t{FC08B706-5661-47FA-A840-053B06125750}.ReleaseSigned|ARM64.Build.0 = ReleaseSigned|ARM64\n\t\t{FC08B706-5661-47FA-A840-053B06125750}.ReleaseSigned|ARM64.Deploy.0 = ReleaseSigned|ARM64\n\t\t{FC08B706-5661-47FA-A840-053B06125750}.ReleaseSigned|x64.ActiveCfg = ReleaseSigned|x64\n\t\t{FC08B706-5661-47FA-A840-053B06125750}.ReleaseSigned|x64.Build.0 = ReleaseSigned|x64\n\t\t{FC08B706-5661-47FA-A840-053B06125750}.ReleaseSigned|x64.Deploy.0 = ReleaseSigned|x64\n\t\t{AB3E45E7-C524-47C1-9677-728BA2A19344}.Debug|ARM64.ActiveCfg = Debug|ARM64\n\t\t{AB3E45E7-C524-47C1-9677-728BA2A19344}.Debug|ARM64.Build.0 = Debug|ARM64\n\t\t{AB3E45E7-C524-47C1-9677-728BA2A19344}.Debug|ARM64.Deploy.0 = Debug|ARM64\n\t\t{AB3E45E7-C524-47C1-9677-728BA2A19344}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{AB3E45E7-C524-47C1-9677-728BA2A19344}.Debug|x64.Build.0 = Debug|x64\n\t\t{AB3E45E7-C524-47C1-9677-728BA2A19344}.Debug|x64.Deploy.0 = Debug|x64\n\t\t{AB3E45E7-C524-47C1-9677-728BA2A19344}.Release|ARM64.ActiveCfg = Release|ARM64\n\t\t{AB3E45E7-C524-47C1-9677-728BA2A19344}.Release|ARM64.Build.0 = Release|ARM64\n\t\t{AB3E45E7-C524-47C1-9677-728BA2A19344}.Release|ARM64.Deploy.0 = Release|ARM64\n\t\t{AB3E45E7-C524-47C1-9677-728BA2A19344}.Release|x64.ActiveCfg = Release|x64\n\t\t{AB3E45E7-C524-47C1-9677-728BA2A19344}.Release|x64.Build.0 = Release|x64\n\t\t{AB3E45E7-C524-47C1-9677-728BA2A19344}.Release|x64.Deploy.0 = Release|x64\n\t\t{AB3E45E7-C524-47C1-9677-728BA2A19344}.ReleaseSigned|ARM64.ActiveCfg = ReleaseSigned|ARM64\n\t\t{AB3E45E7-C524-47C1-9677-728BA2A19344}.ReleaseSigned|ARM64.Build.0 = ReleaseSigned|ARM64\n\t\t{AB3E45E7-C524-47C1-9677-728BA2A19344}.ReleaseSigned|ARM64.Deploy.0 = ReleaseSigned|ARM64\n\t\t{AB3E45E7-C524-47C1-9677-728BA2A19344}.ReleaseSigned|x64.ActiveCfg = ReleaseSigned|x64\n\t\t{AB3E45E7-C524-47C1-9677-728BA2A19344}.ReleaseSigned|x64.Build.0 = ReleaseSigned|x64\n\t\t{AB3E45E7-C524-47C1-9677-728BA2A19344}.ReleaseSigned|x64.Deploy.0 = ReleaseSigned|x64\n\t\t{7AB0A246-AA1C-433B-9E16-88956C51A565}.Debug|ARM64.ActiveCfg = Debug|ARM64\n\t\t{7AB0A246-AA1C-433B-9E16-88956C51A565}.Debug|ARM64.Build.0 = Debug|ARM64\n\t\t{7AB0A246-AA1C-433B-9E16-88956C51A565}.Debug|ARM64.Deploy.0 = Debug|ARM64\n\t\t{7AB0A246-AA1C-433B-9E16-88956C51A565}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{7AB0A246-AA1C-433B-9E16-88956C51A565}.Debug|x64.Build.0 = Debug|x64\n\t\t{7AB0A246-AA1C-433B-9E16-88956C51A565}.Debug|x64.Deploy.0 = Debug|x64\n\t\t{7AB0A246-AA1C-433B-9E16-88956C51A565}.Release|ARM64.ActiveCfg = Release|ARM64\n\t\t{7AB0A246-AA1C-433B-9E16-88956C51A565}.Release|ARM64.Build.0 = Release|ARM64\n\t\t{7AB0A246-AA1C-433B-9E16-88956C51A565}.Release|ARM64.Deploy.0 = Release|ARM64\n\t\t{7AB0A246-AA1C-433B-9E16-88956C51A565}.Release|x64.ActiveCfg = Release|x64\n\t\t{7AB0A246-AA1C-433B-9E16-88956C51A565}.Release|x64.Build.0 = Release|x64\n\t\t{7AB0A246-AA1C-433B-9E16-88956C51A565}.Release|x64.Deploy.0 = Release|x64\n\t\t{7AB0A246-AA1C-433B-9E16-88956C51A565}.ReleaseSigned|ARM64.ActiveCfg = ReleaseSigned|ARM64\n\t\t{7AB0A246-AA1C-433B-9E16-88956C51A565}.ReleaseSigned|ARM64.Build.0 = ReleaseSigned|ARM64\n\t\t{7AB0A246-AA1C-433B-9E16-88956C51A565}.ReleaseSigned|ARM64.Deploy.0 = ReleaseSigned|ARM64\n\t\t{7AB0A246-AA1C-433B-9E16-88956C51A565}.ReleaseSigned|x64.ActiveCfg = ReleaseSigned|x64\n\t\t{7AB0A246-AA1C-433B-9E16-88956C51A565}.ReleaseSigned|x64.Build.0 = ReleaseSigned|x64\n\t\t{7AB0A246-AA1C-433B-9E16-88956C51A565}.ReleaseSigned|x64.Deploy.0 = ReleaseSigned|x64\n\t\t{EE63C42B-F401-4F55-ADBB-14C16BD3B18C}.Debug|ARM64.ActiveCfg = Debug|ARM64\n\t\t{EE63C42B-F401-4F55-ADBB-14C16BD3B18C}.Debug|ARM64.Build.0 = Debug|ARM64\n\t\t{EE63C42B-F401-4F55-ADBB-14C16BD3B18C}.Debug|ARM64.Deploy.0 = Debug|ARM64\n\t\t{EE63C42B-F401-4F55-ADBB-14C16BD3B18C}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{EE63C42B-F401-4F55-ADBB-14C16BD3B18C}.Debug|x64.Build.0 = Debug|x64\n\t\t{EE63C42B-F401-4F55-ADBB-14C16BD3B18C}.Debug|x64.Deploy.0 = Debug|x64\n\t\t{EE63C42B-F401-4F55-ADBB-14C16BD3B18C}.Release|ARM64.ActiveCfg = Release|ARM64\n\t\t{EE63C42B-F401-4F55-ADBB-14C16BD3B18C}.Release|ARM64.Build.0 = Release|ARM64\n\t\t{EE63C42B-F401-4F55-ADBB-14C16BD3B18C}.Release|ARM64.Deploy.0 = Release|ARM64\n\t\t{EE63C42B-F401-4F55-ADBB-14C16BD3B18C}.Release|x64.ActiveCfg = Release|x64\n\t\t{EE63C42B-F401-4F55-ADBB-14C16BD3B18C}.Release|x64.Build.0 = Release|x64\n\t\t{EE63C42B-F401-4F55-ADBB-14C16BD3B18C}.Release|x64.Deploy.0 = Release|x64\n\t\t{EE63C42B-F401-4F55-ADBB-14C16BD3B18C}.ReleaseSigned|ARM64.ActiveCfg = ReleaseSigned|ARM64\n\t\t{EE63C42B-F401-4F55-ADBB-14C16BD3B18C}.ReleaseSigned|ARM64.Build.0 = ReleaseSigned|ARM64\n\t\t{EE63C42B-F401-4F55-ADBB-14C16BD3B18C}.ReleaseSigned|ARM64.Deploy.0 = ReleaseSigned|ARM64\n\t\t{EE63C42B-F401-4F55-ADBB-14C16BD3B18C}.ReleaseSigned|x64.ActiveCfg = ReleaseSigned|x64\n\t\t{EE63C42B-F401-4F55-ADBB-14C16BD3B18C}.ReleaseSigned|x64.Build.0 = ReleaseSigned|x64\n\t\t{EE63C42B-F401-4F55-ADBB-14C16BD3B18C}.ReleaseSigned|x64.Deploy.0 = ReleaseSigned|x64\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\n\tGlobalSection(NestedProjects) = preSolution\n\t\t{87EFA31B-25EB-4944-A30A-300171BFFF57} = {2557B86E-6ED8-495A-B9A5-BF80CD5C4DAC}\n\t\t{FC08B706-5661-47FA-A840-053B06125750} = {2557B86E-6ED8-495A-B9A5-BF80CD5C4DAC}\n\t\t{AB3E45E7-C524-47C1-9677-728BA2A19344} = {2557B86E-6ED8-495A-B9A5-BF80CD5C4DAC}\n\t\t{7AB0A246-AA1C-433B-9E16-88956C51A565} = {2557B86E-6ED8-495A-B9A5-BF80CD5C4DAC}\n\t\t{EE63C42B-F401-4F55-ADBB-14C16BD3B18C} = {2557B86E-6ED8-495A-B9A5-BF80CD5C4DAC}\n\tEndGlobalSection\n\tGlobalSection(ExtensibilityGlobals) = postSolution\n\t\tSolutionGuid = {E8D62F4C-ADCF-4882-AA6B-CA7D97CB284B}\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "LICENSE-GPL.md",
    "content": "The GNU General Public License, Version 2, June 1991 (GPLv2)\n============================================================\n\n> Copyright (C) 1989, 1991 Free Software Foundation, Inc.\n> 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\n\nEveryone is permitted to copy and distribute verbatim copies of this license\ndocument, but changing it is not allowed.\n\n\nPreamble\n--------\n\nThe licenses for most software are designed to take away your freedom to share\nand change it. By contrast, the GNU General Public License is intended to\nguarantee your freedom to share and change free software--to make sure the\nsoftware is free for all its users. This General Public License applies to most\nof the Free Software Foundation's software and to any other program whose\nauthors commit to using it. (Some other Free Software Foundation software is\ncovered by the GNU Lesser General Public License instead.) You can apply it to\nyour programs, too.\n\nWhen we speak of free software, we are referring to freedom, not price. Our\nGeneral Public Licenses are designed to make sure that you have the freedom to\ndistribute copies of free software (and charge for this service if you wish),\nthat you receive source code or can get it if you want it, that you can change\nthe software or use pieces of it in new free programs; and that you know you can\ndo these things.\n\nTo protect your rights, we need to make restrictions that forbid anyone to deny\nyou these rights or to ask you to surrender the rights. These restrictions\ntranslate to certain responsibilities for you if you distribute copies of the\nsoftware, or if you modify it.\n\nFor example, if you distribute copies of such a program, whether gratis or for a\nfee, you must give the recipients all the rights that you have. You must make\nsure that they, too, receive or can get the source code. And you must show them\nthese terms so they know their rights.\n\nWe protect your rights with two steps: (1) copyright the software, and (2) offer\nyou this license which gives you legal permission to copy, distribute and/or\nmodify the software.\n\nAlso, for each author's protection and ours, we want to make certain that\neveryone understands that there is no warranty for this free software. If the\nsoftware is modified by someone else and passed on, we want its recipients to\nknow that what they have is not the original, so that any problems introduced by\nothers will not reflect on the original authors' reputations.\n\nFinally, any free program is threatened constantly by software patents. We wish\nto avoid the danger that redistributors of a free program will individually\nobtain patent licenses, in effect making the program proprietary. To prevent\nthis, we have made it clear that any patent must be licensed for everyone's free\nuse or not licensed at all.\n\nThe precise terms and conditions for copying, distribution and modification\nfollow.\n\n\nTerms And Conditions For Copying, Distribution And Modification\n---------------------------------------------------------------\n\n**0.** This License applies to any program or other work which contains a notice\nplaced by the copyright holder saying it may be distributed under the terms of\nthis General Public License. The \"Program\", below, refers to any such program or\nwork, and a \"work based on the Program\" means either the Program or any\nderivative work under copyright law: that is to say, a work containing the\nProgram or a portion of it, either verbatim or with modifications and/or\ntranslated into another language. (Hereinafter, translation is included without\nlimitation in the term \"modification\".) Each licensee is addressed as \"you\".\n\nActivities other than copying, distribution and modification are not covered by\nthis License; they are outside its scope. The act of running the Program is not\nrestricted, and the output from the Program is covered only if its contents\nconstitute a work based on the Program (independent of having been made by\nrunning the Program). Whether that is true depends on what the Program does.\n\n**1.** You may copy and distribute verbatim copies of the Program's source code\nas you receive it, in any medium, provided that you conspicuously and\nappropriately publish on each copy an appropriate copyright notice and\ndisclaimer of warranty; keep intact all the notices that refer to this License\nand to the absence of any warranty; and give any other recipients of the Program\na copy of this License along with the Program.\n\nYou may charge a fee for the physical act of transferring a copy, and you may at\nyour option offer warranty protection in exchange for a fee.\n\n**2.** You may modify your copy or copies of the Program or any portion of it,\nthus forming a work based on the Program, and copy and distribute such\nmodifications or work under the terms of Section 1 above, provided that you also\nmeet all of these conditions:\n\n*   **a)** You must cause the modified files to carry prominent notices stating\n    that you changed the files and the date of any change.\n\n*   **b)** You must cause any work that you distribute or publish, that in whole\n    or in part contains or is derived from the Program or any part thereof, to\n    be licensed as a whole at no charge to all third parties under the terms of\n    this License.\n\n*   **c)** If the modified program normally reads commands interactively when\n    run, you must cause it, when started running for such interactive use in the\n    most ordinary way, to print or display an announcement including an\n    appropriate copyright notice and a notice that there is no warranty (or\n    else, saying that you provide a warranty) and that users may redistribute\n    the program under these conditions, and telling the user how to view a copy\n    of this License. (Exception: if the Program itself is interactive but does\n    not normally print such an announcement, your work based on the Program is\n    not required to print an announcement.)\n\nThese requirements apply to the modified work as a whole. If identifiable\nsections of that work are not derived from the Program, and can be reasonably\nconsidered independent and separate works in themselves, then this License, and\nits terms, do not apply to those sections when you distribute them as separate\nworks. But when you distribute the same sections as part of a whole which is a\nwork based on the Program, the distribution of the whole must be on the terms of\nthis License, whose permissions for other licensees extend to the entire whole,\nand thus to each and every part regardless of who wrote it.\n\nThus, it is not the intent of this section to claim rights or contest your\nrights to work written entirely by you; rather, the intent is to exercise the\nright to control the distribution of derivative or collective works based on the\nProgram.\n\nIn addition, mere aggregation of another work not based on the Program with the\nProgram (or with a work based on the Program) on a volume of a storage or\ndistribution medium does not bring the other work under the scope of this\nLicense.\n\n**3.** You may copy and distribute the Program (or a work based on it, under\nSection 2) in object code or executable form under the terms of Sections 1 and 2\nabove provided that you also do one of the following:\n\n*   **a)** Accompany it with the complete corresponding machine-readable source\n    code, which must be distributed under the terms of Sections 1 and 2 above on\n    a medium customarily used for software interchange; or,\n\n*   **b)** Accompany it with a written offer, valid for at least three years, to\n    give any third party, for a charge no more than your cost of physically\n    performing source distribution, a complete machine-readable copy of the\n    corresponding source code, to be distributed under the terms of Sections 1\n    and 2 above on a medium customarily used for software interchange; or,\n\n*   **c)** Accompany it with the information you received as to the offer to\n    distribute corresponding source code. (This alternative is allowed only for\n    noncommercial distribution and only if you received the program in object\n    code or executable form with such an offer, in accord with Subsection b\n    above.)\n\nThe source code for a work means the preferred form of the work for making\nmodifications to it. For an executable work, complete source code means all the\nsource code for all modules it contains, plus any associated interface\ndefinition files, plus the scripts used to control compilation and installation\nof the executable. However, as a special exception, the source code distributed\nneed not include anything that is normally distributed (in either source or\nbinary form) with the major components (compiler, kernel, and so on) of the\noperating system on which the executable runs, unless that component itself\naccompanies the executable.\n\nIf distribution of executable or object code is made by offering access to copy\nfrom a designated place, then offering equivalent access to copy the source code\nfrom the same place counts as distribution of the source code, even though third\nparties are not compelled to copy the source along with the object code.\n\n**4.** You may not copy, modify, sublicense, or distribute the Program except as\nexpressly provided under this License. Any attempt otherwise to copy, modify,\nsublicense or distribute the Program is void, and will automatically terminate\nyour rights under this License. However, parties who have received copies, or\nrights, from you under this License will not have their licenses terminated so\nlong as such parties remain in full compliance.\n\n**5.** You are not required to accept this License, since you have not signed\nit. However, nothing else grants you permission to modify or distribute the\nProgram or its derivative works. These actions are prohibited by law if you do\nnot accept this License. Therefore, by modifying or distributing the Program (or\nany work based on the Program), you indicate your acceptance of this License to\ndo so, and all its terms and conditions for copying, distributing or modifying\nthe Program or works based on it.\n\n**6.** Each time you redistribute the Program (or any work based on the\nProgram), the recipient automatically receives a license from the original\nlicensor to copy, distribute or modify the Program subject to these terms and\nconditions. You may not impose any further restrictions on the recipients'\nexercise of the rights granted herein. You are not responsible for enforcing\ncompliance by third parties to this License.\n\n**7.** If, as a consequence of a court judgment or allegation of patent\ninfringement or for any other reason (not limited to patent issues), conditions\nare imposed on you (whether by court order, agreement or otherwise) that\ncontradict the conditions of this License, they do not excuse you from the\nconditions of this License. If you cannot distribute so as to satisfy\nsimultaneously your obligations under this License and any other pertinent\nobligations, then as a consequence you may not distribute the Program at all.\nFor example, if a patent license would not permit royalty-free redistribution of\nthe Program by all those who receive copies directly or indirectly through you,\nthen the only way you could satisfy both it and this License would be to refrain\nentirely from distribution of the Program.\n\nIf any portion of this section is held invalid or unenforceable under any\nparticular circumstance, the balance of the section is intended to apply and the\nsection as a whole is intended to apply in other circumstances.\n\nIt is not the purpose of this section to induce you to infringe any patents or\nother property right claims or to contest validity of any such claims; this\nsection has the sole purpose of protecting the integrity of the free software\ndistribution system, which is implemented by public license practices. Many\npeople have made generous contributions to the wide range of software\ndistributed through that system in reliance on consistent application of that\nsystem; it is up to the author/donor to decide if he or she is willing to\ndistribute software through any other system and a licensee cannot impose that\nchoice.\n\nThis section is intended to make thoroughly clear what is believed to be a\nconsequence of the rest of this License.\n\n**8.** If the distribution and/or use of the Program is restricted in certain\ncountries either by patents or by copyrighted interfaces, the original copyright\nholder who places the Program under this License may add an explicit\ngeographical distribution limitation excluding those countries, so that\ndistribution is permitted only in or among countries not thus excluded. In such\ncase, this License incorporates the limitation as if written in the body of this\nLicense.\n\n**9.** The Free Software Foundation may publish revised and/or new versions of\nthe General Public License from time to time. Such new versions will be similar\nin spirit to the present version, but may differ in detail to address new\nproblems or concerns.\n\nEach version is given a distinguishing version number. If the Program specifies\na version number of this License which applies to it and \"any later version\",\nyou have the option of following the terms and conditions either of that version\nor of any later version published by the Free Software Foundation. If the\nProgram does not specify a version number of this License, you may choose any\nversion ever published by the Free Software Foundation.\n\n**10.** If you wish to incorporate parts of the Program into other free programs\nwhose distribution conditions are different, write to the author to ask for\npermission. For software which is copyrighted by the Free Software Foundation,\nwrite to the Free Software Foundation; we sometimes make exceptions for this.\nOur decision will be guided by the two goals of preserving the free status of\nall derivatives of our free software and of promoting the sharing and reuse of\nsoftware generally.\n\n\nNo Warranty\n-----------\n\n**11.** BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR\nTHE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE\nSTATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM\n\"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,\nBUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A\nPARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE\nPROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF\nALL NECESSARY SERVICING, REPAIR OR CORRECTION.\n\n**12.** IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\nWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE\nTHE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY\nGENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR\nINABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA\nBEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A\nFAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER\nOR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.\n"
  },
  {
    "path": "LICENSE-MIT.md",
    "content": "The MIT License (MIT)\n=====================\n\nCopyright  `2018` `Bingxing Wang`\n\nPermission is hereby granted, free of charge, to any person\nobtaining a copy of this software and associated documentation\nfiles (the Software), to deal in the Software without\nrestriction, including without limitation the rights to use,\ncopy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the\nSoftware is furnished to do so, subject to the following\nconditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\nOF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\nHOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nWHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\nOTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "LICENSE.md",
    "content": "Dual-licensed project notice\n=====================\n\nCopyright 2018-2019, Bingxing Wang and other project contributors.\n\n- The USB PTP project, `AmtPtpDeviceUsbUm` and `AmtPtpDeviceUsbKm` are licensed under [GPLv2](LICENSE-GPL.md).\n- The SPI PTP project, `AmtPtpDeviceSpiKm` is licensed unser [MIT](LICENSE-MIT.md).\n"
  },
  {
    "path": "README.md",
    "content": "# Windows Precision Touchpad Implementation for Apple MacBook family/Magic Trackpad 2\n\n[![Build Status](https://ligstd.visualstudio.com/_apis/public/build/definitions/7694e0d0-94e3-4fd2-b39a-ecd261e1ba2e/22/badge)](https://ligstd.visualstudio.com/Apple%20PTP%20Trackpad/_build?definitionId=22)\n\nThis project implements Windows Precision Touchpad Protocol for Apple MacBook family/Magic Trackpad 2 on Windows 10. Both USB (traditional and T2), SPI and Bluetooth trackpads are supported.\n\n## Donation?\n\nA few people asked me why I removed donation. My current financial situation doesn't require me to accept donation for the budget of future development. If you are considering donation, please consider other meaningful projects and foundations, such as [Electronic Frontier Foundation](https://www.eff.org/).\n\n## Official Driver?\n\nBootcamp 6.1.5 offers official driver for T2-based model and Magic Trackpad 2. You can also consider using the official driver if you have such Mac. If you have an older model (e.g. MacBooks before 2018/2019), this is the only implementation for these models (yet). \n\n## Future Plans and feature tracking\n\nUse the [Azure DevOps Board](https://ligstd.visualstudio.com/Apple%20PTP%20Trackpad/_workitems/) to track feature and device support plans. Bug reports should go to Github issues.\n\n## See it in action (YouTube video)\n\n[![Watch the video](https://img.youtube.com/vi/-GWlfw7omdo/hqdefault.jpg)](https://youtu.be/-GWlfw7omdo)\n\n## Converged Installation Guide\n\n**IMPORTANT:** Given changes in Microsoft driver code signing policy, and the compliance need of EV certificate, CI auto builds beyond 2021/01/06 04:00AM EST will not be automatically signed with normal code signing certificate. These builds are still supposed via TestSigning, but not recommended for normal users. Proper WHQL and EV dual-signed packages will be released manually, which can be downloaded from the release page.\n\n0. Make sure you uninstalled `Trackpad++` completely if you have previously does so\n1. Go to the release tab in Github and download the newest version for your architecture\n2. Right click `AmtPtpDevice.inf` and install it\n3. If you have a Magic Trackpad 2 and want to use it in Bluetooth mode: manaully pair it in PC Settings.\n\n**Note: it is unnecessary to enable test signing, or install the certificate manually. Doing so may cause problems in installation. See [this issue](https://github.com/imbushuo/mac-precision-touchpad/issues/228#issuecomment-538689587) for detailed explanation.**\n\n## Also Uninstallation (extremely important for reinstallation `Trackpad++` and such)\n\nSee also [here](https://magicutilities.net/magic-trackpad/help/mac-precision-touchpad-driver-installed).\n\n1. Go to device manager\n2. Find the \"Apple Precision Touch Device\", \"Apple Multi-touch Trackpad HID filter\" and \"Apple Multi-touch Auxiliary Services\"\n3. Right click \"remove the device\" and also check \"uninstall driver\"\n4. Rescan devices\n\n## Installation with Chocolatey\n\nThe drivers are available as a [Chocolatey package](https://chocolatey.org/packages/mac-precision-touchpad/). To install using [Chocolatey](https://chocolatey.org) run:\n\n```\nchoco install mac-precision-touchpad\n```\n\n## For developers\n\n- SPI/T2 version is kernel-mode driver, using KMDF Framework v1.23. Bluetooth driver uses KMDF Framework 1.15. Windows 10 Driver Development Kit Version 2004 or higher is required for development and testing.\n- USB version is a user-mode driver, using UMDF Framework v2.15. Windows 10 Driver Development Kit Version 2004 or higher is required for development and testing.\n- `ReleaseSigned` configuration is reserved for production build only, and it will be rendered as unsigned if you attempt to build using that configuration. (Historically it's signed, but due to EV certificate's requirements, the process has changed.)\n\n## Device support\n\nThere is a bring-up issue for certain MacBook Pro and MacBook Air. I am looking into it. If you have such device with Windows installed, please contact me so I can look into the issue remotely (as I don't have many devices).\n\n- [x] Non-Retina MacBook \n- [x] Some non-Retina MacBook Pro (2011 and 2012)\n- [x] MacBook Pro with Retina Display (MacBookPro 10,1, MacBookPro10,2 & MacBookPro11,1)\n- [x] All recent MacBook Air (Please report if your model is not supported)\n- [x] MacBook Pro with Retina Display (2013, 2014, 2015, 13-inch & 15-inch)\n- [x] New MacBook (12-inch)\n- [x] MacBook Pro 2015, 2016, 2017 (a few SPI devices are in work-in-progress state)\n- [x] T2-based devices: MacBook Air 2018, MacBook Pro 2017/2018/2019/2020: Use default fallback, experience might not be optimal. Open a issue if you encountered dead touch regions.\n- [x] Magic Trackpad 2 & 3 (USB)\n- [x] Magic Trackpad 2 & 3 (Bluetooth connection)\n\n## Roadmap\n\n- [x] Touchpad Device Power Management\n- [x] Touchpad Protocol Stack Implementation\n- [x] Touchpad Raw Input Output (in Driver Trace)\n- [x] HID Protocol Implementation (PTP Touch)\n- [x] HID Protocol Implementation (Configuration)\n- [x] Device Test (Magic Trackpad 2)\n- [x] Refine input experience (tip switch detection and pressure)\n- [x] Refine input experience (gesture experience)\n- [x] More Models\n- [x] SPI\n- [x] KM Driver cross-cert\n- [x] Bluetooth\n- [ ] Defuzz\n- [ ] Input sensitivity configuration\n\n## Acknowledgements\n\n**UPDATE 2021/05**: She got an M1 Mac now.\n\nPeople familiar with me know that I don't use Apple MacBook (so development work of this driver occurs on a Surface Pro 4). People probably think it doesn't make sense that I started this project. The motivation behind this project origin from complaints from my girlfriend. Hearing about frequent complains about Dell XPS 13's touchpad (though it passed Precision Touchpad certification), I decided to start this project, so by the time she switches to MacBook Pro, she will have excellent touchpad experience out-of-box, even on Windows. This driver is made for you, but also for everyone.\n\nI would like to thank projects like [magictrackpad2-dkms](https://github.com/robbi5/magictrackpad2-dkms) and [macbook12-spi-driver](https://github.com/cb22/macbook12-spi-driver) that inspire me. I would also like to thank my friends for providing me immense help on devices and testing.\n \n## License\n\n- USB driver is licensed under [GPLv2](LICENSE-GPL.md).\n- SPI driver is licensed under [MIT](LICENSE-MIT.md).\n\n"
  },
  {
    "path": "es/New-CabinetFile.ps1",
    "content": " <#\n.SYNOPSIS\n    Creates a new cabinet .CAB file on disk.\n\n.DESCRIPTION\n    This cmdlet creates a new cabinet .CAB file using MAKECAB.EXE and adds\n    all the files specified to the cabinet file itself.\n\n.PARAMETER Name\n    The output file name of the cabinet .CAB file, such as MyNewCabinet.cab.\n    This should not be the entire file path, only the target file name.\n\n.PARAMETER Fil\n    One or more file references that are to be added to the cabinet .CAB file.\n    FileInfo objects (as generated by Get-Item etc) or strings can be passed\n    in via the pipeline to be added to the cabinet file.\n\n.PARAMETER DestinationPath\n    The output file path that the cabinet file will be saved in. It is also\n    used for resolving any ambiguous file references, i.e. any file passed in\n    via file name and not full path.\n\n    If not specified the current working directory is used for the output file\n    and attempting to resolve all ambiguous file references.\n\n.PARAMETER NoClobber\n    Will not overwrite of an existing file. By default, if a file exists in the\n    specified path, New-CabinetFile overwrites the file without warning.\n\n.EXAMPLE\n    New-CabinetFile -Name MyCabinet.cab -File \"File01.exe\",\"File02.txt\"\n    \n    This creates a new MyCabinet.cab file in the current directory and adds the File01.exe and File02.txt files to it, also from the current directory.\n.EXAMPLE\n    Get-ChildItem C:\\CabFile\\ | New-CabinetFile -Name MyCabinet.cab -DestinationPath C:\\Users\\UserA\\Documents\n\n    This creates a new C:\\Users\\UserA\\Documents\\MyCabinet.cab file and adds all files within the C:\\CabFile\\ directory into it.\n#>\nfunction New-CabinetFile {\n    [CmdletBinding()]\n    Param(\n        [Parameter(HelpMessage=\"Target .CAB file name.\", Position=0, Mandatory=$true, ValueFromPipelineByPropertyName=$true)]\n        [ValidateNotNullOrEmpty()]\n        [Alias(\"FilePath\")]\n        [string] $Name,\n\n        [Parameter(HelpMessage=\"Content directory to add to the .CAB.\", Position=1, Mandatory=$true, ValueFromPipeline=$false)]\n        [ValidateNotNullOrEmpty()]\n        [string[]] $ContentDirectory,\n\n\t[Parameter(HelpMessage=\"Default package directory path.\", Position=2, ValueFromPipelineByPropertyName=$true)]\n        [AllowNull()]\n        [string[]] $DestinationDir,\n\n        [Parameter(HelpMessage=\"Default intput/output path.\", Position=3, ValueFromPipelineByPropertyName=$true)]\n        [AllowNull()]\n        [string[]] $DestinationPath,\n\n        [Parameter(HelpMessage=\"Do not overwrite any existing .cab file.\")]\n        [Switch] $NoClobber\n        )\n\n    Begin { \n    \n        ## If $DestinationPath is blank, use the current directory by default\n        if ($DestinationPath -eq $null) { $DestinationPath = (Get-Location).Path; }\n        Write-Verbose \"New-CabinetFile using default path '$DestinationPath'.\";\n        Write-Verbose \"Creating target cabinet file '$(Join-Path $DestinationPath $Name)'.\";\n\n        ## Test the -NoClobber switch\n        if ($NoClobber) {\n            ## If file already exists then throw a terminating error\n            if (Test-Path -Path (Join-Path $DestinationPath $Name)) { throw \"Output file '$(Join-Path $DestinationPath $Name)' already exists.\"; }\n        }\n\n        ## Cab files require a directive file, see 'http://msdn.microsoft.com/en-us/library/bb417343.aspx#dir_file_syntax' for more info\n        $ddf = \";*** MakeCAB Directive file`r`n\";\n        $ddf += \";`r`n\";\n        $ddf += \".OPTION EXPLICIT`r`n\";\n        $ddf += \".Set CabinetNameTemplate=$Name`r`n\";\n        $ddf += \".Set DiskDirectory1=$DestinationPath`r`n\";\n        $ddf += \".Set MaxDiskSize=0`r`n\";\n\t$ddf += \".Set MaxDiskFileCount=0`r`n\";\n\t$ddf += \".Set FolderFileCountThreshold=0`r`n\";\n\t$ddf += \".Set FolderSizeThreshold=0`r`n\";\n\t$ddf += \".Set MaxCabinetSize=0`r`n\";\n\t$ddf += \".Set CompressionType=MSZIP`r`n\";\n        $ddf += \".Set Cabinet=on`r`n\";\n        $ddf += \".Set Compress=on`r`n\";\n        ## Redirect the auto-generated Setup.rpt and Setup.inf files to the temp directory\n        $ddf += \".Set RptFileName=$(Join-Path $ENV:TEMP \"setup.rpt\")`r`n\";\n        $ddf += \".Set InfFileName=$(Join-Path $ENV:TEMP \"setup.inf\")`r`n\";\n\t$ddf += \".Set DestinationDir=$DestinationDir`r`n\";\n\n        ## If -Verbose, echo the directive file\n        if ($PSCmdlet.MyInvocation.BoundParameters[\"Verbose\"].IsPresent) {\n            foreach ($ddfLine in $ddf -split [Environment]::NewLine) {\n                Write-Verbose $ddfLine;\n            }\n        }\n    }\n\n    Process {\n        $File = Get-ChildItem -Path $ContentDirectory\n   \n        ## Enumerate all the files add to the cabinet directive file\n        foreach ($fileToAdd in $File) {\n            Write-Verbose \"\"\"$($fileToAdd.FullName)\"\"\";\n            $ddf += \"\"\"$($fileToAdd.FullName)\"\"`r`n\";\n        }     \n    }\n\n    End {\n    \n        $ddfFile = Join-Path $DestinationPath \"$Name.ddf\";\n        $ddf | Out-File $ddfFile -Encoding ascii | Out-Null;\n\n        Write-Verbose \"Launching 'C:\\Windows\\system32\\makecab.exe /f \"\"$ddfFile\"\"'.\";\n        $makeCab = Invoke-Expression \"C:\\Windows\\system32\\makecab.exe /F \"\"$ddfFile\"\"\";\n\n        ## If Verbose, echo the MakeCab response/output\n        if ($PSCmdlet.MyInvocation.BoundParameters[\"Verbose\"].IsPresent) {\n            ## Recreate the output as Verbose output\n            foreach ($line in $makeCab -split [environment]::NewLine) {\n                if ($line.Contains(\"ERROR:\")) { throw $line; }\n                else { Write-Verbose $line; }\n            }\n        }\n\n        ## Delete the temporary .ddf file\n        Write-Verbose \"Deleting the directive file '$ddfFile'.\";\n        Remove-Item $ddfFile;\n\n        ## Return the newly created .CAB FileInfo object to the pipeline\n        Get-Item (Join-Path $DestinationPath $Name);\n    }\n} \n\n\n# SIG # Begin signature block\n# MIIiHgYJKoZIhvcNAQcCoIIiDzCCIgsCAQExDzANBglghkgBZQMEAgEFADB5Bgor\n# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG\n# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCCRCQB92A0VZQ1H\n# CrjdJBO3wNCibdvKCfaDDpqy7YVEv6CCEaEwggV+MIIEZqADAgECAhBn3vQ+8Xva\n# 4k/1lAYG0sCEMA0GCSqGSIb3DQEBDAUAMHsxCzAJBgNVBAYTAkdCMRswGQYDVQQI\n# DBJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAOBgNVBAcMB1NhbGZvcmQxGjAYBgNVBAoM\n# EUNvbW9kbyBDQSBMaW1pdGVkMSEwHwYDVQQDDBhBQUEgQ2VydGlmaWNhdGUgU2Vy\n# dmljZXMwHhcNMDQwMTAxMDAwMDAwWhcNMjgxMjMxMjM1OTU5WjCBhTELMAkGA1UE\n# BhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2Fs\n# Zm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9E\n# TyBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUA\n# A4ICDwAwggIKAoICAQCR6FSS0gpWsawNJN3Fz0RndJkrN6N9I3AAcbxT38T6KhKP\n# S38QVr2fcHK3YX/JSw8Xpz3jsARh7v8Rl8f0hj4K+j5c+ZPmNHrZFGvnnLOFoIJ6\n# dq9xkNfs/Q36nGz637CC9BR++b7Epi9Pf5l/tfxnQ3K9DADWietrLNPtj5gcFKt+\n# 5eNu/Nio5JIk2kNrYrhV/erBvGy2i/MOjZrkm2xpmfh4SDBF1a3hDTxFYPwyllEn\n# vGfDyi62a+pGx8cgoLEfZd5ICLqkTqnyg0Y3hOvozIFIQ2dOciqbXL1MGyiKXCJ7\n# tKuY2e7gUYPDCUZObT6Z+pUX2nwzV0E8jVHtC7ZcryxjGt9XyD+86V3Em69FmeKj\n# WiS0uqlWPc9vqv9JWL7wqP/0uK3pN/u6uPQLOvnoQ0IeidiEyxPx2bvhiWC4jChW\n# rBQdnArncevPDt09qZahSL0896+1DSJMwBGB7FY79tOi4lu3sgQiUpWAk2nojkxl\n# 8ZEDLXB0AuqLZxUpaVICu9ffUGpVRr+goyhhf3DQw6KqLCGqR84onAZFdr+CGCe0\n# 1a60y1Dma/RMhnEw6abfFobg2P9A3fvQQoh/ozM6LlweQRGBY84YcWsr7KaKtzFc\n# OmpH4MN5WdYgGq/yapiqcrxXStJLnbsQ/LBMQeXtHT1eKJ2czL+zUdqnR+WEUwID\n# AQABo4HyMIHvMB8GA1UdIwQYMBaAFKARCiM+lvEH7OKvKe+CpX/QMKS0MB0GA1Ud\n# DgQWBBS7r34CPfqm8TyEjq3uOJjs2TIy1DAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0T\n# AQH/BAUwAwEB/zARBgNVHSAECjAIMAYGBFUdIAAwQwYDVR0fBDwwOjA4oDagNIYy\n# aHR0cDovL2NybC5jb21vZG9jYS5jb20vQUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5j\n# cmwwNAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5jb21v\n# ZG9jYS5jb20wDQYJKoZIhvcNAQEMBQADggEBAH/yVjWwbZVKTnSvOuJvAYuH0zKX\n# 7fhA0ndTEdfHFi7GneZIVr6Aqfi8eNLIYxeujO0WMfofGMkOx+5IeZ/Hybm8zIgV\n# 42hh0Z8dS2GB11YEY8IIaSbw8OUv38AKK6kF9AJaaonXtIRClePr93YgXjXZwM0l\n# CBNMcTiOh7AzhJGZHpHxrJ4/px1ggSw2QVSg4kYGC6wbx5k2jF6hC6Se2UJGJMXF\n# W4GuraCg3J82uI3CHRX6iK2BEDkfRPArn90QVAwHNLE20RT9BwI9/3JVqyfWLIFB\n# cSmNQfRQVxp+ZWCvy8Uodpius6hTdovmIVJr6iHQhA5JTohT2pIu5x0IZtcwggX1\n# MIIE3aADAgECAhEAzhB+CIZCWs8DPSazYRw0CzANBgkqhkiG9w0BAQsFADCBkTEL\n# MAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE\n# BxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxNzA1BgNVBAMT\n# LkNPTU9ETyBSU0EgRXh0ZW5kZWQgVmFsaWRhdGlvbiBDb2RlIFNpZ25pbmcgQ0Ew\n# HhcNMjAwOTAzMDAwMDAwWhcNMjEwOTAzMjM1OTU5WjCB+TEQMA4GA1UEBRMHMjk0\n# NDU3MDETMBEGCysGAQQBgjc8AgEDEwJISzEdMBsGA1UEDxMUUHJpdmF0ZSBPcmdh\n# bml6YXRpb24xCzAJBgNVBAYTAkhLMRIwEAYDVQQHDAlIb25nIEtvbmcxGzAZBgNV\n# BAkMEkt3dW4gVG9uZywgS293bG9vbjEtMCsGA1UECQwkUm0gODMgMy9GIFlhdSBM\n# ZWUgQ3RyIDQ1IEhvaSBZdWVuIFJkMSEwHwYDVQQKDBhBcGVydHVyZSBTY2llbmNl\n# IExpbWl0ZWQxITAfBgNVBAMMGEFwZXJ0dXJlIFNjaWVuY2UgTGltaXRlZDCCASIw\n# DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANpH4ZmvIRFMLmWWKKkn187aPxTg\n# aIU6w0i8KjrUGA+eowWGAJLCr5Bt3zU9Q3IlAIs+SrvCn/soOADIl90qAg7Z4X57\n# GZUXtBm2LmtIRTFS1d8nTUL0GxRIJvfmv16rDGN/ZIHT7oRnZNqqvDNH0EJSSpPS\n# jULt+JCaIaEPr3ugURNXtUKlAMnc/TVprsZ/uOCfGqoNSzPfBb/Xo+tubb3NgChJ\n# 9vwY9NpuLyNwhTDnA4XD9HYDVWrpXSMuyMUw2tH/NevBD0uycdSeiEOL+QYafR+t\n# 8INUjRkAblsNVBkwv/SrhTFSKYuTaH91QomE118/W/XJmP6srrEKLM0Im+ECAwEA\n# AaOCAdwwggHYMB8GA1UdIwQYMBaAFN+P8yAM6cqmBNhbWDcqPatG3INJMB0GA1Ud\n# DgQWBBRsjK5AOHjIz7lAXUG7aRZD49Ns6jAOBgNVHQ8BAf8EBAMCB4AwDAYDVR0T\n# AQH/BAIwADATBgNVHSUEDDAKBggrBgEFBQcDAzARBglghkgBhvhCAQEEBAMCBBAw\n# SQYDVR0gBEIwQDA1BgwrBgEEAbIxAQIBBgEwJTAjBggrBgEFBQcCARYXaHR0cHM6\n# Ly9zZWN0aWdvLmNvbS9DUFMwBwYFZ4EMAQMwVQYDVR0fBE4wTDBKoEigRoZEaHR0\n# cDovL2NybC5jb21vZG9jYS5jb20vQ09NT0RPUlNBRXh0ZW5kZWRWYWxpZGF0aW9u\n# Q29kZVNpZ25pbmdDQS5jcmwwgYYGCCsGAQUFBwEBBHoweDBQBggrBgEFBQcwAoZE\n# aHR0cDovL2NydC5jb21vZG9jYS5jb20vQ09NT0RPUlNBRXh0ZW5kZWRWYWxpZGF0\n# aW9uQ29kZVNpZ25pbmdDQS5jcnQwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmNv\n# bW9kb2NhLmNvbTAlBgNVHREEHjAcoBoGCCsGAQUFBwgDoA4wDAwKSEstMjk0NDU3\n# MDANBgkqhkiG9w0BAQsFAAOCAQEAM5EqUWtJItHkyrMhjQpQ6UHr/jxpsCQoNqaE\n# 96LCP0mJxEyyS/00x+FiGwGKXZBUdS+JP77A2ndP6pcIS+sNlkoLag3KshBCzkHN\n# 8uLgPsHRRMExTNw5lNVHCURfQZeh94bNGPXpX8hpqrOL2rIjtQw01fo9qmsXymTU\n# LCFEh2hdGDM2SLG9rZ7qVgXa+Wd4IqLJ7Xk850guyf1eeTlza3WzZAzrqxWWLq3u\n# k5fHO2u34ggwBVjBpDbR7Ko7IMR/HrI/1GOVTY4OHZ3eP/jm5vpSvx3ThLegkFt0\n# R6Jw0kAvcwTqsw7DrJCJRnfX8TN9ojsP54vMvwWsXNoh24Fh7jCCBiIwggQKoAMC\n# AQICEG3UcusCrgQG492EP1/hReEwDQYJKoZIhvcNAQEMBQAwgYUxCzAJBgNVBAYT\n# AkdCMRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAOBgNVBAcTB1NhbGZv\n# cmQxGjAYBgNVBAoTEUNPTU9ETyBDQSBMaW1pdGVkMSswKQYDVQQDEyJDT01PRE8g\n# UlNBIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTE0MTIwMzAwMDAwMFoXDTI5\n# MTIwMjIzNTk1OVowgZExCzAJBgNVBAYTAkdCMRswGQYDVQQIExJHcmVhdGVyIE1h\n# bmNoZXN0ZXIxEDAOBgNVBAcTB1NhbGZvcmQxGjAYBgNVBAoTEUNPTU9ETyBDQSBM\n# aW1pdGVkMTcwNQYDVQQDEy5DT01PRE8gUlNBIEV4dGVuZGVkIFZhbGlkYXRpb24g\n# Q29kZSBTaWduaW5nIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA\n# iv29Q/A9yFUf81mK8Fq03JPRZBVKioSlLcsm+OBFOKO5AcVPEwhZ0DFUys2QYaM+\n# LPJNFVzU7sNqIpdI0QZDNAmZyc8wxJ9E/Vac7szng7mBzcjaCxwSSP9vouzEdcsJ\n# cM9R5buLn6q9eAZ9ldZhgfbaU8esnbMAuh7UvkBiCZmDPUXdTWWVBMz8+sdbeuIu\n# DD1VNVc1SImJ8rlWpUtQGxzemJC98y7ciKnxdZuoPqIF2UG173etF8Ba9aPbTZ/R\n# xLF7g7XuEJQrLnKuvu+VKZxSYsUsbSL3fUR6EF9jk2lN2X2ymrFOtVm//4X7vazs\n# 4Sum4yws6Nlu219NF3jLUwIDAQABo4IBfjCCAXowHwYDVR0jBBgwFoAUu69+Aj36\n# pvE8hI6t7jiY7NkyMtQwHQYDVR0OBBYEFN+P8yAM6cqmBNhbWDcqPatG3INJMA4G\n# A1UdDwEB/wQEAwIBhjASBgNVHRMBAf8ECDAGAQH/AgEAMBMGA1UdJQQMMAoGCCsG\n# AQUFBwMDMD4GA1UdIAQ3MDUwMwYEVR0gADArMCkGCCsGAQUFBwIBFh1odHRwczov\n# L3NlY3VyZS5jb21vZG8uY29tL0NQUzBMBgNVHR8ERTBDMEGgP6A9hjtodHRwOi8v\n# Y3JsLmNvbW9kb2NhLmNvbS9DT01PRE9SU0FDZXJ0aWZpY2F0aW9uQXV0aG9yaXR5\n# LmNybDBxBggrBgEFBQcBAQRlMGMwOwYIKwYBBQUHMAKGL2h0dHA6Ly9jcnQuY29t\n# b2RvY2EuY29tL0NPTU9ET1JTQUFkZFRydXN0Q0EuY3J0MCQGCCsGAQUFBzABhhho\n# dHRwOi8vb2NzcC5jb21vZG9jYS5jb20wDQYJKoZIhvcNAQEMBQADggIBAGZO7LcW\n# d28R6Btdak7Z8otssVYoQIvAMcSZSCM9+A7ogJfvbSALHxPEhvsXNBXhjlT3wrgA\n# cxXgKNnauvqCVML367/DNtAwn+WhHJTf73zo9ix4oqzPJmoVoRUx1jE0mL1TT8SE\n# g6PEllw92P7W+VT/Z5Nt+D4rayyiCHxWSIEyGLJurJDB2+TeOYuG5ccYQFmk35ZH\n# urJ/sfhXD4WAdDgOOlhiHv5S4+auUwmG/o+b21ZWzAewicEE8VMLbG937LIf7PZb\n# QENgDxurGFS0EASO+A7py4OxevI0TmpUTOmDKumwMCUczmKODuuF5in+sUrj8q48\n# kfVMob7IFw5cu0JN4xqKks0+IH7d6XWx6h90XJ5UwpQ3smHdBxZZf5aAFuCZtdJu\n# sMkjBhWs0SP0M4vOdfDBhtP/4S76kE/+Rvm720+7t/7RDSsE8dLRlYUsii64hVby\n# w4RSoekzsetQyKGwn+PDizqHnudV09NtNBcwDWgiC9W57XM1csPtpzfN40OuRc00\n# vyjKh2LtQ6Sv+ssxyyFYYUZetsZ6ph5TKqj4XFEfOloQDyjA5HSLdMYEqvhLJigK\n# MonbnSpgcWrDlk4WuWO/YZVnjEsuu7BOg+lNMeWOJyL1PCZ7RJHT1Frw03z0OL4U\n# mpkOi7Fb6uSLDxGdd0KCHFw61NqriC+NVzBUMYIP0zCCD88CAQEwgacwgZExCzAJ\n# BgNVBAYTAkdCMRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAOBgNVBAcT\n# B1NhbGZvcmQxGjAYBgNVBAoTEUNPTU9ETyBDQSBMaW1pdGVkMTcwNQYDVQQDEy5D\n# T01PRE8gUlNBIEV4dGVuZGVkIFZhbGlkYXRpb24gQ29kZSBTaWduaW5nIENBAhEA\n# zhB+CIZCWs8DPSazYRw0CzANBglghkgBZQMEAgEFAKB8MBAGCisGAQQBgjcCAQwx\n# AjAAMBkGCSqGSIb3DQEJAzEMBgorBgEEAYI3AgEEMBwGCisGAQQBgjcCAQsxDjAM\n# BgorBgEEAYI3AgEVMC8GCSqGSIb3DQEJBDEiBCAjxebzHD5YPMAKQpqHpwx+76aQ\n# a0jmJhb7cbUjUTbPdTANBgkqhkiG9w0BAQEFAASCAQCCAt2hgKDtfM+0OHweiT0s\n# JQ92TiwNq91vsGFtzYPbPfeJrfZSp6hDYqgeYdMOSqKLnQghUlDu5Hg+cL3INDjo\n# Nes0CXldNlIBv7cVBq/euacKxe4ihKomILBSPYKCS9dCsqBvGBIblfuXJ3Kz0S9Z\n# IlXiNvRwhz4GNCPeJfYgNxGabG/jZkjGfjJkWIKHmxuErwFWZnASQ9s2F1/tDvBE\n# T2XHjeikoNPA85X73Ivg9E6CzJe02jsZAoQqZyDCqIelxAiIHRHqqV20T868ypln\n# HHLr8nbxj9vcCVRAsZMow2bEhAoIpRLkNqIeghMfi8SEIoug3bCx4bqAwLZAf+6Q\n# oYINfjCCDXoGCisGAQQBgjcDAwExgg1qMIINZgYJKoZIhvcNAQcCoIINVzCCDVMC\n# AQMxDzANBglghkgBZQMEAgEFADB4BgsqhkiG9w0BCRABBKBpBGcwZQIBAQYJYIZI\n# AYb9bAcBMDEwDQYJYIZIAWUDBAIBBQAEIIUw89LmZyq9yuRiOCvCxSfW/yKPr9iv\n# djHHx7eqHD0YAhEAxV6DgaDoWwVUZz4s7WsA7xgPMjAyMTA3MTcyMDEyMzhaoIIK\n# NzCCBP4wggPmoAMCAQICEA1CSuC+Ooj/YEAhzhQA8N0wDQYJKoZIhvcNAQELBQAw\n# cjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQ\n# d3d3LmRpZ2ljZXJ0LmNvbTExMC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVk\n# IElEIFRpbWVzdGFtcGluZyBDQTAeFw0yMTAxMDEwMDAwMDBaFw0zMTAxMDYwMDAw\n# MDBaMEgxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjEgMB4G\n# A1UEAxMXRGlnaUNlcnQgVGltZXN0YW1wIDIwMjEwggEiMA0GCSqGSIb3DQEBAQUA\n# A4IBDwAwggEKAoIBAQDC5mGEZ8WK9Q0IpEXKY2tR1zoRQr0KdXVNlLQMULUmEP4d\n# yG+RawyW5xpcSO9E5b+bYc0VkWJauP9nC5xj/TZqgfop+N0rcIXeAhjzeG28ffnH\n# bQk9vmp2h+mKvfiEXR52yeTGdnY6U9HR01o2j8aj4S8bOrdh1nPsTm0zinxdRS1L\n# sVDmQTo3VobckyON91Al6GTm3dOPL1e1hyDrDo4s1SPa9E14RuMDgzEpSlwMMYpK\n# jIjF9zBa+RSvFV9sQ0kJ/SYjU/aNY+gaq1uxHTDCm2mCtNv8VlS8H6GHq756Wwog\n# L0sJyZWnjbL61mOLTqVyHO6fegFz+BnW/g1JhL0BAgMBAAGjggG4MIIBtDAOBgNV\n# HQ8BAf8EBAMCB4AwDAYDVR0TAQH/BAIwADAWBgNVHSUBAf8EDDAKBggrBgEFBQcD\n# CDBBBgNVHSAEOjA4MDYGCWCGSAGG/WwHATApMCcGCCsGAQUFBwIBFhtodHRwOi8v\n# d3d3LmRpZ2ljZXJ0LmNvbS9DUFMwHwYDVR0jBBgwFoAU9LbhIB3+Ka7S5GGlsqIl\n# ssgXNW4wHQYDVR0OBBYEFDZEho6kurBmvrwoLR1ENt3janq8MHEGA1UdHwRqMGgw\n# MqAwoC6GLGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9zaGEyLWFzc3VyZWQtdHMu\n# Y3JsMDKgMKAuhixodHRwOi8vY3JsNC5kaWdpY2VydC5jb20vc2hhMi1hc3N1cmVk\n# LXRzLmNybDCBhQYIKwYBBQUHAQEEeTB3MCQGCCsGAQUFBzABhhhodHRwOi8vb2Nz\n# cC5kaWdpY2VydC5jb20wTwYIKwYBBQUHMAKGQ2h0dHA6Ly9jYWNlcnRzLmRpZ2lj\n# ZXJ0LmNvbS9EaWdpQ2VydFNIQTJBc3N1cmVkSURUaW1lc3RhbXBpbmdDQS5jcnQw\n# DQYJKoZIhvcNAQELBQADggEBAEgc3LXpmiO85xrnIA6OZ0b9QnJRdAojR6OrktIl\n# xHBZvhSg5SeBpU0UFRkHefDRBMOG2Tu9/kQCZk3taaQP9rhwz2Lo9VFKeHk2eie3\n# 8+dSn5On7UOee+e03UEiifuHokYDTvz0/rdkd2NfI1Jpg4L6GlPtkMyNoRdzDfTz\n# ZTlwS/Oc1np72gy8PTLQG8v1Yfx1CAB2vIEO+MDhXM/EEXLnG2RJ2CKadRVC9S0y\n# OIHa9GCiurRS+1zgYSQlT7LfySmoc0NR2r1j1h9bm/cuG08THfdKDXF+l7f0P4Tr\n# weOjSaH6zqe/Vs+6WXZhiV9+p7SOZ3j5NpjhyyjaW4emii8wggUxMIIEGaADAgEC\n# AhAKoSXW1jIbfkHkBdo2l8IVMA0GCSqGSIb3DQEBCwUAMGUxCzAJBgNVBAYTAlVT\n# MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j\n# b20xJDAiBgNVBAMTG0RpZ2lDZXJ0IEFzc3VyZWQgSUQgUm9vdCBDQTAeFw0xNjAx\n# MDcxMjAwMDBaFw0zMTAxMDcxMjAwMDBaMHIxCzAJBgNVBAYTAlVTMRUwEwYDVQQK\n# EwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xMTAvBgNV\n# BAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJRCBUaW1lc3RhbXBpbmcgQ0EwggEi\n# MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC90DLuS82Pf92puoKZxTlUKFe2\n# I0rEDgdFM1EQfdD5fU1ofue2oPSNs4jkl79jIZCYvxO8V9PD4X4I1moUADj3Lh47\n# 7sym9jJZ/l9lP+Cb6+NGRwYaVX4LJ37AovWg4N4iPw7/fpX786O6Ij4YrBHk8JkD\n# bTuFfAnT7l3ImgtU46gJcWvgzyIQD3XPcXJOCq3fQDpct1HhoXkUxk0kIzBdvOw8\n# YGqsLwfM/fDqR9mIUF79Zm5WYScpiYRR5oLnRlD9lCosp+R1PrqYD4R/nzEU1q3V\n# 8mTLex4F0IQZchfxFwbvPc3WTe8GQv2iUypPhR3EHTyvz9qsEPXdrKzpVv+TAgMB\n# AAGjggHOMIIByjAdBgNVHQ4EFgQU9LbhIB3+Ka7S5GGlsqIlssgXNW4wHwYDVR0j\n# BBgwFoAUReuir/SSy4IxLVGLp6chnfNtyA8wEgYDVR0TAQH/BAgwBgEB/wIBADAO\n# BgNVHQ8BAf8EBAMCAYYwEwYDVR0lBAwwCgYIKwYBBQUHAwgweQYIKwYBBQUHAQEE\n# bTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wQwYIKwYB\n# BQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3Vy\n# ZWRJRFJvb3RDQS5jcnQwgYEGA1UdHwR6MHgwOqA4oDaGNGh0dHA6Ly9jcmw0LmRp\n# Z2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwOqA4oDaGNGh0\n# dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5j\n# cmwwUAYDVR0gBEkwRzA4BgpghkgBhv1sAAIEMCowKAYIKwYBBQUHAgEWHGh0dHBz\n# Oi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwCwYJYIZIAYb9bAcBMA0GCSqGSIb3DQEB\n# CwUAA4IBAQBxlRLpUYdWac3v3dp8qmN6s3jPBjdAhO9LhL/KzwMC/cWnww4gQiyv\n# d/MrHwwhWiq3BTQdaq6Z+CeiZr8JqmDfdqQ6kw/4stHYfBli6F6CJR7Euhx7LCHi\n# 1lssFDVDBGiy23UC4HLHmNY8ZOUfSBAYX4k4YU1iRiSHY4yRUiyvKYnleB/WCxSl\n# gNcSR3CzddWThZN+tpJn+1Nhiaj1a5bA9FhpDXzIAbG5KHW3mWOFIoxhynmUfln8\n# jA/jb7UBJrZspe6HUSHkWGCbugwtK22ixH67xCUrRwIIfEmuE7bhfEJCKMYYVs9B\n# NLZmXbZ0e/VWMyIvIjayS6JKldj1po5SMYIChjCCAoICAQEwgYYwcjELMAkGA1UE\n# BhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2lj\n# ZXJ0LmNvbTExMC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIFRpbWVz\n# dGFtcGluZyBDQQIQDUJK4L46iP9gQCHOFADw3TANBglghkgBZQMEAgEFAKCB0TAa\n# BgkqhkiG9w0BCQMxDQYLKoZIhvcNAQkQAQQwHAYJKoZIhvcNAQkFMQ8XDTIxMDcx\n# NzIwMTIzOFowKwYLKoZIhvcNAQkQAgwxHDAaMBgwFgQU4deCqOGRvu9ryhaRtaq0\n# lKYkm/MwLwYJKoZIhvcNAQkEMSIEIBi4VIMj/rgKAw2B5w6wOyyLTcgf6+XdUArV\n# h8qRoJ0dMDcGCyqGSIb3DQEJEAIvMSgwJjAkMCIEILMQkAa8CtmDB5FXKeBEA0Fc\n# g+MpK2FPJpZMjTVx7PWpMA0GCSqGSIb3DQEBAQUABIIBALhqaRM/3fVZszOSaYxc\n# 96Uswcj3YX2AyqwvZRoSY0ut7bCCc61FVMA6s0//Xgy3dGIjD/oqPH6TjYOO60Re\n# FzeEusomgXtzLW7dIkbLJ+k3KtkyYcu18uGlctTjI13xdP6icr22zGKzrC8YCkLm\n# GWu8gr4cBVNI/oVEWS4MWW3wvmNZNwh8gfZyr8gmLfSygSyxWtmjFyiYiYiTU/Lo\n# gBe+oQcWdRVkkCcqC60ON8a9Ew16qIIV1myCW3SjHRSHqKtZAmWtQDAU7eR8vOmD\n# m7aiwyEmYFovhQakstiMySWnQ5vSu3kHJG+pNmSJ6x9h9vDnj1GeLPUr9+KjqYaN\n# Y24=\n# SIG # End signature block\n"
  },
  {
    "path": "src/AmtPtpDevice.Settings/AmtPtpDevice.Settings.csproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"15.0\" DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <Import Project=\"$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props\" Condition=\"Exists('$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props')\" />\n  <PropertyGroup>\n    <Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>\n    <Platform Condition=\" '$(Platform)' == '' \">x86</Platform>\n    <ProjectGuid>{8FF9D2F4-EC60-4AAE-865D-F11D1B4DEC2F}</ProjectGuid>\n    <OutputType>AppContainerExe</OutputType>\n    <AppDesignerFolder>Properties</AppDesignerFolder>\n    <RootNamespace>AmtPtpDevice.Settings</RootNamespace>\n    <AssemblyName>AmtPtpDevice.Settings</AssemblyName>\n    <DefaultLanguage>en-US</DefaultLanguage>\n    <TargetPlatformIdentifier>UAP</TargetPlatformIdentifier>\n    <TargetPlatformVersion Condition=\" '$(TargetPlatformVersion)' == '' \">10.0.15063.0</TargetPlatformVersion>\n    <TargetPlatformMinVersion>10.0.15063.0</TargetPlatformMinVersion>\n    <MinimumVisualStudioVersion>14</MinimumVisualStudioVersion>\n    <FileAlignment>512</FileAlignment>\n    <ProjectTypeGuids>{A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>\n    <WindowsXamlEnableOverview>true</WindowsXamlEnableOverview>\n    <PackageCertificateKeyFile>AmtPtpDevice.Settings_TemporaryKey.pfx</PackageCertificateKeyFile>\n    <RuntimeIdentifiers>win10-arm;win10-arm-aot;win10-x86;win10-x86-aot;win10-x64;win10-x64-aot</RuntimeIdentifiers>\n    <AppxAutoIncrementPackageRevision>True</AppxAutoIncrementPackageRevision>\n    <AppxBundle>Always</AppxBundle>\n    <AppxBundlePlatforms>x86|x64|arm</AppxBundlePlatforms>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)' == 'Debug|x86'\">\n    <DebugSymbols>true</DebugSymbols>\n    <OutputPath>bin\\x86\\Debug\\</OutputPath>\n    <DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>\n    <NoWarn>;2008</NoWarn>\n    <DebugType>full</DebugType>\n    <PlatformTarget>x86</PlatformTarget>\n    <UseVSHostingProcess>false</UseVSHostingProcess>\n    <ErrorReport>prompt</ErrorReport>\n    <Prefer32Bit>true</Prefer32Bit>\n    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)' == 'Release|x86'\">\n    <OutputPath>bin\\x86\\Release\\</OutputPath>\n    <DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>\n    <Optimize>true</Optimize>\n    <NoWarn>;2008</NoWarn>\n    <DebugType>pdbonly</DebugType>\n    <PlatformTarget>x86</PlatformTarget>\n    <UseVSHostingProcess>false</UseVSHostingProcess>\n    <ErrorReport>prompt</ErrorReport>\n    <Prefer32Bit>true</Prefer32Bit>\n    <UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)' == 'Debug|ARM'\">\n    <DebugSymbols>true</DebugSymbols>\n    <OutputPath>bin\\ARM\\Debug\\</OutputPath>\n    <DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>\n    <NoWarn>;2008</NoWarn>\n    <DebugType>full</DebugType>\n    <PlatformTarget>ARM</PlatformTarget>\n    <UseVSHostingProcess>false</UseVSHostingProcess>\n    <ErrorReport>prompt</ErrorReport>\n    <Prefer32Bit>true</Prefer32Bit>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)' == 'Release|ARM'\">\n    <OutputPath>bin\\ARM\\Release\\</OutputPath>\n    <DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>\n    <Optimize>true</Optimize>\n    <NoWarn>;2008</NoWarn>\n    <DebugType>pdbonly</DebugType>\n    <PlatformTarget>ARM</PlatformTarget>\n    <UseVSHostingProcess>false</UseVSHostingProcess>\n    <ErrorReport>prompt</ErrorReport>\n    <Prefer32Bit>true</Prefer32Bit>\n    <UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)' == 'Debug|x64'\">\n    <DebugSymbols>true</DebugSymbols>\n    <OutputPath>bin\\x64\\Debug\\</OutputPath>\n    <DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>\n    <NoWarn>;2008</NoWarn>\n    <DebugType>full</DebugType>\n    <PlatformTarget>x64</PlatformTarget>\n    <UseVSHostingProcess>false</UseVSHostingProcess>\n    <ErrorReport>prompt</ErrorReport>\n    <Prefer32Bit>true</Prefer32Bit>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)' == 'Release|x64'\">\n    <OutputPath>bin\\x64\\Release\\</OutputPath>\n    <DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>\n    <Optimize>true</Optimize>\n    <NoWarn>;2008</NoWarn>\n    <DebugType>pdbonly</DebugType>\n    <PlatformTarget>x64</PlatformTarget>\n    <UseVSHostingProcess>false</UseVSHostingProcess>\n    <ErrorReport>prompt</ErrorReport>\n    <Prefer32Bit>true</Prefer32Bit>\n    <UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>\n  </PropertyGroup>\n  <ItemGroup>\n    <Compile Include=\"App.xaml.cs\">\n      <DependentUpon>App.xaml</DependentUpon>\n    </Compile>\n    <Compile Include=\"Comm\\UsbHidDeviceAccessSubscription.cs\" />\n    <Compile Include=\"DataObjects\\Mt2BatteryStatusReport.cs\" />\n    <Compile Include=\"DataObjects\\PtpUserModeConfReport.cs\" />\n    <Compile Include=\"MainPage.xaml.cs\">\n      <DependentUpon>MainPage.xaml</DependentUpon>\n    </Compile>\n    <Compile Include=\"Properties\\AssemblyInfo.cs\" />\n  </ItemGroup>\n  <ItemGroup>\n    <AppxManifest Include=\"Package.appxmanifest\">\n      <SubType>Designer</SubType>\n    </AppxManifest>\n    <None Include=\"AmtPtpDevice.Settings_TemporaryKey.pfx\" />\n  </ItemGroup>\n  <ItemGroup>\n    <Content Include=\"Properties\\Default.rd.xml\" />\n    <Content Include=\"Assets\\LockScreenLogo.scale-200.png\" />\n    <Content Include=\"Assets\\SplashScreen.scale-200.png\" />\n    <Content Include=\"Assets\\Square150x150Logo.scale-200.png\" />\n    <Content Include=\"Assets\\Square44x44Logo.scale-200.png\" />\n    <Content Include=\"Assets\\Square44x44Logo.targetsize-24_altform-unplated.png\" />\n    <Content Include=\"Assets\\StoreLogo.png\" />\n    <Content Include=\"Assets\\Wide310x150Logo.scale-200.png\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ApplicationDefinition Include=\"App.xaml\">\n      <Generator>MSBuild:Compile</Generator>\n      <SubType>Designer</SubType>\n    </ApplicationDefinition>\n    <Page Include=\"MainPage.xaml\">\n      <Generator>MSBuild:Compile</Generator>\n      <SubType>Designer</SubType>\n    </Page>\n  </ItemGroup>\n  <ItemGroup>\n    <PackageReference Include=\"Microsoft.NETCore.UniversalWindowsPlatform\">\n      <Version>5.4.2</Version>\n    </PackageReference>\n    <PackageReference Include=\"System.ValueTuple\">\n      <Version>4.4.0</Version>\n    </PackageReference>\n  </ItemGroup>\n  <ItemGroup />\n  <PropertyGroup Condition=\" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '14.0' \">\n    <VisualStudioVersion>14.0</VisualStudioVersion>\n  </PropertyGroup>\n  <Import Project=\"$(MSBuildExtensionsPath)\\Microsoft\\WindowsXaml\\v$(VisualStudioVersion)\\Microsoft.Windows.UI.Xaml.CSharp.targets\" />\n  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. \n       Other similar extension points exist, see Microsoft.Common.targets.\n  <Target Name=\"BeforeBuild\">\n  </Target>\n  <Target Name=\"AfterBuild\">\n  </Target>\n  -->\n</Project>"
  },
  {
    "path": "src/AmtPtpDevice.Settings/App.xaml",
    "content": "﻿<Application\n    x:Class=\"AmtPtpDevice.Settings.App\"\n    xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n    xmlns:local=\"using:AmtPtpDevice.Settings\"\n    RequestedTheme=\"Light\">\n\n</Application>\n"
  },
  {
    "path": "src/AmtPtpDevice.Settings/App.xaml.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Runtime.InteropServices.WindowsRuntime;\nusing Windows.ApplicationModel;\nusing Windows.ApplicationModel.Activation;\nusing Windows.Foundation;\nusing Windows.Foundation.Collections;\nusing Windows.UI.Xaml;\nusing Windows.UI.Xaml.Controls;\nusing Windows.UI.Xaml.Controls.Primitives;\nusing Windows.UI.Xaml.Data;\nusing Windows.UI.Xaml.Input;\nusing Windows.UI.Xaml.Media;\nusing Windows.UI.Xaml.Navigation;\n\nnamespace AmtPtpDevice.Settings\n{\n    /// <summary>\n    /// Provides application-specific behavior to supplement the default Application class.\n    /// </summary>\n    sealed partial class App : Application\n    {\n        /// <summary>\n        /// Initializes the singleton application object.  This is the first line of authored code\n        /// executed, and as such is the logical equivalent of main() or WinMain().\n        /// </summary>\n        public App()\n        {\n            this.InitializeComponent();\n            this.Suspending += OnSuspending;\n        }\n\n        /// <summary>\n        /// Invoked when the application is launched normally by the end user.  Other entry points\n        /// will be used such as when the application is launched to open a specific file.\n        /// </summary>\n        /// <param name=\"e\">Details about the launch request and process.</param>\n        protected override void OnLaunched(LaunchActivatedEventArgs e)\n        {\n            Frame rootFrame = Window.Current.Content as Frame;\n\n            // Do not repeat app initialization when the Window already has content,\n            // just ensure that the window is active\n            if (rootFrame == null)\n            {\n                // Create a Frame to act as the navigation context and navigate to the first page\n                rootFrame = new Frame();\n\n                rootFrame.NavigationFailed += OnNavigationFailed;\n\n                if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)\n                {\n                    //TODO: Load state from previously suspended application\n                }\n\n                // Place the frame in the current Window\n                Window.Current.Content = rootFrame;\n            }\n\n            if (e.PrelaunchActivated == false)\n            {\n                if (rootFrame.Content == null)\n                {\n                    // When the navigation stack isn't restored navigate to the first page,\n                    // configuring the new page by passing required information as a navigation\n                    // parameter\n                    rootFrame.Navigate(typeof(MainPage), e.Arguments);\n                }\n                // Ensure the current window is active\n                Window.Current.Activate();\n            }\n        }\n\n        /// <summary>\n        /// Invoked when Navigation to a certain page fails\n        /// </summary>\n        /// <param name=\"sender\">The Frame which failed navigation</param>\n        /// <param name=\"e\">Details about the navigation failure</param>\n        void OnNavigationFailed(object sender, NavigationFailedEventArgs e)\n        {\n            throw new Exception(\"Failed to load Page \" + e.SourcePageType.FullName);\n        }\n\n        /// <summary>\n        /// Invoked when application execution is being suspended.  Application state is saved\n        /// without knowing whether the application will be terminated or resumed with the contents\n        /// of memory still intact.\n        /// </summary>\n        /// <param name=\"sender\">The source of the suspend request.</param>\n        /// <param name=\"e\">Details about the suspend request.</param>\n        private void OnSuspending(object sender, SuspendingEventArgs e)\n        {\n            var deferral = e.SuspendingOperation.GetDeferral();\n            //TODO: Save application state and stop any background activity\n            deferral.Complete();\n        }\n    }\n}\n"
  },
  {
    "path": "src/AmtPtpDevice.Settings/Comm/UsbHidDeviceAccessSubscription.cs",
    "content": "﻿using System;\nusing System.Threading;\nusing Windows.Devices.Enumeration;\nusing Windows.Devices.HumanInterfaceDevice;\nusing Windows.Storage;\n\nnamespace AmtPtpDevice.Settings.Comm\n{\n    public class UsbHidDeviceAccessSubscription : IDisposable\n    {\n\n        private string m_deviceId;\n        private HidDevice m_device;\n        private int m_refCount;\n        private DeviceWatcher m_deviceWatcher;\n        private EventHandler m_targetDeviceAvailable;\n\n        public string AqsString { get; }\n        public HidDevice Device\n        {\n            get\n            {\n                return m_device;\n            }\n        }\n\n        public event EventHandler TargetDeviceAvailable\n        {\n            add\n            {\n                lock (m_targetDeviceAvailable)\n                {\n                    m_targetDeviceAvailable += value;\n                }\n\n                Interlocked.Increment(ref m_refCount);\n                m_deviceWatcher.Start();\n            }\n            remove\n            {\n                Interlocked.Decrement(ref m_refCount);\n                if (m_refCount == 0)\n                {\n                    m_deviceWatcher.Stop();\n                }\n\n                lock (m_targetDeviceAvailable)\n                {\n                    m_targetDeviceAvailable -= value;\n                }\n            }\n        }\n        public event EventHandler TargetDeviceLost;\n\n        public UsbHidDeviceAccessSubscription(string aqsString)\n        {\n            AqsString = aqsString;\n            m_device = null;\n            m_deviceId = null;\n            m_targetDeviceAvailable = new EventHandler((d, a) => { });\n            m_deviceWatcher = DeviceInformation.CreateWatcher(aqsString);\n            m_deviceWatcher.Added += SbDeviceAdded;\n            m_deviceWatcher.Removed += SbDeviceRemoved;\n        }\n\n        private void SbDeviceRemoved(DeviceWatcher sender, DeviceInformationUpdate args)\n        {\n            if (m_deviceId != args.Id) return;\n\n            try\n            {\n                m_device.Dispose();\n            }\n            finally\n            {\n                TargetDeviceLost?.Invoke(this, null);\n            }\n        }\n\n        private async void SbDeviceAdded(DeviceWatcher sender, DeviceInformation args)\n        {\n            m_device = await HidDevice.FromIdAsync(args.Id, FileAccessMode.ReadWrite);\n            m_deviceId = args.Id;\n            m_targetDeviceAvailable?.Invoke(this, null);\n        }\n\n        #region IDisposable Support\n        private bool disposedValue = false; // To detect redundant calls\n\n        protected virtual void Dispose(bool disposing)\n        {\n            if (!disposedValue)\n            {\n                if (disposing)\n                {\n                    m_deviceWatcher.Added -= SbDeviceAdded;\n                    m_deviceWatcher.Removed -= SbDeviceRemoved;\n                    m_deviceWatcher.Stop();\n                    m_device.Dispose();\n                }\n\n                m_deviceId = null;\n                m_deviceWatcher = null;\n                m_device = null;\n                disposedValue = true;\n            }\n        }\n\n        // This code added to correctly implement the disposable pattern.\n        public void Dispose()\n        {\n            // Do not change this code. Put cleanup code in Dispose(bool disposing) above.\n            Dispose(true);\n        }\n        #endregion\n\n    }\n}\n"
  },
  {
    "path": "src/AmtPtpDevice.Settings/DataObjects/Mt2BatteryStatusReport.cs",
    "content": "﻿using System.Runtime.InteropServices;\n\nnamespace AmtPtpDevice.Settings.DataObjects\n{\n    public struct Mt2BatteryStatusReport\n    {\n        public byte ReportId;\n        public byte BatteryFlags;\n        public byte ChargeStatus;\n    }\n}\n"
  },
  {
    "path": "src/AmtPtpDevice.Settings/DataObjects/PtpUserModeConfReport.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace AmtPtpDevice.Settings.DataObjects\n{\n    public struct PtpUserModeConfReport\n    {\n        public byte ReportId;\n        public byte PressureQualificationLevel;\n        public byte SingleContactSizeQualificationLevel;\n        public byte MultipleContactSizeQualificationLevel;\n    }\n}\n"
  },
  {
    "path": "src/AmtPtpDevice.Settings/MainPage.xaml",
    "content": "﻿<Page\n    x:Class=\"AmtPtpDevice.Settings.MainPage\"\n    xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n    xmlns:local=\"using:AmtPtpDevice.Settings\"\n    xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n    xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\"\n    mc:Ignorable=\"d\">\n\n    <Grid Background=\"{ThemeResource  ApplicationPageBackgroundThemeBrush}\">\n        <Grid.RowDefinitions>\n            <RowDefinition Height=\"48\" />\n            <RowDefinition />\n        </Grid.RowDefinitions>\n        <Grid Grid.Row=\"0\" Background=\"{ThemeResource AppBarBackground}\">\n            <TextBlock Margin=\"15,0,0,0\" VerticalAlignment=\"Center\"\n                Style=\"{StaticResource BaseTextBlockStyle}\">\n                <Run Typography.Capitals=\"AllPetiteCaps\">Input Settings</Run>\n            </TextBlock>\n        </Grid>\n        <StackPanel x:Name=\"m_deviceControl\" Margin=\"15,10\" Grid.Row=\"1\" Visibility=\"Collapsed\">\n            <TextBlock x:Name=\"m_battStatus\" Margin=\"0,0,0,10\"\n                    Style=\"{StaticResource BaseTextBlockStyle}\"  />\n            <Slider x:Name=\"m_sensitivitySlider\" \n                    Minimum=\"0\" Maximum=\"20\" \n                    ValueChanged=\"OnSliderValueChanged\"\n                    Header=\"Touch sensitivity\" />\n            <Slider x:Name=\"m_confidenceSlider\" \n                    Minimum=\"0\" Maximum=\"25\" \n                    ValueChanged=\"OnConfidenceSliderValueChanged\"\n                    Header=\"Single finger confidence threshold\" />\n            <Slider x:Name=\"m_muConfidenceSlider\" \n                    Minimum=\"0\" Maximum=\"25\" \n                    ValueChanged=\"OnMuConfidenceSliderValueChanged\"\n                    Header=\"Multiple finger confidence threshold\" />\n            <HyperlinkButton Margin=\"0,10,0,0\" \n                    Click=\"OnGestureButtonClicked\"\n                    Content=\"Gesture settings\" />\n            <TextBlock Style=\"{StaticResource BodyTextBlockStyle}\"\n                    Text=\"Note: Settings won't be persisted for debug purpose. To reset values, unplug and plug in your trackpad.\" />\n        </StackPanel>\n        <StackPanel x:Name=\"m_disconnctedView\" Margin=\"15,10\" Grid.Row=\"1\">\n            <TextBlock Margin=\"0,0,0,10\"\n                       Text=\"Please connect your device and continue.\"\n                       Style=\"{StaticResource BaseTextBlockStyle}\"  />\n        </StackPanel>\n    </Grid>\n</Page>\n"
  },
  {
    "path": "src/AmtPtpDevice.Settings/MainPage.xaml.cs",
    "content": "﻿using AmtPtpDevice.Settings.Comm;\nusing AmtPtpDevice.Settings.DataObjects;\nusing System;\nusing System.Linq;\nusing System.Runtime.InteropServices;\nusing System.Runtime.InteropServices.WindowsRuntime;\nusing Windows.Devices.HumanInterfaceDevice;\nusing Windows.Foundation;\nusing Windows.Foundation.Metadata;\nusing Windows.Storage.Streams;\nusing Windows.System;\nusing Windows.UI.Core;\nusing Windows.UI.ViewManagement;\nusing Windows.UI.Xaml;\nusing Windows.UI.Xaml.Controls;\nusing Windows.UI.Xaml.Media;\n\nnamespace AmtPtpDevice.Settings\n{\n    public sealed partial class MainPage : Page\n    {\n        private PtpUserModeConfReport m_report;\n        private bool m_isInitialDataPresented = false;\n        private UsbHidDeviceAccessSubscription m_inputDevice;\n        private UsbHidDeviceAccessSubscription m_battery;\n\n        public MainPage()\n        {\n            this.InitializeComponent();\n            ApplicationView.GetForCurrentView().SetPreferredMinSize(new Size(480, 500));\n            ApplicationView.PreferredLaunchViewSize = new Size(480, 500);\n            ApplicationView.PreferredLaunchWindowingMode = ApplicationViewWindowingMode.PreferredLaunchViewSize;\n\n            this.Loaded += OnPageLoaded;\n        }\n\n        private void OnPageLoaded(object sender, RoutedEventArgs e)\n        {\n            SetupWatcher();\n\n            if (ApiInformation.IsTypePresent(\"Windows.UI.ViewManagement.ApplicationView\"))\n            {\n                var titleBar = ApplicationView.GetForCurrentView().TitleBar;\n                if (titleBar != null)\n                {\n                    titleBar.ButtonBackgroundColor = titleBar.ButtonInactiveBackgroundColor \n                        = ((SolidColorBrush) Resources[\"AppBarBackground\"]).Color;\n                    titleBar.ButtonForegroundColor = ((SolidColorBrush) Resources[\"ApplicationForegroundThemeBrush\"]).Color;\n                    titleBar.BackgroundColor = titleBar.InactiveBackgroundColor \n                        = ((SolidColorBrush) Resources[\"AppBarBackground\"]).Color;\n                    titleBar.ForegroundColor = ((SolidColorBrush) Resources[\"ApplicationForegroundThemeBrush\"]).Color;\n                }\n            }\n        }\n\n        private void SetupWatcher()\n        {\n            m_inputDevice = new UsbHidDeviceAccessSubscription(HidDevice.GetDeviceSelector(0xff00, 0x0001, 0x05ac, 0x0265));\n            m_battery = new UsbHidDeviceAccessSubscription(HidDevice.GetDeviceSelector(0xff00, 0x0014, 0x05ac, 0x0265));\n\n            m_inputDevice.TargetDeviceAvailable += OnInputDeviceAvailable;\n            m_inputDevice.TargetDeviceLost += OnInputDeviceLost;\n            m_battery.TargetDeviceAvailable += OnBatteryAvailable;\n        }\n\n        private async void OnBatteryAvailable(object sender, EventArgs e)\n        {\n            var bReport = await m_battery.Device.GetInputReportAsync(0x90);\n            var ptr = Marshal.AllocHGlobal((int) bReport.Data.Length);\n            Marshal.Copy(bReport.Data.ToArray(), 0, ptr, (int) bReport.Data.Length);\n\n            var battReport = Marshal.PtrToStructure<Mt2BatteryStatusReport>(ptr);\n            await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>\n            {\n                m_battStatus.Text = $\"Battery is {battReport.ChargeStatus}% charged.\";\n            });\n\n            Marshal.FreeHGlobal(ptr);\n        }\n\n        private async void OnInputDeviceLost(object sender, EventArgs e)\n        {\n            await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>\n            {\n                // Set visibility\n                m_disconnctedView.Visibility = Visibility.Visible;\n                m_deviceControl.Visibility = Visibility.Collapsed;\n                // Set state\n                m_isInitialDataPresented = false;\n            });\n        }\n\n        private async void OnInputDeviceAvailable(object sender, EventArgs e)\n        {\n            var sReport = await m_inputDevice.Device.GetFeatureReportAsync(0x09);\n            var ptr = Marshal.AllocHGlobal((int)sReport.Data.Length);\n            Marshal.Copy(sReport.Data.ToArray(), 0, ptr, (int)sReport.Data.Length);\n\n            m_report = Marshal.PtrToStructure<PtpUserModeConfReport>(ptr);\n            await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>\n            {\n                // Set value\n                m_sensitivitySlider.Value = m_report.PressureQualificationLevel;\n                m_confidenceSlider.Value = m_report.SingleContactSizeQualificationLevel;\n                m_muConfidenceSlider.Value = m_report.MultipleContactSizeQualificationLevel;\n\n                // Set visibility\n                m_disconnctedView.Visibility = Visibility.Collapsed;\n                m_deviceControl.Visibility = Visibility.Visible;\n\n                // Set state\n                m_isInitialDataPresented = true;\n            });\n\n            Marshal.FreeHGlobal(ptr);\n        }\n\n        private async void ApplySettings()\n        {\n            if (m_inputDevice.Device == null || !m_isInitialDataPresented) return;\n\n            m_report.PressureQualificationLevel = (byte) m_sensitivitySlider.Value;\n            m_report.SingleContactSizeQualificationLevel = (byte) m_confidenceSlider.Value;\n            m_report.MultipleContactSizeQualificationLevel = (byte) m_muConfidenceSlider.Value;\n\n            var featureReport = m_inputDevice.Device.CreateFeatureReport(0x09);\n            using (var datawriter = new DataWriter())\n            {\n                datawriter.WriteByte(0x09);\n                datawriter.WriteByte(m_report.PressureQualificationLevel);\n                datawriter.WriteByte(m_report.SingleContactSizeQualificationLevel);\n                datawriter.WriteByte(m_report.MultipleContactSizeQualificationLevel);\n                featureReport.Data = datawriter.DetachBuffer();\n                await m_inputDevice.Device.SendFeatureReportAsync(featureReport);\n            }\n        }\n\n        private async void OnGestureButtonClicked(object sender, RoutedEventArgs e)\n        {\n            await Launcher.LaunchUriAsync(new Uri(\"ms-settings:devices-touchpad\"));\n        }\n\n        private void OnSliderValueChanged(object sender, Windows.UI.Xaml.Controls.Primitives.RangeBaseValueChangedEventArgs e)\n        {\n            ApplySettings();\n        }\n\n        private void OnConfidenceSliderValueChanged(object sender, Windows.UI.Xaml.Controls.Primitives.RangeBaseValueChangedEventArgs e)\n        {\n            ApplySettings();\n        }\n\n        private void OnMuConfidenceSliderValueChanged(object sender, Windows.UI.Xaml.Controls.Primitives.RangeBaseValueChangedEventArgs e)\n        {\n            ApplySettings();\n        }\n    }\n}\n"
  },
  {
    "path": "src/AmtPtpDevice.Settings/Package.appxmanifest",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Package xmlns=\"http://schemas.microsoft.com/appx/manifest/foundation/windows10\" xmlns:mp=\"http://schemas.microsoft.com/appx/2014/phone/manifest\" xmlns:uap=\"http://schemas.microsoft.com/appx/manifest/uap/windows10\" IgnorableNamespaces=\"uap mp\">\n  <Identity Name=\"4dbffcf3-8ff3-459b-95e8-64691ffade0a\" Publisher=\"CN=imbushuo\" Version=\"1.0.0.0\" />\n  <mp:PhoneIdentity PhoneProductId=\"4dbffcf3-8ff3-459b-95e8-64691ffade0a\" PhonePublisherId=\"00000000-0000-0000-0000-000000000000\" />\n  <Properties>\n    <DisplayName>AmtPtpDevice.Settings</DisplayName>\n    <PublisherDisplayName>imbushuo</PublisherDisplayName>\n    <Logo>Assets\\StoreLogo.png</Logo>\n  </Properties>\n  <Dependencies>\n    <TargetDeviceFamily Name=\"Windows.Universal\" MinVersion=\"10.0.0.0\" MaxVersionTested=\"10.0.0.0\" />\n  </Dependencies>\n  <Resources>\n    <Resource Language=\"x-generate\" />\n  </Resources>\n  <Applications>\n    <Application Id=\"App\" Executable=\"$targetnametoken$.exe\" EntryPoint=\"AmtPtpDevice.Settings.App\">\n      <uap:VisualElements DisplayName=\"Magic Trackpad Settings\" Square150x150Logo=\"Assets\\Square150x150Logo.png\" Square44x44Logo=\"Assets\\Square44x44Logo.png\" Description=\"Apple Magic Trackpad 2 Settings App\" BackgroundColor=\"transparent\">\n        <uap:DefaultTile Wide310x150Logo=\"Assets\\Wide310x150Logo.png\" ShortName=\"Magic Trackpad Settings\">\n        </uap:DefaultTile>\n        <uap:SplashScreen Image=\"Assets\\SplashScreen.png\" />\n      </uap:VisualElements>\n    </Application>\n  </Applications>\n  <Capabilities>\n    <Capability Name=\"internetClient\" />\n    <DeviceCapability Name=\"humaninterfacedevice\">\n      <Device Id=\"vidpid:05ac 0265\">\n        <!-- Input experience settings -->\n        <Function Type=\"usage:FF00 0001\" />\n        <!-- Battery information -->\n        <Function Type=\"usage:FF00 0014\" />\n      </Device>\n    </DeviceCapability>\n  </Capabilities>\n</Package>"
  },
  {
    "path": "src/AmtPtpDevice.Settings/Properties/AssemblyInfo.cs",
    "content": "﻿using System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n// General Information about an assembly is controlled through the following \n// set of attributes. Change these attribute values to modify the information\n// associated with an assembly.\n[assembly: AssemblyTitle(\"AmtPtpDevice.Settings\")]\n[assembly: AssemblyDescription(\"\")]\n[assembly: AssemblyConfiguration(\"\")]\n[assembly: AssemblyCompany(\"\")]\n[assembly: AssemblyProduct(\"AmtPtpDevice.Settings\")]\n[assembly: AssemblyCopyright(\"Copyright ©  2017\")]\n[assembly: AssemblyTrademark(\"\")]\n[assembly: AssemblyCulture(\"\")]\n\n// Version information for an assembly consists of the following four values:\n//\n//      Major Version\n//      Minor Version \n//      Build Number\n//      Revision\n//\n// You can specify all the values or you can default the Build and Revision Numbers \n// by using the '*' as shown below:\n// [assembly: AssemblyVersion(\"1.0.*\")]\n[assembly: AssemblyVersion(\"1.0.0.0\")]\n[assembly: AssemblyFileVersion(\"1.0.0.0\")]\n[assembly: ComVisible(false)]"
  },
  {
    "path": "src/AmtPtpDevice.Settings/Properties/Default.rd.xml",
    "content": "<!--\n    This file contains Runtime Directives used by .NET Native. The defaults here are suitable for most\n    developers. However, you can modify these parameters to modify the behavior of the .NET Native\n    optimizer.\n\n    Runtime Directives are documented at https://go.microsoft.com/fwlink/?LinkID=391919\n\n    To fully enable reflection for App1.MyClass and all of its public/private members\n    <Type Name=\"App1.MyClass\" Dynamic=\"Required All\"/>\n\n    To enable dynamic creation of the specific instantiation of AppClass<T> over System.Int32\n    <TypeInstantiation Name=\"App1.AppClass\" Arguments=\"System.Int32\" Activate=\"Required Public\" />\n\n    Using the Namespace directive to apply reflection policy to all the types in a particular namespace\n    <Namespace Name=\"DataClasses.ViewModels\" Serialize=\"All\" />\n-->\n\n<Directives xmlns=\"http://schemas.microsoft.com/netfx/2013/01/metadata\">\n  <Application>\n    <!--\n      An Assembly element with Name=\"*Application*\" applies to all assemblies in\n      the application package. The asterisks are not wildcards.\n    -->\n    <Assembly Name=\"*Application*\" Dynamic=\"Required All\" />\n    \n    \n    <!-- Add your application specific runtime directives here. -->\n\n\n  </Application>\n</Directives>"
  },
  {
    "path": "src/AmtPtpDeviceSpiKm/AmtPtpDeviceSpiKm.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"12.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"ReleaseSigned|ARM64\">\n      <Configuration>ReleaseSigned</Configuration>\n      <Platform>ARM64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"ReleaseSigned|x64\">\n      <Configuration>ReleaseSigned</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|ARM64\">\n      <Configuration>Debug</Configuration>\n      <Platform>ARM64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|ARM64\">\n      <Configuration>Release</Configuration>\n      <Platform>ARM64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <ItemGroup>\n    <ClCompile Include=\"Device.c\" />\n    <ClCompile Include=\"Driver.c\" />\n    <ClCompile Include=\"Hid.c\" />\n    <ClCompile Include=\"Input.c\" />\n    <ClCompile Include=\"Queue.c\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"AppleDefinition.h\" />\n    <ClInclude Include=\"Device.h\" />\n    <ClInclude Include=\"Driver.h\" />\n    <ClInclude Include=\"Hid.h\" />\n    <ClInclude Include=\"HidCommon.h\" />\n    <ClInclude Include=\"HID\\SpiTrackpadSeries1.h\" />\n    <ClInclude Include=\"HID\\SpiTrackpadSeries2.h\" />\n    <ClInclude Include=\"HID\\SpiTrackpadSeries3.h\" />\n    <ClInclude Include=\"Input.h\" />\n    <ClInclude Include=\"Public.h\" />\n    <ClInclude Include=\"Queue.h\" />\n    <ClInclude Include=\"Trace.h\" />\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{FC08B706-5661-47FA-A840-053B06125750}</ProjectGuid>\n    <TemplateGuid>{497e31cb-056b-4f31-abb8-447fd55ee5a5}</TemplateGuid>\n    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>\n    <MinimumVisualStudioVersion>12.0</MinimumVisualStudioVersion>\n    <Configuration>Debug</Configuration>\n    <Platform Condition=\"'$(Platform)' == ''\">Win32</Platform>\n    <RootNamespace>AmtPtpDeviceSpiKm</RootNamespace>\n  </PropertyGroup>\n  <!-- They told me this: https://help.github.com/en/articles/software-in-virtual-environments-for-github-actions#windows-server-2019 -->\n  <PropertyGroup>\n    <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(BuildEnvironment)'=='Github'\">\n    <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <TargetVersion>Windows10</TargetVersion>\n    <UseDebugLibraries>true</UseDebugLibraries>\n    <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>\n    <ConfigurationType>Driver</ConfigurationType>\n    <DriverType>KMDF</DriverType>\n    <DriverTargetPlatform>Universal</DriverTargetPlatform>\n    <_NT_TARGET_VERSION>0xA000004</_NT_TARGET_VERSION>\n    <KMDF_VERSION_MAJOR>1</KMDF_VERSION_MAJOR>\n    <KMDF_VERSION_MINOR>23</KMDF_VERSION_MINOR>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <TargetVersion>Windows10</TargetVersion>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>\n    <ConfigurationType>Driver</ConfigurationType>\n    <DriverType>KMDF</DriverType>\n    <DriverTargetPlatform>Universal</DriverTargetPlatform>\n    <_NT_TARGET_VERSION>0xA000004</_NT_TARGET_VERSION>\n    <KMDF_VERSION_MAJOR>1</KMDF_VERSION_MAJOR>\n    <KMDF_VERSION_MINOR>23</KMDF_VERSION_MINOR>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseSigned|x64'\" Label=\"Configuration\">\n    <TargetVersion>Windows10</TargetVersion>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>\n    <ConfigurationType>Driver</ConfigurationType>\n    <DriverType>KMDF</DriverType>\n    <DriverTargetPlatform>Universal</DriverTargetPlatform>\n    <_NT_TARGET_VERSION>0xA000004</_NT_TARGET_VERSION>\n    <KMDF_VERSION_MAJOR>1</KMDF_VERSION_MAJOR>\n    <KMDF_VERSION_MINOR>23</KMDF_VERSION_MINOR>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\" Label=\"Configuration\">\n    <TargetVersion>Windows10</TargetVersion>\n    <UseDebugLibraries>true</UseDebugLibraries>\n    <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>\n    <ConfigurationType>Driver</ConfigurationType>\n    <DriverType>KMDF</DriverType>\n    <DriverTargetPlatform>Universal</DriverTargetPlatform>\n    <_NT_TARGET_VERSION>0xA000004</_NT_TARGET_VERSION>\n    <KMDF_VERSION_MAJOR>1</KMDF_VERSION_MAJOR>\n    <KMDF_VERSION_MINOR>23</KMDF_VERSION_MINOR>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\" Label=\"Configuration\">\n    <TargetVersion>Windows10</TargetVersion>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>\n    <ConfigurationType>Driver</ConfigurationType>\n    <DriverType>KMDF</DriverType>\n    <DriverTargetPlatform>Universal</DriverTargetPlatform>\n    <_NT_TARGET_VERSION>0xA000004</_NT_TARGET_VERSION>\n    <KMDF_VERSION_MAJOR>1</KMDF_VERSION_MAJOR>\n    <KMDF_VERSION_MINOR>23</KMDF_VERSION_MINOR>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseSigned|ARM64'\" Label=\"Configuration\">\n    <TargetVersion>Windows10</TargetVersion>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>\n    <ConfigurationType>Driver</ConfigurationType>\n    <DriverType>KMDF</DriverType>\n    <DriverTargetPlatform>Universal</DriverTargetPlatform>\n    <_NT_TARGET_VERSION>0xA000004</_NT_TARGET_VERSION>\n    <KMDF_VERSION_MAJOR>1</KMDF_VERSION_MAJOR>\n    <KMDF_VERSION_MINOR>23</KMDF_VERSION_MINOR>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup />\n  <!-- For release signed config on Azure pipeline, CI pipeline don't sign it. We do that locally -->\n  <PropertyGroup Condition=\"'$(Configuration)'=='ReleaseSigned'\">\n    <TimeStampServer>http://timestamp.digicert.com</TimeStampServer>\n    <ProductionCertificate>$(ProductionCertPath)</ProductionCertificate>\n    <SignMode Condition=\"'$(BuildEnvironment)'!='AzurePipeline'\">ProductionSign</SignMode>\n    <SignMode Condition=\"'$(BuildEnvironment)'=='AzurePipeline'\">Off</SignMode>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>\n    <OutDir>$(SolutionDir)build\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\</OutDir>\n    <IntDir>$(SolutionDir)intermediate\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\</IntDir>\n    <IncludePath>$(SolutionDir)intermediate\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\;$(IncludePath)</IncludePath>\n    <TimeStampServer>http://timestamp.digicert.com</TimeStampServer>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>\n    <OutDir>$(SolutionDir)build\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\</OutDir>\n    <IntDir>$(SolutionDir)intermediate\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\</IntDir>\n    <IncludePath>$(SolutionDir)intermediate\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\;$(IncludePath)</IncludePath>\n    <TimeStampServer>http://timestamp.digicert.com</TimeStampServer>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseSigned|x64'\">\n    <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>\n    <OutDir>$(SolutionDir)build\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\</OutDir>\n    <IntDir>$(SolutionDir)intermediate\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\</IntDir>\n    <IncludePath>$(SolutionDir)intermediate\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\;$(IncludePath)</IncludePath>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">\n    <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>\n    <OutDir>$(SolutionDir)build\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\</OutDir>\n    <IntDir>$(SolutionDir)intermediate\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\</IntDir>\n    <IncludePath>$(SolutionDir)intermediate\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\;$(IncludePath)</IncludePath>\n    <TimeStampServer>http://timestamp.digicert.com</TimeStampServer>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">\n    <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>\n    <OutDir>$(SolutionDir)build\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\</OutDir>\n    <IntDir>$(SolutionDir)intermediate\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\</IntDir>\n    <IncludePath>$(SolutionDir)intermediate\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\;$(IncludePath)</IncludePath>\n    <TimeStampServer>http://timestamp.digicert.com</TimeStampServer>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseSigned|ARM64'\">\n    <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>\n    <OutDir>$(SolutionDir)build\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\</OutDir>\n    <IntDir>$(SolutionDir)intermediate\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\</IntDir>\n    <IncludePath>$(SolutionDir)intermediate\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\;$(IncludePath)</IncludePath>\n  </PropertyGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <ClCompile>\n      <WppEnabled>true</WppEnabled>\n      <WppRecorderEnabled>true</WppRecorderEnabled>\n      <WppScanConfigurationData Condition=\"'%(ClCompile.ScanConfigurationData)' == ''\">trace.h</WppScanConfigurationData>\n      <WppKernelMode>true</WppKernelMode>\n      <DisableSpecificWarnings>4214</DisableSpecificWarnings>\n    </ClCompile>\n    <DriverSign>\n      <FileDigestAlgorithm>sha256</FileDigestAlgorithm>\n    </DriverSign>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <ClCompile>\n      <WppEnabled>true</WppEnabled>\n      <WppRecorderEnabled>true</WppRecorderEnabled>\n      <WppScanConfigurationData Condition=\"'%(ClCompile.ScanConfigurationData)' == ''\">trace.h</WppScanConfigurationData>\n      <WppKernelMode>true</WppKernelMode>\n      <DisableSpecificWarnings>4214</DisableSpecificWarnings>\n    </ClCompile>\n    <DriverSign>\n      <FileDigestAlgorithm>sha256</FileDigestAlgorithm>\n    </DriverSign>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseSigned|x64'\">\n    <ClCompile>\n      <WppEnabled>true</WppEnabled>\n      <WppRecorderEnabled>true</WppRecorderEnabled>\n      <WppScanConfigurationData Condition=\"'%(ClCompile.ScanConfigurationData)' == ''\">trace.h</WppScanConfigurationData>\n      <WppKernelMode>true</WppKernelMode>\n      <DisableSpecificWarnings>4214</DisableSpecificWarnings>\n    </ClCompile>\n    <DriverSign>\n      <FileDigestAlgorithm>sha256</FileDigestAlgorithm>\n    </DriverSign>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">\n    <ClCompile>\n      <WppEnabled>true</WppEnabled>\n      <WppRecorderEnabled>true</WppRecorderEnabled>\n      <WppScanConfigurationData Condition=\"'%(ClCompile.ScanConfigurationData)' == ''\">trace.h</WppScanConfigurationData>\n      <WppKernelMode>true</WppKernelMode>\n      <DisableSpecificWarnings>4214</DisableSpecificWarnings>\n    </ClCompile>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseSigned|ARM64'\">\n    <ClCompile>\n      <WppEnabled>true</WppEnabled>\n      <WppRecorderEnabled>true</WppRecorderEnabled>\n      <WppScanConfigurationData Condition=\"'%(ClCompile.ScanConfigurationData)' == ''\">trace.h</WppScanConfigurationData>\n      <WppKernelMode>true</WppKernelMode>\n      <DisableSpecificWarnings>4214</DisableSpecificWarnings>\n    </ClCompile>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">\n    <ClCompile>\n      <WppEnabled>true</WppEnabled>\n      <WppRecorderEnabled>true</WppRecorderEnabled>\n      <WppScanConfigurationData Condition=\"'%(ClCompile.ScanConfigurationData)' == ''\">trace.h</WppScanConfigurationData>\n      <WppKernelMode>true</WppKernelMode>\n      <DisableSpecificWarnings>4214</DisableSpecificWarnings>\n    </ClCompile>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <FilesToPackage Include=\"$(TargetPath)\" />\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "src/AmtPtpDeviceSpiKm/AmtPtpDeviceSpiKm.vcxproj.filters",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup>\n    <Filter Include=\"Header Files\">\n      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>\n      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>\n    </Filter>\n    <Filter Include=\"Resource Files\">\n      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>\n      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>\n    </Filter>\n    <Filter Include=\"Driver Files\">\n      <UniqueIdentifier>{8E41214B-6785-4CFE-B992-037D68949A14}</UniqueIdentifier>\n      <Extensions>inf;inv;inx;mof;mc;</Extensions>\n    </Filter>\n    <Filter Include=\"Device Specific Metadata Files\">\n      <UniqueIdentifier>{895871d8-b6bd-4578-bd98-bec2cb45183b}</UniqueIdentifier>\n    </Filter>\n    <Filter Include=\"Source Files\">\n      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>\n      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>\n    </Filter>\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"Device.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"Driver.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"Public.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"Queue.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"Trace.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"AppleDefinition.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"Hid.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"HID\\SpiTrackpadSeries1.h\">\n      <Filter>Device Specific Metadata Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"HidCommon.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"Input.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"HID\\SpiTrackpadSeries2.h\">\n      <Filter>Device Specific Metadata Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"HID\\SpiTrackpadSeries3.h\">\n      <Filter>Device Specific Metadata Files</Filter>\n    </ClInclude>\n  </ItemGroup>\n  <ItemGroup>\n    <ClCompile Include=\"Device.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"Driver.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"Queue.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"Hid.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"Input.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "src/AmtPtpDeviceSpiKm/AppleDefinition.h",
    "content": "#pragma once\n\n#define SPI_TRACKPAD_MAX_FINGERS 10\n#define DEVICE_VID 0x8910\n\ntypedef struct _SPI_TRACKPAD_FINGER\n{\n\tSHORT OriginalX;\n\tSHORT OriginalY;\n\tSHORT X;\n\tSHORT Y;\n\tSHORT HorizontalAccel;\n\tSHORT VerticalAccel;\n\tSHORT ToolMajor;\n\tSHORT ToolMinor;\n\tSHORT Orientation;\n\tSHORT TouchMajor;\n\tSHORT TouchMinor;\n\tSHORT Rsvd1;\n\tSHORT Rsvd2;\n\tSHORT Pressure;\n\tSHORT Rsvd3;\n} SPI_TRACKPAD_FINGER, *PSPI_TRACKPAD_FINGER;\n\ntypedef struct _SPI_TRACKPAD_PACKET\n{\n\tUINT8 PacketType;\n\tUINT8 ClickOccurred;\n\tUINT8 Reserved0[5];\n\tUINT8 IsFinger;\n\tUINT8 Reserved1[16];\n\tUINT8 FingerDataLength;\n\tUINT8 Reserved2[5];\n\tUINT8 NumOfFingers;\n\tUINT8 ClickOccurred2;\n\tUINT8 State1;\n\tUINT8 State2;\n\tUINT8 State3;\n\tUINT8 Padding;\n\tUINT8 Reserved3[10];\n\tSPI_TRACKPAD_FINGER Fingers[SPI_TRACKPAD_MAX_FINGERS];\n} SPI_TRACKPAD_PACKET, *PSPI_TRACKPAD_PACKET;\n\ntypedef struct _SPI_SET_FEATURE {\n\tUINT8 BusLocation;\n\tUINT8 Status;\n} SPI_SET_FEATURE, *PSPI_SET_FEATURE;\n\n#define HID_REPORTID_MOUSE  2\n#define HID_XFER_PACKET_SIZE 255\n\nstatic const SPI_TRACKPAD_INFO SpiTrackpadConfigTable[] = \n{\n\t/* MacBookPro11,1 / MacBookPro12,1 */\n\t{ 0x05ac, 0x0272, -4750, 5280, -150, 6730 },\n\t{ 0x05ac, 0x0273, -4750, 5280, -150, 6730 },\n\t/* MacBook9 */\n\t{ 0x05ac, 0x0275, -5087, 5579, -128, 6089 },\n\t/* MacBookPro14,1 / MacBookPro14,2 */\n\t{ 0x05ac, 0x0276, -6243, 6749, -170, 7685 },\n\t{ 0x05ac, 0x0277, -6243, 6749, -170, 7685 },\n\t/* MacBookPro14,3 */\n\t{ 0x05ac, 0x0278, -7456, 7976, -163, 9283 },\n\t/* MacBook10 */\n\t{ 0x05ac, 0x0279, -5087, 5579, -128, 6089 },\n\t/* MacBookAir7,2 fallback */\n\t{ 0x05ac, 0x0290, -5087, 5579, -128, 6089 },\n\t{ 0x05ac, 0x0291, -5087, 5579, -128, 6089 },\n\t/* Terminator */\n\t{ 0 }\n};\n"
  },
  {
    "path": "src/AmtPtpDeviceSpiKm/Device.c",
    "content": "/*++\n\nModule Name:\n\n    device.c - Device handling events for example driver.\n\nAbstract:\n\n   This file contains the device entry points and callbacks.\n    \nEnvironment:\n\n    Kernel-mode Driver Framework\n\n--*/\n\n#include \"driver.h\"\n#include \"device.tmh\"\n\n#ifdef ALLOC_PRAGMA\n#pragma alloc_text (PAGE, AmtPtpDeviceSpiKmCreateDevice)\n#endif\n\nNTSTATUS\nAmtPtpDeviceSpiKmCreateDevice(\n    _Inout_ PWDFDEVICE_INIT DeviceInit\n    )\n{\n    WDF_OBJECT_ATTRIBUTES DeviceAttributes;\n\tWDF_OBJECT_ATTRIBUTES TimerAttributes;\n    PDEVICE_CONTEXT pDeviceContext;\n\tWDF_TIMER_CONFIG TimerConfig;\n    WDFDEVICE Device;\n    NTSTATUS Status;\n\n\tWDF_PNPPOWER_EVENT_CALLBACKS pnpPowerCallbacks;\n\n    PAGED_CODE();\n\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION,\n\t\tTRACE_DRIVER,\n\t\t\"%!FUNC! Entry\"\n\t);\n\n\t// Initialize Power Callback\n\tWDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpPowerCallbacks);\n\n\t// Initialize PNP power event callbacks\n\tpnpPowerCallbacks.EvtDevicePrepareHardware = AmtPtpEvtDevicePrepareHardware;\n\tpnpPowerCallbacks.EvtDeviceD0Entry = AmtPtpEvtDeviceD0Entry;\n\tpnpPowerCallbacks.EvtDeviceD0Exit = AmtPtpEvtDeviceD0Exit;\n\tpnpPowerCallbacks.EvtDeviceSelfManagedIoInit = AmtPtpEvtDeviceSelfManagedIoInitOrRestart;\n\tpnpPowerCallbacks.EvtDeviceSelfManagedIoRestart = AmtPtpEvtDeviceSelfManagedIoInitOrRestart;\n\tWdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpPowerCallbacks);\n\n\t// Create WDF device object\n    WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&DeviceAttributes, DEVICE_CONTEXT);\n\n    Status = WdfDeviceCreate(&DeviceInit, &DeviceAttributes, &Device);\n\n    if (NT_SUCCESS(Status)) \n\t{\n        //\n        // Get a pointer to the device context structure that we just associated\n        // with the device object. We define this structure in the device.h\n        // header file. DeviceGetContext is an inline function generated by\n        // using the WDF_DECLARE_CONTEXT_TYPE_WITH_NAME macro in device.h.\n        // This function will do the type checking and return the device context.\n        // If you pass a wrong object handle it will return NULL and assert if\n        // run under framework verifier mode.\n        //\n        pDeviceContext = DeviceGetContext(Device);\n\n\t\t//\n\t\t// Put itself in\n\t\t//\n\t\tpDeviceContext->SpiDevice = Device;\n\n\t\t//\n\t\t// Create a list of buffers\n\t\t//\n\t\tStatus = WdfLookasideListCreate(\n\t\t\tWDF_NO_OBJECT_ATTRIBUTES,\n\t\t\tREPORT_BUFFER_SIZE,\n\t\t\tNonPagedPoolNx,\n\t\t\tWDF_NO_OBJECT_ATTRIBUTES,\n\t\t\tPTP_LIST_POOL_TAG,\n\t\t\t&pDeviceContext->HidReadBufferLookaside\n\t\t);\n\n\t\tif (!NT_SUCCESS(Status)) {\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_ERROR,\n\t\t\t\tTRACE_DRIVER,\n\t\t\t\t\"%!FUNC! WdfLookasideListCreate failed with %!STATUS!\",\n\t\t\t\tStatus\n\t\t\t);\n\t\t\tgoto exit;\n\t\t}\n\n\t\t//\n\t\t// Create power-on recovery timer\n\t\t//\n\t\tWDF_TIMER_CONFIG_INIT(&TimerConfig, AmtPtpPowerRecoveryTimerCallback);\n\t\tTimerConfig.AutomaticSerialization = TRUE;\n\t\tWDF_OBJECT_ATTRIBUTES_INIT(&TimerAttributes);\n\t\tTimerAttributes.ParentObject = Device;\n\t\tTimerAttributes.ExecutionLevel = WdfExecutionLevelPassive;\n\t\tStatus = WdfTimerCreate(&TimerConfig, &TimerAttributes, &pDeviceContext->PowerOnRecoveryTimer);\n\t\tif (!NT_SUCCESS(Status)) {\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_ERROR,\n\t\t\t\tTRACE_DRIVER,\n\t\t\t\t\"%!FUNC! WdfTimerCreate failed with %!STATUS!\",\n\t\t\t\tStatus\n\t\t\t);\n\t\t\tgoto exit;\n\t\t}\n\n\t\t//\n\t\t// Retrieve IO target.\n\t\t//\n\t\tpDeviceContext->SpiTrackpadIoTarget = WdfDeviceGetIoTarget(Device);\n\t\tif (pDeviceContext->SpiTrackpadIoTarget == NULL) \n\t\t{\n\t\t\tStatus = STATUS_INVALID_DEVICE_STATE;\n\t\t\tgoto exit;\n\t\t}\n\n\t\t//\n\t\t// Reset power status.\n\t\t//\n\t\tpDeviceContext->DeviceStatus = D3;\n\n        //\n        // Create a device interface so that applications can find and talk\n        // to us.\n        //\n        Status = WdfDeviceCreateDeviceInterface(\n            Device,\n            &GUID_DEVINTERFACE_AmtPtpDeviceSpiKm,\n            NULL // ReferenceString\n        );\n\n        if (NT_SUCCESS(Status)) \n\t\t{\n            //\n            // Initialize the I/O Package and any Queues\n            //\n            Status = AmtPtpDeviceSpiKmQueueInitialize(Device);\n        }\n    }\n\nexit:\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION,\n\t\tTRACE_DRIVER,\n\t\t\"%!FUNC! Exit, Status = %!STATUS!\",\n\t\tStatus\n\t);\n\n    return Status;\n}\n\nNTSTATUS\nAmtPtpEvtDevicePrepareHardware(\n\t_In_ WDFDEVICE Device,\n\t_In_ WDFCMRESLIST ResourceList,\n\t_In_ WDFCMRESLIST ResourceListTranslated\n)\n{\n\tNTSTATUS Status = STATUS_SUCCESS;\n\tPDEVICE_CONTEXT pDeviceContext;\n\n\tWDF_MEMORY_DESCRIPTOR HidAttributeMemoryDescriptor;\n\tHID_DEVICE_ATTRIBUTES DeviceAttributes;\n\t\n\tconst SPI_TRACKPAD_INFO* pTrackpadInfo;\n\tBOOLEAN DeviceFound = FALSE;\n\n\tWDFKEY ParamRegistryKey;\n\tDECLARE_CONST_UNICODE_STRING(DesiredReportTypeKey, L\"DesiredReportType\");\n\tULONG DesiredReportTypeValue, Length, ValueType = 0;\n\n\tPAGED_CODE();\n\tUNREFERENCED_PARAMETER(ResourceList);\n\tUNREFERENCED_PARAMETER(ResourceListTranslated);\n\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION,\n\t\tTRACE_DRIVER,\n\t\t\"%!FUNC! Entry\"\n\t);\n\n\tpDeviceContext = DeviceGetContext(Device);\n\tif (pDeviceContext == NULL)\n\t{\n\t\tStatus = STATUS_INVALID_DEVICE_STATE;\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_INFORMATION,\n\t\t\tTRACE_DRIVER,\n\t\t\t\"%!FUNC! pDeviceContext == NULL\"\n\t\t);\n\n\t\tgoto exit;\n\t}\n\n\t// Request device attribute descriptor for self-identification.\n\tRtlZeroMemory(&DeviceAttributes, sizeof(DeviceAttributes));\n\tWDF_MEMORY_DESCRIPTOR_INIT_BUFFER(\n\t\t&HidAttributeMemoryDescriptor,\n\t\t(PVOID) &DeviceAttributes,\n\t\tsizeof(DeviceAttributes)\n\t);\n\n\tStatus = WdfIoTargetSendInternalIoctlSynchronously(\n\t\tpDeviceContext->SpiTrackpadIoTarget,\n\t\tNULL,\n\t\tIOCTL_HID_GET_DEVICE_ATTRIBUTES,\n\t\tNULL,\n\t\t&HidAttributeMemoryDescriptor,\n\t\tNULL,\n\t\tNULL\n\t);\n\n\tif (!NT_SUCCESS(Status))\n\t{\n\t\tKdPrintEx((\n\t\t\tDPFLTR_IHVDRIVER_ID,\n\t\t\tDPFLTR_INFO_LEVEL,\n\t\t\t\"WdfIoTargetSendInternalIoctlSynchronously failed, status = 0x%x \\n\",\n\t\t\tStatus\n\t\t));\n\n\t\tgoto exit;\n\t}\n\n\tpDeviceContext->HidVendorID = DeviceAttributes.VendorID;\n\tpDeviceContext->HidProductID = DeviceAttributes.ProductID;\n\tpDeviceContext->HidVersionNumber = DeviceAttributes.VersionNumber;\n\n\t// Find proper metadata in HID registry\n\tfor (pTrackpadInfo = SpiTrackpadConfigTable; pTrackpadInfo->VendorId; ++pTrackpadInfo)\n\t{\n\t\tif (pTrackpadInfo->VendorId == DeviceAttributes.VendorID &&\n\t\t\tpTrackpadInfo->ProductId == DeviceAttributes.ProductID)\n\t\t{\n\t\t\tpDeviceContext->TrackpadInfo.ProductId = pTrackpadInfo->ProductId;\n\t\t\tpDeviceContext->TrackpadInfo.VendorId = pTrackpadInfo->VendorId;\n\t\t\tpDeviceContext->TrackpadInfo.XMin = pTrackpadInfo->XMin;\n\t\t\tpDeviceContext->TrackpadInfo.XMax = pTrackpadInfo->XMax;\n\t\t\tpDeviceContext->TrackpadInfo.YMin = pTrackpadInfo->YMin;\n\t\t\tpDeviceContext->TrackpadInfo.YMax = pTrackpadInfo->YMax;\n\n\t\t\tDeviceFound = TRUE;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (!DeviceFound)\n\t{\n\t\tStatus = STATUS_NOT_FOUND;\n\t\tgoto exit;\n\t}\n\n\t// Check the desired report type.\n\tStatus = WdfDriverOpenParametersRegistryKey(\n\t\tWdfDeviceGetDriver(Device),\n\t\tKEY_READ,\n\t\tWDF_NO_OBJECT_ATTRIBUTES,\n\t\t&ParamRegistryKey\n\t);\n\n\tif (NT_SUCCESS(Status))\n\t{\n\t\tStatus = WdfRegistryQueryValue(\n\t\t\tParamRegistryKey,\n\t\t\t&DesiredReportTypeKey,\n\t\t\tsizeof(ULONG),\n\t\t\t&DesiredReportTypeValue,\n\t\t\t&Length,\n\t\t\t&ValueType\n\t\t);\n\n\t\tif (NT_SUCCESS(Status))\n\t\t{\n\t\t\tswitch (DesiredReportTypeValue)\n\t\t\t{\n\t\t\tcase 0:\n\t\t\t\tpDeviceContext->ReportType = PrecisionTouchpad;\n\t\t\t\tbreak;\n\t\t\tcase 1:\n\t\t\t\tpDeviceContext->ReportType = Touchscreen;\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tStatus = STATUS_INVALID_PARAMETER;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tWdfRegistryClose(ParamRegistryKey);\n\t}\n\n\t// We don't really care if that param read fails.\n\tStatus = STATUS_SUCCESS;\n\nexit:\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION,\n\t\tTRACE_DRIVER,\n\t\t\"%!FUNC! Exit, Status = %!STATUS!\",\n\t\tStatus\n\t);\n\n\treturn Status;\n}\n\nNTSTATUS\nAmtPtpEvtDeviceD0Entry(\n\t_In_ WDFDEVICE Device,\n\t_In_ WDF_POWER_DEVICE_STATE PreviousState\n)\n{\n\tNTSTATUS Status = STATUS_SUCCESS;\n\tPDEVICE_CONTEXT pDeviceContext;\n\n\t// Log status\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION,\n\t\tTRACE_DRIVER,\n\t\t\"%!FUNC! -->AmtPtpDeviceEvtDeviceD0Entry - coming from %s\",\n\t\tDbgDevicePowerString(PreviousState)\n\t);\n\n\tpDeviceContext = DeviceGetContext(Device);\n\n\t// We will configure the device in Self Managed IO init / restart routine\n\tpDeviceContext->DeviceStatus = D0ActiveAndUnconfigured;\n\n\t// Set time\n\tKeQueryPerformanceCounter(&pDeviceContext->LastReportTime);\n\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION,\n\t\tTRACE_DRIVER,\n\t\t\"%!FUNC! <-- AmtPtpDeviceEvtDeviceD0Entry\"\n\t);\n\n\treturn Status;\n}\n\nNTSTATUS\nAmtPtpEvtDeviceD0Exit(\n\t_In_ WDFDEVICE Device,\n\t_In_ WDF_POWER_DEVICE_STATE TargetState\n)\n{\n\tNTSTATUS Status = STATUS_SUCCESS;\n\tPDEVICE_CONTEXT pDeviceContext;\n\tWDFREQUEST OutstandingRequest;\n\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION,\n\t\tTRACE_DRIVER,\n\t\t\"%!FUNC! -->AmtPtpDeviceEvtDeviceD0Exit - moving to %s\",\n\t\tDbgDevicePowerString(TargetState)\n\t);\n\n\tpDeviceContext = DeviceGetContext(Device);\n\tpDeviceContext->DeviceStatus = D3;\n\n\t// Cancel all outstanding requests\n\twhile (NT_SUCCESS(Status)) {\n\t\tStatus = WdfIoQueueRetrieveNextRequest(\n\t\t\tpDeviceContext->HidQueue, \n\t\t\t&OutstandingRequest\n\t\t);\n\n\t\tif (NT_SUCCESS(Status)) {\n\t\t\tWdfRequestComplete(OutstandingRequest, STATUS_CANCELLED);\n\t\t}\n\t}\n\n\t// When the queue is empty, this is expected\n\tStatus = STATUS_SUCCESS;\n\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION,\n\t\tTRACE_DRIVER,\n\t\t\"%!FUNC! <--AmtPtpDeviceEvtDeviceD0Exit\"\n\t);\n\n\treturn Status;\n}\n\nNTSTATUS\nAmtPtpEvtDeviceSelfManagedIoInitOrRestart(\n\t_In_ WDFDEVICE Device\n)\n{\n\tNTSTATUS Status = STATUS_SUCCESS;\n\tPDEVICE_CONTEXT pDeviceContext;\n\n\tTraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, \"%!FUNC! Entry\");\n\tpDeviceContext = DeviceGetContext(Device);\n\t\n\tStatus = AmtPtpSpiSetState(Device, TRUE);\n\tif (!NT_SUCCESS(Status))\n\t{\n\t\t// In this case, we will retry after 5 seconds. Block any incoming requests.\n\t\tTraceEvents(TRACE_LEVEL_ERROR, TRACE_DRIVER, \"%!FUNC! AmtPtpSpiSetState failed with %!STATUS!. Retry after 5 seconds\", Status);\n\t\tStatus = STATUS_SUCCESS;\n\t\tWdfTimerStart(pDeviceContext->PowerOnRecoveryTimer, WDF_REL_TIMEOUT_IN_SEC(5));\n\t\tgoto exit;\n\t}\n\telse\n\t{\n\t\t// Set time and status\n\t\tpDeviceContext->DeviceStatus = D0ActiveAndConfigured;\n\t\tKeQueryPerformanceCounter(&pDeviceContext->LastReportTime);\n\t}\n\nexit:\n\tTraceEvents(TRACE_LEVEL_INFORMATION,TRACE_DRIVER, \"%!FUNC! Exit, Status = %!STATUS!\", Status);\n\treturn Status;\n}\n\nPCHAR\nDbgDevicePowerString(\n\t_In_ WDF_POWER_DEVICE_STATE Type\n)\n{\n\tswitch (Type)\n\t{\n\tcase WdfPowerDeviceInvalid:\n\t\treturn \"WdfPowerDeviceInvalid\";\n\tcase WdfPowerDeviceD0:\n\t\treturn \"WdfPowerDeviceD0\";\n\tcase WdfPowerDeviceD1:\n\t\treturn \"WdfPowerDeviceD1\";\n\tcase WdfPowerDeviceD2:\n\t\treturn \"WdfPowerDeviceD2\";\n\tcase WdfPowerDeviceD3:\n\t\treturn \"WdfPowerDeviceD3\";\n\tcase WdfPowerDeviceD3Final:\n\t\treturn \"WdfPowerDeviceD3Final\";\n\tcase WdfPowerDevicePrepareForHibernation:\n\t\treturn \"WdfPowerDevicePrepareForHibernation\";\n\tcase WdfPowerDeviceMaximum:\n\t\treturn \"WdfPowerDeviceMaximum\";\n\tdefault:\n\t\treturn \"UnKnown Device Power State\";\n\t}\n}\n\nNTSTATUS\nAmtPtpSpiSetState(\n\t_In_ WDFDEVICE Device,\n\t_In_ BOOLEAN DesiredState\n)\n{\n\tNTSTATUS Status;\n\tPDEVICE_CONTEXT pDeviceContext;\n\tUCHAR HidPacketBuffer[HID_XFER_PACKET_SIZE];\n\tWDF_MEMORY_DESCRIPTOR HidMemoryDescriptor;\n\tPHID_XFER_PACKET pHidPacket;\n\tPSPI_SET_FEATURE pSpiSetStatus;\n\n\tpDeviceContext = DeviceGetContext(Device);\n\tif (pDeviceContext == NULL)\n\t{\n\t\tStatus = STATUS_INVALID_DEVICE_STATE;\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_INFORMATION,\n\t\t\tTRACE_DRIVER,\n\t\t\t\"%!FUNC! pDeviceContext == NULL\"\n\t\t);\n\n\t\tgoto exit;\n\t}\n\n\tRtlZeroMemory(HidPacketBuffer, sizeof(HidPacketBuffer));\n\tpHidPacket = (PHID_XFER_PACKET) &HidPacketBuffer;\n\tWDF_MEMORY_DESCRIPTOR_INIT_BUFFER(\n\t\t&HidMemoryDescriptor,\n\t\t(PVOID) &HidPacketBuffer,\n\t\tHID_XFER_PACKET_SIZE\n\t);\n\n\tpHidPacket->reportId = HID_REPORTID_MOUSE;\n\tpHidPacket->reportBufferLen = sizeof(SPI_SET_FEATURE);\n\tpHidPacket->reportBuffer = (PUCHAR) pHidPacket + sizeof(HID_XFER_PACKET);\n\tpSpiSetStatus = (PSPI_SET_FEATURE) pHidPacket->reportBuffer;\n\n\t// SPI Bus, location 2\n\tpSpiSetStatus->BusLocation = 2;\n\tpSpiSetStatus->Status = DesiredState ? 1 : 0;\n\n\t// Will non-internal IOCTL work?\n\tStatus = WdfIoTargetSendInternalIoctlSynchronously(\n\t\tpDeviceContext->SpiTrackpadIoTarget,\n\t\tNULL,\n\t\tIOCTL_HID_SET_FEATURE,\n\t\t&HidMemoryDescriptor,\n\t\tNULL,\n\t\tNULL,\n\t\tNULL\n\t);\n\n\tif (!NT_SUCCESS(Status))\n\t{\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_ERROR,\n\t\t\tTRACE_DRIVER,\n\t\t\t\"%!FUNC! WdfIoTargetSendIoctlSynchronously failed with %!STATUS!\",\n\t\t\tStatus\n\t\t);\n\t}\n\telse\n\t{\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_INFORMATION,\n\t\t\tTRACE_DRIVER,\n\t\t\t\"%!FUNC! Changed trackpad status to %d\",\n\t\t\tDesiredState\n\t\t);\n\t}\n\nexit:\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION,\n\t\tTRACE_DRIVER,\n\t\t\"%!FUNC! Exit, Status = %!STATUS!\",\n\t\tStatus\n\t);\n\n\treturn Status;\n}\n\nvoid AmtPtpPowerRecoveryTimerCallback(\n\tWDFTIMER Timer\n)\n{\n\tWDFDEVICE Device;\n\tPDEVICE_CONTEXT pDeviceContext;\n\tNTSTATUS Status = STATUS_SUCCESS;\n\n\tTraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, \"%!FUNC! Entry\");\n\tDevice = WdfTimerGetParentObject(Timer);\n\tpDeviceContext = DeviceGetContext(Device);\n\n\tStatus = AmtPtpSpiSetState(Device, TRUE);\n\tif (NT_SUCCESS(Status))\n\t{\n\t\t// Triage request and set status\n\t\tAmtPtpSpiInputIssueRequest(Device);\n\t\tpDeviceContext->DeviceStatus = D0ActiveAndConfigured;\n\t}\n\n\tTraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, \"%!FUNC! Exit, Status = %!STATUS!\", Status);\n}\n"
  },
  {
    "path": "src/AmtPtpDeviceSpiKm/Device.h",
    "content": "/*++\n\nModule Name:\n\n    device.h\n\nAbstract:\n\n    This file contains the device definitions.\n\nEnvironment:\n\n    Kernel-mode Driver Framework\n\n--*/\n\n#include \"public.h\"\n\nEXTERN_C_START\n\ntypedef struct _SPI_TRACKPAD_INFO {\n\tUSHORT VendorId;\n\tUSHORT ProductId;\n\tSHORT XMin;\n\tSHORT XMax;\n\tSHORT YMin;\n\tSHORT YMax;\n} SPI_TRACKPAD_INFO, *PSPI_TRACKPAD_INFO;\n\n// Stupid Microsoft only assigns a UCHAR for touch ID\n// we could have a better approach\ntypedef struct _PTP_AAPL_MAPPING {\n\tSHORT OriginalX;\n\tSHORT OriginalY;\n\tINT8 ContactID;\n} PTP_AAPL_MAPPING, *PPTP_AAPL_MAPPING;\n\n#define MAPPING_MAX 10\n\ntypedef enum _REPORT_TYPE {\n\tPrecisionTouchpad = 0,\n\tTouchscreen = 1,\n\tInvalidReportType = 0x7fffffff,\n} REPORT_TYPE;\n\ntypedef enum _PTP_AAPL_DEVICE_POWER_STATUS {\n\tD3 = 0,\n\tD0ActiveAndConfigured = 1,\n\tD0ActiveAndUnconfigured = 2\n} PTP_AAPL_DEVICE_POWER_STATUS;\n\n//\n// The device context performs the same job as\n// a WDM device extension in the driver frameworks\n//\ntypedef struct _DEVICE_CONTEXT\n{\n\t// IO content\n\tWDFDEVICE\tSpiDevice;\n\tWDFIOTARGET SpiTrackpadIoTarget;\n\tPTP_AAPL_DEVICE_POWER_STATUS DeviceStatus;\n\tHANDLE\t\tInputPollThreadHandle;\n\tWDFQUEUE\tHidQueue;\n\n\t// SPI device metadata\n\tUSHORT HidVendorID;\n\tUSHORT HidProductID;\n\tUSHORT HidVersionNumber;\n\tSPI_TRACKPAD_INFO TrackpadInfo;\n\tREPORT_TYPE ReportType;\n\n\t// Windows PTP context\n\tBOOLEAN PtpInputOn;\n\tBOOLEAN PtpReportTouch;\n\tBOOLEAN PtpReportButton;\n\n\t// Timer\n\tLARGE_INTEGER LastReportTime;\n\tWDFTIMER PowerOnRecoveryTimer;\n\n\t// List of buffers\n\tWDFLOOKASIDE HidReadBufferLookaside;\n\n} DEVICE_CONTEXT, *PDEVICE_CONTEXT;\n\n//\n// This macro will generate an inline function called DeviceGetContext\n// which will be used to get a pointer to the device context memory\n// in a type safe manner.\n//\nWDF_DECLARE_CONTEXT_TYPE_WITH_NAME(DEVICE_CONTEXT, DeviceGetContext)\n\n//\n// Request context\n//\ntypedef struct _WORKER_REQUEST_CONTEXT {\n\tPDEVICE_CONTEXT DeviceContext;\n\tWDFMEMORY RequestMemory;\n} WORKER_REQUEST_CONTEXT, *PWORKER_REQUEST_CONTEXT;\n\nWDF_DECLARE_CONTEXT_TYPE_WITH_NAME(WORKER_REQUEST_CONTEXT, WorkerRequestGetContext)\n\n//\n// Function to initialize the device and its callbacks\n//\nNTSTATUS\nAmtPtpDeviceSpiKmCreateDevice(\n    _Inout_ PWDFDEVICE_INIT DeviceInit\n    );\n\nEVT_WDF_DEVICE_PREPARE_HARDWARE AmtPtpEvtDevicePrepareHardware;\nEVT_WDF_DEVICE_D0_ENTRY AmtPtpEvtDeviceD0Entry;\nEVT_WDF_DEVICE_D0_EXIT AmtPtpEvtDeviceD0Exit;\n\nNTSTATUS\nAmtPtpEvtDeviceSelfManagedIoInitOrRestart(\n\t_In_ WDFDEVICE Device\n);\n\nPCHAR\nDbgDevicePowerString(\n\t_In_ WDF_POWER_DEVICE_STATE Type\n);\n\nNTSTATUS\nAmtPtpSpiSetState(\n\t_In_ WDFDEVICE Device,\n\t_In_ BOOLEAN DesiredState\n);\n\nvoid AmtPtpPowerRecoveryTimerCallback(\n\tWDFTIMER Timer\n);\n\nEXTERN_C_END\n"
  },
  {
    "path": "src/AmtPtpDeviceSpiKm/Driver.c",
    "content": "/*++\n\nModule Name:\n\n    driver.c\n\nAbstract:\n\n    This file contains the driver entry points and callbacks.\n\nEnvironment:\n\n    Kernel-mode Driver Framework\n\n--*/\n\n#include \"driver.h\"\n#include \"driver.tmh\"\n\n#ifdef ALLOC_PRAGMA\n#pragma alloc_text (INIT, DriverEntry)\n#pragma alloc_text (PAGE, AmtPtpDeviceSpiKmEvtDeviceAdd)\n#pragma alloc_text (PAGE, AmtPtpDeviceSpiKmEvtDriverContextCleanup)\n#endif\n\nNTSTATUS\nDriverEntry(\n    _In_ PDRIVER_OBJECT  DriverObject,\n    _In_ PUNICODE_STRING RegistryPath\n    )\n/*++\n\nRoutine Description:\n    DriverEntry initializes the driver and is the first routine called by the\n    system after the driver is loaded. DriverEntry specifies the other entry\n    points in the function driver, such as EvtDevice and DriverUnload.\n\nParameters Description:\n\n    DriverObject - represents the instance of the function driver that is loaded\n    into memory. DriverEntry must initialize members of DriverObject before it\n    returns to the caller. DriverObject is allocated by the system before the\n    driver is loaded, and it is released by the system after the system unloads\n    the function driver from memory.\n\n    RegistryPath - represents the driver specific path in the Registry.\n    The function driver can use the path to store driver related data between\n    reboots. The path does not store hardware instance specific data.\n\nReturn Value:\n\n    STATUS_SUCCESS if successful,\n    STATUS_UNSUCCESSFUL otherwise.\n\n--*/\n{\n    WDF_DRIVER_CONFIG config;\n    NTSTATUS status;\n    WDF_OBJECT_ATTRIBUTES attributes;\n\n    //\n    // Initialize WPP Tracing\n    //\n    WPP_INIT_TRACING(DriverObject, RegistryPath);\n\n    TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, \"%!FUNC! Entry\");\n\tKdPrintEx((DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, \"DriverEntry Entry \\n\"));\n\n    //\n    // Register a cleanup callback so that we can call WPP_CLEANUP when\n    // the framework driver object is deleted during driver unload.\n    //\n    WDF_OBJECT_ATTRIBUTES_INIT(&attributes);\n    attributes.EvtCleanupCallback = AmtPtpDeviceSpiKmEvtDriverContextCleanup;\n\n    WDF_DRIVER_CONFIG_INIT(&config,\n                           AmtPtpDeviceSpiKmEvtDeviceAdd\n                           );\n\n    status = WdfDriverCreate(DriverObject,\n                             RegistryPath,\n                             &attributes,\n                             &config,\n                             WDF_NO_HANDLE\n                             );\n\n    if (!NT_SUCCESS(status)) {\n        TraceEvents(TRACE_LEVEL_ERROR, TRACE_DRIVER, \"WdfDriverCreate failed %!STATUS!\", status);\n\t\tKdPrintEx((DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, \"WdfDriverCreate failed \\n\"));\n        WPP_CLEANUP(DriverObject);\n        return status;\n    }\n\n\tKdPrintEx((DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, \"DriverEntry Exit \\n\"));\n    TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, \"%!FUNC! Exit\");\n\n    return status;\n}\n\nNTSTATUS\nAmtPtpDeviceSpiKmEvtDeviceAdd(\n    _In_    WDFDRIVER       Driver,\n    _Inout_ PWDFDEVICE_INIT DeviceInit\n    )\n/*++\nRoutine Description:\n\n    EvtDeviceAdd is called by the framework in response to AddDevice\n    call from the PnP manager. We create and initialize a device object to\n    represent a new instance of the device.\n\nArguments:\n\n    Driver - Handle to a framework driver object created in DriverEntry\n\n    DeviceInit - Pointer to a framework-allocated WDFDEVICE_INIT structure.\n\nReturn Value:\n\n    NTSTATUS\n\n--*/\n{\n    NTSTATUS status;\n\n    UNREFERENCED_PARAMETER(Driver);\n    PAGED_CODE();\n\n    TraceEvents(\n\t\tTRACE_LEVEL_INFORMATION, \n\t\tTRACE_DRIVER, \n\t\t\"%!FUNC! Entry\"\n\t);\n\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION,\n\t\tTRACE_DRIVER,\n\t\t\"%!FUNC! Set FDO driver filter\"\n\t);\n\n\tWdfFdoInitSetFilter(DeviceInit);\n\tWdfPdoInitAllowForwardingRequestToParent(DeviceInit);\n\n    status = AmtPtpDeviceSpiKmCreateDevice(DeviceInit);\n\n    TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, \"%!FUNC! Exit\");\n\n    return status;\n}\n\nVOID\nAmtPtpDeviceSpiKmEvtDriverContextCleanup(\n    _In_ WDFOBJECT DriverObject\n    )\n/*++\nRoutine Description:\n\n    Free all the resources allocated in DriverEntry.\n\nArguments:\n\n    DriverObject - handle to a WDF Driver object.\n\nReturn Value:\n\n    VOID.\n\n--*/\n{\n    UNREFERENCED_PARAMETER(DriverObject);\n    PAGED_CODE();\n\n    TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, \"%!FUNC! Entry\");\n\n    //\n    // Stop WPP Tracing\n    //\n    WPP_CLEANUP(WdfDriverWdmGetDriverObject((WDFDRIVER) DriverObject));\n}\n"
  },
  {
    "path": "src/AmtPtpDeviceSpiKm/Driver.h",
    "content": "/*++\n\nModule Name:\n\n    driver.h\n\nAbstract:\n\n    This file contains the driver definitions.\n\nEnvironment:\n\n    Kernel-mode Driver Framework\n\n--*/\n\n#include <ntddk.h>\n#include <wdf.h>\n#include <initguid.h>\n#include <hidport.h>\n\n#include \"device.h\"\n#include \"queue.h\"\n#include \"trace.h\"\n\n#include \"AppleDefinition.h\"\n#include \"Hid.h\"\n#include \"Input.h\"\n\nEXTERN_C_START\n\n//\n// WDFDRIVER Events\n//\n\nDRIVER_INITIALIZE DriverEntry;\nEVT_WDF_DRIVER_DEVICE_ADD AmtPtpDeviceSpiKmEvtDeviceAdd;\nEVT_WDF_OBJECT_CONTEXT_CLEANUP AmtPtpDeviceSpiKmEvtDriverContextCleanup;\n\n//\n// Pool Tag\n//\n#define PTP_LIST_POOL_TAG 'LTPA'\n\n//\n// State Switch Max Retries\n//\n#define STATE_SWITCH_MAX_RETRIES 5\n\nEXTERN_C_END\n"
  },
  {
    "path": "src/AmtPtpDeviceSpiKm/HID/SpiTrackpadSeries1.h",
    "content": "// Trackpad HID definition for MacBook8, 9, 10\n\n#pragma once\n\n#include \"..\\HidCommon.h\"\n\n#define AAPL_SPI_SERIES1_PTP_FINGER_COLLECTION_1 \\\n\tBEGIN_COLLECTION, 0x02, /* Begin Collection: Logical */ \\\n\t\t/* Begin a byte */ \\\n\t\tLOGICAL_MAXIMUM, 0x01, /* Logical Maximum: 1 */ \\\n\t\tUSAGE, 0x47, /* Usage: Confidence */ \\\n\t\tUSAGE, 0x42, /* Usage: Tip switch */ \\\n\t\tREPORT_COUNT, 0x02, /* Report Count: 2 */ \\\n\t\tREPORT_SIZE, 0x01, /* Report Size: 1 */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tREPORT_COUNT, 0x01, /* Report Count: 1 */ \\\n\t\tREPORT_SIZE, 0x03, /* Report Size: 3 */ \\\n\t\tLOGICAL_MAXIMUM, 0x03, /* Logical Maximum: 3 */ \\\n\t\tUSAGE, 0x51, /* Usage: Contract Identifier */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tREPORT_SIZE, 0x01, /* Report Size: 1 */ \\\n\t\tREPORT_COUNT, 0x03, /* Report Count: 3 */ \\\n\t\tINPUT, 0x03, /* Input: (Const, Var, Abs) */ \\\n\t\t/* End of a byte */ \\\n\t\t/* Begin of 4 bytes */ \\\n\t\t/* Size is hard-coded at this moment */ \\\n\t\t/* This hard-coded size is designed for MacBook 8/9/10 */ \\\n\t\tUSAGE_PAGE, 0x01, /* Usage Page: Generic Desktop */ \\\n\t\tLOGICAL_MAXIMUM_2, 0xaa, 0x29, /* Logical Maximum: 10666 (See defintion) */ \\\n\t\tREPORT_SIZE, 0x10, /* Report Size: 0x10 (2 bytes) */ \\\n\t\tUNIT_EXPONENT, 0x0e, /* Unit exponent: -2 */ \\\n\t\tUNIT, 0x11, /* Unit: SI Length (cm) */ \\\n\t\tUSAGE, 0x30, /* Usage: X */ \\\n\t\tPHYSICAL_MAXIMUM_2, 0x5e, 0x04, /* Physical Maximum: 1118 (See Apple Spec) */ \\\n\t\tREPORT_COUNT, 0x01, /* Report count: 1 */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tPHYSICAL_MAXIMUM_2, 0xc7, 0x02, /* Physical Maximum: 711 (See Apple Spec) */ \\\n\t\tLOGICAL_MAXIMUM_2, 0xaf, 0x1e, /* Logical Maximum: 7855 (See definition) */ \\\n\t\tUSAGE, 0x31, /* Usage: Y */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tPHYSICAL_MAXIMUM, 0x00, /* Physical Maximum: 0 */ \\\n\t\tUNIT_EXPONENT, 0x00, /* Unit exponent: 0 */ \\\n\t\tUNIT, 0x00, /* Unit: None */ \\\n\t\t/* End of 4 bytes */ \\\n\tEND_COLLECTION /* End Collection */ \\\n\n#define AAPL_SPI_SERIES1_PTP_FINGER_COLLECTION_2 \\\n\tBEGIN_COLLECTION, 0x02, /* Begin Collection: Logical */ \\\n\t\t/* Begin a byte */ \\\n\t\tLOGICAL_MAXIMUM, 0x01, /* Logical Maximum: 1 */ \\\n\t\tUSAGE, 0x47, /* Usage: Confidence */ \\\n\t\tUSAGE, 0x42, /* Usage: Tip switch */ \\\n\t\tREPORT_COUNT, 0x02, /* Report Count: 2 */ \\\n\t\tREPORT_SIZE, 0x01, /* Report Size: 1 */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tREPORT_COUNT, 0x01, /* Report Count: 1 */ \\\n\t\tREPORT_SIZE, 0x03, /* Report Size: 3 */ \\\n\t\tLOGICAL_MAXIMUM, 0x03, /* Logical Maximum: 3 */ \\\n\t\tUSAGE, 0x51, /* Usage: Contract Identifier */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tREPORT_SIZE, 0x01, /* Report Size: 1 */ \\\n\t\tREPORT_COUNT, 0x03, /* Report Count: 3 */ \\\n\t\tINPUT, 0x03, /* Input: (Const, Var, Abs) */ \\\n\t\t/* End of a byte */ \\\n\t\t/* Begin of 4 bytes */ \\\n\t\t/* Size is hard-coded at this moment */ \\\n\t\tUSAGE_PAGE, 0x01, /* Usage Page: Generic Desktop */ \\\n\t\tLOGICAL_MAXIMUM_2, 0xaa, 0x29, /* Logical Maximum: 10666 (See defintion) */ \\\n\t\tREPORT_SIZE, 0x10, /* Report Size: 0x10 (2 bytes) */ \\\n\t\tUNIT_EXPONENT, 0x0e, /* Unit exponent: -2 */ \\\n\t\tUNIT, 0x11, /* Unit: SI Length (cm) */ \\\n\t\tUSAGE, 0x30, /* Usage: X */ \\\n\t\tPHYSICAL_MAXIMUM_2, 0x5e, 0x04, /* Physical Maximum: 1118 (See Apple Spec) */ \\\n\t\tREPORT_COUNT, 0x01, /* Report count: 1 */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tPHYSICAL_MAXIMUM_2, 0xc7, 0x02, /* Physical Maximum: 711 (See Apple Spec) */ \\\n\t\tLOGICAL_MAXIMUM_2, 0xaf, 0x1e, /* Logical Maximum: 7855 (See definition) */ \\\n\t\tUSAGE, 0x31, /* Usage: Y */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\t/* End of 4 bytes */ \\\n\tEND_COLLECTION /* End Collection */ \\\n\n#define AAPL_SPI_SERIES1_PTP_TLC \\\n\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\tUSAGE, 0x05, /* Usage: Touch Pad */ \\\n\tBEGIN_COLLECTION, 0x01, /* Begin Collection: Application */ \\\n\t\tREPORT_ID, REPORTID_MULTITOUCH, /* Report ID: Multi-touch */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_SPI_SERIES1_PTP_FINGER_COLLECTION_1, /* 1 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_SPI_SERIES1_PTP_FINGER_COLLECTION_1, /* 2 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_SPI_SERIES1_PTP_FINGER_COLLECTION_2, /* 3 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_SPI_SERIES1_PTP_FINGER_COLLECTION_1, /* 4 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_SPI_SERIES1_PTP_FINGER_COLLECTION_2, /* 5 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUNIT_EXPONENT, 0x0c, /* Unit exponent: -4 */ \\\n\t\tUNIT_2, 0x01, 0x10, /* Time: Second */ \\\n\t\tPHYSICAL_MAXIMUM_3, 0xff, 0xff, 0x00, 0x00, \\\n\t\tLOGICAL_MAXIMUM_3, 0xff, 0xff, 0x00, 0x00, \\\n\t\tUSAGE, 0x56, /* Usage: Scan Time */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tUSAGE, 0x54, /* Usage: Contact Count */ \\\n\t\tLOGICAL_MAXIMUM, 0x7f, \\\n\t\tREPORT_SIZE, 0x08, \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tUSAGE_PAGE, 0x09, /* Usage Page: Button */ \\\n\t\tUSAGE, 0x01, /* Button 1 */ \\\n\t\tLOGICAL_MAXIMUM, 0x01, \\\n\t\tREPORT_SIZE, 0x01, \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tREPORT_COUNT, 0x07, \\\n\t\tINPUT, 0x03, /* Input: (Const, Var, Abs) */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tREPORT_ID, REPORTID_DEVICE_CAPS, \\\n\t\tUSAGE, 0x55, /* Usage: Maximum Contacts */ \\\n\t\tUSAGE, 0x59, /* Usage: Touchpad Button Type*/ \\\n\t\tLOGICAL_MINIMUM, 0x00, \\\n\t\tLOGICAL_MAXIMUM_2, 0xff, 0x00, \\\n\t\tREPORT_SIZE, 0x08, \\\n\t\tREPORT_COUNT, 0x02, \\\n\t\tFEATURE, 0x02, \\\n\t\tUSAGE_PAGE_1, 0x00, 0xff, \\\n\t\tREPORT_ID, REPORTID_PTPHQA, \\\n\t\tUSAGE, 0xc5, \\\n\t\tLOGICAL_MINIMUM, 0x00, \\\n\t\tLOGICAL_MAXIMUM_2, 0xff, 0x00, \\\n\t\tREPORT_SIZE, 0x08, \\\n\t\tREPORT_COUNT_2, 0x00, 0x01, \\\n\t\tFEATURE, 0x02, \\\n\tEND_COLLECTION /* End Collection */\n\n#define AAPL_SPI_SERIES1_TOUCHSCREEN_TLC \\\n\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\tUSAGE, 0x04, /* Usage: Touch Screen */ \\\n\tBEGIN_COLLECTION, 0x01, /* Begin Collection: Application */ \\\n\t\tREPORT_ID, REPORTID_MULTITOUCH, /* Report ID: Multi-touch */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_SPI_SERIES1_PTP_FINGER_COLLECTION_1, /* 1 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_SPI_SERIES1_PTP_FINGER_COLLECTION_1, /* 2 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_SPI_SERIES1_PTP_FINGER_COLLECTION_2, /* 3 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_SPI_SERIES1_PTP_FINGER_COLLECTION_1, /* 4 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_SPI_SERIES1_PTP_FINGER_COLLECTION_2, /* 5 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUNIT_EXPONENT, 0x0c, /* Unit exponent: -4 */ \\\n\t\tUNIT_2, 0x01, 0x10, /* Time: Second */ \\\n\t\tPHYSICAL_MAXIMUM_3, 0xff, 0xff, 0x00, 0x00, \\\n\t\tLOGICAL_MAXIMUM_3, 0xff, 0xff, 0x00, 0x00, \\\n\t\tUSAGE, 0x56, /* Usage: Scan Time */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tUSAGE, 0x54, /* Usage: Contact Count */ \\\n\t\tLOGICAL_MAXIMUM, 0x7f, \\\n\t\tREPORT_SIZE, 0x08, \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tUSAGE_PAGE, 0x09, /* Usage Page: Button */ \\\n\t\tUSAGE, 0x01, /* Button 1 */ \\\n\t\tLOGICAL_MAXIMUM, 0x01, \\\n\t\tREPORT_SIZE, 0x01, \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tREPORT_COUNT, 0x07, \\\n\t\tINPUT, 0x03, /* Input: (Const, Var, Abs) */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tREPORT_ID, REPORTID_DEVICE_CAPS, \\\n\t\tUSAGE, 0x55, /* Usage: Maximum Contacts */ \\\n\t\tUSAGE, 0x59, /* Usage: Touchpad Button Type*/ \\\n\t\tLOGICAL_MINIMUM, 0x00, \\\n\t\tLOGICAL_MAXIMUM_2, 0xff, 0x00, \\\n\t\tREPORT_SIZE, 0x08, \\\n\t\tREPORT_COUNT, 0x02, \\\n\t\tFEATURE, 0x02, \\\n\t\tUSAGE_PAGE_1, 0x00, 0xff, \\\n\t\tREPORT_ID, REPORTID_PTPHQA, \\\n\t\tUSAGE, 0xc5, \\\n\t\tLOGICAL_MINIMUM, 0x00, \\\n\t\tLOGICAL_MAXIMUM_2, 0xff, 0x00, \\\n\t\tREPORT_SIZE, 0x08, \\\n\t\tREPORT_COUNT_2, 0x00, 0x01, \\\n\t\tFEATURE, 0x02, \\\n\tEND_COLLECTION /* End Collection */"
  },
  {
    "path": "src/AmtPtpDeviceSpiKm/HID/SpiTrackpadSeries2.h",
    "content": "// Trackpad HID definition for MacBookPro 10, 11\n\n#pragma once\n\n#include \"..\\HidCommon.h\"\n\n#define AAPL_SPI_SERIES2_PTP_FINGER_COLLECTION_1 \\\n\tBEGIN_COLLECTION, 0x02, /* Begin Collection: Logical */ \\\n\t\t/* Begin a byte */ \\\n\t\tLOGICAL_MAXIMUM, 0x01, /* Logical Maximum: 1 */ \\\n\t\tUSAGE, 0x47, /* Usage: Confidence */ \\\n\t\tUSAGE, 0x42, /* Usage: Tip switch */ \\\n\t\tREPORT_COUNT, 0x02, /* Report Count: 2 */ \\\n\t\tREPORT_SIZE, 0x01, /* Report Size: 1 */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tREPORT_COUNT, 0x01, /* Report Count: 1 */ \\\n\t\tREPORT_SIZE, 0x03, /* Report Size: 3 */ \\\n\t\tLOGICAL_MAXIMUM, 0x03, /* Logical Maximum: 3 */ \\\n\t\tUSAGE, 0x51, /* Usage: Contract Identifier */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tREPORT_SIZE, 0x01, /* Report Size: 1 */ \\\n\t\tREPORT_COUNT, 0x03, /* Report Count: 3 */ \\\n\t\tINPUT, 0x03, /* Input: (Const, Var, Abs) */ \\\n\t\t/* End of a byte */ \\\n\t\t/* Begin of 4 bytes */ \\\n\t\t/* Size is hard-coded at this moment */ \\\n\t\t/* This hard-coded size is designed for MacBookPro 11,1 */ \\\n\t\tUSAGE_PAGE, 0x01, /* Usage Page: Generic Desktop */ \\\n\t\tLOGICAL_MAXIMUM_2, 0x2e, 0x27, /* Logical Maximum: 10030 (See defintion) */ \\\n\t\tREPORT_SIZE, 0x10, /* Report Size: 0x10 (2 bytes) */ \\\n\t\tUNIT_EXPONENT, 0x0e, /* Unit exponent: -2 */ \\\n\t\tUNIT, 0x11, /* Unit: SI Length (cm) */ \\\n\t\tUSAGE, 0x30, /* Usage: X */ \\\n\t\tPHYSICAL_MAXIMUM_2, 0x28, 0x04, /* Physical Maximum: 1064 (See Apple Spec) */ \\\n\t\tREPORT_COUNT, 0x01, /* Report count: 1 */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tPHYSICAL_MAXIMUM_2, 0x05, 0x03, /* Physical Maximum: 773 (See Apple Spec) */ \\\n\t\tLOGICAL_MAXIMUM_2, 0xe0, 0x1a, /* Logical Maximum: 6880 (See definition) */ \\\n\t\tUSAGE, 0x31, /* Usage: Y */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tPHYSICAL_MAXIMUM, 0x00, /* Physical Maximum: 0 */ \\\n\t\tUNIT_EXPONENT, 0x00, /* Unit exponent: 0 */ \\\n\t\tUNIT, 0x00, /* Unit: None */ \\\n\t\t/* End of 4 bytes */ \\\n\tEND_COLLECTION /* End Collection */ \\\n\n#define AAPL_SPI_SERIES2_PTP_FINGER_COLLECTION_2 \\\n\tBEGIN_COLLECTION, 0x02, /* Begin Collection: Logical */ \\\n\t\t/* Begin a byte */ \\\n\t\tLOGICAL_MAXIMUM, 0x01, /* Logical Maximum: 1 */ \\\n\t\tUSAGE, 0x47, /* Usage: Confidence */ \\\n\t\tUSAGE, 0x42, /* Usage: Tip switch */ \\\n\t\tREPORT_COUNT, 0x02, /* Report Count: 2 */ \\\n\t\tREPORT_SIZE, 0x01, /* Report Size: 1 */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tREPORT_COUNT, 0x01, /* Report Count: 1 */ \\\n\t\tREPORT_SIZE, 0x03, /* Report Size: 3 */ \\\n\t\tLOGICAL_MAXIMUM, 0x03, /* Logical Maximum: 3 */ \\\n\t\tUSAGE, 0x51, /* Usage: Contract Identifier */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tREPORT_SIZE, 0x01, /* Report Size: 1 */ \\\n\t\tREPORT_COUNT, 0x03, /* Report Count: 3 */ \\\n\t\tINPUT, 0x03, /* Input: (Const, Var, Abs) */ \\\n\t\t/* End of a byte */ \\\n\t\t/* Begin of 4 bytes */ \\\n\t\t/* Size is hard-coded at this moment */ \\\n\t\tUSAGE_PAGE, 0x01, /* Usage Page: Generic Desktop */ \\\n\t\tLOGICAL_MAXIMUM_2, 0x2e, 0x27, /* Logical Maximum: 10030 (See defintion) */ \\\n\t\tREPORT_SIZE, 0x10, /* Report Size: 0x10 (2 bytes) */ \\\n\t\tUNIT_EXPONENT, 0x0e, /* Unit exponent: -2 */ \\\n\t\tUNIT, 0x11, /* Unit: SI Length (cm) */ \\\n\t\tUSAGE, 0x30, /* Usage: X */ \\\n\t\tPHYSICAL_MAXIMUM_2, 0x28, 0x04, /* Physical Maximum: 1064 (See Apple Spec) */ \\\n\t\tREPORT_COUNT, 0x01, /* Report count: 1 */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tPHYSICAL_MAXIMUM_2, 0x05, 0x03, /* Physical Maximum: 773 (See Apple Spec) */ \\\n\t\tLOGICAL_MAXIMUM_2, 0xe0, 0x1a, /* Logical Maximum: 6880 (See definition) */ \\\n\t\tUSAGE, 0x31, /* Usage: Y */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\t/* End of 4 bytes */ \\\n\tEND_COLLECTION /* End Collection */ \\\n\n#define AAPL_SPI_SERIES2_PTP_TLC \\\n\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\tUSAGE, 0x05, /* Usage: Touch Pad */ \\\n\tBEGIN_COLLECTION, 0x01, /* Begin Collection: Application */ \\\n\t\tREPORT_ID, REPORTID_MULTITOUCH, /* Report ID: Multi-touch */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_SPI_SERIES2_PTP_FINGER_COLLECTION_1, /* 1 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_SPI_SERIES2_PTP_FINGER_COLLECTION_1, /* 2 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_SPI_SERIES2_PTP_FINGER_COLLECTION_2, /* 3 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_SPI_SERIES2_PTP_FINGER_COLLECTION_1, /* 4 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_SPI_SERIES2_PTP_FINGER_COLLECTION_2, /* 5 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUNIT_EXPONENT, 0x0c, /* Unit exponent: -4 */ \\\n\t\tUNIT_2, 0x01, 0x10, /* Time: Second */ \\\n\t\tPHYSICAL_MAXIMUM_3, 0xff, 0xff, 0x00, 0x00, \\\n\t\tLOGICAL_MAXIMUM_3, 0xff, 0xff, 0x00, 0x00, \\\n\t\tUSAGE, 0x56, /* Usage: Scan Time */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tUSAGE, 0x54, /* Usage: Contact Count */ \\\n\t\tLOGICAL_MAXIMUM, 0x7f, \\\n\t\tREPORT_SIZE, 0x08, \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tUSAGE_PAGE, 0x09, /* Usage Page: Button */ \\\n\t\tUSAGE, 0x01, /* Button 1 */ \\\n\t\tLOGICAL_MAXIMUM, 0x01, \\\n\t\tREPORT_SIZE, 0x01, \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tREPORT_COUNT, 0x07, \\\n\t\tINPUT, 0x03, /* Input: (Const, Var, Abs) */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tREPORT_ID, REPORTID_DEVICE_CAPS, \\\n\t\tUSAGE, 0x55, /* Usage: Maximum Contacts */ \\\n\t\tUSAGE, 0x59, /* Usage: Touchpad Button Type*/ \\\n\t\tLOGICAL_MINIMUM, 0x00, \\\n\t\tLOGICAL_MAXIMUM_2, 0xff, 0x00, \\\n\t\tREPORT_SIZE, 0x08, \\\n\t\tREPORT_COUNT, 0x02, \\\n\t\tFEATURE, 0x02, \\\n\t\tUSAGE_PAGE_1, 0x00, 0xff, \\\n\t\tREPORT_ID, REPORTID_PTPHQA, \\\n\t\tUSAGE, 0xc5, \\\n\t\tLOGICAL_MINIMUM, 0x00, \\\n\t\tLOGICAL_MAXIMUM_2, 0xff, 0x00, \\\n\t\tREPORT_SIZE, 0x08, \\\n\t\tREPORT_COUNT_2, 0x00, 0x01, \\\n\t\tFEATURE, 0x02, \\\n\tEND_COLLECTION /* End Collection */\n\n#define AAPL_SPI_SERIES2_TOUCHSCREEN_TLC \\\n\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\tUSAGE, 0x04, /* Usage: Touch Screen */ \\\n\tBEGIN_COLLECTION, 0x01, /* Begin Collection: Application */ \\\n\t\tREPORT_ID, REPORTID_MULTITOUCH, /* Report ID: Multi-touch */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_SPI_SERIES2_PTP_FINGER_COLLECTION_1, /* 1 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_SPI_SERIES2_PTP_FINGER_COLLECTION_1, /* 2 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_SPI_SERIES2_PTP_FINGER_COLLECTION_2, /* 3 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_SPI_SERIES2_PTP_FINGER_COLLECTION_1, /* 4 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_SPI_SERIES2_PTP_FINGER_COLLECTION_2, /* 5 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUNIT_EXPONENT, 0x0c, /* Unit exponent: -4 */ \\\n\t\tUNIT_2, 0x01, 0x10, /* Time: Second */ \\\n\t\tPHYSICAL_MAXIMUM_3, 0xff, 0xff, 0x00, 0x00, \\\n\t\tLOGICAL_MAXIMUM_3, 0xff, 0xff, 0x00, 0x00, \\\n\t\tUSAGE, 0x56, /* Usage: Scan Time */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tUSAGE, 0x54, /* Usage: Contact Count */ \\\n\t\tLOGICAL_MAXIMUM, 0x7f, \\\n\t\tREPORT_SIZE, 0x08, \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tUSAGE_PAGE, 0x09, /* Usage Page: Button */ \\\n\t\tUSAGE, 0x01, /* Button 1 */ \\\n\t\tLOGICAL_MAXIMUM, 0x01, \\\n\t\tREPORT_SIZE, 0x01, \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tREPORT_COUNT, 0x07, \\\n\t\tINPUT, 0x03, /* Input: (Const, Var, Abs) */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tREPORT_ID, REPORTID_DEVICE_CAPS, \\\n\t\tUSAGE, 0x55, /* Usage: Maximum Contacts */ \\\n\t\tUSAGE, 0x59, /* Usage: Touchpad Button Type*/ \\\n\t\tLOGICAL_MINIMUM, 0x00, \\\n\t\tLOGICAL_MAXIMUM_2, 0xff, 0x00, \\\n\t\tREPORT_SIZE, 0x08, \\\n\t\tREPORT_COUNT, 0x02, \\\n\t\tFEATURE, 0x02, \\\n\t\tUSAGE_PAGE_1, 0x00, 0xff, \\\n\t\tREPORT_ID, REPORTID_PTPHQA, \\\n\t\tUSAGE, 0xc5, \\\n\t\tLOGICAL_MINIMUM, 0x00, \\\n\t\tLOGICAL_MAXIMUM_2, 0xff, 0x00, \\\n\t\tREPORT_SIZE, 0x08, \\\n\t\tREPORT_COUNT_2, 0x00, 0x01, \\\n\t\tFEATURE, 0x02, \\\n\tEND_COLLECTION /* End Collection */"
  },
  {
    "path": "src/AmtPtpDeviceSpiKm/HID/SpiTrackpadSeries3.h",
    "content": "// Trackpad HID definition for MacBookPro 13, 14\n\n#pragma once\n\n#include \"..\\HidCommon.h\"\n\n#define AAPL_SPI_SERIES3_13_PTP_FINGER_COLLECTION_1 \\\n\tBEGIN_COLLECTION, 0x02, /* Begin Collection: Logical */ \\\n\t\t/* Begin a byte */ \\\n\t\tLOGICAL_MAXIMUM, 0x01, /* Logical Maximum: 1 */ \\\n\t\tUSAGE, 0x47, /* Usage: Confidence */ \\\n\t\tUSAGE, 0x42, /* Usage: Tip switch */ \\\n\t\tREPORT_COUNT, 0x02, /* Report Count: 2 */ \\\n\t\tREPORT_SIZE, 0x01, /* Report Size: 1 */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tREPORT_COUNT, 0x01, /* Report Count: 1 */ \\\n\t\tREPORT_SIZE, 0x03, /* Report Size: 3 */ \\\n\t\tLOGICAL_MAXIMUM, 0x03, /* Logical Maximum: 3 */ \\\n\t\tUSAGE, 0x51, /* Usage: Contract Identifier */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tREPORT_SIZE, 0x01, /* Report Size: 1 */ \\\n\t\tREPORT_COUNT, 0x03, /* Report Count: 3 */ \\\n\t\tINPUT, 0x03, /* Input: (Const, Var, Abs) */ \\\n\t\t/* End of a byte */ \\\n\t\t/* Begin of 4 bytes */ \\\n\t\t/* Size is hard-coded at this moment */ \\\n\t\t/* This hard-coded size is designed for MacBookPro 13 / 14 */ \\\n\t\tUSAGE_PAGE, 0x01, /* Usage Page: Generic Desktop */ \\\n\t\tLOGICAL_MAXIMUM_2, 0xc0, 0x32, /* Logical Maximum: 12992 (See defintion) */ \\\n\t\tREPORT_SIZE, 0x10, /* Report Size: 0x10 (2 bytes) */ \\\n\t\tUNIT_EXPONENT, 0x0e, /* Unit exponent: -2 */ \\\n\t\tUNIT, 0x11, /* Unit: SI Length (cm) */ \\\n\t\tUSAGE, 0x30, /* Usage: X */ \\\n\t\tPHYSICAL_MAXIMUM_2, 0x48, 0x05, /* Physical Maximum: 1352 (See Apple Spec) */ \\\n\t\tREPORT_COUNT, 0x01, /* Report count: 1 */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tPHYSICAL_MAXIMUM_2, 0x44, 0x03, /* Physical Maximum: 836 (See Apple Spec) */ \\\n\t\tLOGICAL_MAXIMUM_2, 0xaf, 0x1e, /* Logical Maximum: 7855 (See definition) */ \\\n\t\tUSAGE, 0x31, /* Usage: Y */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tPHYSICAL_MAXIMUM, 0x00, /* Physical Maximum: 0 */ \\\n\t\tUNIT_EXPONENT, 0x00, /* Unit exponent: 0 */ \\\n\t\tUNIT, 0x00, /* Unit: None */ \\\n\t\t/* End of 4 bytes */ \\\n\tEND_COLLECTION /* End Collection */ \\\n\n#define AAPL_SPI_SERIES3_13_PTP_FINGER_COLLECTION_2 \\\n\tBEGIN_COLLECTION, 0x02, /* Begin Collection: Logical */ \\\n\t\t/* Begin a byte */ \\\n\t\tLOGICAL_MAXIMUM, 0x01, /* Logical Maximum: 1 */ \\\n\t\tUSAGE, 0x47, /* Usage: Confidence */ \\\n\t\tUSAGE, 0x42, /* Usage: Tip switch */ \\\n\t\tREPORT_COUNT, 0x02, /* Report Count: 2 */ \\\n\t\tREPORT_SIZE, 0x01, /* Report Size: 1 */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tREPORT_COUNT, 0x01, /* Report Count: 1 */ \\\n\t\tREPORT_SIZE, 0x03, /* Report Size: 3 */ \\\n\t\tLOGICAL_MAXIMUM, 0x03, /* Logical Maximum: 3 */ \\\n\t\tUSAGE, 0x51, /* Usage: Contract Identifier */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tREPORT_SIZE, 0x01, /* Report Size: 1 */ \\\n\t\tREPORT_COUNT, 0x03, /* Report Count: 3 */ \\\n\t\tINPUT, 0x03, /* Input: (Const, Var, Abs) */ \\\n\t\t/* End of a byte */ \\\n\t\t/* Begin of 4 bytes */ \\\n\t\t/* Size is hard-coded at this moment */ \\\n\t\tUSAGE_PAGE, 0x01, /* Usage Page: Generic Desktop */ \\\n\t\tLOGICAL_MAXIMUM_2, 0xc0, 0x32, /* Logical Maximum: 12992 (See defintion) */ \\\n\t\tREPORT_SIZE, 0x10, /* Report Size: 0x10 (2 bytes) */ \\\n\t\tUNIT_EXPONENT, 0x0e, /* Unit exponent: -2 */ \\\n\t\tUNIT, 0x11, /* Unit: SI Length (cm) */ \\\n\t\tUSAGE, 0x30, /* Usage: X */ \\\n\t\tPHYSICAL_MAXIMUM_2, 0x48, 0x05, /* Physical Maximum: 1352 (See Apple Spec) */ \\\n\t\tREPORT_COUNT, 0x01, /* Report count: 1 */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tPHYSICAL_MAXIMUM_2, 0x44, 0x03, /* Physical Maximum: 836 (See Apple Spec) */ \\\n\t\tLOGICAL_MAXIMUM_2, 0xaf, 0x1e, /* Logical Maximum: 7855 (See definition) */ \\\n\t\tUSAGE, 0x31, /* Usage: Y */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\t/* End of 4 bytes */ \\\n\tEND_COLLECTION /* End Collection */ \\\n\n#define AAPL_SPI_SERIES3_13_PTP_TLC \\\n\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\tUSAGE, 0x05, /* Usage: Touch Pad */ \\\n\tBEGIN_COLLECTION, 0x01, /* Begin Collection: Application */ \\\n\t\tREPORT_ID, REPORTID_MULTITOUCH, /* Report ID: Multi-touch */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_SPI_SERIES3_13_PTP_FINGER_COLLECTION_1, /* 1 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_SPI_SERIES3_13_PTP_FINGER_COLLECTION_1, /* 2 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_SPI_SERIES3_13_PTP_FINGER_COLLECTION_2, /* 3 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_SPI_SERIES3_13_PTP_FINGER_COLLECTION_1, /* 4 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_SPI_SERIES3_13_PTP_FINGER_COLLECTION_2, /* 5 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUNIT_EXPONENT, 0x0c, /* Unit exponent: -4 */ \\\n\t\tUNIT_2, 0x01, 0x10, /* Time: Second */ \\\n\t\tPHYSICAL_MAXIMUM_3, 0xff, 0xff, 0x00, 0x00, \\\n\t\tLOGICAL_MAXIMUM_3, 0xff, 0xff, 0x00, 0x00, \\\n\t\tUSAGE, 0x56, /* Usage: Scan Time */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tUSAGE, 0x54, /* Usage: Contact Count */ \\\n\t\tLOGICAL_MAXIMUM, 0x7f, \\\n\t\tREPORT_SIZE, 0x08, \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tUSAGE_PAGE, 0x09, /* Usage Page: Button */ \\\n\t\tUSAGE, 0x01, /* Button 1 */ \\\n\t\tLOGICAL_MAXIMUM, 0x01, \\\n\t\tREPORT_SIZE, 0x01, \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tREPORT_COUNT, 0x07, \\\n\t\tINPUT, 0x03, /* Input: (Const, Var, Abs) */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tREPORT_ID, REPORTID_DEVICE_CAPS, \\\n\t\tUSAGE, 0x55, /* Usage: Maximum Contacts */ \\\n\t\tUSAGE, 0x59, /* Usage: Touchpad Button Type*/ \\\n\t\tLOGICAL_MINIMUM, 0x00, \\\n\t\tLOGICAL_MAXIMUM_2, 0xff, 0x00, \\\n\t\tREPORT_SIZE, 0x08, \\\n\t\tREPORT_COUNT, 0x02, \\\n\t\tFEATURE, 0x02, \\\n\t\tUSAGE_PAGE_1, 0x00, 0xff, \\\n\t\tREPORT_ID, REPORTID_PTPHQA, \\\n\t\tUSAGE, 0xc5, \\\n\t\tLOGICAL_MINIMUM, 0x00, \\\n\t\tLOGICAL_MAXIMUM_2, 0xff, 0x00, \\\n\t\tREPORT_SIZE, 0x08, \\\n\t\tREPORT_COUNT_2, 0x00, 0x01, \\\n\t\tFEATURE, 0x02, \\\n\tEND_COLLECTION /* End Collection */\n\n#define AAPL_SPI_SERIES3_13_TOUCHSCREEN_TLC \\\n\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\tUSAGE, 0x04, /* Usage: Touch Screen */ \\\n\tBEGIN_COLLECTION, 0x01, /* Begin Collection: Application */ \\\n\t\tREPORT_ID, REPORTID_MULTITOUCH, /* Report ID: Multi-touch */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_SPI_SERIES3_13_PTP_FINGER_COLLECTION_1, /* 1 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_SPI_SERIES3_13_PTP_FINGER_COLLECTION_1, /* 2 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_SPI_SERIES3_13_PTP_FINGER_COLLECTION_2, /* 3 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_SPI_SERIES3_13_PTP_FINGER_COLLECTION_1, /* 4 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_SPI_SERIES3_13_PTP_FINGER_COLLECTION_2, /* 5 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUNIT_EXPONENT, 0x0c, /* Unit exponent: -4 */ \\\n\t\tUNIT_2, 0x01, 0x10, /* Time: Second */ \\\n\t\tPHYSICAL_MAXIMUM_3, 0xff, 0xff, 0x00, 0x00, \\\n\t\tLOGICAL_MAXIMUM_3, 0xff, 0xff, 0x00, 0x00, \\\n\t\tUSAGE, 0x56, /* Usage: Scan Time */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tUSAGE, 0x54, /* Usage: Contact Count */ \\\n\t\tLOGICAL_MAXIMUM, 0x7f, \\\n\t\tREPORT_SIZE, 0x08, \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tUSAGE_PAGE, 0x09, /* Usage Page: Button */ \\\n\t\tUSAGE, 0x01, /* Button 1 */ \\\n\t\tLOGICAL_MAXIMUM, 0x01, \\\n\t\tREPORT_SIZE, 0x01, \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tREPORT_COUNT, 0x07, \\\n\t\tINPUT, 0x03, /* Input: (Const, Var, Abs) */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tREPORT_ID, REPORTID_DEVICE_CAPS, \\\n\t\tUSAGE, 0x55, /* Usage: Maximum Contacts */ \\\n\t\tUSAGE, 0x59, /* Usage: Touchpad Button Type*/ \\\n\t\tLOGICAL_MINIMUM, 0x00, \\\n\t\tLOGICAL_MAXIMUM_2, 0xff, 0x00, \\\n\t\tREPORT_SIZE, 0x08, \\\n\t\tREPORT_COUNT, 0x02, \\\n\t\tFEATURE, 0x02, \\\n\t\tUSAGE_PAGE_1, 0x00, 0xff, \\\n\t\tREPORT_ID, REPORTID_PTPHQA, \\\n\t\tUSAGE, 0xc5, \\\n\t\tLOGICAL_MINIMUM, 0x00, \\\n\t\tLOGICAL_MAXIMUM_2, 0xff, 0x00, \\\n\t\tREPORT_SIZE, 0x08, \\\n\t\tREPORT_COUNT_2, 0x00, 0x01, \\\n\t\tFEATURE, 0x02, \\\n\tEND_COLLECTION /* End Collection */\n\n#define AAPL_SPI_SERIES3_15_PTP_FINGER_COLLECTION_1 \\\n\tBEGIN_COLLECTION, 0x02, /* Begin Collection: Logical */ \\\n\t\t/* Begin a byte */ \\\n\t\tLOGICAL_MAXIMUM, 0x01, /* Logical Maximum: 1 */ \\\n\t\tUSAGE, 0x47, /* Usage: Confidence */ \\\n\t\tUSAGE, 0x42, /* Usage: Tip switch */ \\\n\t\tREPORT_COUNT, 0x02, /* Report Count: 2 */ \\\n\t\tREPORT_SIZE, 0x01, /* Report Size: 1 */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tREPORT_COUNT, 0x01, /* Report Count: 1 */ \\\n\t\tREPORT_SIZE, 0x03, /* Report Size: 3 */ \\\n\t\tLOGICAL_MAXIMUM, 0x03, /* Logical Maximum: 3 */ \\\n\t\tUSAGE, 0x51, /* Usage: Contract Identifier */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tREPORT_SIZE, 0x01, /* Report Size: 1 */ \\\n\t\tREPORT_COUNT, 0x03, /* Report Count: 3 */ \\\n\t\tINPUT, 0x03, /* Input: (Const, Var, Abs) */ \\\n\t\t/* End of a byte */ \\\n\t\t/* Begin of 4 bytes */ \\\n\t\t/* Size is hard-coded at this moment */ \\\n\t\t/* This hard-coded size is designed for MacBookPro 13 / 14 */ \\\n\t\tUSAGE_PAGE, 0x01, /* Usage Page: Generic Desktop */ \\\n\t\tLOGICAL_MAXIMUM_2, 0x48, 0x3c, /* Logical Maximum: 15432 (See defintion) */ \\\n\t\tREPORT_SIZE, 0x10, /* Report Size: 0x10 (2 bytes) */ \\\n\t\tUNIT_EXPONENT, 0x0e, /* Unit exponent: -2 */ \\\n\t\tUNIT, 0x11, /* Unit: SI Length (cm) */ \\\n\t\tUSAGE, 0x30, /* Usage: X */ \\\n\t\tPHYSICAL_MAXIMUM_2, 0x30, 0x06, /* Physical Maximum: 1584 (See Apple Spec) */ \\\n\t\tREPORT_COUNT, 0x01, /* Report count: 1 */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tPHYSICAL_MAXIMUM_2, 0xe0, 0x03, /* Physical Maximum: 992 (See Apple Spec) */ \\\n\t\tLOGICAL_MAXIMUM_2, 0xe6, 0x24, /* Logical Maximum: 9446 (See definition) */ \\\n\t\tUSAGE, 0x31, /* Usage: Y */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tPHYSICAL_MAXIMUM, 0x00, /* Physical Maximum: 0 */ \\\n\t\tUNIT_EXPONENT, 0x00, /* Unit exponent: 0 */ \\\n\t\tUNIT, 0x00, /* Unit: None */ \\\n\t\t/* End of 4 bytes */ \\\n\tEND_COLLECTION /* End Collection */ \\\n\n#define AAPL_SPI_SERIES3_15_PTP_FINGER_COLLECTION_2 \\\n\tBEGIN_COLLECTION, 0x02, /* Begin Collection: Logical */ \\\n\t\t/* Begin a byte */ \\\n\t\tLOGICAL_MAXIMUM, 0x01, /* Logical Maximum: 1 */ \\\n\t\tUSAGE, 0x47, /* Usage: Confidence */ \\\n\t\tUSAGE, 0x42, /* Usage: Tip switch */ \\\n\t\tREPORT_COUNT, 0x02, /* Report Count: 2 */ \\\n\t\tREPORT_SIZE, 0x01, /* Report Size: 1 */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tREPORT_COUNT, 0x01, /* Report Count: 1 */ \\\n\t\tREPORT_SIZE, 0x03, /* Report Size: 3 */ \\\n\t\tLOGICAL_MAXIMUM, 0x03, /* Logical Maximum: 3 */ \\\n\t\tUSAGE, 0x51, /* Usage: Contract Identifier */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tREPORT_SIZE, 0x01, /* Report Size: 1 */ \\\n\t\tREPORT_COUNT, 0x03, /* Report Count: 3 */ \\\n\t\tINPUT, 0x03, /* Input: (Const, Var, Abs) */ \\\n\t\t/* End of a byte */ \\\n\t\t/* Begin of 4 bytes */ \\\n\t\t/* Size is hard-coded at this moment */ \\\n\t\tUSAGE_PAGE, 0x01, /* Usage Page: Generic Desktop */ \\\n\t\tLOGICAL_MAXIMUM_2, 0x48, 0x3c, /* Logical Maximum: 15432 (See defintion) */ \\\n\t\tREPORT_SIZE, 0x10, /* Report Size: 0x10 (2 bytes) */ \\\n\t\tUNIT_EXPONENT, 0x0e, /* Unit exponent: -2 */ \\\n\t\tUNIT, 0x11, /* Unit: SI Length (cm) */ \\\n\t\tUSAGE, 0x30, /* Usage: X */ \\\n\t\tPHYSICAL_MAXIMUM_2, 0x30, 0x06, /* Physical Maximum: 1584 (See Apple Spec) */ \\\n\t\tREPORT_COUNT, 0x01, /* Report count: 1 */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tPHYSICAL_MAXIMUM_2, 0xe0, 0x03, /* Physical Maximum: 992 (See Apple Spec) */ \\\n\t\tLOGICAL_MAXIMUM_2, 0xe6, 0x24, /* Logical Maximum: 9446 (See definition) */ \\\n\t\tUSAGE, 0x31, /* Usage: Y */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\t/* End of 4 bytes */ \\\n\tEND_COLLECTION /* End Collection */ \\\n\n#define AAPL_SPI_SERIES3_15_PTP_TLC \\\n\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\tUSAGE, 0x05, /* Usage: Touch Pad */ \\\n\tBEGIN_COLLECTION, 0x01, /* Begin Collection: Application */ \\\n\t\tREPORT_ID, REPORTID_MULTITOUCH, /* Report ID: Multi-touch */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_SPI_SERIES3_15_PTP_FINGER_COLLECTION_1, /* 1 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_SPI_SERIES3_15_PTP_FINGER_COLLECTION_1, /* 2 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_SPI_SERIES3_15_PTP_FINGER_COLLECTION_2, /* 3 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_SPI_SERIES3_15_PTP_FINGER_COLLECTION_1, /* 4 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_SPI_SERIES3_15_PTP_FINGER_COLLECTION_2, /* 5 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUNIT_EXPONENT, 0x0c, /* Unit exponent: -4 */ \\\n\t\tUNIT_2, 0x01, 0x10, /* Time: Second */ \\\n\t\tPHYSICAL_MAXIMUM_3, 0xff, 0xff, 0x00, 0x00, \\\n\t\tLOGICAL_MAXIMUM_3, 0xff, 0xff, 0x00, 0x00, \\\n\t\tUSAGE, 0x56, /* Usage: Scan Time */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tUSAGE, 0x54, /* Usage: Contact Count */ \\\n\t\tLOGICAL_MAXIMUM, 0x7f, \\\n\t\tREPORT_SIZE, 0x08, \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tUSAGE_PAGE, 0x09, /* Usage Page: Button */ \\\n\t\tUSAGE, 0x01, /* Button 1 */ \\\n\t\tLOGICAL_MAXIMUM, 0x01, \\\n\t\tREPORT_SIZE, 0x01, \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tREPORT_COUNT, 0x07, \\\n\t\tINPUT, 0x03, /* Input: (Const, Var, Abs) */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tREPORT_ID, REPORTID_DEVICE_CAPS, \\\n\t\tUSAGE, 0x55, /* Usage: Maximum Contacts */ \\\n\t\tUSAGE, 0x59, /* Usage: Touchpad Button Type*/ \\\n\t\tLOGICAL_MINIMUM, 0x00, \\\n\t\tLOGICAL_MAXIMUM_2, 0xff, 0x00, \\\n\t\tREPORT_SIZE, 0x08, \\\n\t\tREPORT_COUNT, 0x02, \\\n\t\tFEATURE, 0x02, \\\n\t\tUSAGE_PAGE_1, 0x00, 0xff, \\\n\t\tREPORT_ID, REPORTID_PTPHQA, \\\n\t\tUSAGE, 0xc5, \\\n\t\tLOGICAL_MINIMUM, 0x00, \\\n\t\tLOGICAL_MAXIMUM_2, 0xff, 0x00, \\\n\t\tREPORT_SIZE, 0x08, \\\n\t\tREPORT_COUNT_2, 0x00, 0x01, \\\n\t\tFEATURE, 0x02, \\\n\tEND_COLLECTION /* End Collection */\n\n#define AAPL_SPI_SERIES3_15_TOUCHSCREEN_TLC \\\n\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\tUSAGE, 0x04, /* Usage: Touch Screen */ \\\n\tBEGIN_COLLECTION, 0x01, /* Begin Collection: Application */ \\\n\t\tREPORT_ID, REPORTID_MULTITOUCH, /* Report ID: Multi-touch */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_SPI_SERIES3_15_PTP_FINGER_COLLECTION_1, /* 1 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_SPI_SERIES3_15_PTP_FINGER_COLLECTION_1, /* 2 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_SPI_SERIES3_15_PTP_FINGER_COLLECTION_2, /* 3 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_SPI_SERIES3_15_PTP_FINGER_COLLECTION_1, /* 4 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_SPI_SERIES3_15_PTP_FINGER_COLLECTION_2, /* 5 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUNIT_EXPONENT, 0x0c, /* Unit exponent: -4 */ \\\n\t\tUNIT_2, 0x01, 0x10, /* Time: Second */ \\\n\t\tPHYSICAL_MAXIMUM_3, 0xff, 0xff, 0x00, 0x00, \\\n\t\tLOGICAL_MAXIMUM_3, 0xff, 0xff, 0x00, 0x00, \\\n\t\tUSAGE, 0x56, /* Usage: Scan Time */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tUSAGE, 0x54, /* Usage: Contact Count */ \\\n\t\tLOGICAL_MAXIMUM, 0x7f, \\\n\t\tREPORT_SIZE, 0x08, \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tUSAGE_PAGE, 0x09, /* Usage Page: Button */ \\\n\t\tUSAGE, 0x01, /* Button 1 */ \\\n\t\tLOGICAL_MAXIMUM, 0x01, \\\n\t\tREPORT_SIZE, 0x01, \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tREPORT_COUNT, 0x07, \\\n\t\tINPUT, 0x03, /* Input: (Const, Var, Abs) */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tREPORT_ID, REPORTID_DEVICE_CAPS, \\\n\t\tUSAGE, 0x55, /* Usage: Maximum Contacts */ \\\n\t\tUSAGE, 0x59, /* Usage: Touchpad Button Type*/ \\\n\t\tLOGICAL_MINIMUM, 0x00, \\\n\t\tLOGICAL_MAXIMUM_2, 0xff, 0x00, \\\n\t\tREPORT_SIZE, 0x08, \\\n\t\tREPORT_COUNT, 0x02, \\\n\t\tFEATURE, 0x02, \\\n\t\tUSAGE_PAGE_1, 0x00, 0xff, \\\n\t\tREPORT_ID, REPORTID_PTPHQA, \\\n\t\tUSAGE, 0xc5, \\\n\t\tLOGICAL_MINIMUM, 0x00, \\\n\t\tLOGICAL_MAXIMUM_2, 0xff, 0x00, \\\n\t\tREPORT_SIZE, 0x08, \\\n\t\tREPORT_COUNT_2, 0x00, 0x01, \\\n\t\tFEATURE, 0x02, \\\n\tEND_COLLECTION /* End Collection */"
  },
  {
    "path": "src/AmtPtpDeviceSpiKm/Hid.c",
    "content": "// Hid.c: HID-related routine\n\n#include \"Driver.h\"\n#include \"Hid.tmh\"\n\n#ifndef __AAPL_HID_DESCRIPTOR_H__\n#define __AAPL_HID_DESCRIPTOR_H__\n\nHID_REPORT_DESCRIPTOR AmtPtpSpiFamily1ReportDescriptor[] = {\n\tAAPL_SPI_SERIES1_PTP_TLC,\n\tAAPL_PTP_WINDOWS_CONFIGURATION_TLC,\n\tAAPL_PTP_USERMODE_CONFIGURATION_APP_TLC\n};\n\nHID_REPORT_DESCRIPTOR AmtPtpSpiFamily1TouchscreenReportDescriptor[] = {\n\tAAPL_SPI_SERIES1_TOUCHSCREEN_TLC,\n\tAAPL_PTP_WINDOWS_CONFIGURATION_TLC,\n\tAAPL_PTP_USERMODE_CONFIGURATION_APP_TLC\n};\n\nCONST HID_DESCRIPTOR AmtPtpSpiFamily1DefaultHidDescriptor = {\n\t0x09,   // bLength\n\t0x21,   // bDescriptorType\n\t0x0100, // bcdHID\n\t0x00,   // bCountryCode\n\t0x01,   // bNumDescriptors\n\t{\n\t\t0x22,\t\t\t\t\t\t\t\t\t\t// bDescriptorType\n\t\tsizeof(AmtPtpSpiFamily1ReportDescriptor)    // bDescriptorLength\n\t}\n};\n\nHID_REPORT_DESCRIPTOR AmtPtpSpiFamily2ReportDescriptor[] = {\n\tAAPL_SPI_SERIES2_PTP_TLC,\n\tAAPL_PTP_WINDOWS_CONFIGURATION_TLC,\n\tAAPL_PTP_USERMODE_CONFIGURATION_APP_TLC\n};\n\nHID_REPORT_DESCRIPTOR AmtPtpSpiFamily2TouchscreenReportDescriptor[] = {\n\tAAPL_SPI_SERIES2_TOUCHSCREEN_TLC,\n\tAAPL_PTP_WINDOWS_CONFIGURATION_TLC,\n\tAAPL_PTP_USERMODE_CONFIGURATION_APP_TLC\n};\n\nCONST HID_DESCRIPTOR AmtPtpSpiFamily2DefaultHidDescriptor = {\n\t0x09,   // bLength\n\t0x21,   // bDescriptorType\n\t0x0100, // bcdHID\n\t0x00,   // bCountryCode\n\t0x01,   // bNumDescriptors\n\t{\n\t\t0x22,\t\t\t\t\t\t\t\t\t\t// bDescriptorType\n\t\tsizeof(AmtPtpSpiFamily2ReportDescriptor)    // bDescriptorLength\n\t}\n};\n\nHID_REPORT_DESCRIPTOR AmtPtpSpiFamily3aReportDescriptor[] = {\n\tAAPL_SPI_SERIES3_13_PTP_TLC,\n\tAAPL_PTP_WINDOWS_CONFIGURATION_TLC,\n\tAAPL_PTP_USERMODE_CONFIGURATION_APP_TLC\n};\n\nHID_REPORT_DESCRIPTOR AmtPtpSpiFamily3aTouchscreenReportDescriptor[] = {\n\tAAPL_SPI_SERIES3_13_TOUCHSCREEN_TLC,\n\tAAPL_PTP_WINDOWS_CONFIGURATION_TLC,\n\tAAPL_PTP_USERMODE_CONFIGURATION_APP_TLC\n};\n\nCONST HID_DESCRIPTOR AmtPtpSpiFamily3aDefaultHidDescriptor = {\n\t0x09,   // bLength\n\t0x21,   // bDescriptorType\n\t0x0100, // bcdHID\n\t0x00,   // bCountryCode\n\t0x01,   // bNumDescriptors\n\t{\n\t\t0x22,\t\t\t\t\t\t\t\t\t\t// bDescriptorType\n\t\tsizeof(AmtPtpSpiFamily3aReportDescriptor)    // bDescriptorLength\n\t}\n};\n\nHID_REPORT_DESCRIPTOR AmtPtpSpiFamily3bReportDescriptor[] = {\n\tAAPL_SPI_SERIES3_15_PTP_TLC,\n\tAAPL_PTP_WINDOWS_CONFIGURATION_TLC,\n\tAAPL_PTP_USERMODE_CONFIGURATION_APP_TLC\n};\n\nHID_REPORT_DESCRIPTOR AmtPtpSpiFamily3bTouchscreenReportDescriptor[] = {\n\tAAPL_SPI_SERIES3_15_TOUCHSCREEN_TLC,\n\tAAPL_PTP_WINDOWS_CONFIGURATION_TLC,\n\tAAPL_PTP_USERMODE_CONFIGURATION_APP_TLC\n};\n\nCONST HID_DESCRIPTOR AmtPtpSpiFamily3bDefaultHidDescriptor = {\n\t0x09,   // bLength\n\t0x21,   // bDescriptorType\n\t0x0100, // bcdHID\n\t0x00,   // bCountryCode\n\t0x01,   // bNumDescriptors\n\t{\n\t\t0x22,\t\t\t\t\t\t\t\t\t\t// bDescriptorType\n\t\tsizeof(AmtPtpSpiFamily3bReportDescriptor)    // bDescriptorLength\n\t}\n};\n\n#endif\n\n_IRQL_requires_(PASSIVE_LEVEL)\nNTSTATUS\nAmtPtpGetHidDescriptor(\n\t_In_ WDFDEVICE Device,\n\t_In_ WDFREQUEST Request\n)\n{\n\tNTSTATUS Status = STATUS_SUCCESS;\n\tWDFMEMORY RequestMemory;\n\tsize_t CopiedSize = 0;\n\tPDEVICE_CONTEXT pDeviceContext;\n\tBOOLEAN DescriptorFound = TRUE;\n\n\tPAGED_CODE();\n\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION,\n\t\tTRACE_DRIVER,\n\t\t\"%!FUNC! Entry\"\n\t);\n\n\tpDeviceContext = DeviceGetContext(Device);\n\tStatus = WdfRequestRetrieveOutputMemory(\n\t\tRequest,\n\t\t&RequestMemory\n\t);\n\n\tif (!NT_SUCCESS(Status))\n\t{\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_ERROR,\n\t\t\tTRACE_DRIVER,\n\t\t\t\"%!FUNC! WdfRequestRetrieveOutputBuffer failed with %!STATUS!\",\n\t\t\tStatus\n\t\t);\n\n\t\tgoto exit;\n\t}\n\n\t// Get HID descriptor from registry\n\tswitch (pDeviceContext->HidProductID)\n\t{\n\t\t// MacBook 9, 10\n\t\tcase 0x0275:\n\t\tcase 0x0279:\n\t\t// MacBookAir7,2 also use this fallback\n\t\tcase 0x0290:\n\t\tcase 0x0291:\n\t\t{\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_INFORMATION,\n\t\t\t\tTRACE_DRIVER,\n\t\t\t\t\"%!FUNC! Request HID Report Descriptor for Apple SPI Trackpad, Family 1\"\n\t\t\t);\n\n\t\t\tCopiedSize = AmtPtpSpiFamily1DefaultHidDescriptor.bLength;\n\t\t\tStatus = WdfMemoryCopyFromBuffer(\n\t\t\t\tRequestMemory,\n\t\t\t\t0,\n\t\t\t\t(PVOID)&AmtPtpSpiFamily1DefaultHidDescriptor,\n\t\t\t\tCopiedSize\n\t\t\t);\n\n\t\t\tif (!NT_SUCCESS(Status))\n\t\t\t{\n\t\t\t\tTraceEvents(\n\t\t\t\t\tTRACE_LEVEL_ERROR,\n\t\t\t\t\tTRACE_DRIVER,\n\t\t\t\t\t\"%!FUNC! WdfMemoryCopyFromBuffer failed with %!STATUS!\",\n\t\t\t\t\tStatus\n\t\t\t\t);\n\t\t\t\treturn Status;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\t// MacBookPro 11, 12 (13-inch). 15-inch is USB trackpad\n\t\tcase 0x0272:\n\t\tcase 0x0273:\n\t\t{\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_INFORMATION,\n\t\t\t\tTRACE_DRIVER,\n\t\t\t\t\"%!FUNC! Request HID Report Descriptor for Apple SPI Trackpad, Family 2\"\n\t\t\t);\n\n\t\t\tCopiedSize = AmtPtpSpiFamily2DefaultHidDescriptor.bLength;\n\t\t\tStatus = WdfMemoryCopyFromBuffer(\n\t\t\t\tRequestMemory,\n\t\t\t\t0,\n\t\t\t\t(PVOID)&AmtPtpSpiFamily2DefaultHidDescriptor,\n\t\t\t\tCopiedSize\n\t\t\t);\n\n\t\t\tif (!NT_SUCCESS(Status))\n\t\t\t{\n\t\t\t\tTraceEvents(\n\t\t\t\t\tTRACE_LEVEL_ERROR,\n\t\t\t\t\tTRACE_DRIVER,\n\t\t\t\t\t\"%!FUNC! WdfMemoryCopyFromBuffer failed with %!STATUS!\",\n\t\t\t\t\tStatus\n\t\t\t\t);\n\t\t\t\treturn Status;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\t// MacBookPro 13, 14 (13-inch)\n\t\tcase 0x0276:\n\t\tcase 0x0277:\n\t\t{\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_INFORMATION,\n\t\t\t\tTRACE_DRIVER,\n\t\t\t\t\"%!FUNC! Request HID Report Descriptor for Apple SPI Trackpad, Family 3A\"\n\t\t\t);\n\n\t\t\tCopiedSize = AmtPtpSpiFamily3aDefaultHidDescriptor.bLength;\n\t\t\tStatus = WdfMemoryCopyFromBuffer(\n\t\t\t\tRequestMemory,\n\t\t\t\t0,\n\t\t\t\t(PVOID)&AmtPtpSpiFamily3aDefaultHidDescriptor,\n\t\t\t\tCopiedSize\n\t\t\t);\n\n\t\t\tif (!NT_SUCCESS(Status))\n\t\t\t{\n\t\t\t\tTraceEvents(\n\t\t\t\t\tTRACE_LEVEL_ERROR,\n\t\t\t\t\tTRACE_DRIVER,\n\t\t\t\t\t\"%!FUNC! WdfMemoryCopyFromBuffer failed with %!STATUS!\",\n\t\t\t\t\tStatus\n\t\t\t\t);\n\t\t\t\treturn Status;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\t// MacBookPro 13, 14 (15-inch)\n\t\tcase 0x0278:\n\t\t{\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_INFORMATION,\n\t\t\t\tTRACE_DRIVER,\n\t\t\t\t\"%!FUNC! Request HID Report Descriptor for Apple SPI Trackpad, Family 3B\"\n\t\t\t);\n\n\t\t\tCopiedSize = AmtPtpSpiFamily3bDefaultHidDescriptor.bLength;\n\t\t\tStatus = WdfMemoryCopyFromBuffer(\n\t\t\t\tRequestMemory,\n\t\t\t\t0,\n\t\t\t\t(PVOID)&AmtPtpSpiFamily3bDefaultHidDescriptor,\n\t\t\t\tCopiedSize\n\t\t\t);\n\n\t\t\tif (!NT_SUCCESS(Status))\n\t\t\t{\n\t\t\t\tTraceEvents(\n\t\t\t\t\tTRACE_LEVEL_ERROR,\n\t\t\t\t\tTRACE_DRIVER,\n\t\t\t\t\t\"%!FUNC! WdfMemoryCopyFromBuffer failed with %!STATUS!\",\n\t\t\t\t\tStatus\n\t\t\t\t);\n\t\t\t\treturn Status;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tdefault:\n\t\t{\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_INFORMATION,\n\t\t\t\tTRACE_DRIVER,\n\t\t\t\t\"%!FUNC! Request HID Report Descriptor not found\"\n\t\t\t);\n\n\t\t\tDescriptorFound = FALSE;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (DescriptorFound)\n\t{\n\t\tWdfRequestSetInformation(\n\t\t\tRequest,\n\t\t\tCopiedSize\n\t\t);\n\t}\n\telse\n\t{\n\t\tStatus = STATUS_NOT_FOUND;\n\t}\n\nexit:\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION,\n\t\tTRACE_DRIVER,\n\t\t\"%!FUNC! Exit\"\n\t);\n\n\treturn Status;\n}\n\n_IRQL_requires_(PASSIVE_LEVEL)\nNTSTATUS\nAmtPtpGetDeviceAttribs(\n\t_In_ WDFDEVICE Device,\n\t_In_ WDFREQUEST Request\n)\n{\n\tNTSTATUS Status = STATUS_SUCCESS;\n\tPDEVICE_CONTEXT pDeviceContext = DeviceGetContext(Device);\n\tPHID_DEVICE_ATTRIBUTES pDeviceAttributes = NULL;\n\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION,\n\t\tTRACE_DRIVER,\n\t\t\"%!FUNC! Entry\"\n\t);\n\n\tStatus = WdfRequestRetrieveOutputBuffer(\n\t\tRequest,\n\t\tsizeof(HID_DEVICE_ATTRIBUTES),\n\t\t&pDeviceAttributes,\n\t\tNULL\n\t);\n\n\tif (!NT_SUCCESS(Status)) \n\t{\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_ERROR,\n\t\t\tTRACE_DRIVER,\n\t\t\t\"%!FUNC! WdfRequestRetrieveOutputBuffer failed with %!STATUS!\",\n\t\t\tStatus\n\t\t);\n\t\t\n\t\tgoto exit;\n\t}\n\n\tpDeviceAttributes->Size = sizeof(HID_DEVICE_ATTRIBUTES);\n\t// Okay here's one thing: we cannot report the real ID here, otherwise there's will be some great conflict with the USB/BT driver.\n\t// Therefore Vendor ID is changed to a hardcoded number\n\tpDeviceAttributes->VendorID = DEVICE_VID;\n\tpDeviceAttributes->ProductID = pDeviceContext->HidProductID;\n\tpDeviceAttributes->VersionNumber = pDeviceContext->HidVersionNumber;\n\n\tWdfRequestSetInformation(\n\t\tRequest,\n\t\tsizeof(HID_DEVICE_ATTRIBUTES)\n\t);\n\nexit:\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION,\n\t\tTRACE_DRIVER,\n\t\t\"%!FUNC! Exit\"\n\t);\n\n\treturn Status;\n}\n\n_IRQL_requires_(PASSIVE_LEVEL)\nNTSTATUS\nAmtPtpGetReportDescriptor(\n\t_In_ WDFDEVICE Device,\n\t_In_ WDFREQUEST Request\n)\n{\n\tNTSTATUS Status = STATUS_SUCCESS;\n\tsize_t CopiedSize = 0;\n\tWDFMEMORY RequestMemory;\n\tPDEVICE_CONTEXT pDeviceContext;\n\tPVOID Descriptor = NULL;\n\n\tPAGED_CODE();\n\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION,\n\t\tTRACE_DRIVER,\n\t\t\"%!FUNC! Entry\"\n\t);\n\n\tpDeviceContext = DeviceGetContext(Device);\n\tStatus = WdfRequestRetrieveOutputMemory(\n\t\tRequest,\n\t\t&RequestMemory\n\t);\n\n\tif (!NT_SUCCESS(Status))\n\t{\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_ERROR,\n\t\t\tTRACE_DRIVER,\n\t\t\t\"%!FUNC! WdfRequestRetrieveOutputBuffer failed with %!STATUS!\",\n\t\t\tStatus\n\t\t);\n\t\t\n\t\tgoto exit;\n\t}\n\n\tswitch (pDeviceContext->HidProductID)\n\t{\n\t\t// MacBook 9, 10\n\t\tcase 0x0275:\n\t\tcase 0x0279:\n\t\t// MacBookAir7,2 also use this fallback\n\t\tcase 0x0290:\n\t\tcase 0x0291:\n\t\t{\n\t\t\tif (pDeviceContext->ReportType == PrecisionTouchpad)\n\t\t\t{\n\t\t\t\tCopiedSize = AmtPtpSpiFamily1DefaultHidDescriptor.DescriptorList[0].wReportLength;\n\t\t\t\tDescriptor = (PVOID) &AmtPtpSpiFamily1ReportDescriptor;\n\t\t\t}\n\t\t\telse if (pDeviceContext->ReportType == Touchscreen)\n\t\t\t{\n\t\t\t\tCopiedSize = AmtPtpSpiFamily1DefaultHidDescriptor.DescriptorList[0].wReportLength;\n\t\t\t\tDescriptor = (PVOID) &AmtPtpSpiFamily1TouchscreenReportDescriptor;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\t// MacBookPro 11, 12 (13-inch)\n\t\tcase 0x0272:\n\t\tcase 0x0273:\n\t\t{\n\t\t\tif (pDeviceContext->ReportType == PrecisionTouchpad)\n\t\t\t{\n\t\t\t\tCopiedSize = AmtPtpSpiFamily2DefaultHidDescriptor.DescriptorList[0].wReportLength;\n\t\t\t\tDescriptor = (PVOID)&AmtPtpSpiFamily2ReportDescriptor;\n\t\t\t}\n\t\t\telse if (pDeviceContext->ReportType == Touchscreen)\n\t\t\t{\n\t\t\t\tCopiedSize = AmtPtpSpiFamily2DefaultHidDescriptor.DescriptorList[0].wReportLength;\n\t\t\t\tDescriptor = (PVOID)&AmtPtpSpiFamily2TouchscreenReportDescriptor;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\t// MacBookPro 13, 14 (13-inch)\n\t\tcase 0x0276:\n\t\tcase 0x0277:\n\t\t{\n\t\t\tif (pDeviceContext->ReportType == PrecisionTouchpad)\n\t\t\t{\n\t\t\t\tCopiedSize = AmtPtpSpiFamily3aDefaultHidDescriptor.DescriptorList[0].wReportLength;\n\t\t\t\tDescriptor = (PVOID)&AmtPtpSpiFamily3aReportDescriptor;\n\t\t\t}\n\t\t\telse if (pDeviceContext->ReportType == Touchscreen)\n\t\t\t{\n\t\t\t\tCopiedSize = AmtPtpSpiFamily3aDefaultHidDescriptor.DescriptorList[0].wReportLength;\n\t\t\t\tDescriptor = (PVOID)&AmtPtpSpiFamily3aTouchscreenReportDescriptor;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\t// MacBookPro 13, 14 (15-inch)\n\t\tcase 0x0278:\n\t\t{\n\t\t\tif (pDeviceContext->ReportType == PrecisionTouchpad)\n\t\t\t{\n\t\t\t\tCopiedSize = AmtPtpSpiFamily3bDefaultHidDescriptor.DescriptorList[0].wReportLength;\n\t\t\t\tDescriptor = (PVOID)&AmtPtpSpiFamily3bReportDescriptor;\n\t\t\t}\n\t\t\telse if (pDeviceContext->ReportType == Touchscreen)\n\t\t\t{\n\t\t\t\tCopiedSize = AmtPtpSpiFamily3bDefaultHidDescriptor.DescriptorList[0].wReportLength;\n\t\t\t\tDescriptor = (PVOID)&AmtPtpSpiFamily3bTouchscreenReportDescriptor;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tdefault:\n\t\t{\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (Descriptor == NULL)\n\t{\n\t\tStatus = STATUS_NOT_FOUND;\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_WARNING,\n\t\t\tTRACE_DRIVER,\n\t\t\t\"%!FUNC! Device HID descriptor not found\"\n\t\t);\n\t\treturn Status;\n\t}\n\n\tif (CopiedSize == 0)\n\t{\n\t\tStatus = STATUS_INVALID_DEVICE_STATE;\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_WARNING,\n\t\t\tTRACE_DRIVER,\n\t\t\t\"%!FUNC! Device HID report length is zero\"\n\t\t);\n\t\treturn Status;\n\t}\n\n\tStatus = WdfMemoryCopyFromBuffer(\n\t\tRequestMemory,\n\t\t0,\n\t\tDescriptor,\n\t\tCopiedSize\n\t);\n\n\tif (!NT_SUCCESS(Status)) {\n\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_ERROR,\n\t\t\tTRACE_DRIVER,\n\t\t\t\"%!FUNC! WdfMemoryCopyFromBuffer failed with %!STATUS!\",\n\t\t\tStatus\n\t\t);\n\t\treturn Status;\n\n\t}\n\n\tWdfRequestSetInformation(\n\t\tRequest,\n\t\tCopiedSize\n\t);\n\nexit:\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION,\n\t\tTRACE_DRIVER,\n\t\t\"%!FUNC! Exit\"\n\t);\n\n\treturn Status;\n}\n\n_IRQL_requires_(PASSIVE_LEVEL)\nNTSTATUS\nAmtPtpGetStrings(\n\t_In_ WDFDEVICE Device,\n\t_In_ WDFREQUEST Request,\n\t_Out_ BOOLEAN *Pending\n)\n{\n\tNTSTATUS Status = STATUS_SUCCESS;\n\tPDEVICE_CONTEXT pDeviceContext;\n\tBOOLEAN RequestSent;\n\tWDF_REQUEST_SEND_OPTIONS SendOptions;\n\n\tPAGED_CODE();\n\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION,\n\t\tTRACE_DRIVER,\n\t\t\"%!FUNC! called\"\n\t);\n\n\tpDeviceContext = DeviceGetContext(Device);\n\n\t// Forward the IRP to our upstream IO target\n\t// We don't really care about the content\n\tWdfRequestFormatRequestUsingCurrentType(Request);\n\tWDF_REQUEST_SEND_OPTIONS_INIT(\n\t\t&SendOptions,\n\t\tWDF_REQUEST_SEND_OPTION_SEND_AND_FORGET\n\t);\n\n\tRequestSent = WdfRequestSend(\n\t\tRequest,\n\t\tpDeviceContext->SpiTrackpadIoTarget,\n\t\t&SendOptions\n\t);\n\n\t*Pending = TRUE;\n\n\tif (!RequestSent)\n\t{\n\t\tStatus = WdfRequestGetStatus(Request);\n\t\t*Pending = FALSE;\n\t}\n\n\treturn Status;\n}\n\n_IRQL_requires_(PASSIVE_LEVEL)\nNTSTATUS\nAmtPtpReportFeatures(\n\t_In_ WDFDEVICE Device,\n\t_In_ WDFREQUEST Request\n)\n{\n\tNTSTATUS Status;\n\tPDEVICE_CONTEXT pDeviceContext;\n\tPHID_XFER_PACKET pHidPacket;\n\tWDF_REQUEST_PARAMETERS RequestParameters;\n\tsize_t ReportSize;\n\n\tPAGED_CODE();\n\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION,\n\t\tTRACE_DRIVER,\n\t\t\"%!FUNC! Entry\"\n\t);\n\n\tStatus = STATUS_SUCCESS;\n\tpDeviceContext = DeviceGetContext(Device);\n\n\tWDF_REQUEST_PARAMETERS_INIT(&RequestParameters);\n\tWdfRequestGetParameters(Request, &RequestParameters);\n\n\tif (RequestParameters.Parameters.DeviceIoControl.OutputBufferLength < sizeof(HID_XFER_PACKET))\n\t{\n\t\tStatus = STATUS_BUFFER_TOO_SMALL;\n\t\tgoto exit;\n\t}\n\n\tpHidPacket = (PHID_XFER_PACKET) WdfRequestWdmGetIrp(Request)->UserBuffer;\n\tif (pHidPacket == NULL)\n\t{\n\t\tStatus = STATUS_INVALID_DEVICE_REQUEST;\n\t\tgoto exit;\n\t}\n\n\tswitch (pHidPacket->reportId)\n\t{\n\t\tcase REPORTID_DEVICE_CAPS:\n\t\t{\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_INFORMATION,\n\t\t\t\tTRACE_DRIVER,\n\t\t\t\t\"%!FUNC! Report REPORTID_DEVICE_CAPS is requested\"\n\t\t\t);\n\n\t\t\t// Size sanity check\n\t\t\tReportSize = sizeof(PTP_DEVICE_CAPS_FEATURE_REPORT);\n\t\t\tif (pHidPacket->reportBufferLen < ReportSize) {\n\t\t\t\tStatus = STATUS_INVALID_BUFFER_SIZE;\n\t\t\t\tTraceEvents(\n\t\t\t\t\tTRACE_LEVEL_ERROR,\n\t\t\t\t\tTRACE_DRIVER,\n\t\t\t\t\t\"%!FUNC! Report buffer is too small\"\n\t\t\t\t);\n\t\t\t\tgoto exit;\n\t\t\t}\n\n\t\t\tPPTP_DEVICE_CAPS_FEATURE_REPORT capsReport = (PPTP_DEVICE_CAPS_FEATURE_REPORT) pHidPacket->reportBuffer;\n\n\t\t\tcapsReport->MaximumContactPoints = PTP_MAX_CONTACT_POINTS;\n\t\t\tcapsReport->ButtonType = PTP_BUTTON_TYPE_CLICK_PAD;\n\t\t\tcapsReport->ReportID = REPORTID_DEVICE_CAPS;\n\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_INFORMATION,\n\t\t\t\tTRACE_DRIVER,\n\t\t\t\t\"%!FUNC! Report REPORTID_DEVICE_CAPS has maximum contact points of %d\",\n\t\t\t\tcapsReport->MaximumContactPoints\n\t\t\t);\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_INFORMATION,\n\t\t\t\tTRACE_DRIVER,\n\t\t\t\t\"%!FUNC! Report REPORTID_DEVICE_CAPS has touchpad type %d\",\n\t\t\t\tcapsReport->ButtonType\n\t\t\t);\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_INFORMATION,\n\t\t\t\tTRACE_DRIVER,\n\t\t\t\t\"%!FUNC! Report REPORTID_DEVICE_CAPS is fulfilled\"\n\t\t\t);\n\n\t\t\tbreak;\n\t\t}\n\t\tcase REPORTID_PTPHQA:\n\t\t{\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_INFORMATION,\n\t\t\t\tTRACE_DRIVER,\n\t\t\t\t\"%!FUNC! Report REPORTID_PTPHQA is requested\"\n\t\t\t);\n\n\t\t\t// Size sanity check\n\t\t\tReportSize = sizeof(PTP_DEVICE_HQA_CERTIFICATION_REPORT);\n\t\t\tif (pHidPacket->reportBufferLen < ReportSize) \n\t\t\t{\n\t\t\t\tStatus = STATUS_INVALID_BUFFER_SIZE;\n\t\t\t\tTraceEvents(\n\t\t\t\t\tTRACE_LEVEL_ERROR,\n\t\t\t\t\tTRACE_DRIVER,\n\t\t\t\t\t\"%!FUNC! Report buffer is too small.\"\n\t\t\t\t);\n\t\t\t\tgoto exit;\n\t\t\t}\n\n\t\t\tPPTP_DEVICE_HQA_CERTIFICATION_REPORT certReport = (PPTP_DEVICE_HQA_CERTIFICATION_REPORT) pHidPacket->reportBuffer;\n\n\t\t\t*certReport->CertificationBlob = DEFAULT_PTP_HQA_BLOB;\n\t\t\tcertReport->ReportID = REPORTID_PTPHQA;\n\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_INFORMATION,\n\t\t\t\tTRACE_DRIVER,\n\t\t\t\t\"%!FUNC! Report REPORTID_PTPHQA is fulfilled\"\n\t\t\t);\n\n\t\t\tbreak;\n\t\t}\n\t\tdefault:\n\t\t{\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_INFORMATION,\n\t\t\t\tTRACE_DRIVER,\n\t\t\t\t\"%!FUNC! Unsupported type %d is requested\",\n\t\t\t\tpHidPacket->reportId\n\t\t\t);\n\n\t\t\tStatus = STATUS_NOT_SUPPORTED;\n\t\t\tgoto exit;\n\t\t}\n\t}\n\nexit:\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION,\n\t\tTRACE_DRIVER,\n\t\t\"%!FUNC! Exit\"\n\t);\n\n\treturn Status;\n}\n\n_IRQL_requires_(PASSIVE_LEVEL)\nNTSTATUS\nAmtPtpSetFeatures(\n\t_In_ WDFDEVICE Device,\n\t_In_ WDFREQUEST Request\n)\n{\n\tNTSTATUS        Status;\n\tPHID_XFER_PACKET pHidPacket;\n\tWDF_REQUEST_PARAMETERS RequestParameters;\n\tPDEVICE_CONTEXT pDeviceContext;\n\n\tPAGED_CODE();\n\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION,\n\t\tTRACE_DRIVER,\n\t\t\"%!FUNC! Entry\"\n\t);\n\n\tStatus = STATUS_SUCCESS;\n\tpDeviceContext = DeviceGetContext(Device);\n\n\tWDF_REQUEST_PARAMETERS_INIT(&RequestParameters);\n\tWdfRequestGetParameters(Request, &RequestParameters);\n\n\tif (RequestParameters.Parameters.DeviceIoControl.InputBufferLength < sizeof(HID_XFER_PACKET))\n\t{\n\t\tStatus = STATUS_BUFFER_TOO_SMALL;\n\t\tgoto exit;\n\t}\n\n\tpHidPacket = (PHID_XFER_PACKET) WdfRequestWdmGetIrp(Request)->UserBuffer;\n\tif (pHidPacket == NULL)\n\t{\n\t\tStatus = STATUS_INVALID_DEVICE_REQUEST;\n\t\tgoto exit;\n\t}\n\n\tswitch (pHidPacket->reportId)\n\t{\n\t\tcase REPORTID_REPORTMODE:\n\t\t{\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_INFORMATION,\n\t\t\t\tTRACE_DRIVER,\n\t\t\t\t\"%!FUNC! Report REPORTID_REPORTMODE is requested\"\n\t\t\t);\n\n\t\t\tPPTP_DEVICE_INPUT_MODE_REPORT DeviceInputMode = (PPTP_DEVICE_INPUT_MODE_REPORT) pHidPacket->reportBuffer;\n\t\t\tswitch (DeviceInputMode->Mode)\n\t\t\t{\n\t\t\t\tcase PTP_COLLECTION_MOUSE:\n\t\t\t\t{\n\t\t\t\t\tTraceEvents(\n\t\t\t\t\t\tTRACE_LEVEL_INFORMATION,\n\t\t\t\t\t\tTRACE_DRIVER,\n\t\t\t\t\t\t\"%!FUNC! Report REPORTID_REPORTMODE requested Mouse Input\"\n\t\t\t\t\t);\n\n\t\t\t\t\tpDeviceContext->PtpInputOn = FALSE;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase PTP_COLLECTION_WINDOWS:\n\t\t\t\t{\n\n\t\t\t\t\tTraceEvents(\n\t\t\t\t\t\tTRACE_LEVEL_INFORMATION,\n\t\t\t\t\t\tTRACE_DRIVER,\n\t\t\t\t\t\t\"%!FUNC! Report REPORTID_REPORTMODE requested Windows PTP Input\"\n\t\t\t\t\t);\n\n\t\t\t\t\tpDeviceContext->PtpInputOn = TRUE;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_INFORMATION,\n\t\t\t\tTRACE_DRIVER,\n\t\t\t\t\"%!FUNC! Report REPORTID_REPORTMODE is fulfilled\"\n\t\t\t);\n\t\t\tbreak;\n\t\t}\n\t\tcase REPORTID_FUNCSWITCH:\n\t\t{\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_INFORMATION,\n\t\t\t\tTRACE_DRIVER,\n\t\t\t\t\"%!FUNC! Report REPORTID_FUNCSWITCH is requested\"\n\t\t\t);\n\n\t\t\tPPTP_DEVICE_SELECTIVE_REPORT_MODE_REPORT InputSelection = (PPTP_DEVICE_SELECTIVE_REPORT_MODE_REPORT) pHidPacket->reportBuffer;\n\t\t\tpDeviceContext->PtpReportButton = InputSelection->ButtonReport;\n\t\t\tpDeviceContext->PtpReportTouch = InputSelection->SurfaceReport;\n\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_INFORMATION,\n\t\t\t\tTRACE_DRIVER,\n\t\t\t\t\"%!FUNC! Report REPORTID_FUNCSWITCH requested Button = %d, Surface = %d\",\n\t\t\t\tInputSelection->ButtonReport,\n\t\t\t\tInputSelection->SurfaceReport\n\t\t\t);\n\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_INFORMATION,\n\t\t\t\tTRACE_DRIVER,\n\t\t\t\t\"%!FUNC! Report REPORTID_FUNCSWITCH is fulfilled\"\n\t\t\t);\n\n\t\t\tbreak;\n\t\t}\n\t\tdefault:\n\t\t{\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_INFORMATION,\n\t\t\t\tTRACE_DRIVER,\n\t\t\t\t\"%!FUNC! Unsupported type %d is requested\",\n\t\t\t\tpHidPacket->reportId\n\t\t\t);\n\n\t\t\tStatus = STATUS_NOT_SUPPORTED;\n\t\t\tgoto exit;\n\t\t}\n\t}\n\nexit:\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION,\n\t\tTRACE_DRIVER,\n\t\t\"%!FUNC! Exit\"\n\t);\n\n\treturn Status;\n}\n"
  },
  {
    "path": "src/AmtPtpDeviceSpiKm/Hid.h",
    "content": "#pragma once\n\n#include <hidport.h>\n\n#include \"AppleDefinition.h\"\n#include \"HidCommon.h\"\n\n// Device family metadata\n#include \"HID\\SpiTrackpadSeries1.h\"\n#include \"HID\\SpiTrackpadSeries2.h\"\n#include \"HID\\SpiTrackpadSeries3.h\"\n\ntypedef UCHAR HID_REPORT_DESCRIPTOR, *PHID_REPORT_DESCRIPTOR;\n\n#define REPORT_BUFFER_SIZE   1024\n#define DEVICE_VERSION 0x01\n#define MAX_FINGERS\t16\n\n#define AAPL_PTP_USERMODE_CONFIGURATION_APP_TLC \\\n\tUSAGE_PAGE_1, 0x00, 0xff, /* Usage Page: Vendor defined */ \\\n\tUSAGE, 0x01, /* Usage: Vendor Usage 0x01 */ \\\n\tBEGIN_COLLECTION, 0x01, /* Begin Collection: Application */ \\\n\t\tREPORT_ID, REPORTID_UMAPP_CONF, /* Report ID: User-mode Application configuration */ \\\n\t\tUSAGE, 0x01, /* Usage: Vendor Usage 0x01 */ \\\n\t\tLOGICAL_MINIMUM, 0x00, /* Logical Minimum 0 */ \\\n\t\tLOGICAL_MAXIMUM_2, 0xff, 0x00, /* Logical Maximum 255 */ \\\n\t\tREPORT_SIZE, 0x08, /* Report Size: 8 */ \\\n\t\tREPORT_COUNT, 0x03, /* Report Count: 3 */ \\\n\t\tFEATURE, 0x02, /* Feature: (Data, Var, Abs) */ \\\n\tEND_COLLECTION\n\n#define AAPL_PTP_WINDOWS_CONFIGURATION_TLC \\\n\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\tUSAGE, 0x0e, /* Usage: Configuration */ \\\n\tBEGIN_COLLECTION, 0x01, /* Begin Collection: Application */ \\\n\t\tREPORT_ID, REPORTID_REPORTMODE, /* Report ID: Mode Selection */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tBEGIN_COLLECTION, 0x02, /* Begin Collection: Logical */ \\\n\t\t\tUSAGE, 0x52, /* Usage: Input Mode */ \\\n\t\t\tLOGICAL_MINIMUM, 0x00, /* Logical Minumum: 0 finger */ \\\n\t\t\tLOGICAL_MAXIMUM, MAX_FINGERS, /* Logical Maximum: MAX_TOUCH_COUNT fingers */ \\\n\t\t\tREPORT_SIZE, 0x08, /* Report Size: 0x08 */ \\\n\t\t\tREPORT_COUNT, 0x01, /* Report Count: 0x01 */ \\\n\t\t\tFEATURE, 0x02, /* Feature: (Data, Var, Abs) */ \\\n\t\tEND_COLLECTION, /* End Collection */ \\\n\t\tBEGIN_COLLECTION, 0x00, /* Begin Collection: Physical */ \\\n\t\t\tREPORT_ID, REPORTID_FUNCSWITCH, /* Report ID: Function Switch */ \\\n\t\t\tUSAGE, BUTTON_SWITCH, /* Usage: Button Switch */ \\\n\t\t\tUSAGE, SURFACE_SWITCH, /* Usage: Surface Switch */ \\\n\t\t\tREPORT_SIZE, 0x01, /* Report Size: 0x01 */ \\\n\t\t\tREPORT_COUNT, 0x02, /* Report Count: 0x02 */ \\\n\t\t\tLOGICAL_MAXIMUM, 0x01, /* Logical Maximum: 0x01 */ \\\n\t\t\tFEATURE, 0x02, /* Feature: (Data, Var, Abs) */ \\\n\t\t\tREPORT_COUNT, 0x06, /* Report Count: 0x06 */ \\\n\t\t\tFEATURE, 0x03, /* Feature: (Const, Var, Abs) */ \\\n\t\tEND_COLLECTION, /* End Collection */ \\\n\tEND_COLLECTION /* End Collection */\n\n#define DEFAULT_PTP_HQA_BLOB \\\n\t0xfc, 0x28, 0xfe, 0x84, 0x40, 0xcb, 0x9a, 0x87, \\\n\t0x0d, 0xbe, 0x57, 0x3c, 0xb6, 0x70, 0x09, 0x88, \\\n\t0x07, 0x97, 0x2d, 0x2b, 0xe3, 0x38, 0x34, 0xb6, \\\n\t0x6c, 0xed, 0xb0, 0xf7, 0xe5, 0x9c, 0xf6, 0xc2, \\\n\t0x2e, 0x84, 0x1b, 0xe8, 0xb4, 0x51, 0x78, 0x43, \\\n\t0x1f, 0x28, 0x4b, 0x7c, 0x2d, 0x53, 0xaf, 0xfc, \\\n\t0x47, 0x70, 0x1b, 0x59, 0x6f, 0x74, 0x43, 0xc4, \\\n\t0xf3, 0x47, 0x18, 0x53, 0x1a, 0xa2, 0xa1, 0x71, \\\n\t0xc7, 0x95, 0x0e, 0x31, 0x55, 0x21, 0xd3, 0xb5, \\\n\t0x1e, 0xe9, 0x0c, 0xba, 0xec, 0xb8, 0x89, 0x19, \\\n\t0x3e, 0xb3, 0xaf, 0x75, 0x81, 0x9d, 0x53, 0xb9, \\\n\t0x41, 0x57, 0xf4, 0x6d, 0x39, 0x25, 0x29, 0x7c, \\\n\t0x87, 0xd9, 0xb4, 0x98, 0x45, 0x7d, 0xa7, 0x26, \\\n\t0x9c, 0x65, 0x3b, 0x85, 0x68, 0x89, 0xd7, 0x3b, \\\n\t0xbd, 0xff, 0x14, 0x67, 0xf2, 0x2b, 0xf0, 0x2a, \\\n\t0x41, 0x54, 0xf0, 0xfd, 0x2c, 0x66, 0x7c, 0xf8, \\\n\t0xc0, 0x8f, 0x33, 0x13, 0x03, 0xf1, 0xd3, 0xc1, \\\n\t0x0b, 0x89, 0xd9, 0x1b, 0x62, 0xcd, 0x51, 0xb7, \\\n\t0x80, 0xb8, 0xaf, 0x3a, 0x10, 0xc1, 0x8a, 0x5b, \\\n\t0xe8, 0x8a, 0x56, 0xf0, 0x8c, 0xaa, 0xfa, 0x35, \\\n\t0xe9, 0x42, 0xc4, 0xd8, 0x55, 0xc3, 0x38, 0xcc, \\\n\t0x2b, 0x53, 0x5c, 0x69, 0x52, 0xd5, 0xc8, 0x73, \\\n\t0x02, 0x38, 0x7c, 0x73, 0xb6, 0x41, 0xe7, 0xff, \\\n\t0x05, 0xd8, 0x2b, 0x79, 0x9a, 0xe2, 0x34, 0x60, \\\n\t0x8f, 0xa3, 0x32, 0x1f, 0x09, 0x78, 0x62, 0xbc, \\\n\t0x80, 0xe3, 0x0f, 0xbd, 0x65, 0x20, 0x08, 0x13, \\\n\t0xc1, 0xe2, 0xee, 0x53, 0x2d, 0x86, 0x7e, 0xa7, \\\n\t0x5a, 0xc5, 0xd3, 0x7d, 0x98, 0xbe, 0x31, 0x48, \\\n\t0x1f, 0xfb, 0xda, 0xaf, 0xa2, 0xa8, 0x6a, 0x89, \\\n\t0xd6, 0xbf, 0xf2, 0xd3, 0x32, 0x2a, 0x9a, 0xe4, \\\n\t0xcf, 0x17, 0xb7, 0xb8, 0xf4, 0xe1, 0x33, 0x08, \\\n\t0x24, 0x8b, 0xc4, 0x43, 0xa5, 0xe5, 0x24, 0xc2\n\n#define PTP_MAX_CONTACT_POINTS 5\n#define PTP_BUTTON_TYPE_CLICK_PAD 0\n#define PTP_BUTTON_TYPE_PRESSURE_PAD 1\n\n#define PTP_COLLECTION_MOUSE 0\n#define PTP_COLLECTION_WINDOWS 3\n\n#define PTP_CONTACT_CONFIDENCE_BIT   1\n#define PTP_CONTACT_TIPSWITCH_BIT    2\n\ntypedef struct _PTP_DEVICE_CAPS_FEATURE_REPORT {\n\tUCHAR ReportID;\n\tUCHAR MaximumContactPoints;\n\tUCHAR ButtonType;\n} PTP_DEVICE_CAPS_FEATURE_REPORT, *PPTP_DEVICE_CAPS_FEATURE_REPORT;\n\ntypedef struct _PTP_DEVICE_HQA_CERTIFICATION_REPORT {\n\tUCHAR ReportID;\n\tUCHAR CertificationBlob[256];\n} PTP_DEVICE_HQA_CERTIFICATION_REPORT, *PPTP_DEVICE_HQA_CERTIFICATION_REPORT;\n\ntypedef struct _PTP_DEVICE_INPUT_MODE_REPORT {\n\tUCHAR ReportID;\n\tUCHAR Mode;\n} PTP_DEVICE_INPUT_MODE_REPORT, *PPTP_DEVICE_INPUT_MODE_REPORT;\n\n#pragma pack(push)\n#pragma pack(1)\ntypedef struct _PTP_DEVICE_SELECTIVE_REPORT_MODE_REPORT {\n\tUCHAR ReportID;\n\tUCHAR DeviceMode;\n\tUCHAR ButtonReport : 1;\n\tUCHAR SurfaceReport : 1;\n\tUCHAR Padding : 6;\n} PTP_DEVICE_SELECTIVE_REPORT_MODE_REPORT, *PPTP_DEVICE_SELECTIVE_REPORT_MODE_REPORT;\n#pragma pack(pop)\n\n#pragma pack(push)\n#pragma pack(1)\ntypedef struct _PTP_CONTACT {\n\tUCHAR\t\tConfidence : 1;\n\tUCHAR\t\tTipSwitch : 1;\n\tUCHAR\t\tContactID : 3;\n\tUCHAR\t\tPadding : 3;\n\tUSHORT\t\tX;\n\tUSHORT\t\tY;\n} PTP_CONTACT, *PPTP_CONTACT;\n#pragma pack(pop)\n\nenum CONTACT_STATE {\n\tCONTACT_NEW = 0,\n\tCONTACT_CONTINUED = 1,\n\tCONTACT_CONFIDENCE_CANCELLED = 2,\n\tCONTACT_INVALID = 3\n};\n\n// Used for defuzz - not report\ntypedef struct _PTP_CONTACT_RAW {\n\tUSHORT\t\t\t\tX;\n\tUSHORT\t\t\t\tY;\n\tUCHAR\t\t\t\tPressure;\n\tUCHAR\t\t\t\tSize;\n\tUCHAR\t\t\t\tContactId;\n\tUSHORT\t\t\t\tTouchMajor;\n\tUSHORT\t\t\t\tTouchMinor;\n\tUSHORT\t\t\t\tOrientation;\n\tenum CONTACT_STATE\tState;\n} PTP_CONTACT_RAW, *PPTP_CONTACT_RAW;\n\ntypedef struct _PTP_CONTACT_RAW_LL {\n\tPTP_CONTACT_RAW\t\t\t\t\tContactRaw;\n\tstruct _PTP_CONTACT_RAW_LL\t\t*pNext;\n} PTP_CONTACT_RAW_LL, *PPTP_CONTACT_RAW_LL;\n\ntypedef struct _PTP_REPORT {\n\tUCHAR       ReportID;\n\tPTP_CONTACT Contacts[5];\n\tUSHORT      ScanTime;\n\tUCHAR       ContactCount;\n\tUCHAR       IsButtonClicked;\n} PTP_REPORT, *PPTP_REPORT;\n\ntypedef struct _PTP_USERMODEAPP_CONF_REPORT {\n\tUCHAR\t\tReportID;\n\tUCHAR\t\tPressureQualificationLevel;\n\tUCHAR\t\tSingleContactSizeQualificationLevel;\n\tUCHAR\t\tMultipleContactSizeQualificationLevel;\n} PTP_USERMODEAPP_CONF_REPORT, *PPTP_USERMODEAPP_CONF_REPORT;\n\n// HID routines\n_IRQL_requires_(PASSIVE_LEVEL)\nNTSTATUS\nAmtPtpGetHidDescriptor(\n\t_In_ WDFDEVICE Device,\n\t_In_ WDFREQUEST Request\n);\n\n_IRQL_requires_(PASSIVE_LEVEL)\nNTSTATUS\nAmtPtpGetDeviceAttribs(\n\t_In_ WDFDEVICE Device,\n\t_In_ WDFREQUEST Request\n);\n\n_IRQL_requires_(PASSIVE_LEVEL)\nNTSTATUS\nAmtPtpGetReportDescriptor(\n\t_In_ WDFDEVICE Device,\n\t_In_ WDFREQUEST Request\n);\n\n_IRQL_requires_(PASSIVE_LEVEL)\nNTSTATUS\nAmtPtpGetStrings(\n\t_In_ WDFDEVICE Device,\n\t_In_ WDFREQUEST Request,\n\t_Out_ BOOLEAN *Pending\n);\n\n_IRQL_requires_(PASSIVE_LEVEL)\nNTSTATUS\nAmtPtpReportFeatures(\n\t_In_ WDFDEVICE Device,\n\t_In_ WDFREQUEST Request\n);\n\n_IRQL_requires_(PASSIVE_LEVEL)\nNTSTATUS\nAmtPtpSetFeatures(\n\t_In_ WDFDEVICE Device,\n\t_In_ WDFREQUEST Request\n);\n"
  },
  {
    "path": "src/AmtPtpDeviceSpiKm/HidCommon.h",
    "content": "#pragma once\n\n#define REPORTID_STANDARDMOUSE 0x02\n#define REPORTID_MULTITOUCH 0x05\n#define REPORTID_REPORTMODE 0x04\n#define REPORTID_PTPHQA 0x08\n#define REPORTID_FUNCSWITCH 0x06\n#define REPORTID_DEVICE_CAPS 0x07\n#define REPORTID_UMAPP_CONF  0x09\n\n#define BUTTON_SWITCH 0x57\n#define SURFACE_SWITCH 0x58\n\n#define USAGE_PAGE 0x05\n#define USAGE_PAGE_1 0x06\n#define USAGE      0x09\n#define USAGE_MINIMUM 0x19\n#define USAGE_MAXIMUM 0x29\n#define LOGICAL_MINIMUM 0x15\n#define LOGICAL_MAXIMUM 0x25\n#define LOGICAL_MAXIMUM_2 0x26\n#define LOGICAL_MAXIMUM_3 0x27\n#define PHYSICAL_MINIMUM 0x35\n#define PHYSICAL_MAXIMUM 0x45\n#define PHYSICAL_MAXIMUM_2 0x46\n#define PHYSICAL_MAXIMUM_3 0x47\n#define UNIT_EXPONENT 0x55\n#define UNIT 0x65\n#define UNIT_2 0x66\n\n#define REPORT_ID       0x85\n#define REPORT_COUNT    0x95\n#define REPORT_COUNT_2\t0x96\n#define REPORT_SIZE     0x75\n#define INPUT           0x81\n#define FEATURE         0xb1\n\n#define BEGIN_COLLECTION 0xa1\n#define END_COLLECTION   0xc0\n"
  },
  {
    "path": "src/AmtPtpDeviceSpiKm/Input.c",
    "content": "#include \"driver.h\"\n#include \"Input.tmh\"\n\nVOID\nAmtPtpSpiInputRoutineWorker(\n\tWDFDEVICE Device,\n\tWDFREQUEST PtpRequest\n)\n{\n\tNTSTATUS Status;\n\tPDEVICE_CONTEXT pDeviceContext;\n\tpDeviceContext = DeviceGetContext(Device);\n\n\tStatus = WdfRequestForwardToIoQueue(\n\t\tPtpRequest,\n\t\tpDeviceContext->HidQueue\n\t);\n\n\tif (!NT_SUCCESS(Status)) {\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_INFORMATION,\n\t\t\tTRACE_DRIVER,\n\t\t\t\"%!FUNC! WdfRequestForwardToIoQueue fails, status = %!STATUS!\",\n\t\t\tStatus\n\t\t);\n\n\t\tWdfRequestComplete(PtpRequest, Status);\n\t\treturn;\n\t}\n\n\t// Only issue request when fully configured.\n\t// Otherwise we will let power recovery process to triage it\n\tif (pDeviceContext->DeviceStatus == D0ActiveAndConfigured) {\n\t\tAmtPtpSpiInputIssueRequest(Device);\n\t}\n}\n\nVOID\nAmtPtpSpiInputIssueRequest(\n\tWDFDEVICE Device\n)\n{\n\tNTSTATUS Status;\n\tPDEVICE_CONTEXT pDeviceContext;\n\tWDF_OBJECT_ATTRIBUTES Attributes;\n\tBOOLEAN RequestStatus = FALSE;\n\tWDFREQUEST SpiHidReadRequest;\n\tWDFMEMORY SpiHidReadOutputMemory;\n\tPWORKER_REQUEST_CONTEXT RequestContext;\n\tpDeviceContext = DeviceGetContext(Device);\n\n\tWDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&Attributes, WORKER_REQUEST_CONTEXT);\n\tAttributes.ParentObject = Device;\n\n\tStatus = WdfRequestCreate(\n\t\t&Attributes,\n\t\tpDeviceContext->SpiTrackpadIoTarget,\n\t\t&SpiHidReadRequest\n\t);\n\n\tif (!NT_SUCCESS(Status))\n\t{\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_INFORMATION,\n\t\t\tTRACE_DEVICE,\n\t\t\t\"%!FUNC! WdfRequestCreate fails, status = %!STATUS!\",\n\t\t\tStatus\n\t\t);\n\n\t\treturn;\n\t}\n\n\tStatus = WdfMemoryCreateFromLookaside(\n\t\tpDeviceContext->HidReadBufferLookaside,\n\t\t&SpiHidReadOutputMemory\n\t);\n\n\tif (!NT_SUCCESS(Status))\n\t{\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_INFORMATION,\n\t\t\tTRACE_DEVICE,\n\t\t\t\"%!FUNC! WdfMemoryCreateFromLookaside fails, status = %!STATUS!\",\n\t\t\tStatus\n\t\t);\n\n\t\tWdfObjectDelete(SpiHidReadRequest);\n\t\treturn;\n\t}\n\n\t// Assign context information\n\tRequestContext = WorkerRequestGetContext(SpiHidReadRequest);\n\tRequestContext->DeviceContext = pDeviceContext;\n\tRequestContext->RequestMemory = SpiHidReadOutputMemory;\n\n\t// Invoke HID read request to the device.\n\tStatus = WdfIoTargetFormatRequestForInternalIoctl(\n\t\tpDeviceContext->SpiTrackpadIoTarget,\n\t\tSpiHidReadRequest,\n\t\tIOCTL_HID_READ_REPORT,\n\t\tNULL,\n\t\t0,\n\t\tSpiHidReadOutputMemory,\n\t\t0\n\t);\n\n\tif (!NT_SUCCESS(Status))\n\t{\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_INFORMATION,\n\t\t\tTRACE_DEVICE,\n\t\t\t\"%!FUNC! WdfIoTargetFormatRequestForInternalIoctl fails, status = %!STATUS!\",\n\t\t\tStatus\n\t\t);\n\n\t\tif (SpiHidReadOutputMemory != NULL) {\n\t\t\tWdfObjectDelete(SpiHidReadOutputMemory);\n\t\t}\n\n\t\tif (SpiHidReadRequest != NULL) {\n\t\t\tWdfObjectDelete(SpiHidReadRequest);\n\t\t}\n\n\t\treturn;\n\t}\n\n\tWdfRequestSetCompletionRoutine(\n\t\tSpiHidReadRequest,\n\t\tAmtPtpRequestCompletionRoutine,\n\t\tRequestContext\n\t);\n\n\tRequestStatus = WdfRequestSend(\n\t\tSpiHidReadRequest,\n\t\tpDeviceContext->SpiTrackpadIoTarget,\n\t\tNULL\n\t);\n\n\tif (!RequestStatus)\n\t{\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_INFORMATION,\n\t\t\tTRACE_DEVICE,\n\t\t\t\"%!FUNC! AmtPtpSpiInputRoutineWorker request failed to sent\"\n\t\t);\n\n\t\tif (SpiHidReadOutputMemory != NULL) {\n\t\t\tWdfObjectDelete(SpiHidReadOutputMemory);\n\t\t}\n\n\t\tif (SpiHidReadRequest != NULL) {\n\t\t\tWdfObjectDelete(SpiHidReadRequest);\n\t\t}\n\t}\n}\n\nVOID\nAmtPtpRequestCompletionRoutine(\n\tWDFREQUEST SpiRequest,\n\tWDFIOTARGET Target,\n\tPWDF_REQUEST_COMPLETION_PARAMS Params,\n\tWDFCONTEXT Context\n)\n{\n\tNTSTATUS Status;\n\tPWORKER_REQUEST_CONTEXT RequestContext;\n\tPDEVICE_CONTEXT pDeviceContext;\n\n\tLONG SpiRequestLength;\n\tPSPI_TRACKPAD_PACKET pSpiTrackpadPacket;\n\n\tWDFREQUEST PtpRequest;\n\tPTP_REPORT PtpReport;\n\tWDFMEMORY PtpRequestMemory;\n\n\tLARGE_INTEGER CurrentCounter;\n\tLONGLONG CounterDelta;\n\n\tUNREFERENCED_PARAMETER(Target);\n\n\t// Get context\n\tRequestContext = (PWORKER_REQUEST_CONTEXT) Context;\n\tpDeviceContext = RequestContext->DeviceContext;\n\n\t// Read report and fulfill PTP request.\n\t// If no report is found, just exit.\n\tStatus = WdfIoQueueRetrieveNextRequest(pDeviceContext->HidQueue, &PtpRequest);\n\tif (!NT_SUCCESS(Status)) {\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_ERROR,\n\t\t\tTRACE_DRIVER,\n\t\t\t\"%!FUNC! WdfIoQueueRetrieveNextRequest failed with %!STATUS!\",\n\t\t\tStatus\n\t\t);\n\n\t\tgoto cleanup;\n\t}\n\n\tSpiRequestLength = (LONG) WdfRequestGetInformation(SpiRequest);\n\tpSpiTrackpadPacket = (PSPI_TRACKPAD_PACKET) WdfMemoryGetBuffer(Params->Parameters.Ioctl.Output.Buffer, NULL);\n\n\t// Safe measurement for buffer overrun and device state reset\n\tif (SpiRequestLength < 46) {\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_ERROR,\n\t\t\tTRACE_DRIVER,\n\t\t\t\"%!FUNC! Input too small: %d < 46. Attempt to re-enable the device.\",\n\t\t\tSpiRequestLength\n\t\t);\n\n\t\tStatus = STATUS_DEVICE_DATA_ERROR;\n\t\tgoto exit;\n\t}\n\n\t// Get Counter\n\tKeQueryPerformanceCounter(\n\t\t&CurrentCounter\n\t);\n\n\tCounterDelta = (CurrentCounter.QuadPart - pDeviceContext->LastReportTime.QuadPart) / 100;\n\tpDeviceContext->LastReportTime.QuadPart = CurrentCounter.QuadPart;\n\n\t// Write report\n\tPtpReport.ReportID = REPORTID_MULTITOUCH;\n\tPtpReport.ContactCount = pSpiTrackpadPacket->NumOfFingers;\n\tPtpReport.IsButtonClicked = pSpiTrackpadPacket->ClickOccurred;\n\n\tUINT8 AdjustedCount = (pSpiTrackpadPacket->NumOfFingers > 5) ? 5 : pSpiTrackpadPacket->NumOfFingers;\n\tfor (UINT8 Count = 0; Count < AdjustedCount; Count++)\n\t{\n\t\tPtpReport.Contacts[Count].ContactID = Count;\n\t\tPtpReport.Contacts[Count].X = ((pSpiTrackpadPacket->Fingers[Count].X - pDeviceContext->TrackpadInfo.XMin) > 0) ? \n\t\t\t(USHORT)(pSpiTrackpadPacket->Fingers[Count].X - pDeviceContext->TrackpadInfo.XMin) : 0;\n\t\tPtpReport.Contacts[Count].Y = ((pDeviceContext->TrackpadInfo.YMax - pSpiTrackpadPacket->Fingers[Count].Y) > 0) ? \n\t\t\t(USHORT)(pDeviceContext->TrackpadInfo.YMax - pSpiTrackpadPacket->Fingers[Count].Y) : 0;\n\t\tPtpReport.Contacts[Count].TipSwitch = (pSpiTrackpadPacket->Fingers[Count].Pressure > 0) ? 1 : 0;\n\n\t\t// $S = \\pi * (Touch_{Major} * Touch_{Minor}) / 4$\n\t\t// $S = \\pi * r^2$\n\t\t// $r^2 = (Touch_{Major} * Touch_{Minor}) / 4$\n\t\t// Using i386 in 2018 is evil\n\t\tPtpReport.Contacts[Count].Confidence = (pSpiTrackpadPacket->Fingers[Count].TouchMajor < 2500 &&\n\t\t\tpSpiTrackpadPacket->Fingers[Count].TouchMinor < 2500) ? 1 : 0;\n\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_INFORMATION,\n\t\t\tTRACE_HID_INPUT,\n\t\t\t\"%!FUNC! PTP Contact %d OX %d, OY %d, X %d, Y %d\",\n\t\t\tCount,\n\t\t\tpSpiTrackpadPacket->Fingers[Count].OriginalX,\n\t\t\tpSpiTrackpadPacket->Fingers[Count].OriginalY,\n\t\t\tpSpiTrackpadPacket->Fingers[Count].X,\n\t\t\tpSpiTrackpadPacket->Fingers[Count].Y\n\t\t);\n\t}\n\n\tif (CounterDelta >= 0xFF)\n\t{\n\t\tPtpReport.ScanTime = 0xFF;\n\t}\n\telse\n\t{\n\t\tPtpReport.ScanTime = (USHORT) CounterDelta;\n\t}\n\n\tStatus = WdfRequestRetrieveOutputMemory(\n\t\tPtpRequest,\n\t\t&PtpRequestMemory\n\t);\n\n\tif (!NT_SUCCESS(Status))\n\t{\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_ERROR,\n\t\t\tTRACE_DRIVER,\n\t\t\t\"%!FUNC! WdfRequestRetrieveOutputBuffer failed with %!STATUS!\",\n\t\t\tStatus\n\t\t);\n\n\t\tgoto exit;\n\t}\n\n\tStatus = WdfMemoryCopyFromBuffer(\n\t\tPtpRequestMemory,\n\t\t0,\n\t\t(PVOID) &PtpReport,\n\t\tsizeof(PTP_REPORT)\n\t);\n\n\tif (!NT_SUCCESS(Status))\n\t{\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_ERROR,\n\t\t\tTRACE_DRIVER,\n\t\t\t\"%!FUNC! WdfMemoryCopyFromBuffer failed with %!STATUS!\",\n\t\t\tStatus\n\t\t);\n\n\t\tgoto exit;\n\t}\n\n\t// Set information\n\tWdfRequestSetInformation(\n\t\tPtpRequest,\n\t\tsizeof(PTP_REPORT)\n\t);\n\nexit:\n\tWdfRequestComplete(\n\t\tPtpRequest,\n\t\tStatus\n\t);\n\ncleanup:\n\t// Clean up\n\tpSpiTrackpadPacket = NULL;\n\tWdfObjectDelete(SpiRequest);\n\tif (RequestContext->RequestMemory != NULL) {\n\t\tWdfObjectDelete(RequestContext->RequestMemory);\n\t}\n}\n"
  },
  {
    "path": "src/AmtPtpDeviceSpiKm/Input.h",
    "content": "#pragma once\n\nEVT_WDF_REQUEST_COMPLETION_ROUTINE AmtPtpRequestCompletionRoutine;\n\nVOID\nAmtPtpSpiInputRoutineWorker(\n\tWDFDEVICE Device,\n\tWDFREQUEST PtpRequest\n);\n\nVOID\nAmtPtpSpiInputIssueRequest(\n\tWDFDEVICE Device\n);\n"
  },
  {
    "path": "src/AmtPtpDeviceSpiKm/Public.h",
    "content": "/*++\n\nModule Name:\n\n    public.h\n\nAbstract:\n\n    This module contains the common declarations shared by driver\n    and user applications.\n\nEnvironment:\n\n    user and kernel\n\n--*/\n\n//\n// Define an Interface Guid so that apps can find the device and talk to it.\n//\n\nDEFINE_GUID (GUID_DEVINTERFACE_AmtPtpDeviceSpiKm,\n    0xf271e39d,0xd211,0x4a6e,0xa4,0x39,0x63,0xe5,0x19,0x40,0xd2,0x10);\n// {f271e39d-d211-4a6e-a439-63e51940d210}\n"
  },
  {
    "path": "src/AmtPtpDeviceSpiKm/Queue.c",
    "content": "/*++\n\nModule Name:\n\n    queue.c\n\nAbstract:\n\n    This file contains the queue entry points and callbacks.\n\nEnvironment:\n\n    Kernel-mode Driver Framework\n\n--*/\n\n#include \"driver.h\"\n#include \"queue.tmh\"\n\n#ifdef ALLOC_PRAGMA\n#pragma alloc_text (PAGE, AmtPtpDeviceSpiKmQueueInitialize)\n#endif\n\nNTSTATUS\nAmtPtpDeviceSpiKmQueueInitialize(\n    _In_ WDFDEVICE Device\n    )\n{\n    WDFQUEUE Queue;\n    NTSTATUS Status;\n    WDF_IO_QUEUE_CONFIG QueueConfig;\n\tPDEVICE_CONTEXT pDeviceContext;\n\n    PAGED_CODE();\n\n\t// By the time this is being called, it should exist\n\tpDeviceContext = DeviceGetContext(Device);\n\n    //\n    // Configure a default queue so that requests that are not\n    // configure-fowarded using WdfDeviceConfigureRequestDispatching to goto\n    // other queues get dispatched here.\n    //\n    WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(\n        &QueueConfig,\n        WdfIoQueueDispatchParallel\n    );\n\n\tQueueConfig.EvtIoInternalDeviceControl = AmtPtpDeviceSpiKmEvtIoInternalDeviceControl;\n    QueueConfig.EvtIoStop = AmtPtpDeviceSpiKmEvtIoStop;\n\n    Status = WdfIoQueueCreate(\n        Device,\n        &QueueConfig,\n        WDF_NO_OBJECT_ATTRIBUTES,\n        &Queue\n    );\n\n    if(!NT_SUCCESS(Status)) \n\t{\n        TraceEvents(TRACE_LEVEL_ERROR, TRACE_QUEUE, \"WdfIoQueueCreate failed %!STATUS!\", Status);\n\t\tgoto exit;\n    }\n\n\t//\n\t// Create secondary queues for touch read requests.\n\t//\n\tWDF_IO_QUEUE_CONFIG_INIT(&QueueConfig, WdfIoQueueDispatchManual);\n\tQueueConfig.PowerManaged = WdfFalse;\n\n\tStatus = WdfIoQueueCreate(\n\t\tDevice,\n\t\t&QueueConfig,\n\t\tWDF_NO_OBJECT_ATTRIBUTES,\n\t\t&pDeviceContext->HidQueue\n\t);\n\n\tif (!NT_SUCCESS(Status)) {\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_ERROR, TRACE_QUEUE, \n\t\t\t\"%!FUNC! WdfIoQueueCreate (Input) failed %!STATUS!\",\n\t\t\tStatus\n\t\t);\n\t}\n\nexit:\n    return Status;\n}\n\nPCHAR\nDbgIoControlGetString(\n\t_In_ ULONG IoControlCode\n)\n{\n\n\tswitch (IoControlCode)\n\t{\n\tcase IOCTL_HID_GET_DEVICE_DESCRIPTOR:\n\t\treturn \"IOCTL_HID_GET_DEVICE_DESCRIPTOR\";\n\tcase IOCTL_HID_GET_DEVICE_ATTRIBUTES:\n\t\treturn \"IOCTL_HID_GET_DEVICE_ATTRIBUTES\";\n\tcase IOCTL_HID_GET_REPORT_DESCRIPTOR:\n\t\treturn \"IOCTL_HID_GET_REPORT_DESCRIPTOR\";\n\tcase IOCTL_HID_GET_STRING:\n\t\treturn \"IOCTL_HID_GET_STRING\";\n\tcase IOCTL_HID_READ_REPORT:\n\t\treturn \"IOCTL_HID_READ_REPORT\";\n\tcase IOCTL_HID_WRITE_REPORT:\n\t\treturn \"IOCTL_HID_WRITE_REPORT\";\n\tcase IOCTL_UMDF_HID_GET_INPUT_REPORT:\n\t\treturn \"IOCTL_UMDF_HID_GET_INPUT_REPORT\";\n\tcase IOCTL_UMDF_HID_SET_OUTPUT_REPORT:\n\t\treturn \"IOCTL_UMDF_HID_SET_OUTPUT_REPORT\";\n\tcase IOCTL_UMDF_HID_GET_FEATURE:\n\t\treturn \"IOCTL_UMDF_HID_GET_FEATURE\";\n\tcase IOCTL_UMDF_HID_SET_FEATURE:\n\t\treturn \"IOCTL_UMDF_HID_SET_FEATURE\";\n\tcase IOCTL_HID_ACTIVATE_DEVICE:\n\t\treturn \"IOCTL_HID_ACTIVATE_DEVICE\";\n\tcase IOCTL_HID_DEACTIVATE_DEVICE:\n\t\treturn \"IOCTL_HID_DEACTIVATE_DEVICE\";\n\tcase IOCTL_HID_SEND_IDLE_NOTIFICATION_REQUEST:\n\t\treturn \"IOCTL_HID_SEND_IDLE_NOTIFICATION_REQUEST\";\n\tcase IOCTL_HID_GET_FEATURE:\n\t\treturn \"IOCTL_HID_GET_FEATURE\";\n\tcase IOCTL_HID_SET_FEATURE:\n\t\treturn \"IOCTL_HID_SET_FEATURE\";\n\tdefault:\n\t\treturn \"IOCTL_UNKNOWN\";\n\t}\n}\n\nVOID\nAmtPtpDeviceSpiKmEvtIoInternalDeviceControl(\n    _In_ WDFQUEUE Queue,\n    _In_ WDFREQUEST Request,\n    _In_ size_t OutputBufferLength,\n    _In_ size_t InputBufferLength,\n    _In_ ULONG IoControlCode\n    )\n{\n\tUNREFERENCED_PARAMETER(InputBufferLength);\n\tUNREFERENCED_PARAMETER(OutputBufferLength);\n\n\tNTSTATUS Status = STATUS_SUCCESS;\n\tWDFDEVICE Device = WdfIoQueueGetDevice(Queue);\n\tBOOLEAN RequestPending = FALSE;\n\n\t// Dispatch IOCTL to handler\n\tswitch (IoControlCode)\n\t{\n\tcase IOCTL_HID_GET_DEVICE_DESCRIPTOR:\n\t\tStatus = AmtPtpGetHidDescriptor(\n\t\t\tDevice,\n\t\t\tRequest\n\t\t);\n\t\tbreak;\n\tcase IOCTL_HID_GET_DEVICE_ATTRIBUTES:\n\t\tStatus = AmtPtpGetDeviceAttribs(\n\t\t\tDevice,\n\t\t\tRequest\n\t\t);\n\t\tbreak;\n\tcase IOCTL_HID_GET_REPORT_DESCRIPTOR:\n\t\tStatus = AmtPtpGetReportDescriptor(\n\t\t\tDevice,\n\t\t\tRequest\n\t\t);\n\t\tbreak;\n\tcase IOCTL_HID_GET_STRING:\n\t\tStatus = AmtPtpGetStrings(\n\t\t\tDevice,\n\t\t\tRequest,\n\t\t\t&RequestPending\n\t\t);\n\t\tbreak;\n\tcase IOCTL_HID_READ_REPORT:\n\t\tAmtPtpSpiInputRoutineWorker(\n\t\t\tDevice,\n\t\t\tRequest\n\t\t);\n\t\tRequestPending = TRUE;\n\t\tbreak;\n\tcase IOCTL_HID_GET_FEATURE:\n\t\tStatus = AmtPtpReportFeatures(\n\t\t\tDevice,\n\t\t\tRequest\n\t\t);\n\t\tbreak;\n\tcase IOCTL_HID_SET_FEATURE:\n\t\tStatus = AmtPtpSetFeatures(\n\t\t\tDevice,\n\t\t\tRequest\n\t\t);\n\t\tbreak;\n\tcase IOCTL_HID_WRITE_REPORT:\n\tcase IOCTL_UMDF_HID_SET_OUTPUT_REPORT:\n\tcase IOCTL_UMDF_HID_GET_INPUT_REPORT:\n\tcase IOCTL_HID_ACTIVATE_DEVICE:\n\tcase IOCTL_HID_DEACTIVATE_DEVICE:\n\tcase IOCTL_HID_SEND_IDLE_NOTIFICATION_REQUEST:\n\tdefault:\n\t\tStatus = STATUS_NOT_SUPPORTED;\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_WARNING,\n\t\t\tTRACE_QUEUE,\n\t\t\t\"%!FUNC!: %s is not yet implemented\",\n\t\t\tDbgIoControlGetString(IoControlCode)\n\t\t);\n\t\tbreak;\n\t}\n\n\tif (RequestPending != TRUE) \n\t{\n\t\tWdfRequestComplete(\n\t\t\tRequest,\n\t\t\tStatus\n\t\t);\n\t}\n\n    return;\n}\n\nVOID\nAmtPtpDeviceSpiKmEvtIoStop(\n    _In_ WDFQUEUE Queue,\n    _In_ WDFREQUEST Request,\n    _In_ ULONG ActionFlags\n)\n{\n\tUNREFERENCED_PARAMETER(Queue);\n\tUNREFERENCED_PARAMETER(Request);\n\tUNREFERENCED_PARAMETER(ActionFlags);\n\n    //\n    // In most cases, the EvtIoStop callback function completes, cancels, or postpones\n    // further processing of the I/O request.\n    //\n    // Typically, the driver uses the following rules:\n    //\n    // - If the driver owns the I/O request, it calls WdfRequestUnmarkCancelable\n    //   (if the request is cancelable) and either calls WdfRequestStopAcknowledge\n    //   with a Requeue value of TRUE, or it calls WdfRequestComplete with a\n    //   completion status value of STATUS_SUCCESS or STATUS_CANCELLED.\n    //\n    //   Before it can call these methods safely, the driver must make sure that\n    //   its implementation of EvtIoStop has exclusive access to the request.\n    //\n    //   In order to do that, the driver must synchronize access to the request\n    //   to prevent other threads from manipulating the request concurrently.\n    //   The synchronization method you choose will depend on your driver's design.\n    //\n    //   For example, if the request is held in a shared context, the EvtIoStop callback\n    //   might acquire an internal driver lock, take the request from the shared context,\n    //   and then release the lock. At this point, the EvtIoStop callback owns the request\n    //   and can safely complete or requeue the request.\n    //\n    // - If the driver has forwarded the I/O request to an I/O target, it either calls\n    //   WdfRequestCancelSentRequest to attempt to cancel the request, or it postpones\n    //   further processing of the request and calls WdfRequestStopAcknowledge with\n    //   a Requeue value of FALSE.\n    //\n    // A driver might choose to take no action in EvtIoStop for requests that are\n    // guaranteed to complete in a small amount of time.\n    //\n    // In this case, the framework waits until the specified request is complete\n    // before moving the device (or system) to a lower power state or removing the device.\n    // Potentially, this inaction can prevent a system from entering its hibernation state\n    // or another low system power state. In extreme cases, it can cause the system\n    // to crash with bugcheck code 9F.\n    //\n\n    return;\n}\n"
  },
  {
    "path": "src/AmtPtpDeviceSpiKm/Queue.h",
    "content": "/*++\n\nModule Name:\n\n    queue.h\n\nAbstract:\n\n    This file contains the queue definitions.\n\nEnvironment:\n\n    Kernel-mode Driver Framework\n\n--*/\n\nEXTERN_C_START\n\n//\n// This is the context that can be placed per queue\n// and would contain per queue information.\n//\ntypedef struct _QUEUE_CONTEXT {\n\n    ULONG PrivateDeviceData;  // just a placeholder\n\n} QUEUE_CONTEXT, *PQUEUE_CONTEXT;\n\nWDF_DECLARE_CONTEXT_TYPE_WITH_NAME(QUEUE_CONTEXT, QueueGetContext)\n\nNTSTATUS\nAmtPtpDeviceSpiKmQueueInitialize(\n    _In_ WDFDEVICE Device\n);\n\n_IRQL_requires_(PASSIVE_LEVEL)\nPCHAR\nDbgIoControlGetString(\n\t_In_ ULONG IoControlCode\n);\n\n//\n// Events from the IoQueue object\n//\nEVT_WDF_IO_QUEUE_IO_INTERNAL_DEVICE_CONTROL AmtPtpDeviceSpiKmEvtIoInternalDeviceControl;\nEVT_WDF_IO_QUEUE_IO_STOP AmtPtpDeviceSpiKmEvtIoStop;\n\nEXTERN_C_END\n"
  },
  {
    "path": "src/AmtPtpDeviceSpiKm/Trace.h",
    "content": "/*++\n\nModule Name:\n\n    Trace.h\n\nAbstract:\n\n    Header file for the debug tracing related function defintions and macros.\n\nEnvironment:\n\n    Kernel mode\n\n--*/\n\n//\n// Define the tracing flags.\n//\n// Tracing GUID - 9b319d80-fe25-41e4-80ef-7d8528f7f1b5\n//\n\n#define WPP_CONTROL_GUIDS                                              \\\n    WPP_DEFINE_CONTROL_GUID(                                           \\\n        AmtPtpDeviceSpiKmTraceGuid, (9b319d80,fe25,41e4,80ef,7d8528f7f1b5), \\\n                                                                            \\\n        WPP_DEFINE_BIT(TRACE_DRIVER)                                   \\\n        WPP_DEFINE_BIT(TRACE_DEVICE)                                   \\\n        WPP_DEFINE_BIT(TRACE_QUEUE)                                    \\\n\t\tWPP_DEFINE_BIT(TRACE_HID_INPUT)\t\t\t\t\t\t\t\t   \\\n        )                             \n\n#define WPP_FLAG_LEVEL_LOGGER(flag, level)                                  \\\n    WPP_LEVEL_LOGGER(flag)\n\n#define WPP_FLAG_LEVEL_ENABLED(flag, level)                                 \\\n    (WPP_LEVEL_ENABLED(flag) &&                                             \\\n     WPP_CONTROL(WPP_BIT_ ## flag).Level >= level)\n\n#define WPP_LEVEL_FLAGS_LOGGER(lvl,flags) \\\n           WPP_LEVEL_LOGGER(flags)\n               \n#define WPP_LEVEL_FLAGS_ENABLED(lvl, flags) \\\n           (WPP_LEVEL_ENABLED(flags) && WPP_CONTROL(WPP_BIT_ ## flags).Level >= lvl)\n\n//           \n// WPP orders static parameters before dynamic parameters. To support the Trace function\n// defined below which sets FLAGS=MYDRIVER_ALL_INFO, a custom macro must be defined to\n// reorder the arguments to what the .tpl configuration file expects.\n//\n#define WPP_RECORDER_FLAGS_LEVEL_ARGS(flags, lvl) WPP_RECORDER_LEVEL_FLAGS_ARGS(lvl, flags)\n#define WPP_RECORDER_FLAGS_LEVEL_FILTER(flags, lvl) WPP_RECORDER_LEVEL_FLAGS_FILTER(lvl, flags)\n\n//\n// This comment block is scanned by the trace preprocessor to define our\n// Trace function.\n//\n// begin_wpp config\n// FUNC Trace{FLAGS=TRACE_DRIVER}(LEVEL, MSG, ...);\n// FUNC TraceEvents(LEVEL, FLAGS, MSG, ...);\n// end_wpp\n//\n"
  },
  {
    "path": "src/AmtPtpDeviceUniversalPkg/AmtPtpDevice.inf",
    "content": ";\n; AmtPtpDevice.inf\n;\n\n[Version]\nSignature = \"$WINDOWS NT$\"\nClass = HIDClass\nClassGuid = {745a17a0-74d3-11d0-b6fe-00a0c90f57da}\nProvider = %ManufacturerName%\nCatalogFile = AmtPtpDevice.cat\nDriverVer =\nPnpLockdown = 1\n\n[DestinationDirs]\nDefaultDestDir = 13\nPtpUmDrivers_Dir = 13\n\n[SourceDisksNames]\n1 = %DiskName%,,,\"\"\n\n[SourceDisksFiles]\nAmtPtpDeviceUsbKm.sys = 1,,\nAmtPtpDeviceUsbUm.dll = 1,,\nAmtPtpDeviceSpiKm.sys = 1,,\nAmtPtpHidFilter.sys   = 1,,\n\n[Manufacturer]\n%ManufacturerName%=Standard,NT$ARCH$\n\n[Standard.NT$ARCH$]\n; Apple T2\n%AmtPtpDeviceUsbKm.DeviceDesc%=AmtPtpDeviceUsbKm_Device, USB\\Vid_05ac&Pid_0273&MI_02\n%AmtPtpDeviceUsbKm.DeviceDesc%=AmtPtpDeviceUsbKm_Device, USB\\Vid_05ac&Pid_0274&MI_02\n%AmtPtpDeviceUsbKm.DeviceDesc%=AmtPtpDeviceUsbKm_Device, USB\\Vid_05ac&Pid_0277&MI_02\n%AmtPtpDeviceUsbKm.DeviceDesc%=AmtPtpDeviceUsbKm_Device, USB\\Vid_05ac&Pid_027A&MI_02\n%AmtPtpDeviceUsbKm.DeviceDesc%=AmtPtpDeviceUsbKm_Device, USB\\Vid_05ac&Pid_027B&MI_02\n%AmtPtpDeviceUsbKm.DeviceDesc%=AmtPtpDeviceUsbKm_Device, USB\\Vid_05ac&Pid_027C&MI_02\n%AmtPtpDeviceUsbKm.DeviceDesc%=AmtPtpDeviceUsbKm_Device, USB\\Vid_05ac&Pid_027D&MI_02\n%AmtPtpDeviceUsbKm.DeviceDesc%=AmtPtpDeviceUsbKm_Device, USB\\Vid_05ac&Pid_027E&MI_02\n%AmtPtpDeviceUsbKm.DeviceDesc%=AmtPtpDeviceUsbKm_Device, USB\\Vid_05ac&Pid_027F&MI_02\n%AmtPtpDeviceUsbKm.DeviceDesc%=AmtPtpDeviceUsbKm_Device, USB\\Vid_05ac&Pid_0280&MI_02\n%AmtPtpDeviceUsbKm.DeviceDesc%=AmtPtpDeviceUsbKm_Device, USB\\Vid_05ac&Pid_0290&MI_02\n%AmtPtpDeviceUsbKm.DeviceDesc%=AmtPtpDeviceUsbKm_Device, USB\\Vid_05ac&Pid_0291&MI_02\n%AmtPtpDeviceUsbKm.DeviceDesc%=AmtPtpDeviceUsbKm_Device, USB\\Vid_05ac&Pid_0340&MI_02\n\n; Traditional Mac trackpad\n%AmtPtpDeviceUsbUm.DeviceDesc%=AmtPtpDeviceUsbUm_Install, USB\\Vid_05ac&Pid_0236&MI_01\n%AmtPtpDeviceUsbUm.DeviceDesc%=AmtPtpDeviceUsbUm_Install, USB\\Vid_05ac&Pid_0237&MI_01\n%AmtPtpDeviceUsbUm.DeviceDesc%=AmtPtpDeviceUsbUm_Install, USB\\Vid_05ac&Pid_0238&MI_01\n%AmtPtpDeviceUsbUm.DeviceDesc%=AmtPtpDeviceUsbUm_Install, USB\\Vid_05ac&Pid_0245&MI_01\n%AmtPtpDeviceUsbUm.DeviceDesc%=AmtPtpDeviceUsbUm_Install, USB\\Vid_05ac&Pid_0246&MI_01\n%AmtPtpDeviceUsbUm.DeviceDesc%=AmtPtpDeviceUsbUm_Install, USB\\Vid_05ac&Pid_0247&MI_01\n%AmtPtpDeviceUsbUm.DeviceDesc%=AmtPtpDeviceUsbUm_Install, USB\\Vid_05ac&Pid_0249&MI_01\n%AmtPtpDeviceUsbUm.DeviceDesc%=AmtPtpDeviceUsbUm_Install, USB\\Vid_05ac&Pid_024a&MI_01\n%AmtPtpDeviceUsbUm.DeviceDesc%=AmtPtpDeviceUsbUm_Install, USB\\Vid_05ac&Pid_024b&MI_01\n%AmtPtpDeviceUsbUm.DeviceDesc%=AmtPtpDeviceUsbUm_Install, USB\\Vid_05ac&Pid_024c&MI_01\n%AmtPtpDeviceUsbUm.DeviceDesc%=AmtPtpDeviceUsbUm_Install, USB\\Vid_05ac&Pid_024d&MI_01\n%AmtPtpDeviceUsbUm.DeviceDesc%=AmtPtpDeviceUsbUm_Install, USB\\Vid_05ac&Pid_024e&MI_01\n%AmtPtpDeviceUsbUm.DeviceDesc%=AmtPtpDeviceUsbUm_Install, USB\\Vid_05ac&Pid_0252&MI_01\n%AmtPtpDeviceUsbUm.DeviceDesc%=AmtPtpDeviceUsbUm_Install, USB\\Vid_05ac&Pid_0253&MI_01\n%AmtPtpDeviceUsbUm.DeviceDesc%=AmtPtpDeviceUsbUm_Install, USB\\Vid_05ac&Pid_0254&MI_01\n%AmtPtpDeviceUsbUm.DeviceDesc%=AmtPtpDeviceUsbUm_Install, USB\\Vid_05ac&Pid_0259&MI_01\n%AmtPtpDeviceUsbUm.DeviceDesc%=AmtPtpDeviceUsbUm_Install, USB\\Vid_05ac&Pid_025a&MI_01\n%AmtPtpDeviceUsbUm.DeviceDesc%=AmtPtpDeviceUsbUm_Install, USB\\Vid_05ac&Pid_025b&MI_01\n%AmtPtpDeviceUsbUm.DeviceDesc%=AmtPtpDeviceUsbUm_Install, USB\\Vid_05ac&Pid_0262&MI_01\n%AmtPtpDeviceUsbUm.DeviceDesc%=AmtPtpDeviceUsbUm_Install, USB\\Vid_05ac&Pid_0263&MI_01\n%AmtPtpDeviceUsbUm.DeviceDesc%=AmtPtpDeviceUsbUm_Install, USB\\Vid_05ac&Pid_0264&MI_01\n%AmtPtpDeviceUsbUm.DeviceDesc%=AmtPtpDeviceUsbUm_Install, USB\\Vid_05ac&Pid_0272&MI_02\n%AmtPtpDeviceUsbUm.DeviceDesc%=AmtPtpDeviceUsbUm_Install, USB\\Vid_05ac&Pid_0273&MI_02\n%AmtPtpDeviceUsbUm.DeviceDesc%=AmtPtpDeviceUsbUm_Install, USB\\Vid_05ac&Pid_0274&MI_02\n%AmtPtpDeviceUsbUm.DeviceDesc%=AmtPtpDeviceUsbUm_Install, USB\\Vid_05ac&Pid_0290&MI_02\n%AmtPtpDeviceUsbUm.DeviceDesc%=AmtPtpDeviceUsbUm_Install, USB\\Vid_05ac&Pid_0291&MI_02\n\n; SPI\n%AmtPtpDeviceSpiKm.DeviceDesc%=AmtPtpDeviceSpiKm_Device, SPI\\VID_05ac&PID_0272&MI_02\n%AmtPtpDeviceSpiKm.DeviceDesc%=AmtPtpDeviceSpiKm_Device, SPI\\VID_05ac&PID_0273&MI_02\n%AmtPtpDeviceSpiKm.DeviceDesc%=AmtPtpDeviceSpiKm_Device, SPI\\VID_05ac&PID_0275&MI_02\n%AmtPtpDeviceSpiKm.DeviceDesc%=AmtPtpDeviceSpiKm_Device, SPI\\VID_05ac&PID_0276&MI_02\n%AmtPtpDeviceSpiKm.DeviceDesc%=AmtPtpDeviceSpiKm_Device, SPI\\VID_05ac&PID_0277&MI_02\n%AmtPtpDeviceSpiKm.DeviceDesc%=AmtPtpDeviceSpiKm_Device, SPI\\VID_05ac&PID_0278&MI_02\n%AmtPtpDeviceSpiKm.DeviceDesc%=AmtPtpDeviceSpiKm_Device, SPI\\VID_05ac&PID_0279&MI_02\n%AmtPtpDeviceSpiKm.DeviceDesc%=AmtPtpDeviceSpiKm_Device, SPI\\VID_05ac&PID_0280&MI_02\n%AmtPtpDeviceSpiKm.DeviceDesc%=AmtPtpDeviceSpiKm_Device, SPI\\VID_05ac&PID_0290&MI_02\n%AmtPtpDeviceSpiKm.DeviceDesc%=AmtPtpDeviceSpiKm_Device, SPI\\VID_05ac&PID_0291&MI_02\n\n; Magic Trackpad 2 USB\n; Note: this will be a last few versions where Magic Trackpad 2 uses this old implementation\n%AmtPtpDeviceUsbUm.DeviceDesc%=AmtPtpDeviceUsbUm_Install, USB\\Vid_05ac&Pid_0265&MI_01\n; Magic Trackpad 2 Bluetooth\n%AmtPtpHidFilter.DeviceDesc%=AmtPtpHidFilter_MiniPortDevice, HID\\{00001124-0000-1000-8000-00805f9b34fb}_VID&0001004c_PID&0265&Col01\n%AmtPtpHidFilter.NullDeviceDesc%=AmtPtpHidFilter_NullDevice, HID\\{00001124-0000-1000-8000-00805f9b34fb}_VID&0001004c_PID&0265&Col02\n\n; Null Device\n[AmtPtpHidFilter_NullDevice]\n; Nothing!\n\n[AmtPtpHidFilter_NullDevice.Services]\nAddService = ,2    ; no value for the service name\n\n; File paylods for each set of driver\n[FilterDriver_Payload]\nAmtPtpHidFilter.sys\n\n[PtpKmDrivers_Dir]\nAmtPtpDeviceUsbKm.sys\n\n[PtpUmDrivers_Dir]\nAmtPtpDeviceUsbUm.dll\n\n[SpiKmDrivers_Dir]\nAmtPtpDeviceSpiKm.sys\n\n; Microsoft HID KMDF driver install sections\n[mshidkmdf_Service_Inst]\nServiceType    = 1                  ; SERVICE_KERNEL_DRIVER\nStartType      = 3                  ; SERVICE_DEMAND_START\nErrorControl   = 1                  ; SERVICE_ERROR_NORMAL\nServiceBinary  = %10%\\System32\\Drivers\\mshidkmdf.sys\n\n; PTP filter\n[AmtPtpHidFilter_MiniPortDevice.NT]\nCopyFiles=FilterDriver_Payload\n\n[AmtPtpHidFilter_MiniPortDevice.NT.Services]\nAddService = AmtPtpHidFilter,, AmtPtpHidFilter_Service_Inst\nAddService = mshidkmdf, %SPSVCINST_ASSOCSERVICE%, mshidkmdf_Service_Inst\n\n[AmtPtpHidFilter_MiniPortDevice.NT.HW]\nAddReg=AmtPtpHidFilter_AddReg\n\n[AmtPtpHidFilter_AddReg]\nHKR,,FriendlyName,,%AmtPtpHidFilter.DeviceDesc%\nHKR,,\"LowerFilters\",0x00010008,\"AmtPtpHidFilter\"\n\n[AmtPtpHidFilter_MiniPortDevice.NT.Wdf]\nKmdfService = AmtPtpHidFilter, AmtPtpHidFilter_wdfsect\n\n[AmtPtpHidFilter_Service_Inst]\nDisplayName    = %AmtPtpHidFilter.SVCDESC%\nServiceType    = 1               ; SERVICE_KERNEL_DRIVER\nStartType      = 3               ; SERVICE_DEMAND_START\nErrorControl   = 1               ; SERVICE_ERROR_NORMAL\nServiceBinary  = %13%\\AmtPtpHidFilter.sys\n\n[AmtPtpHidFilter_wdfsect]\nKmdfLibraryVersion = $KMDFVERSION$\n\n; USB KM\n[AmtPtpDeviceUsbKm_Device.NT]\nCopyFiles=PtpKmDrivers_Dir\n\n[AmtPtpDeviceUsbKm_Device.NT.Services]\nAddService = AmtPtpDeviceUsbKm,, AmtPtpDeviceUsbKm_Service_Inst\nAddService = mshidkmdf, %SPSVCINST_ASSOCSERVICE%, mshidkmdf_Service_Inst\n\n[AmtPtpDeviceUsbKm_Device.NT.HW]\nAddReg=AmtPtpDeviceUsbKm_AddReg\n\n[AmtPtpDeviceUsbKm_AddReg]\nHKR,,FriendlyName,,%AmtPtpDeviceUsbKm.DeviceDesc%\nHKR,,\"LowerFilters\",0x00010008,\"AmtPtpDeviceUsbKm\"\n\n; -------------- AmtPtpDeviceUsbKm driver install sections\n[AmtPtpDeviceUsbKm_Service_Inst]\nDisplayName    = %AmtPtpDeviceUsbKm.SVCDESC%\nServiceType    = 1               ; SERVICE_KERNEL_DRIVER\nStartType      = 3               ; SERVICE_DEMAND_START\nErrorControl   = 1               ; SERVICE_ERROR_NORMAL\nServiceBinary  = %13%\\AmtPtpDeviceUsbKm.sys\n\n[AmtPtpDeviceUsbKm_Device.NT.Wdf]\nKmdfService = AmtPtpDeviceUsbKm, AmtPtpDeviceUsbKm_wdfsect\n\n[AmtPtpDeviceUsbKm_wdfsect]\nKmdfLibraryVersion = $KMDFVERSION$\n\n; USB UM\n[AmtPtpDeviceUsbUm_Install.NT]\nCopyFiles=PtpUmDrivers_Dir\n\n[AmtPtpDeviceUsbUm_Install.NT.hw]\nAddReg=AmtPtpDeviceUsbUm_AddReg\n\n[AmtPtpDeviceUsbUm_Install.NT.Services]\nAddService=mshidumdf, 0x000001fa, MSHIDUMDF_ServiceInstall ; flag 0x2 sets this as the service for the device\nAddService=WUDFRd,0x000001f8,WUDFRD_ServiceInstall         ; this service is installed because its a filter.\n\n[AmtPtpDeviceUsbUm_Install.NT.Wdf]\nUmdfDispatcher=NativeUSB\nUmdfService=AmtPtpDeviceUsbUm,AmtPtpDeviceUsbUm_Install\nUmdfServiceOrder=AmtPtpDeviceUsbUm\nUmdfKernelModeClientPolicy=AllowKernelModeClients\nUmdfFileObjectPolicy=AllowNullAndUnknownFileObjects\nUmdfMethodNeitherAction=Copy\nUmdfFsContextUsePolicy=CanUseFsContext2\nUmdfHostPriority=PriorityHigh\n\n[AmtPtpDeviceUsbUm_Install]\nUmdfLibraryVersion=2.15.0\nServiceBinary=%13%\\AmtPtpDeviceUsbUm.dll\n\n[AmtPtpDeviceUsbUm_AddReg]\nHKR,,FriendlyName,,%AmtPtpDeviceUsbUm.DeviceDesc%\nHKR,,\"LowerFilters\",0x00010008,\"WUDFRd\" ; FLG_ADDREG_TYPE_MULTI_SZ | FLG_ADDREG_APPEND\n\n[mshidumdf_ServiceInstall]\nServiceType    = 1                  ; SERVICE_KERNEL_DRIVER\nStartType      = 3                  ; SERVICE_DEMAND_START\nErrorControl   = 1                  ; SERVICE_ERROR_NORMAL\nServiceBinary  = %12%\\mshidumdf.sys\n\n[WUDFRD_ServiceInstall]\nDisplayName = %WudfRdDisplayName%\nServiceType = 1\nStartType = 3\nErrorControl = 1\nServiceBinary = %12%\\WUDFRd.sys\n\n; SPI KM\n[AmtPtpDeviceSpiKm_Device.NT]\nCopyFiles=SpiKmDrivers_Dir\n\n[AmtPtpDeviceSpiKm_Device.NT.Services]\nAddService = AmtPtpDeviceSpiKm,, AmtPtpDeviceSpiKm_Service_Inst\nAddService = mshidkmdf, %SPSVCINST_ASSOCSERVICE%, mshidkmdf_Service_Inst ;flag 0x2 sets this as the service for the device\n\n[AmtPtpDeviceSpiKm_Device.NT.HW]\nAddReg = AmtPtpDeviceSpiKm_Device.NT.AddReg\n\n[AmtPtpDeviceSpiKm_Device.NT.AddReg]\nHKR,,\"LowerFilters\",0x00010008,\"AmtPtpDeviceSpiKm\"\n\n[AmtPtpDeviceSpiKm_Service_Inst]\nDisplayName    = %AmtPtpDeviceSpiKm.SVCDESC%\nServiceType    = 1               ; SERVICE_KERNEL_DRIVER\nStartType      = 3               ; SERVICE_DEMAND_START\nErrorControl   = 1               ; SERVICE_ERROR_NORMAL\nServiceBinary  = %13%\\AmtPtpDeviceSpiKm.sys\nLoadOrderGroup = Extended Base\n\n[AmtPtpDeviceSpiKm_Device.NT.Wdf]\nKmdfService = AmtPtpDeviceSpiKm, AmtPtpDeviceSpiKm_wdfsect\n\n[AmtPtpDeviceSpiKm_wdfsect]\nKmdfLibraryVersion = $KMDFVERSION$\n\n[Strings]\nREG_MULTI_SZ = 0x00010000\nSPSVCINST_ASSOCSERVICE = 0x00000002\nManufacturerName = \"Bingxing Wang\"\nClassName = \"Universal Serial Bus devices\"\nDiskName = \"AmtPtpDeviceUsbKm Installation Disk\"\nAmtPtpDeviceUsbKm.DeviceDesc = \"Apple USB Precision Touchpad Device (Kernel-mode)\"\nAmtPtpDeviceUsbUm.DeviceDesc = \"Apple USB Precision Touchpad Device (User-mode)\"\nAmtPtpDeviceSpiKm.DeviceDesc = \"Apple SPI Precision Touchpad Device\"\nAmtPtpDeviceSpiKm.SVCDESC = \"Apple SPI Precision Touchpad Driver Service\"\nAmtPtpDeviceUsbKm.SVCDESC = \"Apple USB Precision Touchpad Service\"\nWudfRdDisplayName = \"Windows Driver Foundation - User-mode Driver Framework Reflector\"\nAmtPtpHidRootDevice.DeviceDesc = \"Apple Multi-touch Trackpad HID Device\"\nAmtPtpHidFilter.DeviceDesc = \"Apple Multi-touch Trackpad HID Filter\"\nAmtPtpHidFilter.NullDeviceDesc = \"Apple Multi-touch Auxiliary Services\"\nAmtPtpHidFilter.SVCDESC = \"Apple Multi-touch Trackpad HID Filter Service\"\n"
  },
  {
    "path": "src/AmtPtpDeviceUniversalPkg/AmtPtpDeviceUniversalPkg.vcxproj",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"ReleaseSigned|ARM64\">\n      <Configuration>ReleaseSigned</Configuration>\n      <Platform>ARM64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"ReleaseSigned|x64\">\n      <Configuration>ReleaseSigned</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|ARM64\">\n      <Configuration>Debug</Configuration>\n      <Platform>ARM64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|ARM64\">\n      <Configuration>Release</Configuration>\n      <Platform>ARM64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <ItemGroup>\n    <ProjectReference Include=\"..\\AmtPtpDeviceSpiKm\\AmtPtpDeviceSpiKm.vcxproj\">\n      <Project>{fc08b706-5661-47fa-a840-053b06125750}</Project>\n    </ProjectReference>\n    <ProjectReference Include=\"..\\AmtPtpDeviceUsbKm\\AmtPtpDeviceUsbKm.vcxproj\">\n      <Project>{ab3e45e7-c524-47c1-9677-728ba2a19344}</Project>\n    </ProjectReference>\n    <ProjectReference Include=\"..\\AmtPtpDeviceUsbUm\\MagicTrackpad2PtpDevice.vcxproj\">\n      <Project>{87efa31b-25eb-4944-a30a-300171bfff57}</Project>\n    </ProjectReference>\n    <ProjectReference Include=\"..\\AmtPtpHidFilter\\AmtPtpHidFilter.vcxproj\">\n      <Project>{ee63c42b-f401-4f55-adbb-14c16bd3b18c}</Project>\n    </ProjectReference>\n  </ItemGroup>\n  <ItemGroup>\n    <Inf Include=\"AmtPtpDevice.inf\" />\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{7AB0A246-AA1C-433B-9E16-88956C51A565}</ProjectGuid>\n    <TemplateGuid>{4605da2c-74a5-4865-98e1-152ef136825f}</TemplateGuid>\n    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>\n    <MinimumVisualStudioVersion>12.0</MinimumVisualStudioVersion>\n    <Configuration>Debug</Configuration>\n    <Platform Condition=\"'$(Platform)' == ''\">Win32</Platform>\n    <RootNamespace>AmtPtpDeviceUniversalPkg</RootNamespace>\n  </PropertyGroup>\n  <PropertyGroup>\n    <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(BuildEnvironment)'=='Github'\">\n    <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <TargetVersion>Windows10</TargetVersion>\n    <UseDebugLibraries>true</UseDebugLibraries>\n    <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>\n    <ConfigurationType>Utility</ConfigurationType>\n    <DriverType>Package</DriverType>\n    <DisableFastUpToDateCheck>true</DisableFastUpToDateCheck>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <TargetVersion>Windows10</TargetVersion>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>\n    <ConfigurationType>Utility</ConfigurationType>\n    <DriverType>Package</DriverType>\n    <DisableFastUpToDateCheck>true</DisableFastUpToDateCheck>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseSigned|x64'\" Label=\"Configuration\">\n    <TargetVersion>Windows10</TargetVersion>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>\n    <ConfigurationType>Utility</ConfigurationType>\n    <DriverType>Package</DriverType>\n    <DisableFastUpToDateCheck>true</DisableFastUpToDateCheck>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\" Label=\"Configuration\">\n    <TargetVersion>Windows10</TargetVersion>\n    <UseDebugLibraries>true</UseDebugLibraries>\n    <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>\n    <ConfigurationType>Utility</ConfigurationType>\n    <DriverType>Package</DriverType>\n    <DisableFastUpToDateCheck>true</DisableFastUpToDateCheck>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\" Label=\"Configuration\">\n    <TargetVersion>Windows10</TargetVersion>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>\n    <ConfigurationType>Utility</ConfigurationType>\n    <DriverType>Package</DriverType>\n    <DisableFastUpToDateCheck>true</DisableFastUpToDateCheck>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseSigned|ARM64'\" Label=\"Configuration\">\n    <TargetVersion>Windows10</TargetVersion>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>\n    <ConfigurationType>Utility</ConfigurationType>\n    <DriverType>Package</DriverType>\n    <DisableFastUpToDateCheck>true</DisableFastUpToDateCheck>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup />\n  <!-- Signature mode settings -->\n  <PropertyGroup Condition=\"'$(Configuration)'=='Debug'\">\n    <TimeStampServer>http://timestamp.digicert.com</TimeStampServer>\n    <SignMode>TestSign</SignMode>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)'=='Release'\">\n    <TimeStampServer>http://timestamp.digicert.com</TimeStampServer>\n    <SignMode>TestSign</SignMode>\n  </PropertyGroup>\n  <!-- For release signed config on Azure pipeline, CI pipeline don't sign it. We do that locally -->\n  <PropertyGroup Condition=\"'$(Configuration)'=='ReleaseSigned'\">\n    <TimeStampServer>http://timestamp.digicert.com</TimeStampServer>\n    <ProductionCertificate>$(ProductionCertPath)</ProductionCertificate>\n    <SignMode Condition=\"'$(BuildEnvironment)'!='AzurePipeline'\">ProductionSign</SignMode>\n    <SignMode Condition=\"'$(BuildEnvironment)'=='AzurePipeline'\">Off</SignMode>\n  </PropertyGroup>\n  <ItemDefinitionGroup>\n    <DriverSign>\n      <FileDigestAlgorithm>sha256</FileDigestAlgorithm>\n    </DriverSign>\n    <Inf>\n      <TimeStamp Condition=\"'$(BuildEnvironment)'=='AzurePipeline'\">2021.$(PipelineReleaseID).1.1000</TimeStamp>\n    </Inf>\n    <Inf>\n      <TimeStamp Condition=\"'$(BuildEnvironment)'!='AzurePipeline'\">*</TimeStamp>\n    </Inf>\n    <PreBuildEvent>\n      <Command Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">\n      </Command>\n    </PreBuildEvent>\n    <PreBuildEvent />\n    <PreBuildEvent>\n      <Command Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n      </Command>\n    </PreBuildEvent>\n    <PreLinkEvent>\n      <Command Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">\n      </Command>\n    </PreLinkEvent>\n    <PreLinkEvent />\n    <PreLinkEvent>\n      <Command Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n      </Command>\n    </PreLinkEvent>\n  </ItemDefinitionGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>\n    <HardwareIdString />\n    <CommandLine />\n    <DeployFiles />\n    <EnableVerifier>False</EnableVerifier>\n    <AllDrivers>False</AllDrivers>\n    <VerifyProjectOutput>True</VerifyProjectOutput>\n    <VerifyDrivers />\n    <VerifyFlags>133563</VerifyFlags>\n    <OutDir>$(SolutionDir)build\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\</OutDir>\n    <IntDir>$(SolutionDir)intermediate\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\</IntDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>\n    <HardwareIdString />\n    <CommandLine />\n    <DeployFiles />\n    <EnableVerifier>False</EnableVerifier>\n    <AllDrivers>False</AllDrivers>\n    <VerifyProjectOutput>True</VerifyProjectOutput>\n    <VerifyDrivers />\n    <VerifyFlags>133563</VerifyFlags>\n    <OutDir>$(SolutionDir)build\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\</OutDir>\n    <IntDir>$(SolutionDir)intermediate\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\</IntDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseSigned|x64'\">\n    <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>\n    <HardwareIdString />\n    <CommandLine />\n    <DeployFiles />\n    <EnableVerifier>False</EnableVerifier>\n    <AllDrivers>False</AllDrivers>\n    <VerifyProjectOutput>True</VerifyProjectOutput>\n    <VerifyDrivers />\n    <VerifyFlags>133563</VerifyFlags>\n    <OutDir>$(SolutionDir)build\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\</OutDir>\n    <IntDir>$(SolutionDir)intermediate\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\</IntDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">\n    <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>\n    <HardwareIdString />\n    <CommandLine />\n    <DeployFiles />\n    <EnableVerifier>False</EnableVerifier>\n    <AllDrivers>False</AllDrivers>\n    <VerifyProjectOutput>True</VerifyProjectOutput>\n    <VerifyDrivers />\n    <VerifyFlags>133563</VerifyFlags>\n    <OutDir>$(SolutionDir)build\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\</OutDir>\n    <IntDir>$(SolutionDir)intermediate\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\</IntDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">\n    <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>\n    <HardwareIdString />\n    <CommandLine />\n    <DeployFiles />\n    <EnableVerifier>False</EnableVerifier>\n    <AllDrivers>False</AllDrivers>\n    <VerifyProjectOutput>True</VerifyProjectOutput>\n    <VerifyDrivers />\n    <VerifyFlags>133563</VerifyFlags>\n    <OutDir>$(SolutionDir)build\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\</OutDir>\n    <IntDir>$(SolutionDir)intermediate\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\</IntDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseSigned|ARM64'\">\n    <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>\n    <HardwareIdString />\n    <CommandLine />\n    <DeployFiles />\n    <EnableVerifier>False</EnableVerifier>\n    <AllDrivers>False</AllDrivers>\n    <VerifyProjectOutput>True</VerifyProjectOutput>\n    <VerifyDrivers />\n    <VerifyFlags>133563</VerifyFlags>\n    <OutDir>$(SolutionDir)build\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\</OutDir>\n    <IntDir>$(SolutionDir)intermediate\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\</IntDir>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "src/AmtPtpDeviceUniversalPkg/AmtPtpDeviceUniversalPkg.vcxproj.filters",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup>\n    <Filter Include=\"Driver Files\">\n      <UniqueIdentifier>{8E41214B-6785-4CFE-B992-037D68949A14}</UniqueIdentifier>\n      <Extensions>inf;inv;inx;mof;mc;</Extensions>\n    </Filter>\n  </ItemGroup>\n  <ItemGroup>\n    <Inf Include=\"AmtPtpDevice.inf\">\n      <Filter>Driver Files</Filter>\n    </Inf>\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "src/AmtPtpDeviceUsbKm/AmtPtpDeviceUsbKm.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"12.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"ReleaseSigned|ARM64\">\n      <Configuration>ReleaseSigned</Configuration>\n      <Platform>ARM64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"ReleaseSigned|x64\">\n      <Configuration>ReleaseSigned</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|ARM64\">\n      <Configuration>Debug</Configuration>\n      <Platform>ARM64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|ARM64\">\n      <Configuration>Release</Configuration>\n      <Platform>ARM64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <ItemGroup>\n    <ClCompile Include=\"DebugUtils.c\" />\n    <ClCompile Include=\"Device.c\" />\n    <ClCompile Include=\"Driver.c\" />\n    <ClCompile Include=\"Hid.c\" />\n    <ClCompile Include=\"Interrupt.c\" />\n    <ClCompile Include=\"Queue.c\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"Device.h\" />\n    <ClInclude Include=\"Driver.h\" />\n    <ClInclude Include=\"Public.h\" />\n    <ClInclude Include=\"Queue.h\" />\n    <ClInclude Include=\"resource.h\" />\n    <ClInclude Include=\"Trace.h\" />\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{AB3E45E7-C524-47C1-9677-728BA2A19344}</ProjectGuid>\n    <TemplateGuid>{8c0e3d8b-df43-455b-815a-4a0e72973bc6}</TemplateGuid>\n    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>\n    <MinimumVisualStudioVersion>12.0</MinimumVisualStudioVersion>\n    <Configuration>Debug</Configuration>\n    <Platform Condition=\"'$(Platform)' == ''\">Win32</Platform>\n    <RootNamespace>AmtPtpDeviceUsbKm</RootNamespace>\n  </PropertyGroup>\n  <!-- They told me this: https://help.github.com/en/articles/software-in-virtual-environments-for-github-actions#windows-server-2019 -->\n  <PropertyGroup>\n    <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(BuildEnvironment)'=='Github'\">\n    <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>\n  </PropertyGroup>\n  <PropertyGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>\n    <ConfigurationType>Driver</ConfigurationType>\n    <DriverType>KMDF</DriverType>\n    <DriverTargetPlatform>Universal</DriverTargetPlatform>\n  </PropertyGroup>\n  <PropertyGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>\n    <ConfigurationType>Driver</ConfigurationType>\n    <DriverType>KMDF</DriverType>\n    <DriverTargetPlatform>Universal</DriverTargetPlatform>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseSigned|x64'\" Label=\"PropertySheets\">\n    <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>\n    <ConfigurationType>Driver</ConfigurationType>\n    <DriverType>KMDF</DriverType>\n    <DriverTargetPlatform>Universal</DriverTargetPlatform>\n  </PropertyGroup>\n  <PropertyGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">\n    <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>\n    <ConfigurationType>Driver</ConfigurationType>\n    <DriverType>KMDF</DriverType>\n    <DriverTargetPlatform>Universal</DriverTargetPlatform>\n  </PropertyGroup>\n  <PropertyGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">\n    <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>\n    <ConfigurationType>Driver</ConfigurationType>\n    <DriverType>KMDF</DriverType>\n    <DriverTargetPlatform>Universal</DriverTargetPlatform>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseSigned|ARM64'\" Label=\"PropertySheets\">\n    <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>\n    <ConfigurationType>Driver</ConfigurationType>\n    <DriverType>KMDF</DriverType>\n    <DriverTargetPlatform>Universal</DriverTargetPlatform>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <TargetVersion>Windows10</TargetVersion>\n    <UseDebugLibraries>true</UseDebugLibraries>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <TargetVersion>Windows10</TargetVersion>\n    <UseDebugLibraries>false</UseDebugLibraries>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseSigned|x64'\" Label=\"Configuration\">\n    <TargetVersion>Windows10</TargetVersion>\n    <UseDebugLibraries>false</UseDebugLibraries>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\" Label=\"Configuration\">\n    <TargetVersion>Windows10</TargetVersion>\n    <UseDebugLibraries>true</UseDebugLibraries>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\" Label=\"Configuration\">\n    <TargetVersion>Windows10</TargetVersion>\n    <UseDebugLibraries>false</UseDebugLibraries>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseSigned|ARM64'\" Label=\"Configuration\">\n    <TargetVersion>Windows10</TargetVersion>\n    <UseDebugLibraries>false</UseDebugLibraries>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>\n    <OutDir>$(SolutionDir)build\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\</OutDir>\n    <IntDir>$(SolutionDir)intermediate\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\</IntDir>\n    <IncludePath>$(SolutionDir)intermediate\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\;$(ProjectDir)include;$(IncludePath)</IncludePath>\n    <TimeStampServer>http://timestamp.digicert.com</TimeStampServer>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>\n    <OutDir>$(SolutionDir)build\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\</OutDir>\n    <IntDir>$(SolutionDir)intermediate\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\</IntDir>\n    <IncludePath>$(SolutionDir)intermediate\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\;$(ProjectDir)include;$(IncludePath)</IncludePath>\n    <TimeStampServer>http://timestamp.digicert.com</TimeStampServer>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseSigned|x64'\">\n    <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>\n    <OutDir>$(SolutionDir)build\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\</OutDir>\n    <IntDir>$(SolutionDir)intermediate\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\</IntDir>\n    <IncludePath>$(SolutionDir)intermediate\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\;$(ProjectDir)include;$(IncludePath)</IncludePath>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">\n    <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>\n    <OutDir>$(SolutionDir)build\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\</OutDir>\n    <IntDir>$(SolutionDir)intermediate\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\</IntDir>\n    <IncludePath>$(SolutionDir)intermediate\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\;$(ProjectDir)include;$(IncludePath)</IncludePath>\n    <TimeStampServer>http://timestamp.digicert.com</TimeStampServer>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">\n    <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>\n    <OutDir>$(SolutionDir)build\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\</OutDir>\n    <IntDir>$(SolutionDir)intermediate\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\</IntDir>\n    <IncludePath>$(SolutionDir)intermediate\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\;$(ProjectDir)include;$(IncludePath)</IncludePath>\n    <TimeStampServer>http://timestamp.digicert.com</TimeStampServer>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseSigned|ARM64'\">\n    <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>\n    <OutDir>$(SolutionDir)build\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\</OutDir>\n    <IntDir>$(SolutionDir)intermediate\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\</IntDir>\n    <IncludePath>$(SolutionDir)intermediate\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\;$(ProjectDir)include;$(IncludePath)</IncludePath>\n  </PropertyGroup>\n  <!-- For release signed config on Azure pipeline, CI pipeline don't sign it. We do that locally -->\n  <PropertyGroup Condition=\"'$(Configuration)'=='ReleaseSigned'\">\n    <TimeStampServer>http://timestamp.digicert.com</TimeStampServer>\n    <ProductionCertificate>$(ProductionCertPath)</ProductionCertificate>\n    <SignMode Condition=\"'$(BuildEnvironment)'!='AzurePipeline'\">ProductionSign</SignMode>\n    <SignMode Condition=\"'$(BuildEnvironment)'=='AzurePipeline'\">Off</SignMode>\n  </PropertyGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <ClCompile>\n      <WppEnabled>true</WppEnabled>\n      <WppRecorderEnabled>true</WppRecorderEnabled>\n      <WppScanConfigurationData Condition=\"'%(ClCompile.ScanConfigurationData)' == ''\">trace.h</WppScanConfigurationData>\n      <WppKernelMode>true</WppKernelMode>\n      <DisableSpecificWarnings>4214;%(DisableSpecificWarnings)</DisableSpecificWarnings>\n    </ClCompile>\n    <Link>\n      <AdditionalDependencies>%(AdditionalDependencies);usbdex.lib;ntstrsafe.lib</AdditionalDependencies>\n    </Link>\n    <DriverSign>\n      <FileDigestAlgorithm>sha256</FileDigestAlgorithm>\n    </DriverSign>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <ClCompile>\n      <WppEnabled>true</WppEnabled>\n      <WppRecorderEnabled>true</WppRecorderEnabled>\n      <WppScanConfigurationData Condition=\"'%(ClCompile.ScanConfigurationData)' == ''\">trace.h</WppScanConfigurationData>\n      <WppKernelMode>true</WppKernelMode>\n      <DisableSpecificWarnings>4214;%(DisableSpecificWarnings)</DisableSpecificWarnings>\n    </ClCompile>\n    <Link>\n      <AdditionalDependencies>%(AdditionalDependencies);usbdex.lib;ntstrsafe.lib</AdditionalDependencies>\n    </Link>\n    <DriverSign>\n      <FileDigestAlgorithm>sha256</FileDigestAlgorithm>\n    </DriverSign>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseSigned|x64'\">\n    <ClCompile>\n      <WppEnabled>true</WppEnabled>\n      <WppRecorderEnabled>true</WppRecorderEnabled>\n      <WppScanConfigurationData Condition=\"'%(ClCompile.ScanConfigurationData)' == ''\">trace.h</WppScanConfigurationData>\n      <WppKernelMode>true</WppKernelMode>\n      <DisableSpecificWarnings>4214;%(DisableSpecificWarnings)</DisableSpecificWarnings>\n    </ClCompile>\n    <Link>\n      <AdditionalDependencies>%(AdditionalDependencies);usbdex.lib;ntstrsafe.lib</AdditionalDependencies>\n    </Link>\n    <DriverSign>\n      <FileDigestAlgorithm>sha256</FileDigestAlgorithm>\n    </DriverSign>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">\n    <ClCompile>\n      <WppEnabled>true</WppEnabled>\n      <WppRecorderEnabled>true</WppRecorderEnabled>\n      <WppScanConfigurationData Condition=\"'%(ClCompile.ScanConfigurationData)' == ''\">trace.h</WppScanConfigurationData>\n      <WppKernelMode>true</WppKernelMode>\n      <DisableSpecificWarnings>4214;%(DisableSpecificWarnings)</DisableSpecificWarnings>\n    </ClCompile>\n    <Link>\n      <AdditionalDependencies>%(AdditionalDependencies);usbdex.lib;ntstrsafe.lib</AdditionalDependencies>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">\n    <ClCompile>\n      <WppEnabled>true</WppEnabled>\n      <WppRecorderEnabled>true</WppRecorderEnabled>\n      <WppScanConfigurationData Condition=\"'%(ClCompile.ScanConfigurationData)' == ''\">trace.h</WppScanConfigurationData>\n      <WppKernelMode>true</WppKernelMode>\n      <DisableSpecificWarnings>4214;%(DisableSpecificWarnings)</DisableSpecificWarnings>\n    </ClCompile>\n    <Link>\n      <AdditionalDependencies>%(AdditionalDependencies);usbdex.lib;ntstrsafe.lib</AdditionalDependencies>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseSigned|ARM64'\">\n    <ClCompile>\n      <WppEnabled>true</WppEnabled>\n      <WppRecorderEnabled>true</WppRecorderEnabled>\n      <WppScanConfigurationData Condition=\"'%(ClCompile.ScanConfigurationData)' == ''\">trace.h</WppScanConfigurationData>\n      <WppKernelMode>true</WppKernelMode>\n      <DisableSpecificWarnings>4214;%(DisableSpecificWarnings)</DisableSpecificWarnings>\n    </ClCompile>\n    <Link>\n      <AdditionalDependencies>%(AdditionalDependencies);usbdex.lib;ntstrsafe.lib</AdditionalDependencies>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <FilesToPackage Include=\"$(TargetPath)\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ResourceCompile Include=\"Resource.rc\" />\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "src/AmtPtpDeviceUsbKm/AmtPtpDeviceUsbKm.vcxproj.filters",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup>\n    <Filter Include=\"Source Files\">\n      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>\n      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>\n    </Filter>\n    <Filter Include=\"Header Files\">\n      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>\n      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>\n    </Filter>\n    <Filter Include=\"Resource Files\">\n      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>\n      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>\n    </Filter>\n    <Filter Include=\"Driver Files\">\n      <UniqueIdentifier>{8E41214B-6785-4CFE-B992-037D68949A14}</UniqueIdentifier>\n      <Extensions>inf;inv;inx;mof;mc;</Extensions>\n    </Filter>\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"Device.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"Driver.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"Public.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"Queue.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"Trace.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"resource.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n  </ItemGroup>\n  <ItemGroup>\n    <ClCompile Include=\"Device.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"Driver.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"Queue.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"Interrupt.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"DebugUtils.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"Hid.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n  </ItemGroup>\n  <ItemGroup>\n    <ResourceCompile Include=\"Resource.rc\">\n      <Filter>Resource Files</Filter>\n    </ResourceCompile>\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "src/AmtPtpDeviceUsbKm/DebugUtils.c",
    "content": "#include \"Driver.h\"\n\nPCHAR\nDbgDevicePowerString(\n\t_In_ WDF_POWER_DEVICE_STATE Type\n)\n{\n\tswitch (Type)\n\t{\n\tcase WdfPowerDeviceInvalid:\n\t\treturn \"WdfPowerDeviceInvalid\";\n\tcase WdfPowerDeviceD0:\n\t\treturn \"WdfPowerDeviceD0\";\n\tcase WdfPowerDeviceD1:\n\t\treturn \"WdfPowerDeviceD1\";\n\tcase WdfPowerDeviceD2:\n\t\treturn \"WdfPowerDeviceD2\";\n\tcase WdfPowerDeviceD3:\n\t\treturn \"WdfPowerDeviceD3\";\n\tcase WdfPowerDeviceD3Final:\n\t\treturn \"WdfPowerDeviceD3Final\";\n\tcase WdfPowerDevicePrepareForHibernation:\n\t\treturn \"WdfPowerDevicePrepareForHibernation\";\n\tcase WdfPowerDeviceMaximum:\n\t\treturn \"WdfPowerDeviceMaximum\";\n\tdefault:\n\t\treturn \"UnKnown Device Power State\";\n\t}\n}\n\nPCHAR\nDbgIoControlGetString(\n\t_In_ ULONG IoControlCode\n)\n{\n\n\tswitch (IoControlCode)\n\t{\n\tcase IOCTL_HID_GET_DEVICE_DESCRIPTOR:\n\t\treturn \"IOCTL_HID_GET_DEVICE_DESCRIPTOR\";\n\tcase IOCTL_HID_GET_DEVICE_ATTRIBUTES:\n\t\treturn \"IOCTL_HID_GET_DEVICE_ATTRIBUTES\";\n\tcase IOCTL_HID_GET_REPORT_DESCRIPTOR:\n\t\treturn \"IOCTL_HID_GET_REPORT_DESCRIPTOR\";\n\tcase IOCTL_HID_GET_STRING:\n\t\treturn \"IOCTL_HID_GET_STRING\";\n\tcase IOCTL_HID_READ_REPORT:\n\t\treturn \"IOCTL_HID_READ_REPORT\";\n\tcase IOCTL_HID_WRITE_REPORT:\n\t\treturn \"IOCTL_HID_WRITE_REPORT\";\n\tcase IOCTL_UMDF_HID_GET_INPUT_REPORT:\n\t\treturn \"IOCTL_UMDF_HID_GET_INPUT_REPORT\";\n\tcase IOCTL_UMDF_HID_SET_OUTPUT_REPORT:\n\t\treturn \"IOCTL_UMDF_HID_SET_OUTPUT_REPORT\";\n\tcase IOCTL_UMDF_HID_GET_FEATURE:\n\t\treturn \"IOCTL_UMDF_HID_GET_FEATURE\";\n\tcase IOCTL_UMDF_HID_SET_FEATURE:\n\t\treturn \"IOCTL_UMDF_HID_SET_FEATURE\";\n\tcase IOCTL_HID_ACTIVATE_DEVICE:\n\t\treturn \"IOCTL_HID_ACTIVATE_DEVICE\";\n\tcase IOCTL_HID_DEACTIVATE_DEVICE:\n\t\treturn \"IOCTL_HID_DEACTIVATE_DEVICE\";\n\tcase IOCTL_HID_SEND_IDLE_NOTIFICATION_REQUEST:\n\t\treturn \"IOCTL_HID_SEND_IDLE_NOTIFICATION_REQUEST\";\n\tdefault:\n\t\treturn \"IOCTL_UNKNOWN\";\n\t}\n}\n"
  },
  {
    "path": "src/AmtPtpDeviceUsbKm/Device.c",
    "content": "/*++\n\nModule Name:\n\n    device.c - Device handling events for example driver.\n\nAbstract:\n\n   This file contains the device entry points and callbacks.\n    \nEnvironment:\n\n    Kernel-mode Driver Framework\n\n--*/\n\n#include \"driver.h\"\n#include \"device.tmh\"\n\n#ifdef ALLOC_PRAGMA\n#pragma alloc_text (PAGE, AmtPtpDeviceUsbKmCreateDevice)\n#pragma alloc_text (PAGE, AmtPtpDeviceUsbKmEvtDevicePrepareHardware)\n#endif\n\n_IRQL_requires_(PASSIVE_LEVEL)\nstatic const struct BCM5974_CONFIG*\nAmtPtpGetDeviceConfig(\n\t_In_ USB_DEVICE_DESCRIPTOR deviceInfo\n)\n{\n\tUSHORT id = deviceInfo.idProduct;\n\tconst struct BCM5974_CONFIG* cfg;\n\n\tfor (cfg = Bcm5974ConfigTable; cfg->identification; ++cfg) {\n\t\tif (cfg->identification == id) {\n\t\t\treturn cfg;\n\t\t}\n\t}\n\n\t// Generic fallback\n\tTraceEvents(\n\t\tTRACE_LEVEL_WARNING,\n\t\tTRACE_DRIVER,\n\t\t\"%!FUNC! Selected a generic fallback configuration\"\n\t);\n\n\treturn &Bcm5974ConfigTable[0];\n}\n\nNTSTATUS\nAmtPtpDeviceUsbKmCreateDevice(\n    _Inout_ PWDFDEVICE_INIT DeviceInit\n    )\n/*++\n\nRoutine Description:\n\n    Worker routine called to create a device and its software resources.\n\nArguments:\n\n    DeviceInit - Pointer to an opaque init structure. Memory for this\n                    structure will be freed by the framework when the WdfDeviceCreate\n                    succeeds. So don't access the structure after that point.\n\nReturn Value:\n\n    NTSTATUS\n\n--*/\n{\n    WDF_PNPPOWER_EVENT_CALLBACKS pnpPowerCallbacks;\n    WDF_OBJECT_ATTRIBUTES   deviceAttributes;\n    PDEVICE_CONTEXT deviceContext;\n    WDFDEVICE device;\n    NTSTATUS status;\n\n    PAGED_CODE();\n\n\t// Initialize power callback (prep, D0 entry & exit)\n    WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpPowerCallbacks);\n    pnpPowerCallbacks.EvtDevicePrepareHardware = AmtPtpDeviceUsbKmEvtDevicePrepareHardware;\n\tpnpPowerCallbacks.EvtDeviceD0Entry = AmtPtpEvtDeviceD0Entry;\n\tpnpPowerCallbacks.EvtDeviceD0Exit = AmtPtpEvtDeviceD0Exit;\n    WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpPowerCallbacks);\n\n    WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&deviceAttributes, DEVICE_CONTEXT);\n\n    status = WdfDeviceCreate(&DeviceInit, &deviceAttributes, &device);\n\n    if (NT_SUCCESS(status)) {\n        //\n        // Get a pointer to the device context structure that we just associated\n        // with the device object. We define this structure in the device.h\n        // header file. DeviceGetContext is an inline function generated by\n        // using the WDF_DECLARE_CONTEXT_TYPE_WITH_NAME macro in device.h.\n        // This function will do the type checking and return the device context.\n        // If you pass a wrong object handle it will return NULL and assert if\n        // run under framework verifier mode.\n        //\n        deviceContext = DeviceGetContext(device);\n\n        //\n        // Initialize the context.\n        //\n\t\tdeviceContext->PtpReportButton = TRUE;\n\t\tdeviceContext->PtpReportTouch = TRUE;\n\n        //\n        // Create a device interface so that applications can find and talk\n        // to us.\n        //\n        status = WdfDeviceCreateDeviceInterface(\n            device,\n            &GUID_DEVINTERFACE_AmtPtpDeviceUsbKm,\n            NULL // ReferenceString\n            );\n\n        if (NT_SUCCESS(status)) {\n            //\n            // Initialize the I/O Package and any Queues\n            //\n            status = AmtPtpDeviceUsbKmQueueInitialize(device);\n        }\n    }\n\n    return status;\n}\n\nNTSTATUS\nAmtPtpDeviceUsbKmEvtDevicePrepareHardware(\n    _In_ WDFDEVICE Device,\n    _In_ WDFCMRESLIST ResourceList,\n    _In_ WDFCMRESLIST ResourceListTranslated\n    )\n/*++\n\nRoutine Description:\n\n    In this callback, the driver does whatever is necessary to make the\n    hardware ready to use.  In the case of a USB device, this involves\n    reading and selecting descriptors.\n\nArguments:\n\n    Device - handle to a device\n\nReturn Value:\n\n    NT status value\n\n--*/\n{\n    NTSTATUS status;\n    PDEVICE_CONTEXT pDeviceContext;\n\tWDF_USB_DEVICE_INFORMATION deviceInfo;\n\tULONG waitWakeEnable = FALSE;\n\n    UNREFERENCED_PARAMETER(ResourceList);\n    UNREFERENCED_PARAMETER(ResourceListTranslated);\n\n    PAGED_CODE();\n\n    TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, \"%!FUNC! Entry\");\n\n    status = STATUS_SUCCESS;\n    pDeviceContext = DeviceGetContext(Device);\n\n    //\n    // Create a USB device handle so that we can communicate with the\n    // underlying USB stack. The WDFUSBDEVICE handle is used to query,\n    // configure, and manage all aspects of the USB device.\n    // These aspects include device properties, bus properties,\n    // and I/O creation and synchronization. We only create the device the first time\n    // PrepareHardware is called. If the device is restarted by pnp manager\n    // for resource rebalance, we will use the same device handle but then select\n    // the interfaces again because the USB stack could reconfigure the device on\n    // restart.\n    //\n    if (pDeviceContext->UsbDevice == NULL) {\n\t\tstatus = WdfUsbTargetDeviceCreate(Device,\n\t\t\tWDF_NO_OBJECT_ATTRIBUTES,\n\t\t\t&pDeviceContext->UsbDevice\n\t\t);\n\n        if (!NT_SUCCESS(status)) {\n            TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE,\n\t\t\t\t\"WdfUsbTargetDeviceCreate failed 0x%x\", status);\n            return status;\n        }\n    }\n\n\t// Retrieve device information\n\tWdfUsbTargetDeviceGetDeviceDescriptor(\n\t\tpDeviceContext->UsbDevice,\n\t\t&pDeviceContext->DeviceDescriptor\n\t);\n\n\t// Get correct configuration from conf store\n\tpDeviceContext->DeviceInfo = AmtPtpGetDeviceConfig(pDeviceContext->DeviceDescriptor);\n\tif (pDeviceContext->DeviceInfo == NULL) {\n\t\tTraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE,\n\t\t\t\"AmtPtpGetDeviceConfig failed to find the device config\");\n\t\tstatus = STATUS_INVALID_DEVICE_STATE;\n\t\treturn status;\n\t}\n\n\t//\n\t// Retrieve USBD version information, port driver capabilites and device\n\t// capabilites such as speed, power, etc.\n\t//\n\tWDF_USB_DEVICE_INFORMATION_INIT(&deviceInfo);\n\tstatus = WdfUsbTargetDeviceRetrieveInformation(\n\t\tpDeviceContext->UsbDevice,\n\t\t&deviceInfo\n\t);\n\n\tif (NT_SUCCESS(status)) {\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_INFORMATION,\n\t\t\tTRACE_DEVICE,\n\t\t\t\"%!FUNC! IsDeviceHighSpeed: %s\",\n\t\t\t(deviceInfo.Traits & WDF_USB_DEVICE_TRAIT_AT_HIGH_SPEED) ? \"TRUE\" : \"FALSE\");\n\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_INFORMATION,\n\t\t\tTRACE_DEVICE,\n\t\t\t\"%!FUNC! IsDeviceSelfPowered: %s\",\n\t\t\t(deviceInfo.Traits & WDF_USB_DEVICE_TRAIT_SELF_POWERED) ? \"TRUE\" : \"FALSE\");\n\n\t\twaitWakeEnable = deviceInfo.Traits &\n\t\t\tWDF_USB_DEVICE_TRAIT_REMOTE_WAKE_CAPABLE;\n\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_INFORMATION,\n\t\t\tTRACE_DEVICE,\n\t\t\t\"%!FUNC! IsDeviceRemoteWakeable: %s\",\n\t\t\twaitWakeEnable ? \"TRUE\" : \"FALSE\");\n\n\t\t//\n\t\t// Save these for use later.\n\t\t//\n\t\tpDeviceContext->UsbDeviceTraits = deviceInfo.Traits;\n\t}\n\telse {\n\t\tpDeviceContext->UsbDeviceTraits = 0;\n\t}\n\n\t// Select interface to use\n\tstatus = SelectInterruptInterface(Device);\n\tif (!NT_SUCCESS(status)) {\n\t\tTraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE, \n\t\t\t\"%!FUNC! SelectInterruptInterface failed with %!STATUS!\", status);\n\t\treturn status;\n\t}\n\n\t// Set up interrupt\n\tstatus = AmtPtpConfigContReaderForInterruptEndPoint(pDeviceContext);\n\tif (!NT_SUCCESS(status)) {\n\t\tTraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE, \n\t\t\t\"%!FUNC! AmtPtpConfigContReaderForInterruptEndPoint failed with %!STATUS!\", status);\n\t\treturn status;\n\t}\n\n\t// Set default settings\n\tpDeviceContext->PtpReportButton = TRUE;\n\tpDeviceContext->PtpReportTouch = TRUE;\n\n    TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, \"%!FUNC! Exit\");\n\n    return status;\n}\n\n// D0 Entry & Exit\nNTSTATUS\nAmtPtpEvtDeviceD0Entry(\n\t_In_ WDFDEVICE Device,\n\t_In_ WDF_POWER_DEVICE_STATE PreviousState\n)\n{\n\tPDEVICE_CONTEXT         pDeviceContext;\n\tNTSTATUS                status;\n\tBOOLEAN                 isTargetStarted;\n\n\tpDeviceContext = DeviceGetContext(Device);\n\tisTargetStarted = FALSE;\n\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION,\n\t\tTRACE_DRIVER,\n\t\t\"%!FUNC! -->AmtPtpDeviceEvtDeviceD0Entry - coming from %s\",\n\t\tDbgDevicePowerString(PreviousState)\n\t);\n\n\t// Check wellspring mode\n\tif (pDeviceContext->PtpReportButton || pDeviceContext->IsWellspringModeOn) {\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_INFORMATION,\n\t\t\tTRACE_DRIVER,\n\t\t\t\"%!FUNC! <--AmtPtpDeviceEvtDeviceD0Entry - Start Wellspring Mode\"\n\t\t);\n\n\t\tstatus = AmtPtpSetWellspringMode(\n\t\t\tpDeviceContext,\n\t\t\tTRUE\n\t\t);\n\n\t\tif (!NT_SUCCESS(status)) {\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_WARNING,\n\t\t\t\tTRACE_DRIVER,\n\t\t\t\t\"%!FUNC! <--AmtPtpDeviceEvtDeviceD0Entry - Start Wellspring Mode failed with %!STATUS!\",\n\t\t\t\tstatus\n\t\t\t);\n\t\t}\n\t}\n\n\t// Get current time counter\n\tKeQueryPerformanceCounter(&pDeviceContext->LastReportTime);\n\n\t//\n\t// Since continuous reader is configured for this interrupt-pipe, we must explicitly start\n\t// the I/O target to get the framework to post read requests.\n\t//\n\tstatus = WdfIoTargetStart(WdfUsbTargetPipeGetIoTarget(pDeviceContext->InterruptPipe));\n\tif (!NT_SUCCESS(status)) {\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_ERROR,\n\t\t\tTRACE_DRIVER,\n\t\t\t\"%!FUNC! <--AmtPtpDeviceEvtDeviceD0Entry - Failed to start interrupt pipe %!STATUS!\",\n\t\t\tstatus\n\t\t);\n\t\tgoto end;\n\t}\n\n\tisTargetStarted = TRUE;\n\nend:\n\tif (!NT_SUCCESS(status)) {\n\t\t//\n\t\t// Failure in D0Entry will lead to device being removed. So let us stop the continuous\n\t\t// reader in preparation for the ensuing remove.\n\t\t//\n\t\tif (isTargetStarted) {\n\t\t\tWdfIoTargetStop(\n\t\t\t\tWdfUsbTargetPipeGetIoTarget(pDeviceContext->InterruptPipe),\n\t\t\t\tWdfIoTargetCancelSentIo\n\t\t\t);\n\t\t}\n\t}\n\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION,\n\t\tTRACE_DRIVER,\n\t\t\"%!FUNC! <--AmtPtpDeviceEvtDeviceD0Entry\"\n\t);\n\n\treturn status;\n}\n\nNTSTATUS\nAmtPtpEvtDeviceD0Exit(\n\t_In_ WDFDEVICE Device,\n\t_In_ WDF_POWER_DEVICE_STATE TargetState\n)\n{\n\tPDEVICE_CONTEXT         pDeviceContext;\n\tNTSTATUS\t\t\t\tstatus;\n\n\tPAGED_CODE();\n\tstatus = STATUS_SUCCESS;\n\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION,\n\t\tTRACE_DRIVER,\n\t\t\"%!FUNC! -->AmtPtpDeviceEvtDeviceD0Exit - moving to %s\",\n\t\tDbgDevicePowerString(TargetState)\n\t);\n\n\tpDeviceContext = DeviceGetContext(Device);\n\n\t// Stop IO Pipe.\n\tWdfIoTargetStop(WdfUsbTargetPipeGetIoTarget(\n\t\tpDeviceContext->InterruptPipe),\n\t\tWdfIoTargetCancelSentIo\n\t);\n\n\t// Cancel Wellspring mode.\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION,\n\t\tTRACE_DRIVER,\n\t\t\"%!FUNC! -->AmtPtpDeviceEvtDeviceD0Exit - Cancel Wellspring Mode\"\n\t);\n\n\tstatus = AmtPtpSetWellspringMode(\n\t\tpDeviceContext,\n\t\tFALSE\n\t);\n\n\tif (!NT_SUCCESS(status)) {\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_WARNING,\n\t\t\tTRACE_DRIVER,\n\t\t\t\"%!FUNC! -->AmtPtpDeviceEvtDeviceD0Exit - Cancel Wellspring Mode failed with %!STATUS!\",\n\t\t\tstatus\n\t\t);\n\t}\n\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION,\n\t\tTRACE_DRIVER,\n\t\t\"%!FUNC! <--AmtPtpDeviceEvtDeviceD0Exit\"\n\t);\n\n\treturn status;\n}\n\n_IRQL_requires_(PASSIVE_LEVEL)\nNTSTATUS\nSelectInterruptInterface(\n\t_In_ WDFDEVICE Device\n)\n{\n\tWDF_USB_DEVICE_SELECT_CONFIG_PARAMS configParams;\n\tNTSTATUS                            status = STATUS_SUCCESS;\n\tPDEVICE_CONTEXT                     pDeviceContext;\n\tWDFUSBPIPE                          pipe;\n\tWDF_USB_PIPE_INFORMATION            pipeInfo;\n\tUCHAR                               index;\n\tUCHAR                               numberConfiguredPipes;\n\n\tPAGED_CODE();\n\n\tpDeviceContext = DeviceGetContext(Device);\n\tWDF_USB_DEVICE_SELECT_CONFIG_PARAMS_INIT_SINGLE_INTERFACE(&configParams);\n\n\t// It is slightly different than UMDF\n\tstatus = WdfUsbTargetDeviceSelectConfig(pDeviceContext->UsbDevice,\n\t\tWDF_NO_OBJECT_ATTRIBUTES,\n\t\t&configParams);\n\n\tif (!NT_SUCCESS(status)) {\n\t\tTraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE,\n\t\t\t\"WdfUsbTargetDeviceSelectConfig failed %!STATUS! \",\n\t\t\tstatus);\n\t\treturn status;\n\t}\n\n\tpDeviceContext->UsbInterface = configParams.Types.SingleInterface.ConfiguredUsbInterface;\n\tnumberConfiguredPipes = configParams.Types.SingleInterface.NumberConfiguredPipes;\n\n\t//\n\t// Get pipe handles\n\t//\n\tfor (index = 0; index < numberConfiguredPipes; index++) {\n\n\t\tWDF_USB_PIPE_INFORMATION_INIT(&pipeInfo);\n\n\t\tpipe = WdfUsbInterfaceGetConfiguredPipe(\n\t\t\tpDeviceContext->UsbInterface,\n\t\t\tindex, //PipeIndex,\n\t\t\t&pipeInfo\n\t\t);\n\n\t\t//\n\t\t// Tell the framework that it's okay to read less than\n\t\t// MaximumPacketSize\n\t\t//\n\t\tWdfUsbTargetPipeSetNoMaximumPacketSizeCheck(pipe);\n\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_INFORMATION,\n\t\t\tTRACE_DEVICE,\n\t\t\t\"%!FUNC! Found USB pipe type %d\",\n\t\t\tpipeInfo.PipeType\n\t\t);\n\n\t\tif (WdfUsbPipeTypeInterrupt == pipeInfo.PipeType) {\n\t\t\tpDeviceContext->InterruptPipe = pipe;\n\t\t\tbreak;\n\t\t}\n\n\t}\n\n\t//\n\t// If we didn't find interrupt pipe, fail the start.\n\t//\n\tif (!pDeviceContext->InterruptPipe) {\n\t\tstatus = STATUS_INVALID_DEVICE_STATE;\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_ERROR,\n\t\t\tTRACE_DEVICE,\n\t\t\t\"%!FUNC! Device is not configured properly %!STATUS!\",\n\t\t\tstatus\n\t\t);\n\n\t\treturn status;\n\t}\n\n\treturn status;\n}\n\n_IRQL_requires_(PASSIVE_LEVEL)\nNTSTATUS\nAmtPtpSetWellspringMode(\n\t_In_ PDEVICE_CONTEXT DeviceContext,\n\t_In_ BOOLEAN IsWellspringModeOn\n)\n{\n\tNTSTATUS\t\t\t\t\t\tstatus;\n\tWDF_USB_CONTROL_SETUP_PACKET\tsetupPacket;\n\tWDF_MEMORY_DESCRIPTOR\t\t\tmemoryDescriptor;\n\tULONG\t\t\t\t\t\t\tcbTransferred;\n\tWDFMEMORY\t\t\t\t\t\tbufHandle = NULL;\n\tunsigned char* buffer;\n\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION,\n\t\tTRACE_DRIVER,\n\t\t\"%!FUNC! Entry\"\n\t);\n\n\t// Type 3 does not need a mode switch.\n\t// However, turn mode on or off as requested.\n\tif (DeviceContext->DeviceInfo->tp_type == TYPE3) {\n\t\tDeviceContext->IsWellspringModeOn = IsWellspringModeOn;\n\t\treturn STATUS_SUCCESS;\n\t}\n\n\tstatus = WdfMemoryCreate(\n\t\tWDF_NO_OBJECT_ATTRIBUTES,\n\t\tPagedPool,\n\t\tPOOL_TAG_PTP_CONTROL,\n\t\tDeviceContext->DeviceInfo->um_size,\n\t\t&bufHandle,\n\t\t&buffer\n\t);\n\n\tif (!NT_SUCCESS(status)) {\n\t\tgoto cleanup;\n\t}\n\n\tRtlZeroMemory(\n\t\tbuffer,\n\t\tDeviceContext->DeviceInfo->um_size\n\t);\n\n\tWDF_MEMORY_DESCRIPTOR_INIT_BUFFER(\n\t\t&memoryDescriptor,\n\t\tbuffer,\n\t\tsizeof(DeviceContext->DeviceInfo->um_size)\n\t);\n\n\tWDF_USB_CONTROL_SETUP_PACKET_INIT(\n\t\t&setupPacket,\n\t\tBmRequestDeviceToHost,\n\t\tBmRequestToInterface,\n\t\tBCM5974_WELLSPRING_MODE_READ_REQUEST_ID,\n\t\t(USHORT) DeviceContext->DeviceInfo->um_req_val,\n\t\t(USHORT) DeviceContext->DeviceInfo->um_req_idx\n\t);\n\n\t// Set stuffs right\n\tsetupPacket.Packet.bm.Request.Type = BmRequestClass;\n\n\tstatus = WdfUsbTargetDeviceSendControlTransferSynchronously(\n\t\tDeviceContext->UsbDevice,\n\t\tWDF_NO_HANDLE,\n\t\tNULL,\n\t\t&setupPacket,\n\t\t&memoryDescriptor,\n\t\t&cbTransferred\n\t);\n\n\t// Behavior mismatch: Actual device does not transfer bytes as expected (in length)\n\t// So we do not check um_size as a temporary workaround.\n\tif (!NT_SUCCESS(status)) {\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_ERROR,\n\t\t\tTRACE_DEVICE,\n\t\t\t\"%!FUNC! WdfUsbTargetDeviceSendControlTransferSynchronously (Read) failed with %!STATUS!, cbTransferred = %llu, um_size = %d\",\n\t\t\tstatus,\n\t\t\tcbTransferred,\n\t\t\tDeviceContext->DeviceInfo->um_size\n\t\t);\n\t\tgoto cleanup;\n\t}\n\n\t// Apply the mode switch\n\tbuffer[DeviceContext->DeviceInfo->um_switch_idx] = IsWellspringModeOn ?\n\t\t(unsigned char)DeviceContext->DeviceInfo->um_switch_on :\n\t\t(unsigned char)DeviceContext->DeviceInfo->um_switch_off;\n\n\t// Write configuration\n\tWDF_USB_CONTROL_SETUP_PACKET_INIT(\n\t\t&setupPacket,\n\t\tBmRequestHostToDevice,\n\t\tBmRequestToInterface,\n\t\tBCM5974_WELLSPRING_MODE_WRITE_REQUEST_ID,\n\t\t(USHORT)DeviceContext->DeviceInfo->um_req_val,\n\t\t(USHORT)DeviceContext->DeviceInfo->um_req_idx\n\t);\n\n\t// Set stuffs right\n\tsetupPacket.Packet.bm.Request.Type = BmRequestClass;\n\n\tstatus = WdfUsbTargetDeviceSendControlTransferSynchronously(\n\t\tDeviceContext->UsbDevice,\n\t\tWDF_NO_HANDLE,\n\t\tNULL,\n\t\t&setupPacket,\n\t\t&memoryDescriptor,\n\t\t&cbTransferred\n\t);\n\n\tif (!NT_SUCCESS(status)) {\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_ERROR,\n\t\t\tTRACE_DEVICE,\n\t\t\t\"%!FUNC! WdfUsbTargetDeviceSendControlTransferSynchronously (Write) failed with %!STATUS!\",\n\t\t\tstatus\n\t\t);\n\t\tgoto cleanup;\n\t}\n\n\t// Set status\n\tDeviceContext->IsWellspringModeOn = IsWellspringModeOn;\n\ncleanup:\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION,\n\t\tTRACE_DRIVER,\n\t\t\"%!FUNC! Exit\"\n\t);\n\n\tWdfObjectDelete(bufHandle);\n\tbufHandle = NULL;\n\treturn status;\n}\n"
  },
  {
    "path": "src/AmtPtpDeviceUsbKm/Device.h",
    "content": "/*++\n\nModule Name:\n\n    device.h\n\nAbstract:\n\n    This file contains the device definitions.\n\nEnvironment:\n\n    Kernel-mode Driver Framework\n\n--*/\n\n#include \"public.h\"\n\nEXTERN_C_START\n\n//\n// The device context performs the same job as\n// a WDM device extension in the driver frameworks\n//\ntypedef struct _DEVICE_CONTEXT\n{\n\t// USB Things\n\tWDFUSBDEVICE UsbDevice;\n\tWDFUSBPIPE InterruptPipe;\n\tWDFUSBINTERFACE UsbInterface;\n\tWDFQUEUE InputQueue;\n\tUSB_DEVICE_DESCRIPTOR DeviceDescriptor;\n\tULONG UsbDeviceTraits;\n\n\t// Device Config\n\tconst struct BCM5974_CONFIG* DeviceInfo;\n\tBOOLEAN IsWellspringModeOn;\n\n\t// PTP Status\n\tBOOLEAN PtpInputOn;\n\tBOOLEAN PtpReportTouch;\n\tBOOLEAN PtpReportButton;\n\n\t// Timer\n\tLARGE_INTEGER LastReportTime;\n\n} DEVICE_CONTEXT, *PDEVICE_CONTEXT;\n\n//\n// This macro will generate an inline function called DeviceGetContext\n// which will be used to get a pointer to the device context memory\n// in a type safe manner.\n//\nWDF_DECLARE_CONTEXT_TYPE_WITH_NAME(DEVICE_CONTEXT, DeviceGetContext)\n\n//\n// Pool tags\n//\n#define POOL_TAG_PTP_CONTROL 'PTPC'\n\n//\n// Function to initialize the device's queues and callbacks\n//\nNTSTATUS\nAmtPtpDeviceUsbKmCreateDevice(\n    _Inout_ PWDFDEVICE_INIT DeviceInit\n    );\n\n//\n// Function to select the device's USB configuration and get a WDFUSBDEVICE\n// handle\n//\nEVT_WDF_DEVICE_PREPARE_HARDWARE AmtPtpDeviceUsbKmEvtDevicePrepareHardware;\nEVT_WDF_DEVICE_D0_ENTRY AmtPtpEvtDeviceD0Entry;\nEVT_WDF_DEVICE_D0_EXIT AmtPtpEvtDeviceD0Exit;\n\n//\n// Function to select interrupt interface\n//\n_IRQL_requires_(PASSIVE_LEVEL)\nNTSTATUS\nSelectInterruptInterface(\n\t_In_ WDFDEVICE Device\n);\n\n//\n// Function to configure interrupt\n//\n_IRQL_requires_(PASSIVE_LEVEL)\nNTSTATUS\nAmtPtpConfigContReaderForInterruptEndPoint(\n\t_In_ PDEVICE_CONTEXT DeviceContext\n);\n\n//\n// Functions to serve interrupt\n//\nEVT_WDF_USB_READER_COMPLETION_ROUTINE AmtPtpEvtUsbInterruptPipeReadComplete;\nEVT_WDF_USB_READERS_FAILED AmtPtpEvtUsbInterruptReadersFailed;\n\n//\n// Debug utilities\n//\nPCHAR\nDbgDevicePowerString(\n\t_In_ WDF_POWER_DEVICE_STATE Type\n);\n\nPCHAR\nDbgIoControlGetString(\n\t_In_ ULONG IoControlCode\n);\n\n//\n// Device functions\n//\n_IRQL_requires_(PASSIVE_LEVEL)\nNTSTATUS\nAmtPtpSetWellspringMode(\n\t_In_ PDEVICE_CONTEXT DeviceContext,\n\t_In_ BOOLEAN IsWellspringModeOn\n);\n\n//\n// HID routines\n//\n_IRQL_requires_(PASSIVE_LEVEL)\nNTSTATUS\nAmtPtpGetHidDescriptor(\n\t_In_ WDFDEVICE Device,\n\t_In_ WDFREQUEST Request\n);\n\n_IRQL_requires_(PASSIVE_LEVEL)\nNTSTATUS\nAmtPtpGetDeviceAttribs(\n\t_In_ WDFDEVICE Device,\n\t_In_ WDFREQUEST Request\n);\n\n_IRQL_requires_(PASSIVE_LEVEL)\nNTSTATUS\nAmtPtpGetReportDescriptor(\n\t_In_ WDFDEVICE Device,\n\t_In_ WDFREQUEST Request\n);\n\nNTSTATUS\nAmtPtpDispatchReadReportRequests(\n\t_In_ WDFDEVICE Device,\n\t_In_ WDFREQUEST Request,\n\t_Out_ BOOLEAN* Pending\n);\n\n_IRQL_requires_(PASSIVE_LEVEL)\nNTSTATUS\nAmtPtpReportFeatures(\n\t_In_ WDFDEVICE Device,\n\t_In_ WDFREQUEST Request\n);\n\n_IRQL_requires_(PASSIVE_LEVEL)\nNTSTATUS\nAmtPtpSetFeatures(\n\t_In_ WDFDEVICE Device,\n\t_In_ WDFREQUEST Request\n);\n\nEXTERN_C_END\n"
  },
  {
    "path": "src/AmtPtpDeviceUsbKm/Driver.c",
    "content": "/*++\n\nModule Name:\n\n    driver.c\n\nAbstract:\n\n    This file contains the driver entry points and callbacks.\n\nEnvironment:\n\n    Kernel-mode Driver Framework\n\n--*/\n\n#include \"driver.h\"\n#include \"driver.tmh\"\n\n#ifdef ALLOC_PRAGMA\n#pragma alloc_text (INIT, DriverEntry)\n#pragma alloc_text (PAGE, AmtPtpDeviceUsbKmEvtDeviceAdd)\n#pragma alloc_text (PAGE, AmtPtpDeviceUsbKmEvtDriverContextCleanup)\n#endif\n\n\nNTSTATUS\nDriverEntry(\n    _In_ PDRIVER_OBJECT  DriverObject,\n    _In_ PUNICODE_STRING RegistryPath\n    )\n/*++\n\nRoutine Description:\n    DriverEntry initializes the driver and is the first routine called by the\n    system after the driver is loaded. DriverEntry specifies the other entry\n    points in the function driver, such as EvtDevice and DriverUnload.\n\nParameters Description:\n\n    DriverObject - represents the instance of the function driver that is loaded\n    into memory. DriverEntry must initialize members of DriverObject before it\n    returns to the caller. DriverObject is allocated by the system before the\n    driver is loaded, and it is released by the system after the system unloads\n    the function driver from memory.\n\n    RegistryPath - represents the driver specific path in the Registry.\n    The function driver can use the path to store driver related data between\n    reboots. The path does not store hardware instance specific data.\n\nReturn Value:\n\n    STATUS_SUCCESS if successful,\n    STATUS_UNSUCCESSFUL otherwise.\n\n--*/\n{\n    WDF_DRIVER_CONFIG config;\n    NTSTATUS status;\n    WDF_OBJECT_ATTRIBUTES attributes;\n\n    //\n    // Initialize WPP Tracing\n    //\n    WPP_INIT_TRACING( DriverObject, RegistryPath );\n\n    TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, \"%!FUNC! Entry\");\n\n    //\n    // Register a cleanup callback so that we can call WPP_CLEANUP when\n    // the framework driver object is deleted during driver unload.\n    //\n    WDF_OBJECT_ATTRIBUTES_INIT(&attributes);\n    attributes.EvtCleanupCallback = AmtPtpDeviceUsbKmEvtDriverContextCleanup;\n\n    WDF_DRIVER_CONFIG_INIT(&config,\n                           AmtPtpDeviceUsbKmEvtDeviceAdd\n                           );\n\n    status = WdfDriverCreate(DriverObject,\n                             RegistryPath,\n                             &attributes,\n                             &config,\n                             WDF_NO_HANDLE\n                             );\n\n    if (!NT_SUCCESS(status)) {\n        TraceEvents(TRACE_LEVEL_ERROR, TRACE_DRIVER, \"WdfDriverCreate failed %!STATUS!\", status);\n        WPP_CLEANUP(DriverObject);\n        return status;\n    }\n\n    TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, \"%!FUNC! Exit\");\n\n    return status;\n}\n\nNTSTATUS\nAmtPtpDeviceUsbKmEvtDeviceAdd(\n    _In_    WDFDRIVER       Driver,\n    _Inout_ PWDFDEVICE_INIT DeviceInit\n    )\n/*++\nRoutine Description:\n\n    EvtDeviceAdd is called by the framework in response to AddDevice\n    call from the PnP manager. We create and initialize a device object to\n    represent a new instance of the device.\n\nArguments:\n\n    Driver - Handle to a framework driver object created in DriverEntry\n\n    DeviceInit - Pointer to a framework-allocated WDFDEVICE_INIT structure.\n\nReturn Value:\n\n    NTSTATUS\n\n--*/\n{\n    NTSTATUS status;\n\n    UNREFERENCED_PARAMETER(Driver);\n\n    PAGED_CODE();\n\n    TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, \"%!FUNC! Entry\");\n\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION, TRACE_DRIVER,\n\t\t\"%!FUNC! Set FDO driver filter\"\n\t);\n\n\tWdfFdoInitSetFilter(DeviceInit);\n\tWdfPdoInitAllowForwardingRequestToParent(DeviceInit);\n\n    status = AmtPtpDeviceUsbKmCreateDevice(DeviceInit);\n\n    TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, \"%!FUNC! Exit\");\n\n    return status;\n}\n\nVOID\nAmtPtpDeviceUsbKmEvtDriverContextCleanup(\n    _In_ WDFOBJECT DriverObject\n    )\n/*++\nRoutine Description:\n\n    Free all the resources allocated in DriverEntry.\n\nArguments:\n\n    DriverObject - handle to a WDF Driver object.\n\nReturn Value:\n\n    VOID.\n\n--*/\n{\n    UNREFERENCED_PARAMETER(DriverObject);\n\n    PAGED_CODE ();\n\n    TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, \"%!FUNC! Entry\");\n\n    //\n    // Stop WPP Tracing\n    //\n    WPP_CLEANUP( WdfDriverWdmGetDriverObject( (WDFDRIVER) DriverObject) );\n\n}\n"
  },
  {
    "path": "src/AmtPtpDeviceUsbKm/Driver.h",
    "content": "/*++\n\nModule Name:\n\n    driver.h\n\nAbstract:\n\n    This file contains the driver definitions.\n\nEnvironment:\n\n    Kernel-mode Driver Framework\n\n--*/\n\n#include <ntddk.h>\n#include <wdf.h>\n#include <usb.h>\n#include <usbdlib.h>\n#include <wdfusb.h>\n#include <initguid.h>\n\n#include \"device.h\"\n#include \"queue.h\"\n#include \"trace.h\"\n\n#include <Hid.h>\n\nEXTERN_C_START\n\n//\n// WDFDRIVER Events\n//\n\nDRIVER_INITIALIZE DriverEntry;\nEVT_WDF_DRIVER_DEVICE_ADD AmtPtpDeviceUsbKmEvtDeviceAdd;\nEVT_WDF_OBJECT_CONTEXT_CLEANUP AmtPtpDeviceUsbKmEvtDriverContextCleanup;\n\nEXTERN_C_END\n"
  },
  {
    "path": "src/AmtPtpDeviceUsbKm/Hid.c",
    "content": "#include \"Driver.h\"\n#include \"hid.tmh\"\n\n#ifndef _AAPL_HID_DESCRIPTOR_H_\n#define _AAPL_HID_DESCRIPTOR_H_\n\nHID_REPORT_DESCRIPTOR AmtPtpT2ReportDescriptor[] = {\n\tAAPL_WELLSPRING_T2_PTP_TLC,\n\tAAPL_PTP_WINDOWS_CONFIGURATION_TLC,\n};\n\nCONST HID_DESCRIPTOR AmtPtpT2DefaultHidDescriptor = {\n\t0x09,   // bLength\n\t0x21,   // bDescriptorType\n\t0x0100, // bcdHID\n\t0x00,   // bCountryCode\n\t0x01,   // bNumDescriptors\n\t{\n\t\t0x22,                               // bDescriptorType\n\t\tsizeof(AmtPtpT2ReportDescriptor)    // bDescriptorLength\n\t},\n};\n\n#endif\n\n_IRQL_requires_(PASSIVE_LEVEL)\nNTSTATUS\nAmtPtpGetHidDescriptor(\n\t_In_ WDFDEVICE Device,\n\t_In_ WDFREQUEST Request\n)\n{\n\tNTSTATUS status = STATUS_SUCCESS;\n\tPDEVICE_CONTEXT pContext = DeviceGetContext(Device);\n\tsize_t szCopy = 0;\n\tWDFMEMORY requestMemory;\n\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION, TRACE_DRIVER,\n\t\t\"%!FUNC! Entry\"\n\t);\n\n\tstatus = WdfRequestRetrieveOutputMemory(\n\t\tRequest,\n\t\t&requestMemory\n\t);\n\n\tif (!NT_SUCCESS(status)) {\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_ERROR, TRACE_DRIVER,\n\t\t\t\"%!FUNC! WdfRequestRetrieveOutputBuffer failed with %!STATUS!\",\n\t\t\tstatus\n\t\t);\n\t\tgoto exit;\n\t}\n\n\tswitch (pContext->DeviceDescriptor.idProduct) {\n\t\tcase USB_DEVICE_ID_APPLE_T2_7A:\n\t\tcase USB_DEVICE_ID_APPLE_T2_7B:\n\t\tcase USB_DEVICE_ID_APPLE_T2_7C:\n\t\tcase USB_DEVICE_ID_APPLE_T2_7D:\n\t\t{\n\t\t\tszCopy = AmtPtpT2DefaultHidDescriptor.bLength;\n\t\t\tstatus = WdfMemoryCopyFromBuffer(\n\t\t\t\trequestMemory,\n\t\t\t\t0,\n\t\t\t\t(PVOID) &AmtPtpT2DefaultHidDescriptor,\n\t\t\t\tszCopy\n\t\t\t);\n\n\t\t\tif (!NT_SUCCESS(status)) {\n\t\t\t\tTraceEvents(\n\t\t\t\t\tTRACE_LEVEL_ERROR, TRACE_DRIVER,\n\t\t\t\t\t\"%!FUNC! WdfMemoryCopyFromBuffer failed with %!STATUS!\",\n\t\t\t\t\tstatus\n\t\t\t\t);\n\t\t\t\tgoto exit;\n\t\t\t}\n\n\t\t\tWdfRequestSetInformation(Request,szCopy);\n\t\t\tbreak;\n\t\t}\n\t\tdefault:\n\t\t{\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_WARNING, TRACE_DRIVER,\n\t\t\t\t\"%!FUNC! Device HID registry is not found, use a generic fallback\"\n\t\t\t);\n\n\t\t\tszCopy = AmtPtpT2DefaultHidDescriptor.bLength;\n\t\t\tstatus = WdfMemoryCopyFromBuffer(\n\t\t\t\trequestMemory,\n\t\t\t\t0,\n\t\t\t\t(PVOID)&AmtPtpT2DefaultHidDescriptor,\n\t\t\t\tszCopy\n\t\t\t);\n\n\t\t\tif (!NT_SUCCESS(status)) {\n\t\t\t\tTraceEvents(\n\t\t\t\t\tTRACE_LEVEL_ERROR, TRACE_DRIVER,\n\t\t\t\t\t\"%!FUNC! WdfMemoryCopyFromBuffer failed with %!STATUS!\",\n\t\t\t\t\tstatus\n\t\t\t\t);\n\t\t\t\tgoto exit;\n\t\t\t}\n\n\t\t\tWdfRequestSetInformation(Request, szCopy);\n\t\t\tbreak;\n\t\t}\n\t};\n\nexit:\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION, TRACE_DRIVER,\n\t\t\"%!FUNC! Exit\"\n\t);\n\n\treturn status;\n}\n\n_IRQL_requires_(PASSIVE_LEVEL)\nNTSTATUS\nAmtPtpGetDeviceAttribs(\n\t_In_ WDFDEVICE Device,\n\t_In_ WDFREQUEST Request\n)\n{\n\tNTSTATUS status = STATUS_SUCCESS;\n\tPDEVICE_CONTEXT pContext = DeviceGetContext(Device);\n\tPHID_DEVICE_ATTRIBUTES pDeviceAttributes = NULL;\n\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION, TRACE_DRIVER,\n\t\t\"%!FUNC! Entry\"\n\t);\n\n\tstatus = WdfRequestRetrieveOutputBuffer(\n\t\tRequest,\n\t\tsizeof(HID_DEVICE_ATTRIBUTES),\n\t\t&pDeviceAttributes,\n\t\tNULL\n\t);\n\n\tif (!NT_SUCCESS(status)) {\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_ERROR, TRACE_DRIVER,\n\t\t\t\"%!FUNC! WdfRequestRetrieveOutputBuffer failed with %!STATUS!\",\n\t\t\tstatus\n\t\t);\n\t\tgoto exit;\n\t}\n\n\tpDeviceAttributes->Size = sizeof(HID_DEVICE_ATTRIBUTES);\n\tpDeviceAttributes->ProductID = pContext->DeviceDescriptor.idProduct;\n\tpDeviceAttributes->VendorID = pContext->DeviceDescriptor.idVendor;\n\tpDeviceAttributes->VersionNumber = DEVICE_VERSION;\n\n\tWdfRequestSetInformation(Request, sizeof(HID_DEVICE_ATTRIBUTES));\n\nexit:\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION, TRACE_DRIVER,\n\t\t\"%!FUNC! Exit\"\n\t);\n\n\treturn status;\n}\n\n_IRQL_requires_(PASSIVE_LEVEL)\nNTSTATUS\nAmtPtpGetReportDescriptor(\n\t_In_ WDFDEVICE Device,\n\t_In_ WDFREQUEST Request\n)\n{\n\tNTSTATUS status = STATUS_SUCCESS;\n\tPDEVICE_CONTEXT pContext = DeviceGetContext(Device);\n\tsize_t szCopy = 0;\n\tWDFMEMORY requestMemory;\n\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION, TRACE_DRIVER,\n\t\t\"%!FUNC! Entry\"\n\t);\n\n\tstatus = WdfRequestRetrieveOutputMemory(\n\t\tRequest,\n\t\t&requestMemory\n\t);\n\n\tif (!NT_SUCCESS(status)) {\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_ERROR, TRACE_DRIVER,\n\t\t\t\"%!FUNC! WdfRequestRetrieveOutputBuffer failed with %!STATUS!\",\n\t\t\tstatus\n\t\t);\n\t\tgoto exit;\n\t}\n\n\tswitch (pContext->DeviceDescriptor.idProduct) {\n\t\tcase USB_DEVICE_ID_APPLE_T2_7A:\n\t\tcase USB_DEVICE_ID_APPLE_T2_7B:\n\t\tcase USB_DEVICE_ID_APPLE_T2_7C:\n\t\tcase USB_DEVICE_ID_APPLE_T2_7D:\n\t\t{\n\n\t\t\tszCopy = AmtPtpT2DefaultHidDescriptor.DescriptorList[0].wReportLength;\n\t\t\tif (szCopy == 0) {\n\n\t\t\t\tstatus = STATUS_INVALID_DEVICE_STATE;\n\t\t\t\tTraceEvents(\n\t\t\t\t\tTRACE_LEVEL_ERROR, TRACE_DRIVER,\n\t\t\t\t\t\"%!FUNC! Device HID report length is zero\"\n\t\t\t\t);\n\t\t\t\tgoto exit;\n\t\t\t}\n\n\t\t\tstatus = WdfMemoryCopyFromBuffer(\n\t\t\t\trequestMemory,\n\t\t\t\t0,\n\t\t\t\t(PVOID) &AmtPtpT2ReportDescriptor,\n\t\t\t\tszCopy\n\t\t\t);\n\n\t\t\tif (!NT_SUCCESS(status)) {\n\n\t\t\t\tTraceEvents(\n\t\t\t\t\tTRACE_LEVEL_ERROR, TRACE_DRIVER,\n\t\t\t\t\t\"%!FUNC! WdfMemoryCopyFromBuffer failed with %!STATUS!\",\n\t\t\t\t\tstatus\n\t\t\t\t);\n\t\t\t\tgoto exit;\n\t\t\t}\n\n\t\t\tWdfRequestSetInformation(Request, szCopy);\n\t\t\tbreak;\n\t\t}\n\t\tdefault:\n\t\t{\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_WARNING, TRACE_DRIVER,\n\t\t\t\t\"%!FUNC! Device HID registry is not found, use a generic fallback\"\n\t\t\t);\n\t\t\t\n\t\t\tszCopy = AmtPtpT2DefaultHidDescriptor.DescriptorList[0].wReportLength;\n\t\t\tif (szCopy == 0) {\n\n\t\t\t\tstatus = STATUS_INVALID_DEVICE_STATE;\n\t\t\t\tTraceEvents(\n\t\t\t\t\tTRACE_LEVEL_ERROR, TRACE_DRIVER,\n\t\t\t\t\t\"%!FUNC! Device HID report length is zero\"\n\t\t\t\t);\n\t\t\t\tgoto exit;\n\t\t\t}\n\n\t\t\tstatus = WdfMemoryCopyFromBuffer(\n\t\t\t\trequestMemory,\n\t\t\t\t0,\n\t\t\t\t(PVOID)&AmtPtpT2ReportDescriptor,\n\t\t\t\tszCopy\n\t\t\t);\n\n\t\t\tif (!NT_SUCCESS(status)) {\n\n\t\t\t\tTraceEvents(\n\t\t\t\t\tTRACE_LEVEL_ERROR, TRACE_DRIVER,\n\t\t\t\t\t\"%!FUNC! WdfMemoryCopyFromBuffer failed with %!STATUS!\",\n\t\t\t\t\tstatus\n\t\t\t\t);\n\t\t\t\tgoto exit;\n\t\t\t}\n\n\t\t\tWdfRequestSetInformation(Request, szCopy);\n\t\t\tbreak;\n\t\t}\n\t}\n\nexit:\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION, TRACE_DRIVER,\n\t\t\"%!FUNC! Exit\"\n\t);\n\n\treturn status;\n}\n\n_IRQL_requires_(PASSIVE_LEVEL)\nNTSTATUS\nAmtPtpReportFeatures(\n\t_In_ WDFDEVICE Device,\n\t_In_ WDFREQUEST Request\n)\n{\n\tNTSTATUS status;\n\tPDEVICE_CONTEXT pDeviceContext;\n\tPHID_XFER_PACKET pHidPacket;\n\tWDF_REQUEST_PARAMETERS RequestParameters;\n\tsize_t ReportSize;\n\n\tPAGED_CODE();\n\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION, TRACE_DRIVER,\n\t\t\"%!FUNC! Entry\"\n\t);\n\n\tstatus = STATUS_SUCCESS;\n\tpDeviceContext = DeviceGetContext(Device);\n\n\tWDF_REQUEST_PARAMETERS_INIT(&RequestParameters);\n\tWdfRequestGetParameters(Request, &RequestParameters);\n\n\tif (RequestParameters.Parameters.DeviceIoControl.OutputBufferLength < sizeof(HID_XFER_PACKET))\n\t{\n\t\tstatus = STATUS_BUFFER_TOO_SMALL;\n\t\tgoto exit;\n\t}\n\n\tpHidPacket = (PHID_XFER_PACKET)WdfRequestWdmGetIrp(Request)->UserBuffer;\n\tif (pHidPacket == NULL)\n\t{\n\t\tstatus = STATUS_INVALID_DEVICE_REQUEST;\n\t\tgoto exit;\n\t}\n\n\tswitch (pHidPacket->reportId)\n\t{\n\t\tcase REPORTID_DEVICE_CAPS:\n\t\t{\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_INFORMATION, TRACE_DRIVER,\n\t\t\t\t\"%!FUNC! Report REPORTID_DEVICE_CAPS is requested\"\n\t\t\t);\n\n\t\t\t// Size sanity check\n\t\t\tReportSize = sizeof(PTP_DEVICE_CAPS_FEATURE_REPORT);\n\t\t\tif (pHidPacket->reportBufferLen < ReportSize) {\n\t\t\t\tstatus = STATUS_INVALID_BUFFER_SIZE;\n\t\t\t\tTraceEvents(\n\t\t\t\t\tTRACE_LEVEL_ERROR, TRACE_DRIVER,\n\t\t\t\t\t\"%!FUNC! Report buffer is too small\"\n\t\t\t\t);\n\t\t\t\tgoto exit;\n\t\t\t}\n\n\t\t\tPPTP_DEVICE_CAPS_FEATURE_REPORT capsReport = (PPTP_DEVICE_CAPS_FEATURE_REPORT) pHidPacket->reportBuffer;\n\t\t\tcapsReport->MaximumContactPoints = PTP_MAX_CONTACT_POINTS;\n\t\t\tcapsReport->ButtonType = PTP_BUTTON_TYPE_CLICK_PAD;\n\t\t\tcapsReport->ReportID = REPORTID_DEVICE_CAPS;\n\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_INFORMATION, TRACE_DRIVER,\n\t\t\t\t\"%!FUNC! Report REPORTID_DEVICE_CAPS has maximum contact points of %d\",\n\t\t\t\tcapsReport->MaximumContactPoints\n\t\t\t);\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_INFORMATION, TRACE_DRIVER,\n\t\t\t\t\"%!FUNC! Report REPORTID_DEVICE_CAPS has touchpad type %d\",\n\t\t\t\tcapsReport->ButtonType\n\t\t\t);\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_INFORMATION, TRACE_DRIVER,\n\t\t\t\t\"%!FUNC! Report REPORTID_DEVICE_CAPS is fulfilled\"\n\t\t\t);\n\n\t\t\tbreak;\n\t\t}\n\t\tcase REPORTID_PTPHQA:\n\t\t{\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_INFORMATION, TRACE_DRIVER,\n\t\t\t\t\"%!FUNC! Report REPORTID_PTPHQA is requested\"\n\t\t\t);\n\n\t\t\t// Size sanity check\n\t\t\tReportSize = sizeof(PTP_DEVICE_HQA_CERTIFICATION_REPORT);\n\t\t\tif (pHidPacket->reportBufferLen < ReportSize)\n\t\t\t{\n\t\t\t\tstatus = STATUS_INVALID_BUFFER_SIZE;\n\t\t\t\tTraceEvents(\n\t\t\t\t\tTRACE_LEVEL_ERROR, TRACE_DRIVER,\n\t\t\t\t\t\"%!FUNC! Report buffer is too small.\"\n\t\t\t\t);\n\t\t\t\tgoto exit;\n\t\t\t}\n\n\t\t\tPPTP_DEVICE_HQA_CERTIFICATION_REPORT certReport = (PPTP_DEVICE_HQA_CERTIFICATION_REPORT)pHidPacket->reportBuffer;\n\t\t\t*certReport->CertificationBlob = DEFAULT_PTP_HQA_BLOB;\n\t\t\tcertReport->ReportID = REPORTID_PTPHQA;\n\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_INFORMATION, TRACE_DRIVER,\n\t\t\t\t\"%!FUNC! Report REPORTID_PTPHQA is fulfilled\"\n\t\t\t);\n\n\t\t\tbreak;\n\t\t}\n\t\tdefault:\n\t\t{\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_INFORMATION, TRACE_DRIVER,\n\t\t\t\t\"%!FUNC! Unsupported type %d is requested\",\n\t\t\t\tpHidPacket->reportId\n\t\t\t);\n\n\t\t\tstatus = STATUS_NOT_SUPPORTED;\n\t\t\tgoto exit;\n\t\t}\n\t}\n\nexit:\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION, TRACE_DRIVER,\n\t\t\"%!FUNC! Exit\"\n\t);\n\n\treturn status;\n}\n\n_IRQL_requires_(PASSIVE_LEVEL)\nNTSTATUS\nAmtPtpSetFeatures(\n\t_In_ WDFDEVICE Device,\n\t_In_ WDFREQUEST Request\n)\n{\n\n\tNTSTATUS        status;\n\tPHID_XFER_PACKET pHidPacket;\n\tWDF_REQUEST_PARAMETERS RequestParameters;\n\tPDEVICE_CONTEXT pDeviceContext;\n\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION, TRACE_DRIVER,\n\t\t\"%!FUNC! Entry\"\n\t);\n\n\tstatus = STATUS_SUCCESS;\n\tpDeviceContext = DeviceGetContext(Device);\n\n\tWDF_REQUEST_PARAMETERS_INIT(&RequestParameters);\n\tWdfRequestGetParameters(Request, &RequestParameters);\n\n\tif (RequestParameters.Parameters.DeviceIoControl.InputBufferLength < sizeof(HID_XFER_PACKET))\n\t{\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_ERROR, TRACE_DRIVER,\n\t\t\t\"%!FUNC! HID_XFER_PACKET buffer too small\"\n\t\t);\n\n\t\tstatus = STATUS_BUFFER_TOO_SMALL;\n\t\tgoto exit;\n\t}\n\n\tpHidPacket = (PHID_XFER_PACKET) WdfRequestWdmGetIrp(Request)->UserBuffer;\n\tif (pHidPacket == NULL)\n\t{\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_ERROR, TRACE_DRIVER,\n\t\t\t\"%!FUNC! HID_XFER_PACKET has no input packet\"\n\t\t);\n\n\t\tstatus = STATUS_INVALID_DEVICE_REQUEST;\n\t\tgoto exit;\n\t}\n\n\tswitch (pHidPacket->reportId)\n\t{\n\t\tcase REPORTID_REPORTMODE:\n\t\t{\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_INFORMATION, TRACE_DRIVER,\n\t\t\t\t\"%!FUNC! Report REPORTID_REPORTMODE is requested\"\n\t\t\t);\n\n\t\t\tPPTP_DEVICE_INPUT_MODE_REPORT devInputMode = (PPTP_DEVICE_INPUT_MODE_REPORT) pHidPacket->reportBuffer;\n\t\t\tBOOLEAN bWellspringMode = pDeviceContext->IsWellspringModeOn;\n\n\t\t\tswitch (devInputMode->Mode)\n\t\t\t{\n\t\t\t\tcase PTP_COLLECTION_MOUSE:\n\t\t\t\t{\n\t\t\t\t\tTraceEvents(\n\t\t\t\t\t\tTRACE_LEVEL_INFORMATION, TRACE_DRIVER,\n\t\t\t\t\t\t\"%!FUNC! Report REPORTID_REPORTMODE requested Mouse Input but not supported\"\n\t\t\t\t\t);\n\n\t\t\t\t\tstatus = STATUS_NOT_SUPPORTED;\n\t\t\t\t\tgoto exit;\n\t\t\t\t}\n\t\t\t\tcase PTP_COLLECTION_WINDOWS:\n\t\t\t\t{\n\t\t\t\t\tTraceEvents(\n\t\t\t\t\t\tTRACE_LEVEL_INFORMATION, TRACE_DRIVER,\n\t\t\t\t\t\t\"%!FUNC! Report REPORTID_REPORTMODE requested Windows PTP Input\"\n\t\t\t\t\t);\n\n\t\t\t\t\tif (!bWellspringMode) {\n\t\t\t\t\t\tstatus = AmtPtpSetWellspringMode(pDeviceContext, TRUE);\n\t\t\t\t\t\tif (!NT_SUCCESS(status)) {\n\t\t\t\t\t\t\tTraceEvents(\n\t\t\t\t\t\t\t\tTRACE_LEVEL_ERROR, TRACE_DRIVER,\n\t\t\t\t\t\t\t\t\"%!FUNC! -> AmtPtpSetWellspringMode failed with status %!STATUS!\",\n\t\t\t\t\t\t\t\tstatus\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tgoto exit;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_INFORMATION, TRACE_DRIVER,\n\t\t\t\t\"%!FUNC! Report REPORTID_REPORTMODE is fulfilled\"\n\t\t\t);\n\t\t\tbreak;\n\t\t}\n\t\tcase REPORTID_FUNCSWITCH:\n\t\t{\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_INFORMATION, TRACE_DRIVER,\n\t\t\t\t\"%!FUNC! Report REPORTID_FUNCSWITCH is requested\"\n\t\t\t);\n\n\t\t\tPPTP_DEVICE_SELECTIVE_REPORT_MODE_REPORT secInput = (PPTP_DEVICE_SELECTIVE_REPORT_MODE_REPORT) pHidPacket->reportBuffer;\n\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_INFORMATION, TRACE_DRIVER,\n\t\t\t\t\"%!FUNC! Report REPORTID_FUNCSWITCH requested Button = %d, Surface = %d\",\n\t\t\t\tsecInput->ButtonReport,\n\t\t\t\tsecInput->SurfaceReport\n\t\t\t);\n\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_INFORMATION, TRACE_DRIVER,\n\t\t\t\t\"%!FUNC! Report REPORTID_FUNCSWITCH is fulfilled\"\n\t\t\t);\n\t\t\tbreak;\n\t\t}\n\t\tdefault:\n\t\t{\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_INFORMATION, TRACE_DRIVER,\n\t\t\t\t\"%!FUNC! Unsupported type %d is requested\",\n\t\t\t\tpHidPacket->reportId\n\t\t\t);\n\t\t\tstatus = STATUS_NOT_SUPPORTED;\n\t\t\tgoto exit;\n\t\t}\n\t}\n\nexit:\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION, TRACE_DRIVER,\n\t\t\"%!FUNC! Exit\"\n\t);\n\treturn status;\n}\n"
  },
  {
    "path": "src/AmtPtpDeviceUsbKm/Interrupt.c",
    "content": "// Interrupt.c: Handles device input event\n\n#include \"Driver.h\"\n#include \"Interrupt.tmh\"\n\n// Helper function for numberic operation\nstatic inline INT AmtRawToInteger(\n\t_In_ USHORT x\n)\n{\n\treturn (signed short)x;\n}\n\n_IRQL_requires_(PASSIVE_LEVEL)\nNTSTATUS\nAmtPtpConfigContReaderForInterruptEndPoint(\n\t_In_ PDEVICE_CONTEXT DeviceContext\n)\n{\n\tWDF_USB_CONTINUOUS_READER_CONFIG contReaderConfig;\n\tNTSTATUS status;\n\tsize_t transferLength = 0;\n\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION,\n\t\tTRACE_DRIVER,\n\t\t\"%!FUNC! Entry\"\n\t);\n\n\tswitch (DeviceContext->DeviceInfo->tp_type)\n\t{\n\tcase TYPE1:\n\t\ttransferLength = HEADER_TYPE1 + FSIZE_TYPE1 * MAX_FINGERS;\n\t\tbreak;\n\tcase TYPE2:\n\t\ttransferLength = HEADER_TYPE2 + FSIZE_TYPE2 * MAX_FINGERS;\n\t\tbreak;\n\tcase TYPE3:\n\t\ttransferLength = HEADER_TYPE3 + FSIZE_TYPE3 * MAX_FINGERS;\n\t\tbreak;\n\tcase TYPE4:\n\t\ttransferLength = HEADER_TYPE4 + FSIZE_TYPE4 * MAX_FINGERS;\n\t\tbreak;\n\tcase TYPE5:\n\t\ttransferLength = HEADER_TYPE5 + FSIZE_TYPE5 * MAX_FINGERS;\n\t\tbreak;\n\t}\n\n\tif (transferLength <= 0) {\n\t\tstatus = STATUS_UNKNOWN_REVISION;\n\t\tgoto exit;\n\t}\n\n\tWDF_USB_CONTINUOUS_READER_CONFIG_INIT(\n\t\t&contReaderConfig,\n\t\tAmtPtpEvtUsbInterruptPipeReadComplete,\n\t\tDeviceContext,\t\t// Context\n\t\ttransferLength\t\t// Calculate transferred length by device information\n\t);\n\n\tcontReaderConfig.EvtUsbTargetPipeReadersFailed = AmtPtpEvtUsbInterruptReadersFailed;\n\n\t// Remember to turn it on in D0 entry\n\tstatus = WdfUsbTargetPipeConfigContinuousReader(\n\t\tDeviceContext->InterruptPipe,\n\t\t&contReaderConfig\n\t);\n\n\tif (!NT_SUCCESS(status)) {\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_ERROR,\n\t\t\tTRACE_DRIVER,\n\t\t\t\"%!FUNC! AmtPtpConfigContReaderForInterruptEndPoint failed with Status code %!STATUS!\",\n\t\t\tstatus\n\t\t);\n\t\tgoto exit;\n\t}\n\nexit:\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION,\n\t\tTRACE_DRIVER,\n\t\t\"%!FUNC! Exit\"\n\t);\n\n\treturn STATUS_SUCCESS;\n}\n\nVOID\nAmtPtpEvtUsbInterruptPipeReadComplete(\n\t_In_ WDFUSBPIPE  Pipe,\n\t_In_ WDFMEMORY   Buffer,\n\t_In_ size_t      NumBytesTransferred,\n\t_In_ WDFCONTEXT  Context\n)\n{\n\tUNREFERENCED_PARAMETER(Pipe);\n\n\tPDEVICE_CONTEXT pDeviceContext = Context;\n\tsize_t headerSize = (unsigned int)pDeviceContext->DeviceInfo->tp_header;\n\tsize_t fingerprintSize = (unsigned int)pDeviceContext->DeviceInfo->tp_fsize;\n\tsize_t raw_n, i;\n\tUSHORT x = 0, y = 0;\n\tUCHAR* TouchBuffer = NULL;\n\tconst struct TRACKPAD_FINGER* f = NULL;\n\n\tLONGLONG PerfCounterDelta;\n\tLARGE_INTEGER CurrentPerfCounter;\n\tNTSTATUS Status;\n\tPTP_REPORT PtpReport;\n\n\tWDFREQUEST Request;\n\tWDFMEMORY  RequestMemory;\n\n\tif (NumBytesTransferred < headerSize || (NumBytesTransferred - headerSize) % fingerprintSize != 0) {\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_INFORMATION,\n\t\t\tTRACE_DRIVER,\n\t\t\t\"%!FUNC! Malformed input received. Length = %llu\",\n\t\t\tNumBytesTransferred\n\t\t);\n\t\treturn;\n\t}\n\n\t// Retrieve packet\n\tTouchBuffer = WdfMemoryGetBuffer(\n\t\tBuffer,\n\t\tNULL\n\t);\n\n\tif (TouchBuffer == NULL) {\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_INFORMATION, TRACE_DRIVER,\n\t\t\t\"%!FUNC! Failed to retrieve packet\"\n\t\t);\n\t\treturn;\n\t}\n\n\t// Retrieve next PTP touchpad request.\n\tStatus = WdfIoQueueRetrieveNextRequest(\n\t\tpDeviceContext->InputQueue,\n\t\t&Request\n\t);\n\n\tif (!NT_SUCCESS(Status)) {\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_INFORMATION, TRACE_DRIVER,\n\t\t\t\"%!FUNC! No pending PTP request. Disposed\"\n\t\t);\n\t\treturn;\n\t}\n\n\tStatus = WdfRequestRetrieveOutputMemory(\n\t\tRequest,\n\t\t&RequestMemory\n\t);\n\n\tif (!NT_SUCCESS(Status)) {\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_ERROR, TRACE_DRIVER,\n\t\t\t\"%!FUNC! WdfRequestRetrieveOutputMemory failed with %!STATUS!\",\n\t\t\tStatus\n\t\t);\n\t\treturn;\n\t}\n\n\t// Prepare report\n\tStatus = STATUS_SUCCESS;\n\n\tRtlZeroMemory(&PtpReport, sizeof(PTP_REPORT));\n\tPtpReport.ReportID = REPORTID_MULTITOUCH;\n\tPtpReport.IsButtonClicked = 0;\n\traw_n = (NumBytesTransferred - headerSize) / fingerprintSize;\n\tUCHAR* f_base = TouchBuffer + headerSize + pDeviceContext->DeviceInfo->tp_delta;\n\n\t// Scan time is in 100us\n\tKeQueryPerformanceCounter(&CurrentPerfCounter);\n\tPerfCounterDelta = (CurrentPerfCounter.QuadPart - pDeviceContext->LastReportTime.QuadPart) / 100;\n\tif (PerfCounterDelta > 0xFF) {\n\t\tPerfCounterDelta = 0xFF;\n\t}\n\n\tPtpReport.ScanTime = (USHORT) PerfCounterDelta;\n\n\tif (pDeviceContext->PtpReportTouch) {\n\t\tif (raw_n >= PTP_MAX_CONTACT_POINTS) raw_n = PTP_MAX_CONTACT_POINTS;\n\t\tif (raw_n * fingerprintSize < (NumBytesTransferred - headerSize)) {\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_ERROR, TRACE_DRIVER,\n\t\t\t\t\"%!FUNC! Buffer may have a problem\"\n\t\t\t);\n\t\t\tWdfRequestComplete(Request, STATUS_DATA_ERROR);\n\t\t\treturn;\n\t\t}\n\n\t\tPtpReport.ContactCount = (UCHAR) raw_n;\n\n\t\tfor (i = 0; i < raw_n; i++) {\n\t\t\tf = (const struct TRACKPAD_FINGER*) (f_base + i * fingerprintSize);\n\t\t\t\n\t\t\t// Translate X and Y\n\t\t\tx = (AmtRawToInteger(f->abs_x) - pDeviceContext->DeviceInfo->x.min) > 0 ? \n\t\t\t\t((USHORT)(AmtRawToInteger(f->abs_x) - pDeviceContext->DeviceInfo->x.min)) : 0;\n\t\t\ty = (pDeviceContext->DeviceInfo->y.max - AmtRawToInteger(f->abs_y)) > 0 ? \n\t\t\t\t((USHORT)(pDeviceContext->DeviceInfo->y.max - AmtRawToInteger(f->abs_y))) : 0;\n\n\t\t\t// Defuzz functions remain the same\n\t\t\t// TODO: Implement defuzz later\n\t\t\tPtpReport.Contacts[i].ContactID = (UCHAR) i;\n\t\t\tPtpReport.Contacts[i].X = x;\n\t\t\tPtpReport.Contacts[i].Y = y;\n\t\t\tPtpReport.Contacts[i].TipSwitch = (AmtRawToInteger(f->touch_major) << 1) >= 200 || (AmtRawToInteger(f->touch_minor) << 1) >= 150;\n\t\t\tPtpReport.Contacts[i].Confidence = (AmtRawToInteger(f->touch_minor) << 1) > 0;\n\t\t}\n\t}\n\n\tif (pDeviceContext->PtpReportButton) {\n\t\t// Handles trackpad button input here.\n\t\tif (TouchBuffer[pDeviceContext->DeviceInfo->tp_button]) {\n\t\t\tPtpReport.IsButtonClicked = TRUE;\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_INFORMATION, TRACE_INPUT,\n\t\t\t\t\"%!FUNC!: Trackpad button clicked\"\n\t\t\t);\n\t\t}\n\t}\n\n\t// Compose final report and write it back\n\tStatus = WdfMemoryCopyFromBuffer(\n\t\tRequestMemory,\n\t\t0,\n\t\t(PVOID) &PtpReport,\n\t\tsizeof(PTP_REPORT)\n\t);\n\n\tif (!NT_SUCCESS(Status)) {\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_ERROR, TRACE_DRIVER,\n\t\t\t\"%!FUNC! WdfMemoryCopyFromBuffer failed with %!STATUS!\",\n\t\t\tStatus\n\t\t);\n\t\treturn;\n\t}\n\n\t// Set result\n\tWdfRequestSetInformation(Request, sizeof(PTP_REPORT));\n\n\t// Set completion flag\n\tWdfRequestComplete(Request, Status);\n}\n\nBOOLEAN\nAmtPtpEvtUsbInterruptReadersFailed(\n\t_In_ WDFUSBPIPE Pipe,\n\t_In_ NTSTATUS Status,\n\t_In_ USBD_STATUS UsbdStatus\n)\n{\n\tUNREFERENCED_PARAMETER(Pipe);\n\tUNREFERENCED_PARAMETER(UsbdStatus);\n\tUNREFERENCED_PARAMETER(Status);\n\n\treturn TRUE;\n}\n"
  },
  {
    "path": "src/AmtPtpDeviceUsbKm/Public.h",
    "content": "/*++\n\nModule Name:\n\n    public.h\n\nAbstract:\n\n    This module contains the common declarations shared by driver\n    and user applications.\n\nEnvironment:\n\n    user and kernel\n\n--*/\n\n//\n// Define an Interface Guid so that app can find the device and talk to it.\n//\n\nDEFINE_GUID (GUID_DEVINTERFACE_AmtPtpDeviceUsbKm,\n    0x4aa332cc,0x5777,0x4afd,0xaa,0x4e,0x95,0x38,0x73,0x30,0x61,0x2a);\n// {4aa332cc-5777-4afd-aa4e-95387330612a}\n"
  },
  {
    "path": "src/AmtPtpDeviceUsbKm/Queue.c",
    "content": "/*++\n\nModule Name:\n\n    queue.c\n\nAbstract:\n\n    This file contains the queue entry points and callbacks.\n\nEnvironment:\n\n    Kernel-mode Driver Framework\n\n--*/\n\n#include \"driver.h\"\n#include \"queue.tmh\"\n\n#ifdef ALLOC_PRAGMA\n#pragma alloc_text (PAGE, AmtPtpDeviceUsbKmQueueInitialize)\n#endif\n\nNTSTATUS\nAmtPtpDeviceUsbKmQueueInitialize(\n    _In_ WDFDEVICE Device\n    )\n/*++\n\nRoutine Description:\n\n\n     The I/O dispatch callbacks for the frameworks device object\n     are configured in this function.\n\n     A single default I/O Queue is configured for parallel request\n     processing, and a driver context memory allocation is created\n     to hold our structure QUEUE_CONTEXT.\n\nArguments:\n\n    Device - Handle to a framework device object.\n\nReturn Value:\n\n    VOID\n\n--*/\n{\n    WDFQUEUE queue;\n    NTSTATUS status;\n    WDF_IO_QUEUE_CONFIG    queueConfig;\n\tPDEVICE_CONTEXT\t       pDeviceContext;\n\n    PAGED_CODE();\n\n\tpDeviceContext = DeviceGetContext(Device);\n    \n    //\n    // Configure a default queue so that requests that are not\n    // configure-fowarded using WdfDeviceConfigureRequestDispatching to goto\n    // other queues get dispatched here.\n    //\n    WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&queueConfig, WdfIoQueueDispatchParallel);\n\n    queueConfig.EvtIoInternalDeviceControl = AmtPtpDeviceUsbKmEvtIoDeviceControl;\n    queueConfig.EvtIoStop = AmtPtpDeviceUsbKmEvtIoStop;\n\n    status = WdfIoQueueCreate(\n                 Device,\n                 &queueConfig,\n                 WDF_NO_OBJECT_ATTRIBUTES,\n                 &queue\n                 );\n\n    if( !NT_SUCCESS(status) ) {\n        TraceEvents(TRACE_LEVEL_ERROR, TRACE_QUEUE, \"WdfIoQueueCreate failed %!STATUS!\", status);\n        return status;\n    }\n\n\t//\n\t// Create secondary queues for touch read requests.\n\t//\n\tWDF_IO_QUEUE_CONFIG_INIT(&queueConfig, WdfIoQueueDispatchManual);\n\tqueueConfig.PowerManaged = WdfFalse;\n\n\tstatus = WdfIoQueueCreate(\n\t\tDevice,\n\t\t&queueConfig,\n\t\tWDF_NO_OBJECT_ATTRIBUTES,\n\t\t&pDeviceContext->InputQueue\n\t);\n\n\tif (!NT_SUCCESS(status)) {\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_ERROR, TRACE_QUEUE,\n\t\t\t\"%!FUNC! WdfIoQueueCreate (Input) failed %!STATUS!\",\n\t\t\tstatus\n\t\t);\n\t}\n\n    return status;\n}\n\nVOID\nAmtPtpDeviceUsbKmEvtIoDeviceControl(\n    _In_ WDFQUEUE Queue,\n    _In_ WDFREQUEST Request,\n    _In_ size_t OutputBufferLength,\n    _In_ size_t InputBufferLength,\n    _In_ ULONG IoControlCode\n    )\n/*++\n\nRoutine Description:\n\n    This event is invoked when the framework receives IRP_MJ_DEVICE_CONTROL request.\n\nArguments:\n\n    Queue -  Handle to the framework queue object that is associated with the\n             I/O request.\n\n    Request - Handle to a framework request object.\n\n    OutputBufferLength - Size of the output buffer in bytes\n\n    InputBufferLength - Size of the input buffer in bytes\n\n    IoControlCode - I/O control code.\n\nReturn Value:\n\n    VOID\n\n--*/\n{\n\tNTSTATUS status;\n\tWDFDEVICE device = WdfIoQueueGetDevice(Queue);\n\tBOOLEAN requestPending = FALSE;\n\n\tUNREFERENCED_PARAMETER(InputBufferLength);\n\tUNREFERENCED_PARAMETER(OutputBufferLength);\n\n\tswitch (IoControlCode)\n\t{\n\tcase IOCTL_HID_GET_DEVICE_DESCRIPTOR:\n\t\tstatus = AmtPtpGetHidDescriptor(device, Request);\n\t\tbreak;\n\tcase IOCTL_HID_GET_DEVICE_ATTRIBUTES:\n\t\tstatus = AmtPtpGetDeviceAttribs(device, Request);\n\t\tbreak;\n\tcase IOCTL_HID_GET_REPORT_DESCRIPTOR:\n\t\tstatus = AmtPtpGetReportDescriptor(device, Request);\n\t\tbreak;\n\tcase IOCTL_HID_READ_REPORT:\n\t\tstatus = AmtPtpDispatchReadReportRequests(device, Request, &requestPending);\n\t\tbreak;\n\tcase IOCTL_HID_GET_FEATURE:\n\t\tstatus = AmtPtpReportFeatures(device, Request);\n\t\tbreak;\n\tcase IOCTL_HID_SET_FEATURE:\n\t\tstatus = AmtPtpSetFeatures(device, Request);\n\t\tbreak;\n\tcase IOCTL_HID_GET_STRING:\n\tcase IOCTL_HID_WRITE_REPORT:\n\tcase IOCTL_UMDF_HID_SET_OUTPUT_REPORT:\n\tcase IOCTL_UMDF_HID_GET_INPUT_REPORT:\n\tcase IOCTL_HID_ACTIVATE_DEVICE:\n\tcase IOCTL_HID_DEACTIVATE_DEVICE:\n\tcase IOCTL_HID_SEND_IDLE_NOTIFICATION_REQUEST:\n\tdefault:\n\t\tstatus = STATUS_NOT_SUPPORTED;\n\t\tbreak;\n\t}\n\n\tif (requestPending != TRUE) {\n\t\tWdfRequestComplete(Request, status);\n\t}\n\n    return;\n}\n\nNTSTATUS\nAmtPtpDispatchReadReportRequests(\n\t_In_ WDFDEVICE Device,\n\t_In_ WDFREQUEST Request,\n\t_Out_ BOOLEAN* Pending\n)\n{\n\n\tNTSTATUS status;\n\tPDEVICE_CONTEXT pDevContext;\n\n\tstatus = STATUS_SUCCESS;\n\tpDevContext = DeviceGetContext(Device);\n\n\tstatus = WdfRequestForwardToIoQueue(\n\t\tRequest,\n\t\tpDevContext->InputQueue\n\t);\n\n\tif (!NT_SUCCESS(status)) {\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_ERROR,\n\t\t\tTRACE_DRIVER,\n\t\t\t\"%!FUNC! WdfRequestForwardToIoQueue failed with %!STATUS!\",\n\t\t\tstatus\n\t\t);\n\t\tgoto exit;\n\t}\n\n\tif (NULL != Pending) {\n\t\t*Pending = TRUE;\n\t}\n\nexit:\n\treturn status;\n}\n\nVOID\nAmtPtpDeviceUsbKmEvtIoStop(\n    _In_ WDFQUEUE Queue,\n    _In_ WDFREQUEST Request,\n    _In_ ULONG ActionFlags\n)\n/*++\n\nRoutine Description:\n\n    This event is invoked for a power-managed queue before the device leaves the working state (D0).\n\nArguments:\n\n    Queue -  Handle to the framework queue object that is associated with the\n             I/O request.\n\n    Request - Handle to a framework request object.\n\n    ActionFlags - A bitwise OR of one or more WDF_REQUEST_STOP_ACTION_FLAGS-typed flags\n                  that identify the reason that the callback function is being called\n                  and whether the request is cancelable.\n\nReturn Value:\n\n    VOID\n\n--*/\n{\n    TraceEvents(TRACE_LEVEL_INFORMATION, \n                TRACE_QUEUE, \n                \"%!FUNC! Queue 0x%p, Request 0x%p ActionFlags %d\", \n                Queue, Request, ActionFlags);\n\n    //\n    // In most cases, the EvtIoStop callback function completes, cancels, or postpones\n    // further processing of the I/O request.\n    //\n    // Typically, the driver uses the following rules:\n    //\n    // - If the driver owns the I/O request, it either postpones further processing\n    //   of the request and calls WdfRequestStopAcknowledge, or it calls WdfRequestComplete\n    //   with a completion status value of STATUS_SUCCESS or STATUS_CANCELLED.\n    //  \n    //   The driver must call WdfRequestComplete only once, to either complete or cancel\n    //   the request. To ensure that another thread does not call WdfRequestComplete\n    //   for the same request, the EvtIoStop callback must synchronize with the driver's\n    //   other event callback functions, for instance by using interlocked operations.\n    //\n    // - If the driver has forwarded the I/O request to an I/O target, it either calls\n    //   WdfRequestCancelSentRequest to attempt to cancel the request, or it postpones\n    //   further processing of the request and calls WdfRequestStopAcknowledge.\n    //\n    // A driver might choose to take no action in EvtIoStop for requests that are\n    // guaranteed to complete in a small amount of time. For example, the driver might\n    // take no action for requests that are completed in one of the drivers request handlers.\n    //\n\n    return;\n}\n"
  },
  {
    "path": "src/AmtPtpDeviceUsbKm/Queue.h",
    "content": "/*++\n\nModule Name:\n\n    queue.h\n\nAbstract:\n\n    This file contains the queue definitions.\n\nEnvironment:\n\n    Kernel-mode Driver Framework\n\n--*/\n\nEXTERN_C_START\n\n//\n// This is the context that can be placed per queue\n// and would contain per queue information.\n//\ntypedef struct _QUEUE_CONTEXT {\n\n    ULONG PrivateDeviceData;  // just a placeholder\n\n} QUEUE_CONTEXT, *PQUEUE_CONTEXT;\n\nWDF_DECLARE_CONTEXT_TYPE_WITH_NAME(QUEUE_CONTEXT, QueueGetContext)\n\nNTSTATUS\nAmtPtpDeviceUsbKmQueueInitialize(\n    _In_ WDFDEVICE Device\n    );\n\n//\n// Events from the IoQueue object\n//\nEVT_WDF_IO_QUEUE_IO_DEVICE_CONTROL AmtPtpDeviceUsbKmEvtIoDeviceControl;\nEVT_WDF_IO_QUEUE_IO_STOP AmtPtpDeviceUsbKmEvtIoStop;\n\nEXTERN_C_END\n"
  },
  {
    "path": "src/AmtPtpDeviceUsbKm/Trace.h",
    "content": "/*++\n\nModule Name:\n\n    Trace.h\n\nAbstract:\n\n    Header file for the debug tracing related function defintions and macros.\n\nEnvironment:\n\n    Kernel mode\n\n--*/\n\n//\n// Define the tracing flags.\n//\n// Tracing GUID - b409cf52-f41a-4193-98c2-bad95204203b\n//\n\n#define WPP_CONTROL_GUIDS                                              \\\n    WPP_DEFINE_CONTROL_GUID(                                           \\\n        AmtPtpDeviceUsbKmTraceGuid, (b409cf52,f41a,4193,98c2,bad95204203b), \\\n                                                                            \\\n        WPP_DEFINE_BIT(TRACE_DRIVER)                                   \\\n        WPP_DEFINE_BIT(TRACE_DEVICE)                                   \\\n        WPP_DEFINE_BIT(TRACE_QUEUE)                                    \\\n\t\tWPP_DEFINE_BIT(TRACE_INPUT)\t\t\t\t\t\t\t\t\t   \\\n        )                             \n\n#define WPP_FLAG_LEVEL_LOGGER(flag, level)                                  \\\n    WPP_LEVEL_LOGGER(flag)\n\n#define WPP_FLAG_LEVEL_ENABLED(flag, level)                                 \\\n    (WPP_LEVEL_ENABLED(flag) &&                                             \\\n     WPP_CONTROL(WPP_BIT_ ## flag).Level >= level)\n\n#define WPP_LEVEL_FLAGS_LOGGER(lvl,flags) \\\n           WPP_LEVEL_LOGGER(flags)\n               \n#define WPP_LEVEL_FLAGS_ENABLED(lvl, flags) \\\n           (WPP_LEVEL_ENABLED(flags) && WPP_CONTROL(WPP_BIT_ ## flags).Level >= lvl)\n           \n//           \n// WPP orders static parameters before dynamic parameters. To support the Trace function\n// defined below which sets FLAGS=MYDRIVER_ALL_INFO, a custom macro must be defined to\n// reorder the arguments to what the .tpl configuration file expects.\n//\n#define WPP_RECORDER_FLAGS_LEVEL_ARGS(flags, lvl) WPP_RECORDER_LEVEL_FLAGS_ARGS(lvl, flags)\n#define WPP_RECORDER_FLAGS_LEVEL_FILTER(flags, lvl) WPP_RECORDER_LEVEL_FLAGS_FILTER(lvl, flags)\n\n//\n// This comment block is scanned by the trace preprocessor to define our\n// Trace function.\n//\n// begin_wpp config\n// FUNC Trace{FLAGS=TRACE_DRIVER}(LEVEL, MSG, ...);\n// FUNC TraceEvents(LEVEL, FLAGS, MSG, ...);\n// end_wpp\n//\n"
  },
  {
    "path": "src/AmtPtpDeviceUsbKm/include/AppleDefinition.h",
    "content": "#pragma once\n\n#define USB_VENDOR_ID_APPLE\t\t0x05ac\n\n/* Apple T2 USB trackpad */\n#define USB_DEVICE_ID_APPLE_T2_7A 0x027a\n#define USB_DEVICE_ID_APPLE_T2_7B 0x027b\n#define USB_DEVICE_ID_APPLE_T2_7C 0x027c\n#define USB_DEVICE_ID_APPLE_T2_7D 0x027d\n#define USB_DEVICE_ID_DEFAULT_FALLBACK 0xffff\n\n/* button data structure */\nstruct TRACKPAD_BUTTON_DATA {\n\tUCHAR unknown1;\t\t/* constant */\n\tUCHAR button;\t\t\t/* left button */\n\tUCHAR rel_x;\t\t\t/* relative x coordinate */\n\tUCHAR rel_y;\t\t\t/* relative y coordinate */\n};\n\n/* trackpad header types */\nenum TRACKPAD_TYPE {\n\tTYPE1,\t\t\t/* plain trackpad */\n\tTYPE2,\t\t\t/* button integrated in trackpad */\n\tTYPE3,\t\t\t/* additional header fields since June 2013 */\n\tTYPE4,\t\t\t/* additional header field for pressure data */\n\tTYPE5\t\t\t/* format for magic trackpad 2 */\n};\n\n/* Trackpad finger data offsets, le16-aligned */\n#define HEADER_TYPE1\t\t(13 * sizeof(USHORT))\n#define HEADER_TYPE2\t\t(15 * sizeof(USHORT))\n#define HEADER_TYPE3\t\t(19 * sizeof(USHORT))\n#define HEADER_TYPE4\t\t(23 * sizeof(USHORT))\n#define HEADER_TYPE5\t\t( 6 * sizeof(USHORT))\n\n/* Trackpad button data offsets */\n#define BUTTON_TYPE1\t\t0\n#define BUTTON_TYPE2\t\t15\n#define BUTTON_TYPE3\t\t23\n#define BUTTON_TYPE4\t\t31\n#define BUTTON_TYPE5\t\t1\n\n/* List of device capability bits */\n#define HAS_INTEGRATED_BUTTON\t1\n\n/* Trackpad finger data block size */\n#define FSIZE_TYPE1\t\t(14 * sizeof(USHORT))\n#define FSIZE_TYPE2\t\t(14 * sizeof(USHORT))\n#define FSIZE_TYPE3\t\t(14 * sizeof(USHORT))\n#define FSIZE_TYPE4\t\t(15 * sizeof(USHORT))\n#define FSIZE_TYPE5\t\t(9)\n\n/* Offset from header to finger struct */\n#define DELTA_TYPE1\t\t(0 * sizeof(USHORT))\n#define DELTA_TYPE2\t\t(0 * sizeof(USHORT))\n#define DELTA_TYPE3\t\t(0 * sizeof(USHORT))\n#define DELTA_TYPE4\t\t(1 * sizeof(USHORT))\n#define DELTA_TYPE5\t\t(0 * sizeof(USHORT))\n\n/* USB control message mode switch data */\n#define USBMSG_TYPE1\t8, 0x300, 0, 0, 0x1, 0x8\n#define USBMSG_TYPE2\t8, 0x300, 0, 0, 0x1, 0x8\n#define USBMSG_TYPE3\t8, 0x300, 0, 0, 0x1, 0x8\n#define USBMSG_TYPE4\t2, 0x302, 2, 1, 0x1, 0x0\n#define USBMSG_TYPE5\t2, 0x302, 1, 1, 0x1, 0x0\n\n/* Wellspring initialization constants */\n#define BCM5974_WELLSPRING_MODE_READ_REQUEST_ID\t\t1\n#define BCM5974_WELLSPRING_MODE_WRITE_REQUEST_ID\t9\n\n/* Trackpad finger data size, empirically at least ten fingers */\n#define MAX_FINGERS\t\t16\n#define MAX_FINGER_ORIENTATION\t16384\n\n#define BCM5974_MOUSE_SIZE 8\n\n/* trackpad finger structure, le16-aligned */\n__declspec(align(2)) struct TRACKPAD_FINGER {\n\tUSHORT origin;\t\t/* zero when switching track finger */\n\tUSHORT abs_x;\t\t/* absolute x coodinate */\n\tUSHORT abs_y;\t\t/* absolute y coodinate */\n\tUSHORT rel_x;\t\t/* relative x coodinate */\n\tUSHORT rel_y;\t\t/* relative y coodinate */\n\tUSHORT tool_major;\t/* tool area, major axis */\n\tUSHORT tool_minor;\t/* tool area, minor axis */\n\tUSHORT orientation;\t/* 16384 when point, else 15 bit angle */\n\tUSHORT touch_major;\t/* touch area, major axis */\n\tUSHORT touch_minor;\t/* touch area, minor axis */\n\tUSHORT unused[2];\t/* zeros */\n\tUSHORT pressure;\t/* pressure on forcetouch touchpad */\n\tUSHORT multi;\t\t/* one finger: varies, more fingers: constant */\n};\n\n/* device-specific parameters */\nstruct BCM5974_PARAM {\n\tint snratio;\t\t/* signal-to-noise ratio */\n\tint min;\t\t\t/* device minimum reading */\n\tint max;\t\t\t/* device maximum reading */\n};\n\n/* device-specific configuration */\nstruct BCM5974_CONFIG {\n\tint identification;\t\t\t\t/* the product id of this device */\n\tint caps;\t\t\t\t\t\t/* device capability bitmask */\n\tint bt_ep;\t\t\t\t\t\t/* the endpoint of the button interface */\n\tint bt_datalen;\t\t\t\t\t/* data length of the button interface */\n\tint tp_ep;\t\t\t\t\t\t/* the endpoint of the trackpad interface */\n\tenum TRACKPAD_TYPE tp_type;\t\t/* type of trackpad interface */\n\tint tp_header;\t\t\t\t\t/* bytes in header block */\n\tint tp_datalen;\t\t\t\t\t/* data length of the trackpad interface */\n\tint tp_button;\t\t\t\t\t/* offset to button data */\n\tint tp_fsize;\t\t\t\t\t/* bytes in single finger block */\n\tint tp_delta;\t\t\t\t\t/* offset from header to finger struct */\n\tint um_size;\t\t\t\t\t/* usb control message length */\n\tint um_req_val;\t\t\t\t\t/* usb control message value */\n\tint um_req_idx;\t\t\t\t\t/* usb control message index */\n\tint um_switch_idx;\t\t\t\t/* usb control message mode switch index */\n\tint um_switch_on;\t\t\t\t/* usb control message mode switch on */\n\tint um_switch_off;\t\t\t\t/* usb control message mode switch off */\n\tstruct BCM5974_PARAM p;\t\t\t/* finger pressure limits */\n\tstruct BCM5974_PARAM w;\t\t\t/* finger width limits */\n\tstruct BCM5974_PARAM x;\t\t\t/* horizontal limits */\n\tstruct BCM5974_PARAM y;\t\t\t/* vertical limits */\n\tstruct BCM5974_PARAM o;\t\t\t/* orientation limits */\n};\n\n#define DATAFORMAT(type)\t\t\t\t\\\n\ttype,\t\t\t\t\t\t\\\n\tHEADER_##type,\t\t\t\t\t\\\n\tHEADER_##type + (MAX_FINGERS) * (FSIZE_##type),\t\\\n\tBUTTON_##type,\t\t\t\t\t\\\n\tFSIZE_##type,\t\t\t\t\t\\\n\tDELTA_##type,\t\t\t\t\t\\\n\tUSBMSG_##type\n\n/* logical signal quality */\n#define SN_PRESSURE\t45\t\t/* pressure signal-to-noise ratio */\n#define SN_WIDTH\t25\t\t/* width signal-to-noise ratio */\n#define SN_COORD\t250\t\t/* coordinate signal-to-noise ratio */\n#define SN_ORIENT\t10\t\t/* orientation signal-to-noise ratio */\n\n#define PRESSURE_QUALIFICATION_THRESHOLD 2\n#define SIZE_QUALIFICATION_THRESHOLD 9\n#define SIZE_MU_LOWER_THRESHOLD 5\n\n#define PRESSURE_MU_QUALIFICATION_THRESHOLD_TOTAL 15\n#define SIZE_MU_QUALIFICATION_THRESHOLD_TOTAL 25\n\nstatic const struct BCM5974_CONFIG Bcm5974ConfigTable[] = {\n\t/* New device? */\n\t{\n\t\tUSB_DEVICE_ID_DEFAULT_FALLBACK,\n\t\tHAS_INTEGRATED_BUTTON,\n\t\t0, sizeof(struct TRACKPAD_BUTTON_DATA),\n\t\t0x83, DATAFORMAT(TYPE4),\n\t\t{ SN_PRESSURE, 0, 300 },\n\t\t{ SN_WIDTH, 0, 2048 },\n\t\t// Oversampled - this is fine for a trackpad\n\t\t{ SN_COORD, -10000, 10000 },\n\t\t{ SN_COORD, -2000, 10000 },\n\t\t{ SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }\n\t},\n\t/* 13 inch */\n\t{\n\t\tUSB_DEVICE_ID_APPLE_T2_7A,\n\t\tHAS_INTEGRATED_BUTTON,\n\t\t0, sizeof(struct TRACKPAD_BUTTON_DATA),\n\t\t0x83, DATAFORMAT(TYPE4),\n\t\t{ SN_PRESSURE, 0, 300 },\n\t\t{ SN_WIDTH, 0, 2048 },\n\t\t{ SN_COORD, -6243, 6749 },\n\t\t{ SN_COORD, -170, 7685 },\n\t\t{ SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }\n\t},\n\t{\n\t\tUSB_DEVICE_ID_APPLE_T2_7B,\n\t\tHAS_INTEGRATED_BUTTON,\n\t\t0, sizeof(struct TRACKPAD_BUTTON_DATA),\n\t\t0x83, DATAFORMAT(TYPE4),\n\t\t{ SN_PRESSURE, 0, 300 },\n\t\t{ SN_WIDTH, 0, 2048 },\n\t\t{ SN_COORD, -6243, 6749 },\n\t\t{ SN_COORD, -170, 7685 },\n\t\t{ SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }\n\t},\n\t/* 15 inch */\n\t{\n\t\tUSB_DEVICE_ID_APPLE_T2_7C,\n\t\tHAS_INTEGRATED_BUTTON,\n\t\t0, sizeof(struct TRACKPAD_BUTTON_DATA),\n\t\t0x83, DATAFORMAT(TYPE4),\n\t\t{ SN_PRESSURE, 0, 300 },\n\t\t{ SN_WIDTH, 0, 2048 },\n\t\t// Oversampled - this is fine for a trackpad\n\t\t{ SN_COORD, -10000, 10000 },\n\t\t{ SN_COORD, -2000, 10000 },\n\t\t{ SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }\n\t},\n\t{\n\t\tUSB_DEVICE_ID_APPLE_T2_7D,\n\t\tHAS_INTEGRATED_BUTTON,\n\t\t0, sizeof(struct TRACKPAD_BUTTON_DATA),\n\t\t0x83, DATAFORMAT(TYPE4),\n\t\t{ SN_PRESSURE, 0, 300 },\n\t\t{ SN_WIDTH, 0, 2048 },\n\t\t// Oversampled - this is fine for a trackpad\n\t\t{ SN_COORD, -10000, 10000 },\n\t\t{ SN_COORD, -2000, 10000 },\n\t\t{ SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }\n\t},\n\t{\n\t\t0\n\t},\n};\n"
  },
  {
    "path": "src/AmtPtpDeviceUsbKm/include/Hid.h",
    "content": "// Hid.h: Device-related HID definitions\n#pragma once\n\n#include <hidport.h>\n\n#include <AppleDefinition.h>\n#include <hid/HidCommon.h>\n\n// Device family metadata\n#include <metadata/WellspringT2.h>\n\ntypedef UCHAR HID_REPORT_DESCRIPTOR, *PHID_REPORT_DESCRIPTOR;\n\n#define DEVICE_VERSION 0x01\n\n#define AAPL_PTP_USERMODE_CONFIGURATION_APP_TLC \\\n\tUSAGE_PAGE_1, 0x00, 0xff, /* Usage Page: Vendor defined */ \\\n\tUSAGE, 0x01, /* Usage: Vendor Usage 0x01 */ \\\n\tBEGIN_COLLECTION, 0x01, /* Begin Collection: Application */ \\\n\t\tREPORT_ID, REPORTID_UMAPP_CONF, /* Report ID: User-mode Application configuration */ \\\n\t\tUSAGE, 0x01, /* Usage: Vendor Usage 0x01 */ \\\n\t\tLOGICAL_MINIMUM, 0x00, /* Logical Minimum 0 */ \\\n\t\tLOGICAL_MAXIMUM_2, 0xff, 0x00, /* Logical Maximum 255 */ \\\n\t\tREPORT_SIZE, 0x08, /* Report Size: 8 */ \\\n\t\tREPORT_COUNT, 0x03, /* Report Count: 3 */ \\\n\t\tFEATURE, 0x02, /* Feature: (Data, Var, Abs) */ \\\n\tEND_COLLECTION\n\n#define AAPL_PTP_WINDOWS_CONFIGURATION_TLC \\\n\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\tUSAGE, 0x0e, /* Usage: Configuration */ \\\n\tBEGIN_COLLECTION, 0x01, /* Begin Collection: Application */ \\\n\t\tREPORT_ID, REPORTID_REPORTMODE, /* Report ID: Mode Selection */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tBEGIN_COLLECTION, 0x02, /* Begin Collection: Logical */ \\\n\t\t\tUSAGE, 0x52, /* Usage: Input Mode */ \\\n\t\t\tLOGICAL_MINIMUM, 0x00, /* Logical Minumum: 0 finger */ \\\n\t\t\tLOGICAL_MAXIMUM, MAX_FINGERS, /* Logical Maximum: MAX_TOUCH_COUNT fingers */ \\\n\t\t\tREPORT_SIZE, 0x08, /* Report Size: 0x08 */ \\\n\t\t\tREPORT_COUNT, 0x01, /* Report Count: 0x01 */ \\\n\t\t\tFEATURE, 0x02, /* Feature: (Data, Var, Abs) */ \\\n\t\tEND_COLLECTION, /* End Collection */ \\\n\t\tBEGIN_COLLECTION, 0x00, /* Begin Collection: Physical */ \\\n\t\t\tREPORT_ID, REPORTID_FUNCSWITCH, /* Report ID: Function Switch */ \\\n\t\t\tUSAGE, BUTTON_SWITCH, /* Usage: Button Switch */ \\\n\t\t\tUSAGE, SURFACE_SWITCH, /* Usage: Surface Switch */ \\\n\t\t\tREPORT_SIZE, 0x01, /* Report Size: 0x01 */ \\\n\t\t\tREPORT_COUNT, 0x02, /* Report Count: 0x02 */ \\\n\t\t\tLOGICAL_MAXIMUM, 0x01, /* Logical Maximum: 0x01 */ \\\n\t\t\tFEATURE, 0x02, /* Feature: (Data, Var, Abs) */ \\\n\t\t\tREPORT_COUNT, 0x06, /* Report Count: 0x06 */ \\\n\t\t\tFEATURE, 0x03, /* Feature: (Const, Var, Abs) */ \\\n\t\tEND_COLLECTION, /* End Collection */ \\\n\tEND_COLLECTION /* End Collection */\n\n#define DEFAULT_PTP_HQA_BLOB \\\n\t0xfc, 0x28, 0xfe, 0x84, 0x40, 0xcb, 0x9a, 0x87, \\\n\t0x0d, 0xbe, 0x57, 0x3c, 0xb6, 0x70, 0x09, 0x88, \\\n\t0x07, 0x97, 0x2d, 0x2b, 0xe3, 0x38, 0x34, 0xb6, \\\n\t0x6c, 0xed, 0xb0, 0xf7, 0xe5, 0x9c, 0xf6, 0xc2, \\\n\t0x2e, 0x84, 0x1b, 0xe8, 0xb4, 0x51, 0x78, 0x43, \\\n\t0x1f, 0x28, 0x4b, 0x7c, 0x2d, 0x53, 0xaf, 0xfc, \\\n\t0x47, 0x70, 0x1b, 0x59, 0x6f, 0x74, 0x43, 0xc4, \\\n\t0xf3, 0x47, 0x18, 0x53, 0x1a, 0xa2, 0xa1, 0x71, \\\n\t0xc7, 0x95, 0x0e, 0x31, 0x55, 0x21, 0xd3, 0xb5, \\\n\t0x1e, 0xe9, 0x0c, 0xba, 0xec, 0xb8, 0x89, 0x19, \\\n\t0x3e, 0xb3, 0xaf, 0x75, 0x81, 0x9d, 0x53, 0xb9, \\\n\t0x41, 0x57, 0xf4, 0x6d, 0x39, 0x25, 0x29, 0x7c, \\\n\t0x87, 0xd9, 0xb4, 0x98, 0x45, 0x7d, 0xa7, 0x26, \\\n\t0x9c, 0x65, 0x3b, 0x85, 0x68, 0x89, 0xd7, 0x3b, \\\n\t0xbd, 0xff, 0x14, 0x67, 0xf2, 0x2b, 0xf0, 0x2a, \\\n\t0x41, 0x54, 0xf0, 0xfd, 0x2c, 0x66, 0x7c, 0xf8, \\\n\t0xc0, 0x8f, 0x33, 0x13, 0x03, 0xf1, 0xd3, 0xc1, \\\n\t0x0b, 0x89, 0xd9, 0x1b, 0x62, 0xcd, 0x51, 0xb7, \\\n\t0x80, 0xb8, 0xaf, 0x3a, 0x10, 0xc1, 0x8a, 0x5b, \\\n\t0xe8, 0x8a, 0x56, 0xf0, 0x8c, 0xaa, 0xfa, 0x35, \\\n\t0xe9, 0x42, 0xc4, 0xd8, 0x55, 0xc3, 0x38, 0xcc, \\\n\t0x2b, 0x53, 0x5c, 0x69, 0x52, 0xd5, 0xc8, 0x73, \\\n\t0x02, 0x38, 0x7c, 0x73, 0xb6, 0x41, 0xe7, 0xff, \\\n\t0x05, 0xd8, 0x2b, 0x79, 0x9a, 0xe2, 0x34, 0x60, \\\n\t0x8f, 0xa3, 0x32, 0x1f, 0x09, 0x78, 0x62, 0xbc, \\\n\t0x80, 0xe3, 0x0f, 0xbd, 0x65, 0x20, 0x08, 0x13, \\\n\t0xc1, 0xe2, 0xee, 0x53, 0x2d, 0x86, 0x7e, 0xa7, \\\n\t0x5a, 0xc5, 0xd3, 0x7d, 0x98, 0xbe, 0x31, 0x48, \\\n\t0x1f, 0xfb, 0xda, 0xaf, 0xa2, 0xa8, 0x6a, 0x89, \\\n\t0xd6, 0xbf, 0xf2, 0xd3, 0x32, 0x2a, 0x9a, 0xe4, \\\n\t0xcf, 0x17, 0xb7, 0xb8, 0xf4, 0xe1, 0x33, 0x08, \\\n\t0x24, 0x8b, 0xc4, 0x43, 0xa5, 0xe5, 0x24, 0xc2\n\n#define PTP_MAX_CONTACT_POINTS 5\n#define PTP_BUTTON_TYPE_CLICK_PAD 0\n#define PTP_BUTTON_TYPE_PRESSURE_PAD 1\n\n#define PTP_COLLECTION_MOUSE 0\n#define PTP_COLLECTION_WINDOWS 3\n\n#define PTP_CONTACT_CONFIDENCE_BIT   1\n#define PTP_CONTACT_TIPSWITCH_BIT    2\n\ntypedef struct _PTP_DEVICE_CAPS_FEATURE_REPORT {\n\tUCHAR ReportID;\n\tUCHAR MaximumContactPoints;\n\tUCHAR ButtonType;\n} PTP_DEVICE_CAPS_FEATURE_REPORT, *PPTP_DEVICE_CAPS_FEATURE_REPORT;\n\ntypedef struct _PTP_DEVICE_HQA_CERTIFICATION_REPORT {\n\tUCHAR ReportID;\n\tUCHAR CertificationBlob[256];\n} PTP_DEVICE_HQA_CERTIFICATION_REPORT, *PPTP_DEVICE_HQA_CERTIFICATION_REPORT;\n\ntypedef struct _PTP_DEVICE_INPUT_MODE_REPORT {\n\tUCHAR ReportID;\n\tUCHAR Mode;\n} PTP_DEVICE_INPUT_MODE_REPORT, *PPTP_DEVICE_INPUT_MODE_REPORT;\n\n#pragma pack(push)\n#pragma pack(1)\ntypedef struct _PTP_DEVICE_SELECTIVE_REPORT_MODE_REPORT {\n\tUCHAR ReportID;\n\tUCHAR DeviceMode;\n\tUCHAR ButtonReport : 1;\n\tUCHAR SurfaceReport : 1;\n\tUCHAR Padding : 6;\n} PTP_DEVICE_SELECTIVE_REPORT_MODE_REPORT, * PPTP_DEVICE_SELECTIVE_REPORT_MODE_REPORT;\n#pragma pack(pop)\n\n#pragma pack(push)\n#pragma pack(1)\ntypedef struct _PTP_CONTACT {\n\tUCHAR\t\tConfidence : 1;\n\tUCHAR\t\tTipSwitch : 1;\n\tUCHAR\t\tPadding : 6;\n\tULONG\t\tContactID;\n\tUSHORT\t\tX;\n\tUSHORT\t\tY;\n} PTP_CONTACT, * PPTP_CONTACT;\n#pragma pack(pop)\n\ntypedef struct _PTP_REPORT {\n\tUCHAR       ReportID;\n\tPTP_CONTACT Contacts[5];\n\tUSHORT      ScanTime;\n\tUCHAR       ContactCount;\n\tUCHAR       IsButtonClicked;\n} PTP_REPORT, *PPTP_REPORT;\n\ntypedef struct _PTP_USERMODEAPP_CONF_REPORT {\n\tUCHAR\t\tReportID;\n\tUCHAR\t\tPressureQualificationLevel;\n\tUCHAR\t\tSingleContactSizeQualificationLevel;\n\tUCHAR\t\tMultipleContactSizeQualificationLevel;\n} PTP_USERMODEAPP_CONF_REPORT, *PPTP_USERMODEAPP_CONF_REPORT;\n"
  },
  {
    "path": "src/AmtPtpDeviceUsbKm/include/hid/HidCommon.h",
    "content": "#pragma once\n\n#define REPORTID_STANDARDMOUSE 0x02\n#define REPORTID_MULTITOUCH 0x05\n#define REPORTID_REPORTMODE 0x04\n#define REPORTID_PTPHQA 0x08\n#define REPORTID_FUNCSWITCH 0x06\n#define REPORTID_DEVICE_CAPS 0x07\n#define REPORTID_UMAPP_CONF  0x09\n\n#define BUTTON_SWITCH 0x57\n#define SURFACE_SWITCH 0x58\n\n#define USAGE_PAGE 0x05\n#define USAGE_PAGE_1 0x06\n#define USAGE      0x09\n#define USAGE_MINIMUM 0x19\n#define USAGE_MAXIMUM 0x29\n#define LOGICAL_MINIMUM 0x15\n#define LOGICAL_MAXIMUM 0x25\n#define LOGICAL_MAXIMUM_2 0x26\n#define LOGICAL_MAXIMUM_3 0x27\n#define PHYSICAL_MINIMUM 0x35\n#define PHYSICAL_MAXIMUM 0x45\n#define PHYSICAL_MAXIMUM_2 0x46\n#define PHYSICAL_MAXIMUM_3 0x47\n#define UNIT_EXPONENT 0x55\n#define UNIT 0x65\n#define UNIT_2 0x66\n\n#define REPORT_ID       0x85\n#define REPORT_COUNT    0x95\n#define REPORT_COUNT_2\t0x96\n#define REPORT_SIZE     0x75\n#define INPUT           0x81\n#define FEATURE         0xb1\n\n#define BEGIN_COLLECTION 0xa1\n#define END_COLLECTION   0xc0\n"
  },
  {
    "path": "src/AmtPtpDeviceUsbKm/include/metadata/WellspringT2.h",
    "content": "#pragma once\n\n#include <hid/HidCommon.h>\n\n#define AAPL_WELLSPRING_T2_PTP_FINGER_COLLECTION_1 \\\n\tBEGIN_COLLECTION, 0x02, /* Begin Collection: Logical */ \\\n\t\t/* Begin a byte */ \\\n\t\tLOGICAL_MAXIMUM, 0x01, /* Logical Maximum: 1 */ \\\n\t\tUSAGE, 0x47, /* Usage: Confidence */ \\\n\t\tUSAGE, 0x42, /* Usage: Tip switch */ \\\n\t\tREPORT_COUNT, 0x02, /* Report Count: 2 */ \\\n\t\tREPORT_SIZE, 0x01, /* Report Size: 1 */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tREPORT_SIZE, 0x01, /* Report Size: 1 */ \\\n\t\tREPORT_COUNT, 0x06, /* Report Count: 6 */ \\\n\t\tINPUT, 0x03, /* Input: (Const, Var, Abs) */ \\\n\t\t/* End of a byte */ \\\n\t\t/* Begin of 4 bytes */ \\\n\t\tREPORT_COUNT, 0x01, /* Report Count: 1 */ \\\n\t\tREPORT_SIZE, 0x20, /* Report Size: 0x10 (2 bytes) */ \\\n\t\tLOGICAL_MAXIMUM_3, 0xff, 0xff, 0xff, 0xff, /* Logical Maximum: 0xffffffff */ \\\n\t\tUSAGE, 0x51, /* Usage: Contract Identifier */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\t/* End of 4 bytes */ \\\n\t\t/* Begin of 4 bytes */ \\\n\t\t/* Size is hard-coded at this moment */ \\\n\t\tUSAGE_PAGE, 0x01, /* Usage Page: Generic Desktop */ \\\n\t\tLOGICAL_MAXIMUM_2, 0x20, 0x4e, /* Logical Maximum: 20000 (See defintion) */ \\\n\t\tREPORT_SIZE, 0x10, /* Report Size: 0x10 (2 bytes) */ \\\n\t\tUNIT_EXPONENT, 0x0e, /* Unit exponent: -2 */ \\\n\t\tUNIT, 0x11, /* Unit: SI Length (cm) */ \\\n\t\tUSAGE, 0x30, /* Usage: X */ \\\n\t\tPHYSICAL_MAXIMUM_2, 0x14, 0x05, /* Physical Maximum: 1300 (See Apple Spec) */ \\\n\t\tREPORT_COUNT, 0x01, /* Report count: 1 */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tPHYSICAL_MAXIMUM_2, 0x52, 0x03, /* Physical Maximum: 850 (See Apple Spec) */ \\\n\t\tLOGICAL_MAXIMUM_2, 0xe0, 0x2e, /* Logical Maximum: 12000 (See definition) */ \\\n\t\tUSAGE, 0x31, /* Usage: Y */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tPHYSICAL_MAXIMUM, 0x00, /* Physical Maximum: 0 */ \\\n\t\tUNIT_EXPONENT, 0x00, /* Unit exponent: 0 */ \\\n\t\tUNIT, 0x00, /* Unit: None */ \\\n\t\t/* End of 4 bytes */ \\\n\tEND_COLLECTION /* End Collection */ \\\n\n#define AAPL_WELLSPRING_T2_PTP_FINGER_COLLECTION_2 \\\n\tBEGIN_COLLECTION, 0x02, /* Begin Collection: Logical */ \\\n\t\t/* Begin a byte */ \\\n\t\tLOGICAL_MAXIMUM, 0x01, /* Logical Maximum: 1 */ \\\n\t\tUSAGE, 0x47, /* Usage: Confidence */ \\\n\t\tUSAGE, 0x42, /* Usage: Tip switch */ \\\n\t\tREPORT_COUNT, 0x02, /* Report Count: 2 */ \\\n\t\tREPORT_SIZE, 0x01, /* Report Size: 1 */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tREPORT_SIZE, 0x01, /* Report Size: 1 */ \\\n\t\tREPORT_COUNT, 0x06, /* Report Count: 6 */ \\\n\t\tINPUT, 0x03, /* Input: (Const, Var, Abs) */ \\\n\t\t/* End of a byte */ \\\n\t\t/* Begin of 4 bytes */ \\\n\t\tREPORT_COUNT, 0x01, /* Report Count: 1 */ \\\n\t\tREPORT_SIZE, 0x20, /* Report Size: 0x10 (2 bytes) */ \\\n\t\tLOGICAL_MAXIMUM_3, 0xff, 0xff, 0xff, 0xff, /* Logical Maximum: 0xffffffff */ \\\n\t\tUSAGE, 0x51, /* Usage: Contract Identifier */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\t/* End of 4 bytes */ \\\n\t\t/* Begin of 4 bytes */ \\\n\t\t/* Size is hard-coded at this moment */ \\\n\t\tUSAGE_PAGE, 0x01, /* Usage Page: Generic Desktop */ \\\n\t\tLOGICAL_MAXIMUM_2, 0x20, 0x4e, /* Logical Maximum: 20000 (See defintion) */ \\\n\t\tREPORT_SIZE, 0x10, /* Report Size: 0x10 (2 bytes) */ \\\n\t\tUNIT_EXPONENT, 0x0e, /* Unit exponent: -2 */ \\\n\t\tUNIT, 0x11, /* Unit: SI Length (cm) */ \\\n\t\tUSAGE, 0x30, /* Usage: X */ \\\n\t\tPHYSICAL_MAXIMUM_2, 0x14, 0x05, /* Physical Maximum: 1045 (See Apple Spec) */ \\\n\t\tREPORT_COUNT, 0x01, /* Report count: 1 */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tPHYSICAL_MAXIMUM_2, 0x52, 0x03, /* Physical Maximum: 750 (See Apple Spec) */ \\\n\t\tLOGICAL_MAXIMUM_2, 0xe0, 0x2e, /* Logical Maximum: 12000 (See definition) */ \\\n\t\tUSAGE, 0x31, /* Usage: Y */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\t/* End of 4 bytes */ \\\n\tEND_COLLECTION /* End Collection */ \\\n\n#define AAPL_WELLSPRING_T2_PTP_TLC \\\n\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\tUSAGE, 0x05, /* Usage: Touch Pad */ \\\n\tBEGIN_COLLECTION, 0x01, /* Begin Collection: Application */ \\\n\t\tREPORT_ID, REPORTID_MULTITOUCH, /* Report ID: Multi-touch */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_WELLSPRING_T2_PTP_FINGER_COLLECTION_1, /* 1 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_WELLSPRING_T2_PTP_FINGER_COLLECTION_1, /* 2 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_WELLSPRING_T2_PTP_FINGER_COLLECTION_2, /* 3 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_WELLSPRING_T2_PTP_FINGER_COLLECTION_1, /* 4 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_WELLSPRING_T2_PTP_FINGER_COLLECTION_2, /* 5 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUNIT_EXPONENT, 0x0c, /* Unit exponent: -4 */ \\\n\t\tUNIT_2, 0x01, 0x10, /* Time: Second */ \\\n\t\tPHYSICAL_MAXIMUM_3, 0xff, 0xff, 0x00, 0x00, \\\n\t\tLOGICAL_MAXIMUM_3, 0xff, 0xff, 0x00, 0x00, \\\n\t\tUSAGE, 0x56, /* Usage: Scan Time */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tUSAGE, 0x54, /* Usage: Contact Count */ \\\n\t\tLOGICAL_MAXIMUM, 0x7f, \\\n\t\tREPORT_SIZE, 0x08, \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tUSAGE_PAGE, 0x09, /* Usage Page: Button */ \\\n\t\tUSAGE, 0x01, /* Button 1 */ \\\n\t\tLOGICAL_MAXIMUM, 0x01, \\\n\t\tREPORT_SIZE, 0x01, \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tREPORT_COUNT, 0x07, \\\n\t\tINPUT, 0x03, /* Input: (Const, Var, Abs) */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tREPORT_ID, REPORTID_DEVICE_CAPS, \\\n\t\tUSAGE, 0x55, /* Usage: Maximum Contacts */ \\\n\t\tUSAGE, 0x59, /* Usage: Touchpad Button Type*/ \\\n\t\tLOGICAL_MINIMUM, 0x00, \\\n\t\tLOGICAL_MAXIMUM_2, 0xff, 0x00, \\\n\t\tREPORT_SIZE, 0x08, \\\n\t\tREPORT_COUNT, 0x02, \\\n\t\tFEATURE, 0x02, \\\n\t\tUSAGE_PAGE_1, 0x00, 0xff, \\\n\t\tREPORT_ID, REPORTID_PTPHQA, \\\n\t\tUSAGE, 0xc5, \\\n\t\tLOGICAL_MINIMUM, 0x00, \\\n\t\tLOGICAL_MAXIMUM_2, 0xff, 0x00, \\\n\t\tREPORT_SIZE, 0x08, \\\n\t\tREPORT_COUNT_2, 0x00, 0x01, \\\n\t\tFEATURE, 0x02, \\\n\tEND_COLLECTION /* End Collection */\n"
  },
  {
    "path": "src/AmtPtpDeviceUsbKm/resource.h",
    "content": "//{{NO_DEPENDENCIES}}\n// Microsoft Visual C++ generated include file.\n// Used by Resource.rc\n\n#define IDS_APP_TITLE           103\n\n// Next default values for new objects\n// \n#ifdef APSTUDIO_INVOKED\n#ifndef APSTUDIO_READONLY_SYMBOLS\n#define _APS_NEXT_RESOURCE_VALUE        101\n#define _APS_NEXT_COMMAND_VALUE         40001\n#define _APS_NEXT_CONTROL_VALUE         1001\n#define _APS_NEXT_SYMED_VALUE           101\n#endif\n#endif\n"
  },
  {
    "path": "src/AmtPtpDeviceUsbUm/AmtPtpDevice.wprp",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<WindowsPerformanceRecorder Version=\"1.0\" Author=\"AmtPtpDevice Authors\" Copyright=\"AmtPtpDevice Authors\" Company=\"AmtPtpDevice Authors\">\n  <Profiles>\n    <EventCollector Id=\"EventCollector_AmtPtpDeviceTraceProvider\" Name=\"AmtPtpDeviceTraceProvider\">\n      <BufferSize Value=\"64\" />\n      <Buffers Value=\"4\" />\n    </EventCollector>\n    <EventProvider Id=\"EventProvider_AmtPtpDeviceTraceProvider\" Name=\"871B1E2D-CC5A-4ADE-B74E-6CF1004EF149\" />\n    <Profile Id=\"AmtPtpDeviceTraceProvider.Verbose.File\" Name=\"AmtPtpDeviceTraceProvider\" \n             Description=\"AmtPtpDeviceTraceProvider\" LoggingMode=\"File\" DetailLevel=\"Verbose\">\n      <Collectors>\n        <EventCollectorId Value=\"EventCollector_AmtPtpDeviceTraceProvider\">\n          <EventProviders>\n            <EventProviderId Value=\"EventProvider_AmtPtpDeviceTraceProvider\" />\n          </EventProviders>\n        </EventCollectorId>\n      </Collectors>\n    </Profile>\n    <Profile Id=\"AmtPtpDeviceTraceProvider.Light.File\" Name=\"AmtPtpDeviceTraceProvider\" \n             Description=\"AmtPtpDeviceTraceProvider\" Base=\"AmtPtpDeviceTraceProvider.Verbose.File\" \n             LoggingMode=\"File\" DetailLevel=\"Light\" />\n    <Profile Id=\"AmtPtpDeviceTraceProvider.Verbose.Memory\" Name=\"AmtPtpDeviceTraceProvider\" \n             Description=\"AmtPtpDeviceTraceProvider\" Base=\"AmtPtpDeviceTraceProvider.Verbose.File\" \n             LoggingMode=\"Memory\" DetailLevel=\"Verbose\" />\n    <Profile Id=\"AmtPtpDeviceTraceProvider.Light.Memory\" Name=\"AmtPtpDeviceTraceProvider\" \n             Description=\"AmtPtpDeviceTraceProvider\" Base=\"AmtPtpDeviceTraceProvider.Verbose.File\" \n             LoggingMode=\"Memory\" DetailLevel=\"Light\" />\n  </Profiles>\n</WindowsPerformanceRecorder>"
  },
  {
    "path": "src/AmtPtpDeviceUsbUm/Device.c",
    "content": "// Device.c: Device handling events for driver.\n\n#include <driver.h>\n#include \"device.tmh\"\n\n_IRQL_requires_(PASSIVE_LEVEL)\nstatic const struct BCM5974_CONFIG*\nAmtPtpGetDeviceConfig(\n\t_In_ USB_DEVICE_DESCRIPTOR deviceInfo\n)\n{\n\tUSHORT id = deviceInfo.idProduct;\n\tconst struct BCM5974_CONFIG *cfg;\n\n\tfor (cfg = Bcm5974ConfigTable; cfg->ansi; ++cfg) {\n\t\tif (cfg->ansi == id || cfg->iso == id || cfg->jis == id) {\n\t\t\treturn cfg;\n\t\t}\n\t}\n\n\treturn NULL;\n}\n\n_IRQL_requires_(PASSIVE_LEVEL)\nNTSTATUS\nAmtPtpCreateDevice(\n\t_In_    WDFDRIVER       Driver,\n\t_Inout_ PWDFDEVICE_INIT DeviceInit\n)\n{\n\tWDF_PNPPOWER_EVENT_CALLBACKS\t\tpnpPowerCallbacks;\n\tWDF_DEVICE_PNP_CAPABILITIES         pnpCaps;\n\tWDF_OBJECT_ATTRIBUTES\t\t\t\tdeviceAttributes;\n\tPDEVICE_CONTEXT\t\t\t\t\t\tdeviceContext;\n\tWDFDEVICE\t\t\t\t\t\t\tdevice;\n\tNTSTATUS\t\t\t\t\t\t\tstatus;\n\n\tUNREFERENCED_PARAMETER(Driver);\n\tPAGED_CODE();\n\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION, \n\t\tTRACE_DRIVER, \n\t\t\"%!FUNC! Entry\"\n\t);\n\n\t// Initialize Power Callback\n\tWDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpPowerCallbacks);\n\n\t// Initialize PNP power event callbacks\n\tpnpPowerCallbacks.EvtDevicePrepareHardware = AmtPtpEvtDevicePrepareHardware;\n\tpnpPowerCallbacks.EvtDeviceD0Entry = AmtPtpEvtDeviceD0Entry;\n\tpnpPowerCallbacks.EvtDeviceD0Exit = AmtPtpEvtDeviceD0Exit;\n\tWdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpPowerCallbacks);\n\n\t// Create WDF device object\n\tWDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&deviceAttributes, DEVICE_CONTEXT);\n\n\tstatus = WdfDeviceCreate(\n\t\t&DeviceInit, \n\t\t&deviceAttributes, \n\t\t&device\n\t);\n\n\tif (!NT_SUCCESS(status)) {\n\t\tTraceEvents(TRACE_LEVEL_ERROR, TRACE_DRIVER,\n\t\t\t\"%!FUNC! WdfDeviceCreate failed with Status code %!STATUS!\", status);\n\t\treturn status;\n\t}\n\n\t//\n\t// Get a pointer to the device context structure that we just associated\n\t// with the device object. We define this structure in the device.h\n\t// header file. DeviceGetContext is an inline function generated by\n\t// using the WDF_DECLARE_CONTEXT_TYPE_WITH_NAME macro in device.h.\n\t// This function will do the type checking and return the device context.\n\t// If you pass a wrong object handle it will return NULL and assert if\n\t// run under framework verifier mode.\n\t//\n\tdeviceContext = DeviceGetContext(device);\n\n\t//\n\t// Tell the framework to set the SurpriseRemovalOK in the DeviceCaps so\n\t// that you don't get the popup in usermode \n\t// when you surprise remove the device.\n\t//\n\tWDF_DEVICE_PNP_CAPABILITIES_INIT(&pnpCaps);\n\tpnpCaps.SurpriseRemovalOK = WdfTrue;\n\tWdfDeviceSetPnpCapabilities(\n\t\tdevice, \n\t\t&pnpCaps\n\t);\n\n\t//\n\t// Create a device interface so that applications can find and talk\n\t// to us.\n\t//\n\tstatus = WdfDeviceCreateDeviceInterface(\n\t\tdevice,\n\t\t&GUID_DEVINTERFACE_AmtPtpDevice,\n\t\tNULL // ReferenceString\n\t);\n\n\tif (NT_SUCCESS(status)) {\n\t\t//\n\t\t// Initialize the I/O Package and any Queues\n\t\t//\n\t\tstatus = AmtPtpDeviceQueueInitialize(device);\n\t}\n\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION, \n\t\tTRACE_DRIVER, \n\t\t\"%!FUNC! Exit\"\n\t);\n\n\treturn status;\n}\n\nNTSTATUS\nAmtPtpEvtDevicePrepareHardware(\n\t_In_ WDFDEVICE Device,\n\t_In_ WDFCMRESLIST ResourceList,\n\t_In_ WDFCMRESLIST ResourceListTranslated\n)\n{\n\n\tNTSTATUS\t\t\t\t\t\t\t\tstatus;\n\tPDEVICE_CONTEXT\t\t\t\t\t\t\tpDeviceContext;\n\tULONG\t\t\t\t\t\t\t\t\twaitWakeEnable;\n\tWDF_USB_DEVICE_INFORMATION\t\t\t\tdeviceInfo;\n\n\twaitWakeEnable = FALSE;\n\n\tUNREFERENCED_PARAMETER(ResourceList);\n\tUNREFERENCED_PARAMETER(ResourceListTranslated);\n\tPAGED_CODE();\n\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION, \n\t\tTRACE_DRIVER, \n\t\t\"%!FUNC! Entry\"\n\t);\n\n\tstatus = STATUS_SUCCESS;\n\tpDeviceContext = DeviceGetContext(Device);\n\n\tif (pDeviceContext->UsbDevice == NULL) {\n\t\tstatus = WdfUsbTargetDeviceCreate(Device,\n\t\t\tWDF_NO_OBJECT_ATTRIBUTES,\n\t\t\t&pDeviceContext->UsbDevice\n\t\t);\n\n\t\tif (!NT_SUCCESS(status)) {\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_ERROR, \n\t\t\t\tTRACE_DRIVER,\n\t\t\t\t\"%!FUNC! WdfUsbTargetDeviceCreate failed with Status code %!STATUS!\", \n\t\t\t\tstatus\n\t\t\t);\n\t\t\treturn status;\n\t\t}\n\t}\n\n\t// Retrieve device information\n\tWdfUsbTargetDeviceGetDeviceDescriptor(\n\t\tpDeviceContext->UsbDevice, \n\t\t&pDeviceContext->DeviceDescriptor\n\t);\n\n\tif (NT_SUCCESS(status)) {\n\t\t// Get correct configuration from conf store\n\t\tpDeviceContext->DeviceInfo = AmtPtpGetDeviceConfig(pDeviceContext->DeviceDescriptor);\n\t\tif (pDeviceContext->DeviceInfo == NULL) {\n\t\t\tstatus = STATUS_INVALID_DEVICE_STATE;\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_ERROR, \n\t\t\t\tTRACE_DEVICE, \n\t\t\t\t\"%!FUNC! failed because device is not found in registry.\"\n\t\t\t);\n\t\t\tTraceLoggingWrite(\n\t\t\t\tg_hAmtPtpDeviceTraceProvider,\n\t\t\t\tEVENT_DEVICE_IDENTIFICATION,\n\t\t\t\tTraceLoggingString(\"AmtPtpEvtDevicePrepareHardware\", \"Routine\"),\n\t\t\t\tTraceLoggingUInt16(pDeviceContext->DeviceDescriptor.idProduct, \"idProduct\"),\n\t\t\t\tTraceLoggingUInt16(pDeviceContext->DeviceDescriptor.idVendor, \"idVendor\"),\n\t\t\t\tTraceLoggingString(EVENT_DEVICE_ID_SUBTYPE_NOTFOUND, EVENT_DRIVER_FUNC_SUBTYPE)\n\t\t\t);\n\t\t\treturn status;\n\t\t}\n\t}\n\n\t//\n\t// Retrieve USBD version information, port driver capabilites and device\n\t// capabilites such as speed, power, etc.\n\t//\n\tWDF_USB_DEVICE_INFORMATION_INIT(&deviceInfo);\n\tstatus = WdfUsbTargetDeviceRetrieveInformation(\n\t\tpDeviceContext->UsbDevice, \n\t\t&deviceInfo\n\t);\n\n\tif (NT_SUCCESS(status)) {\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_INFORMATION, \n\t\t\tTRACE_DEVICE, \n\t\t\t\"%!FUNC! IsDeviceHighSpeed: %s\",\n\t\t\t(deviceInfo.Traits & WDF_USB_DEVICE_TRAIT_AT_HIGH_SPEED) ? \"TRUE\" : \"FALSE\");\n\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_INFORMATION, \n\t\t\tTRACE_DEVICE,\n\t\t\t\"%!FUNC! IsDeviceSelfPowered: %s\",\n\t\t\t(deviceInfo.Traits & WDF_USB_DEVICE_TRAIT_SELF_POWERED) ? \"TRUE\" : \"FALSE\");\n\n\t\twaitWakeEnable = deviceInfo.Traits &\n\t\t\tWDF_USB_DEVICE_TRAIT_REMOTE_WAKE_CAPABLE;\n\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_INFORMATION,\n\t\t\tTRACE_DEVICE,\n\t\t\t\"%!FUNC! IsDeviceRemoteWakeable: %s\",\n\t\t\twaitWakeEnable ? \"TRUE\" : \"FALSE\");\n\n\t\t//\n\t\t// Save these for use later.\n\t\t//\n\t\tpDeviceContext->UsbDeviceTraits = deviceInfo.Traits;\n\t} else {\n\t\tpDeviceContext->UsbDeviceTraits = 0;\n\t}\n\n\t// Select interface to use\n\tstatus = SelectInterruptInterface(Device);\n\tif (!NT_SUCCESS(status)) {\n\t\tTraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE, \"%!FUNC! SelectInterruptInterface failed with %!STATUS!\", status);\n\t\treturn status;\n\t}\n\n\t// Set up interrupt\n\tstatus = AmtPtpConfigContReaderForInterruptEndPoint(pDeviceContext);\n\tif (!NT_SUCCESS(status)) {\n\t\tTraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE, \"%!FUNC! AmtPtpConfigContReaderForInterruptEndPoint failed with %!STATUS!\", status);\n\t\treturn status;\n\t}\n\n\t// Set default settings\n\tpDeviceContext->IsButtonReportOn = TRUE;\n\tpDeviceContext->IsSurfaceReportOn = TRUE;\n\n\tTraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, \"%!FUNC! Exit\");\n\treturn status;\n}\n\n_IRQL_requires_(PASSIVE_LEVEL)\nNTSTATUS\nAmtPtpGetWellspringMode(\n\t_In_  PDEVICE_CONTEXT DeviceContext,\n\t_Out_ BOOL* IsWellspringModeOn\n)\n{\n\n\tNTSTATUS\t\t\t\t\t\tstatus;\n\tWDF_USB_CONTROL_SETUP_PACKET\tsetupPacket;\n\tWDF_MEMORY_DESCRIPTOR\t\t\tmemoryDescriptor;\n\tULONG\t\t\t\t\t\t\tcbTransferred;\n\tWDFMEMORY\t\t\t\t\t\tbufHandle = NULL;\n\tunsigned char*\t\t\t\t\tbuffer;\n\n\tstatus = STATUS_SUCCESS;\n\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION,\n\t\tTRACE_DRIVER,\n\t\t\"%!FUNC! Entry\"\n\t);\n\n\t// Type 3 does not need a mode switch.\n\tif (DeviceContext->DeviceInfo->tp_type == TYPE3) {\n\t\t*IsWellspringModeOn = TRUE;\n\t\treturn STATUS_SUCCESS;\n\t}\n\n\tstatus = WdfMemoryCreate(\n\t\tWDF_NO_OBJECT_ATTRIBUTES,\n\t\tPagedPool,\n\t\tPOOL_TAG_PTP_CONTROL,\n\t\tDeviceContext->DeviceInfo->um_size,\n\t\t&bufHandle,\n\t\t&buffer\n\t);\n\n\tif (!NT_SUCCESS(status)) {\n\t\tgoto cleanup;\n\t}\n\n\tRtlZeroMemory(\n\t\tbuffer,\n\t\tDeviceContext->DeviceInfo->um_size\n\t);\n\n\tWDF_MEMORY_DESCRIPTOR_INIT_BUFFER(\n\t\t&memoryDescriptor,\n\t\tbuffer,\n\t\tsizeof(DeviceContext->DeviceInfo->um_size)\n\t);\n\n\tWDF_USB_CONTROL_SETUP_PACKET_INIT(\n\t\t&setupPacket,\n\t\tBmRequestDeviceToHost,\n\t\tBmRequestToInterface,\n\t\tBCM5974_WELLSPRING_MODE_READ_REQUEST_ID,\n\t\t(USHORT)DeviceContext->DeviceInfo->um_req_val,\n\t\t(USHORT)DeviceContext->DeviceInfo->um_req_idx\n\t);\n\n\t// Set stuffs right\n\tsetupPacket.Packet.bm.Request.Type = BmRequestClass;\n\n\tstatus = WdfUsbTargetDeviceSendControlTransferSynchronously(\n\t\tDeviceContext->UsbDevice,\n\t\tWDF_NO_HANDLE,\n\t\tNULL,\n\t\t&setupPacket,\n\t\t&memoryDescriptor,\n\t\t&cbTransferred\n\t);\n\n\t// Behavior mismatch: Actual device does not transfer bytes as expected (in length)\n\t// So we do not check um_size as a temporary workaround.\n\tif (!NT_SUCCESS(status)) {\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_ERROR,\n\t\t\tTRACE_DEVICE,\n\t\t\t\"%!FUNC! WdfUsbTargetDeviceSendControlTransferSynchronously (Read) failed with %!STATUS!, cbTransferred = %llu, um_size = %d\",\n\t\t\tstatus,\n\t\t\tcbTransferred,\n\t\t\tDeviceContext->DeviceInfo->um_size\n\t\t);\n\t\tgoto cleanup;\n\t}\n\n\t// Check mode switch\n\tunsigned char wellspringBit = buffer[DeviceContext->DeviceInfo->um_switch_idx];\n\t*IsWellspringModeOn = wellspringBit == DeviceContext->DeviceInfo->um_switch_on ? TRUE : FALSE;\n\ncleanup:\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION,\n\t\tTRACE_DRIVER,\n\t\t\"%!FUNC! Exit\"\n\t);\n\n\tWdfObjectDelete(bufHandle);\n\treturn status;\n\n}\n\n_IRQL_requires_(PASSIVE_LEVEL)\nNTSTATUS\nAmtPtpSetWellspringMode(\n\t_In_ PDEVICE_CONTEXT DeviceContext,\n\t_In_ BOOL IsWellspringModeOn\n)\n{\n\n\tNTSTATUS\t\t\t\t\t\tstatus;\n\tWDF_USB_CONTROL_SETUP_PACKET\tsetupPacket;\n\tWDF_MEMORY_DESCRIPTOR\t\t\tmemoryDescriptor;\n\tULONG\t\t\t\t\t\t\tcbTransferred;\n\tWDFMEMORY\t\t\t\t\t\tbufHandle = NULL;\n\tunsigned char*\t\t\t\t\tbuffer;\n\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION, \n\t\tTRACE_DRIVER, \n\t\t\"%!FUNC! Entry\"\n\t);\n\n\t// Type 3 does not need a mode switch.\n\t// However, turn mode on or off as requested.\n\tif (DeviceContext->DeviceInfo->tp_type == TYPE3) {\n\t\tDeviceContext->IsWellspringModeOn = IsWellspringModeOn;\n\t\treturn STATUS_SUCCESS;\n\t}\n\n\tstatus = WdfMemoryCreate(\n\t\tWDF_NO_OBJECT_ATTRIBUTES, \n\t\tPagedPool, \n\t\tPOOL_TAG_PTP_CONTROL, \n\t\tDeviceContext->DeviceInfo->um_size, \n\t\t&bufHandle, \n\t\t&buffer\n\t);\n\n\tif (!NT_SUCCESS(status)) {\n\t\tgoto cleanup;\n\t}\n\n\tRtlZeroMemory(\n\t\tbuffer, \n\t\tDeviceContext->DeviceInfo->um_size\n\t);\n\n\tWDF_MEMORY_DESCRIPTOR_INIT_BUFFER(\n\t\t&memoryDescriptor, \n\t\tbuffer, \n\t\tsizeof(DeviceContext->DeviceInfo->um_size)\n\t);\n\n\tWDF_USB_CONTROL_SETUP_PACKET_INIT(\n\t\t&setupPacket, \n\t\tBmRequestDeviceToHost, \n\t\tBmRequestToInterface,\n\t\tBCM5974_WELLSPRING_MODE_READ_REQUEST_ID,\n\t\t(USHORT) DeviceContext->DeviceInfo->um_req_val, \n\t\t(USHORT) DeviceContext->DeviceInfo->um_req_idx\n\t);\n\n\t// Set stuffs right\n\tsetupPacket.Packet.bm.Request.Type = BmRequestClass;\n\n\tstatus = WdfUsbTargetDeviceSendControlTransferSynchronously(\n\t\tDeviceContext->UsbDevice, \n\t\tWDF_NO_HANDLE, \n\t\tNULL, \n\t\t&setupPacket, \n\t\t&memoryDescriptor, \n\t\t&cbTransferred\n\t);\n\n\t// Behavior mismatch: Actual device does not transfer bytes as expected (in length)\n\t// So we do not check um_size as a temporary workaround.\n\tif (!NT_SUCCESS(status)) {\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_ERROR, \n\t\t\tTRACE_DEVICE, \n\t\t\t\"%!FUNC! WdfUsbTargetDeviceSendControlTransferSynchronously (Read) failed with %!STATUS!, cbTransferred = %llu, um_size = %d\", \n\t\t\tstatus,\n\t\t\tcbTransferred,\n\t\t\tDeviceContext->DeviceInfo->um_size\n\t\t);\n\t\tgoto cleanup;\n\t}\n\n\t// Apply the mode switch\n\tbuffer[DeviceContext->DeviceInfo->um_switch_idx] = IsWellspringModeOn ?\n\t\t(unsigned char) DeviceContext->DeviceInfo->um_switch_on : \n\t\t(unsigned char) DeviceContext->DeviceInfo->um_switch_off;\n\n\t// Write configuration\n\tWDF_USB_CONTROL_SETUP_PACKET_INIT(\n\t\t&setupPacket, \n\t\tBmRequestHostToDevice, \n\t\tBmRequestToInterface,\n\t\tBCM5974_WELLSPRING_MODE_WRITE_REQUEST_ID,\n\t\t(USHORT) DeviceContext->DeviceInfo->um_req_val, \n\t\t(USHORT) DeviceContext->DeviceInfo->um_req_idx\n\t);\n\n\t// Set stuffs right\n\tsetupPacket.Packet.bm.Request.Type = BmRequestClass;\n\n\tstatus = WdfUsbTargetDeviceSendControlTransferSynchronously(\n\t\tDeviceContext->UsbDevice, \n\t\tWDF_NO_HANDLE, \n\t\tNULL, \n\t\t&setupPacket, \n\t\t&memoryDescriptor, \n\t\t&cbTransferred\n\t);\n\n\tif (!NT_SUCCESS(status)) {\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_ERROR, \n\t\t\tTRACE_DEVICE, \n\t\t\t\"%!FUNC! WdfUsbTargetDeviceSendControlTransferSynchronously (Write) failed with %!STATUS!\", \n\t\t\tstatus\n\t\t);\n\t\tgoto cleanup;\n\t}\n\n\t// Set status\n\tDeviceContext->IsWellspringModeOn = IsWellspringModeOn;\n\ncleanup:\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION,\n\t\tTRACE_DRIVER,\n\t\t\"%!FUNC! Exit\"\n\t);\n\n\tWdfObjectDelete(bufHandle);\n\treturn status;\n\n}\n\nNTSTATUS\nAmtPtpEvtDeviceD0Entry(\n\t_In_ WDFDEVICE Device,\n\t_In_ WDF_POWER_DEVICE_STATE PreviousState\n)\n{\n\tPDEVICE_CONTEXT         pDeviceContext;\n\tNTSTATUS                status;\n\tBOOLEAN                 isTargetStarted;\n\n\tpDeviceContext = DeviceGetContext(Device);\n\tisTargetStarted = FALSE;\n\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION, \n\t\tTRACE_DRIVER, \n\t\t\"%!FUNC! -->AmtPtpDeviceEvtDeviceD0Entry - coming from %s\",\n\t\tDbgDevicePowerString(PreviousState)\n\t);\n\n\t// Check wellspring mode\n\tif (pDeviceContext->IsButtonReportOn || pDeviceContext->IsWellspringModeOn) {\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_INFORMATION,\n\t\t\tTRACE_DRIVER,\n\t\t\t\"%!FUNC! <--AmtPtpDeviceEvtDeviceD0Entry - Start Wellspring Mode\"\n\t\t);\n\n\t\tstatus = AmtPtpSetWellspringMode(\n\t\t\tpDeviceContext,\n\t\t\tTRUE\n\t\t);\n\n\t\tif (!NT_SUCCESS(status)) {\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_WARNING,\n\t\t\t\tTRACE_DRIVER,\n\t\t\t\t\"%!FUNC! <--AmtPtpDeviceEvtDeviceD0Entry - Start Wellspring Mode failed with %!STATUS!\",\n\t\t\t\tstatus\n\t\t\t);\n\t\t}\n\t}\n\n\t// Get current time counter\n\tQueryPerformanceCounter(\n\t\t&pDeviceContext->PerfCounter\n\t);\n\n\t//\n\t// Since continuous reader is configured for this interrupt-pipe, we must explicitly start\n\t// the I/O target to get the framework to post read requests.\n\t//\n\tstatus = WdfIoTargetStart(WdfUsbTargetPipeGetIoTarget(pDeviceContext->InterruptPipe));\n\tif (!NT_SUCCESS(status)) {\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_ERROR, \n\t\t\tTRACE_DRIVER, \n\t\t\t\"%!FUNC! <--AmtPtpDeviceEvtDeviceD0Entry - Failed to start interrupt pipe %!STATUS!\", \n\t\t\tstatus\n\t\t);\n\t\tgoto End;\n\t}\n\n\tisTargetStarted = TRUE;\n\nEnd:\n\n\tif (!NT_SUCCESS(status)) {\n\t\t//\n\t\t// Failure in D0Entry will lead to device being removed. So let us stop the continuous\n\t\t// reader in preparation for the ensuing remove.\n\t\t//\n\t\tif (isTargetStarted) {\n\t\t\tWdfIoTargetStop(\n\t\t\t\tWdfUsbTargetPipeGetIoTarget(pDeviceContext->InterruptPipe), \n\t\t\t\tWdfIoTargetCancelSentIo\n\t\t\t);\n\t\t}\n\t}\n\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION, \n\t\tTRACE_DRIVER, \n\t\t\"%!FUNC! <--AmtPtpDeviceEvtDeviceD0Entry\"\n\t);\n\n\treturn status;\n}\n\nNTSTATUS\nAmtPtpEvtDeviceD0Exit(\n\t_In_ WDFDEVICE Device,\n\t_In_ WDF_POWER_DEVICE_STATE TargetState\n)\n{\n\tPDEVICE_CONTEXT         pDeviceContext;\n\tNTSTATUS\t\t\t\tstatus;\n\n\tPAGED_CODE();\n\tstatus = STATUS_SUCCESS;\n\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION, \n\t\tTRACE_DRIVER,\n\t\t\"%!FUNC! -->AmtPtpDeviceEvtDeviceD0Exit - moving to %s\", \n\t\tDbgDevicePowerString(TargetState)\n\t);\n\n\tpDeviceContext = DeviceGetContext(Device);\n\n\t// Stop IO Pipe.\n\tWdfIoTargetStop(WdfUsbTargetPipeGetIoTarget(\n\t\tpDeviceContext->InterruptPipe),\n\t\tWdfIoTargetCancelSentIo\n\t);\n\n\t// Cancel Wellspring mode.\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION,\n\t\tTRACE_DRIVER,\n\t\t\"%!FUNC! -->AmtPtpDeviceEvtDeviceD0Exit - Cancel Wellspring Mode\"\n\t);\n\n\tstatus = AmtPtpSetWellspringMode(\n\t\tpDeviceContext,\n\t\tFALSE\n\t);\n\n\tif (!NT_SUCCESS(status)) {\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_WARNING,\n\t\t\tTRACE_DRIVER,\n\t\t\t\"%!FUNC! -->AmtPtpDeviceEvtDeviceD0Exit - Cancel Wellspring Mode failed with %!STATUS!\",\n\t\t\tstatus\n\t\t);\n\t}\n\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION, \n\t\tTRACE_DRIVER, \n\t\t\"%!FUNC! <--AmtPtpDeviceEvtDeviceD0Exit\"\n\t);\n\n\treturn status;\n}\n\n_IRQL_requires_(PASSIVE_LEVEL)\nNTSTATUS\nSelectInterruptInterface(\n\t_In_ WDFDEVICE Device\n)\n{\n\tWDF_USB_DEVICE_SELECT_CONFIG_PARAMS configParams;\n\tNTSTATUS                            status = STATUS_SUCCESS;\n\tPDEVICE_CONTEXT                     pDeviceContext;\n\tWDFUSBPIPE                          pipe;\n\tWDF_USB_PIPE_INFORMATION            pipeInfo;\n\tUCHAR                               index;\n\tUCHAR                               numberConfiguredPipes;\n\tWDFUSBINTERFACE                     usbInterface;\n\n\tPAGED_CODE();\n\n\tpDeviceContext = DeviceGetContext(Device);\n\tWDF_USB_DEVICE_SELECT_CONFIG_PARAMS_INIT_SINGLE_INTERFACE(&configParams);\n\tusbInterface = WdfUsbTargetDeviceGetInterface(\n\t\tpDeviceContext->UsbDevice,\n\t\t0\n\t);\n\n\tif (NULL == usbInterface) {\n\t\tstatus = STATUS_UNSUCCESSFUL;\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_ERROR, \n\t\t\tTRACE_DEVICE,\n\t\t\t\"%!FUNC! WdfUsbTargetDeviceGetInterface 0 failed %!STATUS!\",\n\t\t\tstatus\n\t\t);\n\t\treturn status;\n\t}\n\n\tconfigParams.Types.SingleInterface.ConfiguredUsbInterface = usbInterface;\n\tconfigParams.Types.SingleInterface.NumberConfiguredPipes = WdfUsbInterfaceGetNumConfiguredPipes(usbInterface);\n\n\tpDeviceContext->UsbInterface = configParams.Types.SingleInterface.ConfiguredUsbInterface;\n\tnumberConfiguredPipes = configParams.Types.SingleInterface.NumberConfiguredPipes;\n\n\t//\n\t// Get pipe handles\n\t//\n\tfor (index = 0; index < numberConfiguredPipes; index++) {\n\n\t\tWDF_USB_PIPE_INFORMATION_INIT(&pipeInfo);\n\n\t\tpipe = WdfUsbInterfaceGetConfiguredPipe(\n\t\t\tpDeviceContext->UsbInterface,\n\t\t\tindex, //PipeIndex,\n\t\t\t&pipeInfo\n\t\t);\n\n\t\t//\n\t\t// Tell the framework that it's okay to read less than\n\t\t// MaximumPacketSize\n\t\t//\n\t\tWdfUsbTargetPipeSetNoMaximumPacketSizeCheck(pipe);\n\n\t\tif (WdfUsbPipeTypeInterrupt == pipeInfo.PipeType) {\n\t\t\tpDeviceContext->InterruptPipe = pipe;\n\t\t\tbreak;\n\t\t}\n\n\t}\n\n\t//\n\t// If we didn't find interrupt pipe, fail the start.\n\t//\n\tif (!pDeviceContext->InterruptPipe) {\n\t\tstatus = STATUS_INVALID_DEVICE_STATE;\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_ERROR, \n\t\t\tTRACE_DEVICE, \n\t\t\t\"%!FUNC! Device is not configured properly %!STATUS!\", \n\t\t\tstatus\n\t\t);\n\n\t\treturn status;\n\t}\n\n\treturn status;\n}\n\n_IRQL_requires_(PASSIVE_LEVEL)\nPCHAR\nDbgDevicePowerString(\n\t_In_ WDF_POWER_DEVICE_STATE Type\n)\n{\n\tswitch (Type)\n\t{\n\tcase WdfPowerDeviceInvalid:\n\t\treturn \"WdfPowerDeviceInvalid\";\n\tcase WdfPowerDeviceD0:\n\t\treturn \"WdfPowerDeviceD0\";\n\tcase WdfPowerDeviceD1:\n\t\treturn \"WdfPowerDeviceD1\";\n\tcase WdfPowerDeviceD2:\n\t\treturn \"WdfPowerDeviceD2\";\n\tcase WdfPowerDeviceD3:\n\t\treturn \"WdfPowerDeviceD3\";\n\tcase WdfPowerDeviceD3Final:\n\t\treturn \"WdfPowerDeviceD3Final\";\n\tcase WdfPowerDevicePrepareForHibernation:\n\t\treturn \"WdfPowerDevicePrepareForHibernation\";\n\tcase WdfPowerDeviceMaximum:\n\t\treturn \"WdfPowerDeviceMaximum\";\n\tdefault:\n\t\treturn \"UnKnown Device Power State\";\n\t}\n}\n\n_IRQL_requires_(PASSIVE_LEVEL)\nNTSTATUS\nAmtPtpEmergResetDevice(\n\t_In_ PDEVICE_CONTEXT DeviceContext\n)\n{\n\n\tNTSTATUS status;\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION,\n\t\tTRACE_DRIVER,\n\t\t\"%!FUNC! Entry\");\n\n\tstatus = AmtPtpSetWellspringMode(\n\t\tDeviceContext, \n\t\tFALSE);\n\n\tif (!NT_SUCCESS(status)) {\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_ERROR, \n\t\t\tTRACE_DEVICE, \n\t\t\t\"%!FUNC! AmtPtpSetWellspringMode failed with %!STATUS!\", \n\t\t\tstatus);\n\t}\n\n\tstatus = AmtPtpSetWellspringMode(\n\t\tDeviceContext,\n\t\tTRUE);\n\n\tif (!NT_SUCCESS(status)) {\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_ERROR,\n\t\t\tTRACE_DEVICE,\n\t\t\t\"%!FUNC! AmtPtpSetWellspringMode failed with %!STATUS!\",\n\t\t\tstatus);\n\t}\n\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION, \n\t\tTRACE_DRIVER, \n\t\t\"%!FUNC! Exit\");\n\n\treturn status;\n\n}\n"
  },
  {
    "path": "src/AmtPtpDeviceUsbUm/Driver.c",
    "content": "// Driver.c: This file contains the driver entry points and callbacks.\n\n#include <driver.h>\n#include \"driver.tmh\"\n\n// Declares Windows 10 TraceLogger provider here.\nTRACELOGGING_DEFINE_PROVIDER(\n\tg_hAmtPtpDeviceTraceProvider,\n\t\"AmtPtpDeviceTraceProvider\",\n\t(0x871b1e2d, 0xcc5a, 0x4ade, 0xb7, 0x4e, 0x6c, 0xf1, 0x0, 0x4e, 0xf1, 0x49));\n\nNTSTATUS\nDriverEntry(\n\t_In_ PDRIVER_OBJECT  DriverObject,\n\t_In_ PUNICODE_STRING RegistryPath\n)\n{\n\tWDF_DRIVER_CONFIG config;\n\tNTSTATUS status;\n\tWDF_OBJECT_ATTRIBUTES attributes;\n\n\t// Initialize tracing\n\tDriverTraceInit(\n\t\tDriverObject,\n\t\tRegistryPath\n\t);\n\t\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION, \n\t\tTRACE_DRIVER, \n\t\t\"%!FUNC! Entry\"\n\t);\n\n\t//\n\t// Register a cleanup callback so that we can call WPP_CLEANUP when\n\t// the framework driver object is deleted during driver unload.\n\t//\n\tWDF_OBJECT_ATTRIBUTES_INIT(&attributes);\n\tattributes.EvtCleanupCallback = AmtPtpDeviceEvtDriverContextCleanup;\n\n\tWDF_DRIVER_CONFIG_INIT(&config,\n\t\tAmtPtpDeviceEvtDeviceAdd\n\t);\n\n\tstatus = WdfDriverCreate(DriverObject,\n\t\tRegistryPath,\n\t\t&attributes,\n\t\t&config,\n\t\tWDF_NO_HANDLE\n\t);\n\n\tif (!NT_SUCCESS(status)) {\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_ERROR, \n\t\t\tTRACE_DRIVER, \n\t\t\t\"%!FUNC! WdfDriverCreate failed %!STATUS!\", \n\t\t\tstatus\n\t\t);\n\t\tTraceLoggingWrite(\n\t\t\tg_hAmtPtpDeviceTraceProvider,\n\t\t\tEVENT_DRIVER_FUNCTIONAL,\n\t\t\tTraceLoggingString(\"DriverEntry\", \"Routine\"),\n\t\t\tTraceLoggingString(\"WdfDriverCreate\", \"Context\"),\n\t\t\tTraceLoggingInt32(status, \"Status\"),\n\t\t\tTraceLoggingString(EVENT_DRIVER_FUNC_SUBTYPE_CRITFAIL, EVENT_DRIVER_FUNC_SUBTYPE)\n\t\t);\n\t\tDriverTraceCleanup(DriverObject);\n\t\treturn status;\n\t}\n\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION,\n\t\tTRACE_DRIVER,\n\t\t\"%!FUNC! Exit\"\n\t);\n\n\treturn status;\n}\n\nVOID\nDriverTraceInit(\n\t_In_ PDRIVER_OBJECT  DriverObject,\n\t_In_ PUNICODE_STRING RegistryPath\n)\n{\n\t// Initialize WPP Tracing\n\tWPP_INIT_TRACING(\n\t\tDriverObject,\n\t\tRegistryPath\n\t);\n\n\t// Initialize TraceLogger Tracing\n\tTraceLoggingRegister(g_hAmtPtpDeviceTraceProvider);\n}\n\nVOID\nDriverTraceCleanup(\n\t_In_ WDFOBJECT DriverObject\n)\n{\n\tUNREFERENCED_PARAMETER(DriverObject);\n\n\tTraceLoggingUnregister(g_hAmtPtpDeviceTraceProvider);\n\t// This actually directly calls WppCleanupUm() in UMDF drivers\n\tWPP_CLEANUP(WdfDriverWdmGetDriverObject((WDFDRIVER) Driver));\n}\n\nNTSTATUS\nAmtPtpDeviceEvtDeviceAdd(\n\t_In_    WDFDRIVER       Driver,\n\t_Inout_ PWDFDEVICE_INIT DeviceInit\n)\n{\n\tNTSTATUS status = STATUS_SUCCESS;\n\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION, \n\t\tTRACE_DRIVER, \n\t\t\"%!FUNC! Entry\"\n\t);\n\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION,\n\t\tTRACE_DRIVER, \n\t\t\"%!FUNC! Set FDO driver filter\"\n\t);\n\n\tWdfFdoInitSetFilter(DeviceInit);\n\n\tstatus = AmtPtpCreateDevice(\n\t\tDriver, \n\t\tDeviceInit\n\t);\n\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION, \n\t\tTRACE_DRIVER, \n\t\t\"%!FUNC! Exit\"\n\t);\n\treturn status;\n}\n\nVOID\nAmtPtpDeviceEvtDriverContextCleanup(\n\t_In_ WDFOBJECT DriverObject\n)\n{\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION, \n\t\tTRACE_DRIVER, \n\t\t\"%!FUNC! Entry\"\n\t);\n\n\t//\n\t// Stop WPP Tracing\n\t//\n\tDriverTraceCleanup(DriverObject);\n}\n"
  },
  {
    "path": "src/AmtPtpDeviceUsbUm/Hid.c",
    "content": "// Hid.c: HID-related routine\n\n#include <driver.h>\n#include <StaticHidRegistry.h>\n#include \"Hid.tmh\"\n\n_IRQL_requires_(PASSIVE_LEVEL)\nNTSTATUS\nAmtPtpGetHidDescriptor(\n\t_In_ WDFDEVICE Device,\n\t_In_ WDFREQUEST Request\n)\n{\n\n\tNTSTATUS        status   = STATUS_SUCCESS;\n\tPDEVICE_CONTEXT pContext = DeviceGetContext(Device);\n\tsize_t\t\t\tszHidDescriptor = 0;\n\tWDFMEMORY       RequestMemory;\n\tPHID_DESCRIPTOR pSelectedHidDescriptor = NULL;\n\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION, \n\t\tTRACE_DRIVER, \n\t\t\"%!FUNC! Entry\"\n\t);\n\n\tstatus = WdfRequestRetrieveOutputMemory(\n\t\tRequest, \n\t\t&RequestMemory\n\t);\n\n\tif (!NT_SUCCESS(status)) {\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_ERROR, \n\t\t\tTRACE_DRIVER, \n\t\t\t\"%!FUNC! WdfRequestRetrieveOutputBuffer failed with %!STATUS!\", \n\t\t\tstatus\n\t\t);\n\t\treturn status;\n\t}\n\n\tswitch (pContext->DeviceDescriptor.idProduct) {\n\t\tcase USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI:\n\t\tcase USB_DEVICE_ID_APPLE_WELLSPRING3_ISO:\n\t\tcase USB_DEVICE_ID_APPLE_WELLSPRING3_JIS:\n\t\t{\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_INFORMATION,\n\t\t\t\tTRACE_DRIVER,\n\t\t\t\t\"%!FUNC! Request HID Report Descriptor for MacBook Family, Wellspring 3 Series\"\n\t\t\t);\n\n\t\t\tszHidDescriptor = AmtPtp3DefaultHidDescriptor.bLength;\n\t\t\tpSelectedHidDescriptor = &AmtPtp3DefaultHidDescriptor;\n\t\t\tbreak;\n\t\t}\n\t\tcase USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI:\n\t\tcase USB_DEVICE_ID_APPLE_WELLSPRING5_ISO:\n\t\tcase USB_DEVICE_ID_APPLE_WELLSPRING5_JIS:\n\t\tcase USB_DEVICE_ID_APPLE_WELLSPRING5A_ANSI:\n\t\tcase USB_DEVICE_ID_APPLE_WELLSPRING5A_ISO:\n\t\tcase USB_DEVICE_ID_APPLE_WELLSPRING5A_JIS:\n\t\t{\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_INFORMATION,\n\t\t\t\tTRACE_DRIVER,\n\t\t\t\t\"%!FUNC! Request HID Report Descriptor for MacBook Family, Wellspring 5/5A Series\"\n\t\t\t);\n\n\t\t\tszHidDescriptor = AmtPtp5DefaultHidDescriptor.bLength;\n\t\t\tpSelectedHidDescriptor = &AmtPtp5DefaultHidDescriptor;\n\t\t\tbreak;\n\t\t}\n\t\tcase USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI:\n\t\tcase USB_DEVICE_ID_APPLE_WELLSPRING6_ISO:\n\t\tcase USB_DEVICE_ID_APPLE_WELLSPRING6_JIS:\n\t\tcase USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI:\n\t\tcase USB_DEVICE_ID_APPLE_WELLSPRING6A_ISO:\n\t\tcase USB_DEVICE_ID_APPLE_WELLSPRING6A_JIS:\n\t\t{\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_INFORMATION,\n\t\t\t\tTRACE_DRIVER,\n\t\t\t\t\"%!FUNC! Request HID Report Descriptor for MacBook Family, Wellspring 6/6A Series\"\n\t\t\t);\n\n\t\t\tszHidDescriptor = AmtPtp6DefaultHidDescriptor.bLength;\n\t\t\tpSelectedHidDescriptor = &AmtPtp6DefaultHidDescriptor;\n\t\t\tbreak;\n\t\t}\n\t\tcase USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI:\n\t\tcase USB_DEVICE_ID_APPLE_WELLSPRING7_ISO:\n\t\tcase USB_DEVICE_ID_APPLE_WELLSPRING7_JIS:\n\t\tcase USB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI:\n\t\tcase USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO:\n\t\tcase USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS:\n\t\t{\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_INFORMATION,\n\t\t\t\tTRACE_DRIVER,\n\t\t\t\t\"%!FUNC! Request HID Report Descriptor for MacBook Family, Wellspring 7/7A Series\"\n\t\t\t);\n\n\t\t\tszHidDescriptor = AmtPtp7aDefaultHidDescriptor.bLength;\n\t\t\tpSelectedHidDescriptor = &AmtPtp7aDefaultHidDescriptor;\n\t\t\tbreak;\n\t\t}\n\t\tcase USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI:\n\t\tcase USB_DEVICE_ID_APPLE_WELLSPRING8_ISO:\n\t\tcase USB_DEVICE_ID_APPLE_WELLSPRING8_JIS:\n\t\tcase USB_DEVICE_ID_APPLE_WELLSPRING9_JIS:\n\t\tcase USB_DEVICE_ID_APPLE_WELLSPRING9_ANSI:\n\t\tcase USB_DEVICE_ID_APPLE_WELLSPRING9_ISO:\n\t\t{\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_INFORMATION,\n\t\t\t\tTRACE_DRIVER,\n\t\t\t\t\"%!FUNC! Request HID Report Descriptor for MacBook Family, Wellspring 8 Series\"\n\t\t\t);\n\n\t\t\tszHidDescriptor = AmtPtp8DefaultHidDescriptor.bLength;\n\t\t\tpSelectedHidDescriptor = &AmtPtp8DefaultHidDescriptor;\n\t\t\tbreak;\n\t\t}\n\t\tcase USB_DEVICE_ID_APPLE_MAGICTRACKPAD2:\n\t\t{\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_INFORMATION,\n\t\t\t\tTRACE_DRIVER,\n\t\t\t\t\"%!FUNC! Request HID Report Descriptor for Apple Magic Trackpad 2 Family\"\n\t\t\t);\n\n\t\t\tszHidDescriptor = AmtPtpMt2DefaultHidDescriptor.bLength;\n\t\t\tpSelectedHidDescriptor = &AmtPtpMt2DefaultHidDescriptor;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (pSelectedHidDescriptor != NULL && szHidDescriptor > 0) {\n\t\tstatus = WdfMemoryCopyFromBuffer(\n\t\t\tRequestMemory,\n\t\t\t0,\n\t\t\t(PVOID) pSelectedHidDescriptor,\n\t\t\tszHidDescriptor\n\t\t);\n\n\t\tif (!NT_SUCCESS(status)) {\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_ERROR,\n\t\t\t\tTRACE_DRIVER,\n\t\t\t\t\"%!FUNC! WdfMemoryCopyFromBuffer failed with %!STATUS!\",\n\t\t\t\tstatus\n\t\t\t);\n\t\t\tgoto exit;\n\t\t}\n\n\t\tWdfRequestSetInformation(\n\t\t\tRequest,\n\t\t\tszHidDescriptor\n\t\t);\n\t}\n\telse {\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_WARNING,\n\t\t\tTRACE_DRIVER,\n\t\t\t\"%!FUNC! Device HID registry is not found\"\n\t\t);\n\t\tTraceLoggingWrite(\n\t\t\tg_hAmtPtpDeviceTraceProvider,\n\t\t\tEVENT_DEVICE_IDENTIFICATION,\n\t\t\tTraceLoggingString(\"AmtPtpGetHidDescriptor\", \"Routine\"),\n\t\t\tTraceLoggingUInt16(pContext->DeviceDescriptor.idProduct, \"idProduct\"),\n\t\t\tTraceLoggingString(EVENT_DEVICE_ID_SUBTYPE_HIDREG_NOTFOUND, EVENT_DRIVER_FUNC_SUBTYPE)\n\t\t);\n\t\tstatus = STATUS_INVALID_DEVICE_STATE;\n\t\tgoto exit;\n\t}\n\nexit:\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION, \n\t\tTRACE_DRIVER, \n\t\t\"%!FUNC! Exit\"\n\t);\n\treturn status;\n}\n\n_IRQL_requires_(PASSIVE_LEVEL)\nNTSTATUS\nAmtPtpGetDeviceAttribs(\n\t_In_ WDFDEVICE Device,\n\t_In_ WDFREQUEST Request\n)\n{\n\n\tNTSTATUS               status = STATUS_SUCCESS;\n\tPDEVICE_CONTEXT        pContext = DeviceGetContext(Device);\n\tPHID_DEVICE_ATTRIBUTES pDeviceAttributes = NULL;\n\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION, \n\t\tTRACE_DRIVER, \n\t\t\"%!FUNC! Entry\"\n\t);\n\n\tstatus = WdfRequestRetrieveOutputBuffer(\n\t\tRequest, \n\t\tsizeof(HID_DEVICE_ATTRIBUTES), \n\t\t&pDeviceAttributes, \n\t\tNULL\n\t);\n\n\tif (!NT_SUCCESS(status)) {\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_ERROR, \n\t\t\tTRACE_DRIVER, \n\t\t\t\"%!FUNC! WdfRequestRetrieveOutputBuffer failed with %!STATUS!\", \n\t\t\tstatus\n\t\t);\n\t\tgoto exit;\n\t}\n\n\tpDeviceAttributes->Size          = sizeof(HID_DEVICE_ATTRIBUTES);\n\tpDeviceAttributes->ProductID     = pContext->DeviceDescriptor.idProduct;\n\t// Okay here's one thing: we cannot report the real ID here, otherwise there's will be some great conflict with the USB/BT driver.\n\t// Therefore Vendor ID is changed to a hardcoded number\n\tpDeviceAttributes->VendorID      = DEVICE_VID;\n\tpDeviceAttributes->VersionNumber = DEVICE_VERSION;\n\t\n\tWdfRequestSetInformation(\n\t\tRequest, \n\t\tsizeof(HID_DEVICE_ATTRIBUTES)\n\t);\n\nexit:\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION, \n\t\tTRACE_DRIVER, \n\t\t\"%!FUNC! Exit\"\n\t);\n\n\treturn status;\n}\n\n_IRQL_requires_(PASSIVE_LEVEL)\nNTSTATUS\nAmtPtpGetReportDescriptor(\n\t_In_ WDFDEVICE Device,\n\t_In_ WDFREQUEST Request\n)\n{\n\t\n\tNTSTATUS               status = STATUS_SUCCESS;\n\tPDEVICE_CONTEXT        pContext = DeviceGetContext(Device);\n\tsize_t\t\t\t       szHidDescriptor = 0;\n\tWDFMEMORY              RequestMemory;\n\tPHID_REPORT_DESCRIPTOR pSelectedHidDescriptor = NULL;\n\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION, \n\t\tTRACE_DRIVER, \n\t\t\"%!FUNC! Entry\"\n\t);\n\n\tstatus = WdfRequestRetrieveOutputMemory(\n\t\tRequest, \n\t\t&RequestMemory\n\t);\n\n\tif (!NT_SUCCESS(status)) {\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_ERROR, \n\t\t\tTRACE_DRIVER, \n\t\t\t\"%!FUNC! WdfRequestRetrieveOutputBuffer failed with %!STATUS!\", \n\t\t\tstatus\n\t\t);\n\t\tgoto exit;\n\t}\n\n\tswitch (pContext->DeviceDescriptor.idProduct) {\n\t\tcase USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI:\n\t\tcase USB_DEVICE_ID_APPLE_WELLSPRING3_ISO:\n\t\tcase USB_DEVICE_ID_APPLE_WELLSPRING3_JIS:\n\t\t{\n\t\t\tszHidDescriptor = AmtPtp3DefaultHidDescriptor.DescriptorList[0].wReportLength;\n\t\t\tpSelectedHidDescriptor = AmtPtp3ReportDescriptor;\n\t\t\tbreak;\n\t\t}\n\t\tcase USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI:\n\t\tcase USB_DEVICE_ID_APPLE_WELLSPRING5_ISO:\n\t\tcase USB_DEVICE_ID_APPLE_WELLSPRING5_JIS:\n\t\tcase USB_DEVICE_ID_APPLE_WELLSPRING5A_ANSI:\n\t\tcase USB_DEVICE_ID_APPLE_WELLSPRING5A_ISO:\n\t\tcase USB_DEVICE_ID_APPLE_WELLSPRING5A_JIS:\n\t\t{\n\t\t\tszHidDescriptor = AmtPtp5DefaultHidDescriptor.DescriptorList[0].wReportLength;\n\t\t\tpSelectedHidDescriptor = AmtPtp5ReportDescriptor;\n\t\t\tbreak;\n\t\t}\n\t\tcase USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI:\n\t\tcase USB_DEVICE_ID_APPLE_WELLSPRING6_ISO:\n\t\tcase USB_DEVICE_ID_APPLE_WELLSPRING6_JIS:\n\t\tcase USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI:\n\t\tcase USB_DEVICE_ID_APPLE_WELLSPRING6A_ISO:\n\t\tcase USB_DEVICE_ID_APPLE_WELLSPRING6A_JIS:\n\t\t{\n\t\t\tszHidDescriptor = AmtPtp6DefaultHidDescriptor.DescriptorList[0].wReportLength;\n\t\t\tpSelectedHidDescriptor = AmtPtp6ReportDescriptor;\n\t\t\tbreak;\n\t\t}\n\t\tcase USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI:\n\t\tcase USB_DEVICE_ID_APPLE_WELLSPRING7_ISO:\n\t\tcase USB_DEVICE_ID_APPLE_WELLSPRING7_JIS:\n\t\tcase USB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI:\n\t\tcase USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO:\n\t\tcase USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS:\n\t\t{\n\t\t\tszHidDescriptor = AmtPtp7aDefaultHidDescriptor.DescriptorList[0].wReportLength;\n\t\t\tpSelectedHidDescriptor = AmtPtp7aReportDescriptor;\n\t\t\tbreak;\n\t\t}\n\t\tcase USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI:\n\t\tcase USB_DEVICE_ID_APPLE_WELLSPRING8_ISO:\n\t\tcase USB_DEVICE_ID_APPLE_WELLSPRING8_JIS:\n\t\tcase USB_DEVICE_ID_APPLE_WELLSPRING9_JIS:\n\t\tcase USB_DEVICE_ID_APPLE_WELLSPRING9_ANSI:\n\t\tcase USB_DEVICE_ID_APPLE_WELLSPRING9_ISO:\n\t\t{\n\t\t\tszHidDescriptor = AmtPtp8DefaultHidDescriptor.DescriptorList[0].wReportLength;\n\t\t\tpSelectedHidDescriptor = AmtPtp8ReportDescriptor;\n\t\t\tbreak;\n\t\t}\n\t\tcase USB_DEVICE_ID_APPLE_MAGICTRACKPAD2:\n\t\t{\n\t\t\tszHidDescriptor = AmtPtpMt2DefaultHidDescriptor.DescriptorList[0].wReportLength;\n\t\t\tpSelectedHidDescriptor = AmtPtpMt2ReportDescriptor;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (pSelectedHidDescriptor != NULL && szHidDescriptor > 0) {\n\t\tstatus = WdfMemoryCopyFromBuffer(\n\t\t\tRequestMemory,\n\t\t\t0,\n\t\t\t(PVOID) pSelectedHidDescriptor,\n\t\t\tszHidDescriptor\n\t\t);\n\n\t\tif (!NT_SUCCESS(status)) {\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_ERROR,\n\t\t\t\tTRACE_DRIVER,\n\t\t\t\t\"%!FUNC! WdfMemoryCopyFromBuffer failed with %!STATUS!\",\n\t\t\t\tstatus\n\t\t\t);\n\t\t\treturn status;\n\t\t}\n\n\t\tWdfRequestSetInformation(\n\t\t\tRequest,\n\t\t\tszHidDescriptor\n\t\t);\n\t}\n\telse if (szHidDescriptor == 0) {\n\t\tstatus = STATUS_INVALID_DEVICE_STATE;\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_WARNING,\n\t\t\tTRACE_DRIVER,\n\t\t\t\"%!FUNC! Device HID report length is zero\"\n\t\t);\n\t\tgoto exit;\n\t}\n\telse {\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_WARNING,\n\t\t\tTRACE_DRIVER,\n\t\t\t\"%!FUNC! Device HID registry is not found\"\n\t\t);\n\t\tTraceLoggingWrite(\n\t\t\tg_hAmtPtpDeviceTraceProvider,\n\t\t\tEVENT_DEVICE_IDENTIFICATION,\n\t\t\tTraceLoggingString(\"AmtPtpGetReportDescriptor\", \"Routine\"),\n\t\t\tTraceLoggingUInt16(pContext->DeviceDescriptor.idProduct, \"idProduct\"),\n\t\t\tTraceLoggingString(EVENT_DEVICE_ID_SUBTYPE_HIDREG_NOTFOUND, EVENT_DRIVER_FUNC_SUBTYPE)\n\t\t);\n\t\tstatus = STATUS_INVALID_DEVICE_STATE;\n\t\tgoto exit;\n\t}\n\nexit:\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION, \n\t\tTRACE_DRIVER, \n\t\t\"%!FUNC! Exit\"\n\t);\n\treturn status;\n}\n\n_IRQL_requires_(PASSIVE_LEVEL)\nNTSTATUS\nAmtPtpGetStrings(\n\t_In_ WDFDEVICE Device,\n\t_In_ WDFREQUEST Request\n)\n{\n\t\n\tNTSTATUS               status = STATUS_SUCCESS;\n\tPDEVICE_CONTEXT        pContext = DeviceGetContext(Device);\n\tvoid                   *pStringBuffer = NULL;\n\tWDFMEMORY              memHandle;\n\tUSHORT                 wcharCount;\n\tsize_t                 actualSize;\n\tUCHAR                  strIndex;\n\n\tULONG                  inputValue;\n\tWDFMEMORY              inputMemory;\n\tsize_t                 inputBufferLength;\n\tPVOID                  inputBuffer;\n\tULONG                  languageId, stringId;\n\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION, \n\t\tTRACE_DRIVER, \n\t\t\"%!FUNC! Entry\"\n\t);\n\n\tstatus = WdfRequestRetrieveInputMemory(\n\t\tRequest, \n\t\t&inputMemory\n\t);\n\n\tif (!NT_SUCCESS(status)) {\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_INFORMATION,\n\t\t\tTRACE_DRIVER, \n\t\t\t\"%!FUNC! WdfRequestRetrieveInputMemory failed with status %!STATUS!\",\n\t\t\tstatus\n\t\t);\n\t\treturn status;\n\t}\n\n\tinputBuffer = WdfMemoryGetBuffer(\n\t\tinputMemory, \n\t\t&inputBufferLength\n\t);\n\n\t//\n\t// make sure buffer is big enough.\n\t//\n\tif (inputBufferLength < sizeof(ULONG)) {\n\t\tstatus = STATUS_INVALID_BUFFER_SIZE;\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_INFORMATION, \n\t\t\tTRACE_DRIVER, \n\t\t\t\"%!FUNC! GetStringId: invalid input buffer. size %d, expect %d\",\n\t\t\t(int)inputBufferLength, \n\t\t\t(int) sizeof(ULONG)\n\t\t);\n\t\treturn status;\n\t}\n\n\tinputValue = (*(PULONG)inputBuffer);\n\tstringId = (inputValue & 0x0ffff);\n\tlanguageId = (inputValue >> 16);\n\n\t// Get actual string from USB device\n\tswitch (stringId)\n\t{\n\t\tcase HID_STRING_ID_IMANUFACTURER:\n\t\t\tstrIndex = pContext->DeviceDescriptor.iManufacturer;\n\t\t\tbreak;\n\t\tcase HID_STRING_ID_IPRODUCT:\n\t\t\tstrIndex = pContext->DeviceDescriptor.iProduct;\n\t\t\tbreak;\n\t\tcase HID_STRING_ID_ISERIALNUMBER:\n\t\t\tstrIndex = pContext->DeviceDescriptor.iSerialNumber;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_WARNING, \n\t\t\t\tTRACE_DRIVER, \n\t\t\t\t\"%!FUNC! gets invalid string type\"\n\t\t\t);\n\t\t\treturn status;\n\t}\n\n\tstatus = WdfUsbTargetDeviceAllocAndQueryString(\n\t\tpContext->UsbDevice, \n\t\tWDF_NO_OBJECT_ATTRIBUTES, \n\t\t&memHandle, \n\t\t&wcharCount, \n\t\tstrIndex, \n\t\t(USHORT) languageId\n\t);\n\n\tif (!NT_SUCCESS(status)) {\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_ERROR, \n\t\t\tTRACE_DRIVER, \"%!FUNC! WdfUsbTargetDeviceAllocAndQueryString failed with %!STATUS!\", \n\t\t\tstatus\n\t\t);\n\t\treturn status;\n\t}\n\n\tstatus = WdfRequestRetrieveOutputBuffer(\n\t\tRequest, \n\t\twcharCount * sizeof(WCHAR), \n\t\t&pStringBuffer, \n\t\t&actualSize\n\t);\n\n\tif (!NT_SUCCESS(status)) {\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_ERROR, \n\t\t\tTRACE_DRIVER, \n\t\t\t\"%!FUNC! WdfMemoryCopyFromBuffer failed with %!STATUS!\", \n\t\t\tstatus\n\t\t);\n\t\treturn status;\n\t}\n\n\tWdfMemoryCopyToBuffer(\n\t\tmemHandle,\n\t\t0, \n\t\t&pStringBuffer, \n\t\tactualSize\n\t);\n\n\tWdfRequestSetInformation(\n\t\tRequest, \n\t\tactualSize\n\t);\n\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION, \n\t\tTRACE_DRIVER, \n\t\t\"%!FUNC! Exit\"\n\t);\n\treturn status;\n\n}\n\n_IRQL_requires_(PASSIVE_LEVEL)\nNTSTATUS\nRequestGetHidXferPacketToReadFromDevice(\n\t_In_  WDFREQUEST        Request,\n\t_Out_ HID_XFER_PACKET  *Packet\n)\n{\n\n\t//\n\t// Driver need to write to the output buffer (so that App can read from it)\n\t//\n\t//   Report Buffer: Output Buffer\n\t//   Report Id    : Input Buffer\n\t//\n\n\tNTSTATUS                status;\n\tWDFMEMORY               inputMemory;\n\tWDFMEMORY               outputMemory;\n\tsize_t                  inputBufferLength;\n\tsize_t                  outputBufferLength;\n\tPVOID                   inputBuffer;\n\tPVOID                   outputBuffer;\n\n\t//\n\t// Get report Id from input buffer\n\t//\n\tstatus = WdfRequestRetrieveInputMemory(\n\t\tRequest, \n\t\t&inputMemory\n\t);\n\n\tif (!NT_SUCCESS(status)) {\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_ERROR, \n\t\t\tTRACE_DRIVER, \n\t\t\t\"%!FUNC! WdfRequestRetrieveInputMemory failed with %!STATUS!\", \n\t\t\tstatus\n\t\t);\n\t\treturn status;\n\t}\n\tinputBuffer = WdfMemoryGetBuffer(\n\t\tinputMemory, \n\t\t&inputBufferLength\n\t);\n\n\tif (inputBufferLength < sizeof(UCHAR)) {\n\t\tstatus = STATUS_INVALID_BUFFER_SIZE;\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_ERROR,\n\t\t\tTRACE_DRIVER,\n\t\t\t\"%!FUNC! WdfRequestRetrieveInputMemory: invalid input buffer. size %d, expect %d\",\n\t\t\t(int) inputBufferLength, \n\t\t\t(int) sizeof(UCHAR)\n\t\t);\n\t\treturn status;\n\t}\n\n\tPacket->reportId = *(PUCHAR) inputBuffer;\n\n\t//\n\t// Get report buffer from output buffer\n\t//\n\tstatus = WdfRequestRetrieveOutputMemory(\n\t\tRequest, \n\t\t&outputMemory\n\t);\n\n\tif (!NT_SUCCESS(status)) {\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_ERROR,\n\t\t\tTRACE_DRIVER,\n\t\t\t\"%!FUNC! WdfRequestRetrieveOutputMemory failed with %!STATUS!\",\n\t\t\tstatus\n\t\t);\n\t\treturn status;\n\t}\n\n\toutputBuffer = WdfMemoryGetBuffer(\n\t\toutputMemory, \n\t\t&outputBufferLength\n\t);\n\n\tPacket->reportBuffer = (PUCHAR) outputBuffer;\n\tPacket->reportBufferLen = (ULONG) outputBufferLength;\n\n\treturn status;\n\n}\n\n_IRQL_requires_(PASSIVE_LEVEL)\nNTSTATUS\nRequestGetHidXferPacketToWriteToDevice(\n\t_In_  WDFREQUEST        Request,\n\t_Out_ HID_XFER_PACKET  *Packet\n)\n{\n\n\t//\n\t// Driver need to read from the input buffer (which was written by App)\n\t//\n\t//   Report Buffer: Input Buffer\n\t//   Report Id    : Output Buffer Length\n\t//\n\t// Note that the report id is not stored inside the output buffer, as the\n\t// driver has no read-access right to the output buffer, and trying to read\n\t// from the buffer will cause an access violation error.\n\t//\n\t// The workaround is to store the report id in the OutputBufferLength field,\n\t// to which the driver does have read-access right.\n\t//\n\n\tNTSTATUS                status;\n\tWDFMEMORY               inputMemory;\n\tWDFMEMORY               outputMemory;\n\tsize_t                  inputBufferLength;\n\tsize_t                  outputBufferLength;\n\tPVOID                   inputBuffer;\n\n\t//\n\t// Get report Id from output buffer length\n\t//\n\tstatus = WdfRequestRetrieveOutputMemory(\n\t\tRequest, \n\t\t&outputMemory\n\t);\n\tif (!NT_SUCCESS(status)) {\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_ERROR,\n\t\t\tTRACE_DRIVER,\n\t\t\t\"%!FUNC! WdfRequestRetrieveOutputMemory failed with %!STATUS!\",\n\t\t\tstatus\n\t\t);\n\t\treturn status;\n\t}\n\tWdfMemoryGetBuffer(\n\t\toutputMemory, \n\t\t&outputBufferLength\n\t);\n\tPacket->reportId = (UCHAR) outputBufferLength;\n\n\t//\n\t// Get report buffer from input buffer\n\t//\n\tstatus = WdfRequestRetrieveInputMemory(\n\t\tRequest, \n\t\t&inputMemory\n\t);\n\tif (!NT_SUCCESS(status)) {\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_ERROR,\n\t\t\tTRACE_DRIVER,\n\t\t\t\"%!FUNC! WdfRequestRetrieveInputMemory failed with %!STATUS!\",\n\t\t\tstatus\n\t\t);\n\t\treturn status;\n\t}\n\tinputBuffer = WdfMemoryGetBuffer(\n\t\tinputMemory, \n\t\t&inputBufferLength\n\t);\n\n\tPacket->reportBuffer = (PUCHAR) inputBuffer;\n\tPacket->reportBufferLen = (ULONG) inputBufferLength;\n\n\treturn status;\n\n}\n\n_IRQL_requires_(PASSIVE_LEVEL)\nNTSTATUS\nAmtPtpReportFeatures(\n\t_In_ WDFDEVICE Device,\n\t_In_ WDFREQUEST Request\n)\n{\n\n\tNTSTATUS status;\n\tPDEVICE_CONTEXT deviceContext;\n\tHID_XFER_PACKET packet;\n\tsize_t reportSize;\n\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION, \n\t\tTRACE_DRIVER, \n\t\t\"%!FUNC! Entry\"\n\t);\n\n\tstatus = STATUS_SUCCESS;\n\tdeviceContext = DeviceGetContext(Device);\n\n\tstatus = RequestGetHidXferPacketToReadFromDevice(\n\t\tRequest, \n\t\t&packet\n\t);\n\n\tif (!NT_SUCCESS(status)) {\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_ERROR, \n\t\t\tTRACE_DRIVER, \n\t\t\t\"%!FUNC! RequestGetHidXferPacketToReadFromDevice failed with status %!STATUS!\", \n\t\t\tstatus\n\t\t);\n\t\tgoto exit;\n\t}\n\n\tswitch (packet.reportId)\n\t{\n\t\tcase REPORTID_DEVICE_CAPS:\n\t\t{\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_INFORMATION, \n\t\t\t\tTRACE_DRIVER, \n\t\t\t\t\"%!FUNC! Report REPORTID_DEVICE_CAPS is requested\"\n\t\t\t);\n\n\t\t\t// Size sanity check\n\t\t\treportSize = sizeof(PTP_DEVICE_CAPS_FEATURE_REPORT);\n\t\t\tif (packet.reportBufferLen < reportSize) {\n\t\t\t\tstatus = STATUS_INVALID_BUFFER_SIZE;\n\t\t\t\tTraceEvents(\n\t\t\t\t\tTRACE_LEVEL_ERROR, \n\t\t\t\t\tTRACE_DRIVER, \n\t\t\t\t\t\"%!FUNC! Report buffer is too small\"\n\t\t\t\t);\n\t\t\t\tgoto exit;\n\t\t\t}\n\n\t\t\tPPTP_DEVICE_CAPS_FEATURE_REPORT capsReport = (PPTP_DEVICE_CAPS_FEATURE_REPORT) packet.reportBuffer;\n\n\t\t\tcapsReport->MaximumContactPoints = PTP_MAX_CONTACT_POINTS;\n\t\t\tcapsReport->ButtonType = PTP_BUTTON_TYPE_CLICK_PAD;\n\t\t\tcapsReport->ReportID = REPORTID_DEVICE_CAPS;\n\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_INFORMATION, \n\t\t\t\tTRACE_DRIVER, \n\t\t\t\t\"%!FUNC! Report REPORTID_DEVICE_CAPS has maximum contact points of %d\", \n\t\t\t\tcapsReport->MaximumContactPoints\n\t\t\t);\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_INFORMATION, \n\t\t\t\tTRACE_DRIVER, \n\t\t\t\t\"%!FUNC! Report REPORTID_DEVICE_CAPS has touchpad type %d\", \n\t\t\t\tcapsReport->ButtonType\n\t\t\t);\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_INFORMATION, \n\t\t\t\tTRACE_DRIVER, \n\t\t\t\t\"%!FUNC! Report REPORTID_DEVICE_CAPS is fulfilled\"\n\t\t\t);\n\n\t\t\tWdfRequestSetInformation(\n\t\t\t\tRequest, \n\t\t\t\treportSize\n\t\t\t);\n\t\t\tbreak;\n\t\t}\n\t\tcase REPORTID_PTPHQA:\n\t\t{\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_INFORMATION, \n\t\t\t\tTRACE_DRIVER, \n\t\t\t\t\"%!FUNC! Report REPORTID_PTPHQA is requested\"\n\t\t\t);\n\n\t\t\t// Size sanity check\n\t\t\treportSize = sizeof(PTP_DEVICE_HQA_CERTIFICATION_REPORT);\n\t\t\tif (packet.reportBufferLen < reportSize) {\n\t\t\t\tstatus = STATUS_INVALID_BUFFER_SIZE;\n\t\t\t\tTraceEvents(\n\t\t\t\t\tTRACE_LEVEL_ERROR, \n\t\t\t\t\tTRACE_DRIVER, \n\t\t\t\t\t\"%!FUNC! Report buffer is too small.\"\n\t\t\t\t);\n\t\t\t\tgoto exit;\n\t\t\t}\n\n\t\t\tPPTP_DEVICE_HQA_CERTIFICATION_REPORT certReport = (PPTP_DEVICE_HQA_CERTIFICATION_REPORT) packet.reportBuffer;\n\n\t\t\t*certReport->CertificationBlob = DEFAULT_PTP_HQA_BLOB;\n\t\t\tcertReport->ReportID = REPORTID_PTPHQA;\n\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_INFORMATION, \n\t\t\t\tTRACE_DRIVER, \n\t\t\t\t\"%!FUNC! Report REPORTID_PTPHQA is fulfilled\"\n\t\t\t);\n\n\t\t\tWdfRequestSetInformation(\n\t\t\t\tRequest, \n\t\t\t\treportSize\n\t\t\t);\n\t\t\tbreak;\n\t\t}\n\t\tcase REPORTID_UMAPP_CONF:\n\t\t{\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_INFORMATION,\n\t\t\t\tTRACE_DRIVER,\n\t\t\t\t\"%!FUNC! Report REPORTID_UMAPP_CONF is requested\"\n\t\t\t);\n\n\t\t\t// Size sanity check\n\t\t\treportSize = sizeof(PTP_USERMODEAPP_CONF_REPORT);\n\t\t\tif (packet.reportBufferLen < reportSize) {\n\t\t\t\tstatus = STATUS_INVALID_BUFFER_SIZE;\n\t\t\t\tTraceEvents(\n\t\t\t\t\tTRACE_LEVEL_ERROR,\n\t\t\t\t\tTRACE_DRIVER,\n\t\t\t\t\t\"%!FUNC! Report buffer is too small.\"\n\t\t\t\t);\n\t\t\t\tgoto exit;\n\t\t\t}\n\n\t\t\tPPTP_USERMODEAPP_CONF_REPORT confReport = (PPTP_USERMODEAPP_CONF_REPORT)packet.reportBuffer;\n\t\t\t\n\t\t\tconfReport->ReportID = REPORTID_UMAPP_CONF;\n\t\t\tconfReport->MultipleContactSizeQualificationLevel = deviceContext->MuContactSizeQualLevel;\n\t\t\tconfReport->SingleContactSizeQualificationLevel = deviceContext->SgContactSizeQualLevel;\n\t\t\tconfReport->PressureQualificationLevel = deviceContext->PressureQualLevel;\n\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_INFORMATION,\n\t\t\t\tTRACE_DRIVER,\n\t\t\t\t\"%!FUNC! Report REPORTID_UMAPP_CONF is fulfilled\"\n\t\t\t);\n\n\t\t\tWdfRequestSetInformation(\n\t\t\t\tRequest,\n\t\t\t\treportSize\n\t\t\t);\n\t\t\tbreak;\n\t\t}\n\t\tdefault:\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_INFORMATION, \n\t\t\t\tTRACE_DRIVER, \n\t\t\t\t\"%!FUNC! Unsupported type %d is requested\", \n\t\t\t\tpacket.reportId\n\t\t\t);\n\n\t\t\tstatus = STATUS_NOT_SUPPORTED;\n\t\t\tgoto exit;\n\t}\nexit:\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION, \n\t\tTRACE_DRIVER, \n\t\t\"%!FUNC! Exit\"\n\t);\n\treturn status;\n\n}\n\n_IRQL_requires_(PASSIVE_LEVEL)\nNTSTATUS\nAmtPtpSetFeatures(\n\t_In_ WDFDEVICE Device,\n\t_In_ WDFREQUEST Request\n)\n{\n\n\tNTSTATUS        status;\n\tHID_XFER_PACKET packet;\n\tPDEVICE_CONTEXT deviceContext;\n\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION, \n\t\tTRACE_DRIVER, \n\t\t\"%!FUNC! Entry\"\n\t);\n\n\tstatus = STATUS_SUCCESS;\n\tdeviceContext = DeviceGetContext(Device);\n\n\tstatus = RequestGetHidXferPacketToWriteToDevice(\n\t\tRequest, \n\t\t&packet\n\t);\n\n\tif (!NT_SUCCESS(status)) {\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_ERROR, \n\t\t\tTRACE_DRIVER, \n\t\t\t\"%!FUNC! RequestGetHidXferPacketToWriteToDevice failed with status %!STATUS!\", \n\t\t\tstatus\n\t\t);\n\t\tgoto exit;\n\t}\n\n\tswitch (packet.reportId)\n\t{\n\t\tcase REPORTID_REPORTMODE:\n\t\t{\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_INFORMATION, \n\t\t\t\tTRACE_DRIVER, \n\t\t\t\t\"%!FUNC! Report REPORTID_REPORTMODE is requested\"\n\t\t\t);\n\n\t\t\tPPTP_DEVICE_INPUT_MODE_REPORT devInputMode = (PPTP_DEVICE_INPUT_MODE_REPORT) packet.reportBuffer;\n\n\t\t\t// Get current WellSpring mode\n\t\t\tBOOL bWellspringMode = FALSE;\n\t\t\tstatus = AmtPtpGetWellspringMode(\n\t\t\t\tdeviceContext,\n\t\t\t\t&bWellspringMode\n\t\t\t);\n\n\t\t\tif (!NT_SUCCESS(status)) {\n\n\t\t\t\tTraceEvents(\n\t\t\t\t\tTRACE_LEVEL_ERROR,\n\t\t\t\t\tTRACE_DRIVER,\n\t\t\t\t\t\"%!FUNC! -> AmtPtpGetWellspringMode failed with status %!STATUS!\",\n\t\t\t\t\tstatus\n\t\t\t\t);\n\t\t\t\tgoto exit;\n\n\t\t\t}\n\n\t\t\tswitch (devInputMode->Mode)\n\t\t\t{\n\t\t\t\tcase PTP_COLLECTION_MOUSE:\n\t\t\t\t{\n\n\t\t\t\t\tTraceEvents(\n\t\t\t\t\t\tTRACE_LEVEL_INFORMATION,\n\t\t\t\t\t\tTRACE_DRIVER,\n\t\t\t\t\t\t\"%!FUNC! Report REPORTID_REPORTMODE requested Mouse Input\"\n\t\t\t\t\t);\n\n\t\t\t\t\tif (bWellspringMode) {\n\n\t\t\t\t\t\tstatus = AmtPtpSetWellspringMode(\n\t\t\t\t\t\t\tdeviceContext,\n\t\t\t\t\t\t\tFALSE\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\tif (!NT_SUCCESS(status)) {\n\t\t\t\t\t\t\tTraceEvents(\n\t\t\t\t\t\t\t\tTRACE_LEVEL_ERROR,\n\t\t\t\t\t\t\t\tTRACE_DRIVER,\n\t\t\t\t\t\t\t\t\"%!FUNC! -> AmtPtpSetWellspringMode failed with status %!STATUS!\",\n\t\t\t\t\t\t\t\tstatus\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tgoto exit;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\t\t\t\t\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\t\t\t\tcase PTP_COLLECTION_WINDOWS:\n\t\t\t\t{\n\n\t\t\t\t\tTraceEvents(\n\t\t\t\t\t\tTRACE_LEVEL_INFORMATION,\n\t\t\t\t\t\tTRACE_DRIVER,\n\t\t\t\t\t\t\"%!FUNC! Report REPORTID_REPORTMODE requested Windows PTP Input\"\n\t\t\t\t\t);\n\n\t\t\t\t\tif (!bWellspringMode) {\n\t\t\t\t\t\t\n\t\t\t\t\t\tstatus = AmtPtpSetWellspringMode(\n\t\t\t\t\t\t\tdeviceContext,\n\t\t\t\t\t\t\tTRUE\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\tif (!NT_SUCCESS(status)) {\n\t\t\t\t\t\t\tTraceEvents(\n\t\t\t\t\t\t\t\tTRACE_LEVEL_ERROR,\n\t\t\t\t\t\t\t\tTRACE_DRIVER,\n\t\t\t\t\t\t\t\t\"%!FUNC! -> AmtPtpSetWellspringMode failed with status %!STATUS!\",\n\t\t\t\t\t\t\t\tstatus\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tgoto exit;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tWdfRequestSetInformation(\n\t\t\t\tRequest, \n\t\t\t\tsizeof(PTP_DEVICE_INPUT_MODE_REPORT)\n\t\t\t);\n\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_INFORMATION, \n\t\t\t\tTRACE_DRIVER, \n\t\t\t\t\"%!FUNC! Report REPORTID_REPORTMODE is fulfilled\"\n\t\t\t);\n\t\t\tbreak;\n\t\t}\n\t\tcase REPORTID_FUNCSWITCH:\n\t\t{\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_INFORMATION, \n\t\t\t\tTRACE_DRIVER, \n\t\t\t\t\"%!FUNC! Report REPORTID_FUNCSWITCH is requested\"\n\t\t\t);\n\t\t\tPPTP_DEVICE_SELECTIVE_REPORT_MODE_REPORT secInput = (PPTP_DEVICE_SELECTIVE_REPORT_MODE_REPORT) packet.reportBuffer;\n\n\t\t\tdeviceContext->IsButtonReportOn = secInput->ButtonReport;\n\t\t\tdeviceContext->IsSurfaceReportOn = secInput->SurfaceReport;\n\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_INFORMATION, \n\t\t\t\tTRACE_DRIVER, \n\t\t\t\t\"%!FUNC! Report REPORTID_FUNCSWITCH requested Button = %d, Surface = %d\",\n\t\t\t\tsecInput->ButtonReport, \n\t\t\t\tsecInput->SurfaceReport\n\t\t\t);\n\n\t\t\tWdfRequestSetInformation(\n\t\t\t\tRequest,\n\t\t\t\tsizeof(PTP_DEVICE_SELECTIVE_REPORT_MODE_REPORT)\n\t\t\t);\n\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_INFORMATION,\n\t\t\t\tTRACE_DRIVER, \n\t\t\t\t\"%!FUNC! Report REPORTID_FUNCSWITCH is fulfilled\"\n\t\t\t);\n\t\t\tbreak;\n\t\t}\n\t\tcase REPORTID_UMAPP_CONF:\n\t\t{\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_INFORMATION,\n\t\t\t\tTRACE_DRIVER,\n\t\t\t\t\"%!FUNC! Report REPORTID_UMAPP_CONF is requested\"\n\t\t\t);\n\t\t\tPPTP_USERMODEAPP_CONF_REPORT umConfInput = (PPTP_USERMODEAPP_CONF_REPORT) packet.reportBuffer;\n\n\t\t\t// Set value\n\t\t\tdeviceContext->SgContactSizeQualLevel = umConfInput->SingleContactSizeQualificationLevel;\n\t\t\tdeviceContext->MuContactSizeQualLevel = umConfInput->MultipleContactSizeQualificationLevel;\n\t\t\tdeviceContext->PressureQualLevel = umConfInput->PressureQualificationLevel;\n\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_INFORMATION,\n\t\t\t\tTRACE_DRIVER,\n\t\t\t\t\"%!FUNC! Report REPORTID_UMAPP_CONF requested PressureQual = %d, SgSize = %d, MuSize = %d\",\n\t\t\t\tumConfInput->PressureQualificationLevel,\n\t\t\t\tumConfInput->SingleContactSizeQualificationLevel,\n\t\t\t\tumConfInput->MultipleContactSizeQualificationLevel\n\t\t\t);\n\n\t\t\t// Report back\n\t\t\tWdfRequestSetInformation(\n\t\t\t\tRequest,\n\t\t\t\tsizeof(PTP_USERMODEAPP_CONF_REPORT)\n\t\t\t);\n\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_INFORMATION,\n\t\t\t\tTRACE_DRIVER,\n\t\t\t\t\"%!FUNC! Report REPORTID_UMAPP_CONF is fulfilled\"\n\t\t\t);\n\n\t\t\tbreak;\n\t\t}\n\t\tdefault:\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_INFORMATION, \n\t\t\t\tTRACE_DRIVER, \n\t\t\t\t\"%!FUNC! Unsupported type %d is requested\",\n\t\t\t\tpacket.reportId\n\t\t\t);\n\t\t\tstatus = STATUS_NOT_SUPPORTED;\n\t\t\tgoto exit;\n\t}\n\nexit:\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION, \n\t\tTRACE_DRIVER, \n\t\t\"%!FUNC! Exit\"\n\t);\n\treturn STATUS_SUCCESS;\n\n}"
  },
  {
    "path": "src/AmtPtpDeviceUsbUm/InputInterrupt.c",
    "content": "// InputInterrupt.c: Handles device input event\n\n#include <driver.h>\n#include \"InputInterrupt.tmh\"\n\n_IRQL_requires_(PASSIVE_LEVEL)\nNTSTATUS\nAmtPtpConfigContReaderForInterruptEndPoint(\n\t_In_ PDEVICE_CONTEXT DeviceContext\n)\n{\n\n\tWDF_USB_CONTINUOUS_READER_CONFIG contReaderConfig;\n\tNTSTATUS status;\n\tsize_t transferLength = 0;\n\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION,\n\t\tTRACE_DRIVER,\n\t\t\"%!FUNC! Entry\"\n\t);\n\n\tswitch (DeviceContext->DeviceInfo->tp_type)\n\t{\n\t\tcase TYPE1:\n\t\t\ttransferLength = HEADER_TYPE1 + FSIZE_TYPE1 * MAX_FINGERS;\n\t\t\tbreak;\n\t\tcase TYPE2:\n\t\t\ttransferLength = HEADER_TYPE2 + FSIZE_TYPE2 * MAX_FINGERS;\n\t\t\tbreak;\n\t\tcase TYPE3:\n\t\t\ttransferLength = HEADER_TYPE3 + FSIZE_TYPE3 * MAX_FINGERS;\n\t\t\tbreak;\n\t\tcase TYPE4:\n\t\t\ttransferLength = HEADER_TYPE4 + FSIZE_TYPE4 * MAX_FINGERS;\n\t\t\tbreak;\n\t\tcase TYPE5:\n\t\t\ttransferLength = HEADER_TYPE5 + FSIZE_TYPE5 * MAX_FINGERS;\n\t\t\tbreak;\n\t}\n\n\tif (transferLength <= 0) {\n\t\tstatus = STATUS_UNKNOWN_REVISION;\n\t\treturn status;\n\t}\n\n\tWDF_USB_CONTINUOUS_READER_CONFIG_INIT(\n\t\t&contReaderConfig,\n\t\tAmtPtpEvtUsbInterruptPipeReadComplete,\n\t\tDeviceContext,\t\t// Context\n\t\ttransferLength\t\t// Calculate transferred length by device information\n\t);\n\n\tcontReaderConfig.EvtUsbTargetPipeReadersFailed = AmtPtpEvtUsbInterruptReadersFailed;\n\n\t// Remember to turn it on in D0 entry\n\tstatus = WdfUsbTargetPipeConfigContinuousReader(\n\t\tDeviceContext->InterruptPipe,\n\t\t&contReaderConfig\n\t);\n\n\tif (!NT_SUCCESS(status)) {\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_ERROR,\n\t\t\tTRACE_DRIVER,\n\t\t\t\"%!FUNC! AmtPtpConfigContReaderForInterruptEndPoint failed with Status code %!STATUS!\",\n\t\t\tstatus\n\t\t);\n\t\treturn status;\n\t}\n\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION,\n\t\tTRACE_DRIVER,\n\t\t\"%!FUNC! Exit\"\n\t);\n\n\treturn STATUS_SUCCESS;\n\n}\n\n_IRQL_requires_(PASSIVE_LEVEL)\nVOID\nAmtPtpEvtUsbInterruptPipeReadComplete(\n\t_In_ WDFUSBPIPE  Pipe,\n\t_In_ WDFMEMORY   Buffer,\n\t_In_ size_t      NumBytesTransferred,\n\t_In_ WDFCONTEXT  Context\n)\n{\n\tUNREFERENCED_PARAMETER(Pipe);\n\n\tWDFDEVICE       device;\n\tPDEVICE_CONTEXT pDeviceContext = Context;\n\tUCHAR*\t\t\tpBuffer = NULL;\n\tNTSTATUS        status;\n\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION,\n\t\tTRACE_DRIVER,\n\t\t\"%!FUNC! Entry\"\n\t);\n\n\tdevice = WdfObjectContextGetObject(pDeviceContext);\n\tsize_t headerSize = (unsigned int) pDeviceContext->DeviceInfo->tp_header;\n\tsize_t fingerprintSize = (unsigned int) pDeviceContext->DeviceInfo->tp_fsize;\n\n\tif (NumBytesTransferred < headerSize || (NumBytesTransferred - headerSize) % fingerprintSize != 0) {\n\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_INFORMATION,\n\t\t\tTRACE_DRIVER,\n\t\t\t\"%!FUNC! Malformed input received. Length = %llu. Attempt to reset device.\",\n\t\t\tNumBytesTransferred\n\t\t);\n\n\t\tstatus = AmtPtpEmergResetDevice(pDeviceContext);\n\t\tif (!NT_SUCCESS(status)) {\n\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_INFORMATION,\n\t\t\t\tTRACE_DRIVER,\n\t\t\t\t\"%!FUNC! AmtPtpEmergResetDevice failed with %!STATUS!\",\n\t\t\t\tstatus\n\t\t\t);\n\n\t\t}\n\n\t\treturn;\n\t}\n\n\tif (!pDeviceContext->IsWellspringModeOn) {\n\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_WARNING,\n\t\t\tTRACE_DRIVER,\n\t\t\t\"%!FUNC! Routine is called without enabling Wellspring mode\"\n\t\t);\n\n\t\treturn;\n\t}\n\n\t// Dispatch USB Interrupt routine by device family\n\tswitch (pDeviceContext->DeviceInfo->tp_type) {\n\t\tcase TYPE1:\n\t\t{\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_WARNING,\n\t\t\t\tTRACE_DRIVER,\n\t\t\t\t\"%!FUNC! Mode not yet supported\"\n\t\t\t);\n\t\t\tbreak;\n\t\t}\n\t\t// Universal routine handler\n\t\tcase TYPE2:\n\t\tcase TYPE3:\n\t\tcase TYPE4:\n\t\t{\n\t\t\tpBuffer = WdfMemoryGetBuffer(\n\t\t\t\tBuffer,\n\t\t\t\tNULL\n\t\t\t);\n\n\t\t\tstatus = AmtPtpServiceTouchInputInterrupt(\n\t\t\t\tpDeviceContext,\n\t\t\t\tpBuffer,\n\t\t\t\tNumBytesTransferred\n\t\t\t);\n\n\t\t\tif (!NT_SUCCESS(status)) {\n\t\t\t\tTraceEvents(\n\t\t\t\t\tTRACE_LEVEL_WARNING,\n\t\t\t\t\tTRACE_DRIVER,\n\t\t\t\t\t\"%!FUNC! AmtPtpServiceTouchInputInterrupt failed with %!STATUS!\",\n\t\t\t\t\tstatus\n\t\t\t\t);\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\t// Magic Trackpad 2\n\t\tcase TYPE5:\n\t\t{\n\t\t\tpBuffer = WdfMemoryGetBuffer(\n\t\t\t\tBuffer,\n\t\t\t\tNULL\n\t\t\t);\n\t\t\tstatus = AmtPtpServiceTouchInputInterruptType5(\n\t\t\t\tpDeviceContext,\n\t\t\t\tpBuffer,\n\t\t\t\tNumBytesTransferred\n\t\t\t);\n\n\t\t\tif (!NT_SUCCESS(status)) {\n\t\t\t\tTraceEvents(\n\t\t\t\t\tTRACE_LEVEL_WARNING,\n\t\t\t\t\tTRACE_DRIVER,\n\t\t\t\t\t\"%!FUNC! AmtPtpServiceTouchInputInterrupt5 failed with %!STATUS!\",\n\t\t\t\t\tstatus\n\t\t\t\t);\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION,\n\t\tTRACE_DRIVER,\n\t\t\"%!FUNC! Exit\"\n\t);\n\n}\n\n_IRQL_requires_(PASSIVE_LEVEL)\nBOOLEAN\nAmtPtpEvtUsbInterruptReadersFailed(\n\t_In_ WDFUSBPIPE Pipe,\n\t_In_ NTSTATUS Status,\n\t_In_ USBD_STATUS UsbdStatus\n)\n{\n\tUNREFERENCED_PARAMETER(Pipe);\n\tUNREFERENCED_PARAMETER(UsbdStatus);\n\tUNREFERENCED_PARAMETER(Status);\n\n\treturn TRUE;\n}\n\n_IRQL_requires_(PASSIVE_LEVEL)\nNTSTATUS\nAmtPtpServiceTouchInputInterrupt(\n\t_In_ PDEVICE_CONTEXT DeviceContext,\n\t_In_ UCHAR* Buffer,\n\t_In_ size_t NumBytesTransferred\n)\n{\n\tNTSTATUS Status;\n\tWDFREQUEST Request;\n\tWDFMEMORY  RequestMemory;\n\tPTP_REPORT PtpReport;\n\tLARGE_INTEGER CurrentPerfCounter;\n\tLONGLONG PerfCounterDelta;\n\n\tconst struct TRACKPAD_FINGER *f;\n\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION,\n\t\tTRACE_DRIVER,\n\t\t\"%!FUNC! Entry\"\n\t);\n\n\tsize_t raw_n, i = 0;\n\tsize_t headerSize = (unsigned int) DeviceContext->DeviceInfo->tp_header;\n\tsize_t fingerprintSize = (unsigned int) DeviceContext->DeviceInfo->tp_fsize;\n\tUSHORT x = 0, y = 0;\n\n\tStatus = STATUS_SUCCESS;\n\tPtpReport.ReportID = REPORTID_MULTITOUCH;\n\tPtpReport.IsButtonClicked = 0;\n\n\t// Retrieve next PTP touchpad request.\n\tStatus = WdfIoQueueRetrieveNextRequest(\n\t\tDeviceContext->InputQueue,\n\t\t&Request\n\t);\n\n\tif (!NT_SUCCESS(Status)) {\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_INFORMATION,\n\t\t\tTRACE_DRIVER,\n\t\t\t\"%!FUNC! No pending PTP request. Interrupt disposed\"\n\t\t);\n\t\tgoto exit;\n\t}\n\n\tQueryPerformanceCounter(\n\t\t&CurrentPerfCounter\n\t);\n\n\t// Scan time is in 100us\n\tPerfCounterDelta = (CurrentPerfCounter.QuadPart - DeviceContext->PerfCounter.QuadPart) / 100;\n\t// Only two bytes allocated\n\tif (PerfCounterDelta > 0xFF)\n\t{\n\t\tPerfCounterDelta = 0xFF;\n\t}\n\n\tPtpReport.ScanTime = (USHORT) PerfCounterDelta;\n\n\t// Allocate output memory.\n\tStatus = WdfRequestRetrieveOutputMemory(\n\t\tRequest,\n\t\t&RequestMemory\n\t);\n\n\tif (!NT_SUCCESS(Status)) {\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_ERROR,\n\t\t\tTRACE_DRIVER,\n\t\t\t\"%!FUNC! WdfRequestRetrieveOutputMemory failed with %!STATUS!\",\n\t\t\tStatus\n\t\t);\n\t\tgoto exit;\n\t}\n\n\t// Type 2 touchpad surface report\n\tif (DeviceContext->IsSurfaceReportOn) {\n\t\t// Handles trackpad surface report here.\n\t\traw_n = (NumBytesTransferred - headerSize) / fingerprintSize;\n\t\tif (raw_n >= PTP_MAX_CONTACT_POINTS) raw_n = PTP_MAX_CONTACT_POINTS;\n\t\tPtpReport.ContactCount = (UCHAR) raw_n;\n\n#ifdef INPUT_CONTENT_TRACE\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_INFORMATION,\n\t\t\tTRACE_DRIVER,\n\t\t\t\"%!FUNC! with %llu points.\",\n\t\t\traw_n\n\t\t);\n#endif\n\n\t\t// Fingers\n\t\tfor (i = 0; i < raw_n; i++) {\n\n\t\t\tUCHAR *f_base = Buffer + headerSize + DeviceContext->DeviceInfo->tp_delta;\n\t\t\tf = (const struct TRACKPAD_FINGER*) (f_base + i * fingerprintSize);\n\n\t\t\t// Translate X and Y\n\t\t\tx = (AmtRawToInteger(f->abs_x) - DeviceContext->DeviceInfo->x.min) > 0 ? \n\t\t\t\t((USHORT)(AmtRawToInteger(f->abs_x) - DeviceContext->DeviceInfo->x.min)) : 0;\n\t\t\ty = (DeviceContext->DeviceInfo->y.max - AmtRawToInteger(f->abs_y)) > 0 ? \n\t\t\t\t((USHORT)(DeviceContext->DeviceInfo->y.max - AmtRawToInteger(f->abs_y))) : 0;\n\n\t\t\t// Defuzz functions remain the same\n\t\t\t// TODO: Implement defuzz later\n\t\t\tPtpReport.Contacts[i].ContactID = (UCHAR) i;\n\t\t\tPtpReport.Contacts[i].X = x;\n\t\t\tPtpReport.Contacts[i].Y = y;\n\t\t\tPtpReport.Contacts[i].TipSwitch = (AmtRawToInteger(f->touch_major) << 1) >= 200;\n\t\t\tPtpReport.Contacts[i].Confidence = (AmtRawToInteger(f->touch_minor) << 1) > 0;\n\n#ifdef INPUT_CONTENT_TRACE\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_INFORMATION,\n\t\t\t\tTRACE_INPUT,\n\t\t\t\t\"%!FUNC!: Point %llu, X = %d, Y = %d, TipSwitch = %d, Confidence = %d, tMajor = %d, tMinor = %d, origin = %d, PTP Origin = %d\",\n\t\t\t\ti,\n\t\t\t\tPtpReport.Contacts[i].X,\n\t\t\t\tPtpReport.Contacts[i].Y,\n\t\t\t\tPtpReport.Contacts[i].TipSwitch,\n\t\t\t\tPtpReport.Contacts[i].Confidence,\n\t\t\t\tAmtRawToInteger(f->touch_major) << 1,\n\t\t\t\tAmtRawToInteger(f->touch_minor) << 1,\n\t\t\t\tAmtRawToInteger(f->origin),\n\t\t\t\t(UCHAR) i\n\t\t\t);\n#endif\n\t\t}\n\t}\n\n\t// Type 2 touchpad contains integrated trackpad buttons\n\tif (DeviceContext->IsButtonReportOn) {\n\t\t// Handles trackpad button input here.\n\t\tif (Buffer[DeviceContext->DeviceInfo->tp_button]) {\n\t\t\tPtpReport.IsButtonClicked = TRUE;\n\t\t}\n\t}\n\n\t// Compose final report and write it back\n\tStatus = WdfMemoryCopyFromBuffer(\n\t\tRequestMemory,\n\t\t0,\n\t\t(PVOID) &PtpReport,\n\t\tsizeof(PTP_REPORT)\n\t);\n\n\tif (!NT_SUCCESS(Status)) {\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_ERROR,\n\t\t\tTRACE_DRIVER,\n\t\t\t\"%!FUNC! WdfMemoryCopyFromBuffer failed with %!STATUS!\",\n\t\t\tStatus\n\t\t);\n\t\tgoto exit;\n\t}\n\n\t// Set result\n\tWdfRequestSetInformation(\n\t\tRequest,\n\t\tsizeof(PTP_REPORT)\n\t);\n\n\t// Set completion flag\n\tWdfRequestComplete(\n\t\tRequest,\n\t\tStatus\n\t);\n\nexit:\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION,\n\t\tTRACE_DRIVER,\n\t\t\"%!FUNC! Exit\"\n\t);\n\treturn Status;\n\n}\n\n_IRQL_requires_(PASSIVE_LEVEL)\nNTSTATUS\nAmtPtpServiceTouchInputInterruptType5(\n\t_In_ PDEVICE_CONTEXT DeviceContext,\n\t_In_ UCHAR* Buffer,\n\t_In_ size_t NumBytesTransferred\n)\n{\n\n\tNTSTATUS   Status;\n\tWDFREQUEST Request;\n\tWDFMEMORY  RequestMemory;\n\tPTP_REPORT PtpReport;\n\tLARGE_INTEGER CurrentPerfCounter;\n\tLONGLONG PerfCounterDelta;\n\n\tconst struct TRACKPAD_FINGER *f;\n\tconst struct TRACKPAD_FINGER_TYPE5 *f_type5;\n\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION, \n\t\tTRACE_DRIVER, \n\t\t\"%!FUNC! Entry\"\n\t);\n\n\tStatus = STATUS_SUCCESS;\n\tPtpReport.ReportID = REPORTID_MULTITOUCH;\n\tPtpReport.IsButtonClicked = 0;\n\n\tINT x, y = 0;\n\tsize_t raw_n, i = 0;\n\tsize_t headerSize = (unsigned int) DeviceContext->DeviceInfo->tp_header;\n\tsize_t fingerprintSize = (unsigned int) DeviceContext->DeviceInfo->tp_fsize;\n\n\tStatus = WdfIoQueueRetrieveNextRequest(\n\t\tDeviceContext->InputQueue,\n\t\t&Request\n\t);\n\n\tif (!NT_SUCCESS(Status)) {\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_INFORMATION, \n\t\t\tTRACE_DRIVER, \n\t\t\t\"%!FUNC! No pending PTP request. Interrupt disposed\"\n\t\t);\n\t\tgoto exit;\n\t}\n\n\tStatus = WdfRequestRetrieveOutputMemory(\n\t\tRequest, \n\t\t&RequestMemory\n\t);\n\tif (!NT_SUCCESS(Status)) {\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_ERROR, \n\t\t\tTRACE_DRIVER, \n\t\t\t\"%!FUNC! WdfRequestRetrieveOutputBuffer failed with %!STATUS!\", \n\t\t\tStatus\n\t\t);\n\t\tgoto exit;\n\t}\n\n\tQueryPerformanceCounter(\n\t\t&CurrentPerfCounter\n\t);\n\n\t// Scan time is in 100us\n\tPerfCounterDelta = (CurrentPerfCounter.QuadPart - DeviceContext->PerfCounter.QuadPart) / 100;\n\t// Only two bytes allocated\n\tif (PerfCounterDelta > 0xFF)\n\t{\n\t\tPerfCounterDelta = 0xFF;\n\t}\n\n\tPtpReport.ScanTime = (USHORT) PerfCounterDelta;\n\n\t// Type 5 finger report\n\tif (DeviceContext->IsSurfaceReportOn) {\n\t\traw_n = (NumBytesTransferred - headerSize) / fingerprintSize;\n\t\tif (raw_n >= PTP_MAX_CONTACT_POINTS) raw_n = PTP_MAX_CONTACT_POINTS;\n\t\tPtpReport.ContactCount = (UCHAR)raw_n;\n\n#ifdef INPUT_CONTENT_TRACE\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_INFORMATION,\n\t\t\tTRACE_DRIVER,\n\t\t\t\"%!FUNC! with %llu points.\",\n\t\t\traw_n\n\t\t);\n#endif\n\n\t\t// Fingers to array\n\t\tfor (i = 0; i < raw_n; i++) {\n\n\t\t\tUCHAR *f_base = Buffer + headerSize + DeviceContext->DeviceInfo->tp_delta;\n\t\t\tf = (const struct TRACKPAD_FINGER*) (f_base + i * fingerprintSize);\n\t\t\tf_type5 = (const struct TRACKPAD_FINGER_TYPE5*) f;\n\n\t\t\tUSHORT tmp_x = (*((USHORT*)f_type5)) & 0x1fff;\n\t\t\tUINT tmp_y = (INT)(*((UINT*)f_type5));\n\n\t\t\tx = (SHORT) (tmp_x << 3) >> 3;\n\t\t\ty = -(INT) (tmp_y << 6) >> 19;\n\n\t\t\tx = (x - DeviceContext->DeviceInfo->x.min) > 0 ? (x - DeviceContext->DeviceInfo->x.min) : 0;\n\t\t\ty = (y - DeviceContext->DeviceInfo->y.min) > 0 ? (y - DeviceContext->DeviceInfo->y.min) : 0;\n\n\t\t\tPtpReport.Contacts[i].ContactID = f_type5->ContactIdentifier.Id;\n\t\t\tPtpReport.Contacts[i].X = (USHORT) x;\n\t\t\tPtpReport.Contacts[i].Y = (USHORT) y;\n\t\t\tPtpReport.Contacts[i].TipSwitch = (AmtRawToInteger(f_type5->TouchMajor) << 1) > 0;\n\n\t\t\t// The Microsoft spec says reject any input larger than 25mm. This is not ideal\n\t\t\t// for Magic Trackpad 2 - so we raised the threshold a bit higher.\n\t\t\t// Or maybe I used the wrong unit? IDK\n\t\t\tPtpReport.Contacts[i].Confidence = (AmtRawToInteger(f_type5->TouchMinor) << 1) < 345 && \n\t\t\t\t(AmtRawToInteger(f_type5->TouchMinor) << 1) < 345;\n\n#ifdef INPUT_CONTENT_TRACE\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_INFORMATION,\n\t\t\t\tTRACE_INPUT,\n\t\t\t\t\"%!FUNC!: Point %llu, X = %d, Y = %d, TipSwitch = %d, Confidence = %d, tMajor = %d, tMinor = %d, origin = %d\",\n\t\t\t\ti,\n\t\t\t\tPtpReport.Contacts[i].X,\n\t\t\t\tPtpReport.Contacts[i].Y,\n\t\t\t\tPtpReport.Contacts[i].TipSwitch,\n\t\t\t\tPtpReport.Contacts[i].Confidence,\n\t\t\t\tAmtRawToInteger(f_type5->TouchMajor) << 1,\n\t\t\t\tAmtRawToInteger(f_type5->TouchMinor) << 1,\n\t\t\t\tf_type5->ContactIdentifier.Id\n\t\t\t);\n#endif\n\t\t}\n\t}\n\n\t// Button\n\tif (DeviceContext->IsButtonReportOn) {\n\t\tif (Buffer[DeviceContext->DeviceInfo->tp_button]) {\n\t\t\tPtpReport.IsButtonClicked = TRUE;\n\t\t}\n\t}\n\n\t// Write output\n\tStatus = WdfMemoryCopyFromBuffer(\n\t\tRequestMemory, \n\t\t0, \n\t\t(PVOID) &PtpReport, \n\t\tsizeof(PTP_REPORT)\n\t);\n\n\tif (!NT_SUCCESS(Status)) {\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_ERROR, \n\t\t\tTRACE_DRIVER, \n\t\t\t\"%!FUNC! WdfMemoryCopyFromBuffer failed with %!STATUS!\", \n\t\t\tStatus\n\t\t);\n\t\tgoto exit;\n\t}\n\n\t// Set result\n\tWdfRequestSetInformation(\n\t\tRequest, \n\t\tsizeof(PTP_REPORT)\n\t);\n\n\t// Set completion flag\n\tWdfRequestComplete(\n\t\tRequest, \n\t\tStatus\n\t);\n\nexit:\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION, \n\t\tTRACE_DRIVER, \n\t\t\"%!FUNC! Exit\"\n\t);\n\treturn Status;\n\n}\n\n// Helper function for numberic operation\nstatic inline INT AmtRawToInteger(\n\t_In_ USHORT x\n)\n{\n\treturn (signed short) x;\n}\n"
  },
  {
    "path": "src/AmtPtpDeviceUsbUm/MagicTrackpad2PtpDevice.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"12.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"ReleaseSigned|ARM64\">\n      <Configuration>ReleaseSigned</Configuration>\n      <Platform>ARM64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"ReleaseSigned|x64\">\n      <Configuration>ReleaseSigned</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|ARM64\">\n      <Configuration>Debug</Configuration>\n      <Platform>ARM64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|ARM64\">\n      <Configuration>Release</Configuration>\n      <Platform>ARM64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <ItemGroup>\n    <ClCompile Include=\"Device.c\" />\n    <ClCompile Include=\"Driver.c\" />\n    <ClCompile Include=\"Hid.c\" />\n    <ClCompile Include=\"InputInterrupt.c\" />\n    <ClCompile Include=\"Queue.c\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"include\\AppleDefinition.h\" />\n    <ClInclude Include=\"include\\Device.h\" />\n    <ClInclude Include=\"include\\DeviceFamily\\Wellspring3.h\" />\n    <ClInclude Include=\"include\\DeviceFamily\\Wellspring5.h\" />\n    <ClInclude Include=\"include\\DeviceFamily\\Wellspring6.h\" />\n    <ClInclude Include=\"include\\DeviceFamily\\Wellspring7A.h\" />\n    <ClInclude Include=\"include\\DeviceFamily\\Wellspring8.h\" />\n    <ClInclude Include=\"include\\DeviceFamily\\WellspringMt2.h\" />\n    <ClInclude Include=\"include\\Driver.h\" />\n    <ClInclude Include=\"include\\Hid.h\" />\n    <ClInclude Include=\"include\\HidCommon.h\" />\n    <ClInclude Include=\"include\\ModernTrace.h\" />\n    <ClInclude Include=\"include\\Queue.h\" />\n    <ClInclude Include=\"include\\resource.h\" />\n    <ClInclude Include=\"include\\StaticHidRegistry.h\" />\n    <ClInclude Include=\"include\\Trace.h\" />\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{87EFA31B-25EB-4944-A30A-300171BFFF57}</ProjectGuid>\n    <TemplateGuid>{9181db3b-298d-4e39-a572-55bca4e4ac89}</TemplateGuid>\n    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>\n    <MinimumVisualStudioVersion>12.0</MinimumVisualStudioVersion>\n    <Configuration>Debug</Configuration>\n    <Platform Condition=\"'$(Platform)' == ''\">Win32</Platform>\n    <RootNamespace>MagicTrackpad2PtpDevice</RootNamespace>\n    <ProjectName>AmtPtpDeviceUsbUm</ProjectName>\n  </PropertyGroup>\n  <!-- They told me this: https://help.github.com/en/articles/software-in-virtual-environments-for-github-actions#windows-server-2019 -->\n  <PropertyGroup>\n    <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(BuildEnvironment)'=='Github'\">\n    <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <TargetVersion>Windows10</TargetVersion>\n    <UseDebugLibraries>true</UseDebugLibraries>\n    <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset>\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <UMDF_VERSION_MAJOR>2</UMDF_VERSION_MAJOR>\n    <DriverTargetPlatform>Universal</DriverTargetPlatform>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <TargetVersion>Windows10</TargetVersion>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset>\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <UMDF_VERSION_MAJOR>2</UMDF_VERSION_MAJOR>\n    <DriverTargetPlatform>Universal</DriverTargetPlatform>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseSigned|x64'\" Label=\"Configuration\">\n    <TargetVersion>Windows10</TargetVersion>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset>\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <UMDF_VERSION_MAJOR>2</UMDF_VERSION_MAJOR>\n    <DriverTargetPlatform>Universal</DriverTargetPlatform>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\" Label=\"Configuration\">\n    <TargetVersion>Windows10</TargetVersion>\n    <UseDebugLibraries>true</UseDebugLibraries>\n    <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset>\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <UMDF_VERSION_MAJOR>2</UMDF_VERSION_MAJOR>\n    <DriverTargetPlatform>Universal</DriverTargetPlatform>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\" Label=\"Configuration\">\n    <TargetVersion>Windows10</TargetVersion>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset>\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <UMDF_VERSION_MAJOR>2</UMDF_VERSION_MAJOR>\n    <DriverTargetPlatform>Universal</DriverTargetPlatform>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseSigned|ARM64'\" Label=\"Configuration\">\n    <TargetVersion>Windows10</TargetVersion>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset>\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <UMDF_VERSION_MAJOR>2</UMDF_VERSION_MAJOR>\n    <DriverTargetPlatform>Universal</DriverTargetPlatform>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <DebuggerFlavor>DbgengRemoteDebugger</DebuggerFlavor>\n    <OutDir>$(SolutionDir)build\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\</OutDir>\n    <IncludePath>$(DDK_INC_PATH);$(SolutionDir)intermediate\\$(Platform)\\$(ConfigurationName)\\;$(ProjectDir)include;$(IncludePath)</IncludePath>\n    <IntDir>$(SolutionDir)intermediate\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\</IntDir>\n    <TimeStampServer>http://timestamp.digicert.com</TimeStampServer>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <DebuggerFlavor>DbgengRemoteDebugger</DebuggerFlavor>\n    <OutDir>$(SolutionDir)build\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\</OutDir>\n    <IncludePath>$(DDK_INC_PATH);$(SolutionDir)intermediate\\$(Platform)\\$(ConfigurationName)\\;$(ProjectDir)include;$(IncludePath)</IncludePath>\n    <IntDir>$(SolutionDir)intermediate\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\</IntDir>\n    <TimeStampServer>http://timestamp.digicert.com</TimeStampServer>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseSigned|x64'\">\n    <DebuggerFlavor>DbgengRemoteDebugger</DebuggerFlavor>\n    <OutDir>$(SolutionDir)build\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\</OutDir>\n    <IncludePath>$(DDK_INC_PATH);$(SolutionDir)intermediate\\$(Platform)\\$(ConfigurationName)\\;$(ProjectDir)include;$(IncludePath)</IncludePath>\n    <IntDir>$(SolutionDir)intermediate\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\</IntDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">\n    <DebuggerFlavor>DbgengRemoteDebugger</DebuggerFlavor>\n    <OutDir>$(SolutionDir)build\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\</OutDir>\n    <IncludePath>$(DDK_INC_PATH);$(SolutionDir)intermediate\\$(Platform)\\$(ConfigurationName)\\;$(ProjectDir)include;$(IncludePath)</IncludePath>\n    <IntDir>$(SolutionDir)intermediate\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\</IntDir>\n    <TimeStampServer>http://timestamp.digicert.com</TimeStampServer>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">\n    <DebuggerFlavor>DbgengRemoteDebugger</DebuggerFlavor>\n    <OutDir>$(SolutionDir)build\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\</OutDir>\n    <IncludePath>$(DDK_INC_PATH);$(SolutionDir)intermediate\\$(Platform)\\$(ConfigurationName)\\;$(ProjectDir)include;$(IncludePath)</IncludePath>\n    <IntDir>$(SolutionDir)intermediate\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\</IntDir>\n    <TimeStampServer>http://timestamp.digicert.com</TimeStampServer>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseSigned|ARM64'\">\n    <DebuggerFlavor>DbgengRemoteDebugger</DebuggerFlavor>\n    <OutDir>$(SolutionDir)build\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\</OutDir>\n    <IncludePath>$(DDK_INC_PATH);$(SolutionDir)intermediate\\$(Platform)\\$(ConfigurationName)\\;$(ProjectDir)include;$(IncludePath)</IncludePath>\n    <IntDir>$(SolutionDir)intermediate\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\</IntDir>\n  </PropertyGroup>\n  <!-- For release signed config on Azure pipeline, CI pipeline don't sign it. We do that locally -->\n  <PropertyGroup Condition=\"'$(Configuration)'=='ReleaseSigned'\">\n    <TimeStampServer>http://timestamp.digicert.com</TimeStampServer>\n    <ProductionCertificate>$(ProductionCertPath)</ProductionCertificate>\n    <SignMode Condition=\"'$(BuildEnvironment)'!='AzurePipeline'\">ProductionSign</SignMode>\n    <SignMode Condition=\"'$(BuildEnvironment)'=='AzurePipeline'\">Off</SignMode>\n  </PropertyGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <ClCompile>\n      <WppEnabled>true</WppEnabled>\n      <WppRecorderEnabled>true</WppRecorderEnabled>\n      <WppScanConfigurationData Condition=\"'%(ClCompile.ScanConfigurationData)' == ''\">include\\trace.h</WppScanConfigurationData>\n    </ClCompile>\n    <DriverSign>\n      <FileDigestAlgorithm>sha256</FileDigestAlgorithm>\n    </DriverSign>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <ClCompile>\n      <WppEnabled>true</WppEnabled>\n      <WppRecorderEnabled>true</WppRecorderEnabled>\n      <WppScanConfigurationData Condition=\"'%(ClCompile.ScanConfigurationData)' == ''\">include\\trace.h</WppScanConfigurationData>\n    </ClCompile>\n    <DriverSign>\n      <FileDigestAlgorithm>sha256</FileDigestAlgorithm>\n    </DriverSign>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseSigned|x64'\">\n    <ClCompile>\n      <WppEnabled>true</WppEnabled>\n      <WppRecorderEnabled>true</WppRecorderEnabled>\n      <WppScanConfigurationData Condition=\"'%(ClCompile.ScanConfigurationData)' == ''\">include\\trace.h</WppScanConfigurationData>\n    </ClCompile>\n    <DriverSign>\n      <FileDigestAlgorithm>sha256</FileDigestAlgorithm>\n    </DriverSign>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">\n    <ClCompile>\n      <WppEnabled>true</WppEnabled>\n      <WppRecorderEnabled>true</WppRecorderEnabled>\n      <WppScanConfigurationData Condition=\"'%(ClCompile.ScanConfigurationData)' == ''\">include\\trace.h</WppScanConfigurationData>\n    </ClCompile>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">\n    <ClCompile>\n      <WppEnabled>true</WppEnabled>\n      <WppRecorderEnabled>true</WppRecorderEnabled>\n      <WppScanConfigurationData Condition=\"'%(ClCompile.ScanConfigurationData)' == ''\">include\\trace.h</WppScanConfigurationData>\n    </ClCompile>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseSigned|ARM64'\">\n    <ClCompile>\n      <WppEnabled>true</WppEnabled>\n      <WppRecorderEnabled>true</WppRecorderEnabled>\n      <WppScanConfigurationData Condition=\"'%(ClCompile.ScanConfigurationData)' == ''\">include\\trace.h</WppScanConfigurationData>\n    </ClCompile>\n    <DriverSign />\n    <DriverSign />\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <FilesToPackage Include=\"$(TargetPath)\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ResourceCompile Include=\"Resource.rc\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"AmtPtpDevice.wprp\" />\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "src/AmtPtpDeviceUsbUm/MagicTrackpad2PtpDevice.vcxproj.filters",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup>\n    <Filter Include=\"Source Files\">\n      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>\n      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>\n    </Filter>\n    <Filter Include=\"Header Files\">\n      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>\n      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>\n    </Filter>\n    <Filter Include=\"Resource Files\">\n      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>\n      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>\n    </Filter>\n    <Filter Include=\"Driver Files\">\n      <UniqueIdentifier>{8E41214B-6785-4CFE-B992-037D68949A14}</UniqueIdentifier>\n      <Extensions>inf;inv;inx;mof;mc;</Extensions>\n    </Filter>\n    <Filter Include=\"Device Specific Metadata Files\">\n      <UniqueIdentifier>{d3b4239b-c0e3-4d91-a6ee-730df7a15240}</UniqueIdentifier>\n    </Filter>\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"include\\AppleDefinition.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"include\\Device.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"include\\Driver.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"include\\Hid.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"include\\HidCommon.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"include\\ModernTrace.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"include\\Queue.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"include\\resource.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"include\\Trace.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"include\\StaticHidRegistry.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"include\\DeviceFamily\\Wellspring3.h\">\n      <Filter>Device Specific Metadata Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"include\\DeviceFamily\\Wellspring5.h\">\n      <Filter>Device Specific Metadata Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"include\\DeviceFamily\\Wellspring6.h\">\n      <Filter>Device Specific Metadata Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"include\\DeviceFamily\\Wellspring7A.h\">\n      <Filter>Device Specific Metadata Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"include\\DeviceFamily\\Wellspring8.h\">\n      <Filter>Device Specific Metadata Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"include\\DeviceFamily\\WellspringMt2.h\">\n      <Filter>Device Specific Metadata Files</Filter>\n    </ClInclude>\n  </ItemGroup>\n  <ItemGroup>\n    <ClCompile Include=\"Device.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"Driver.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"Queue.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"InputInterrupt.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"Hid.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n  </ItemGroup>\n  <ItemGroup>\n    <ResourceCompile Include=\"Resource.rc\">\n      <Filter>Resource Files</Filter>\n    </ResourceCompile>\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"AmtPtpDevice.wprp\">\n      <Filter>Resource Files</Filter>\n    </None>\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "src/AmtPtpDeviceUsbUm/Queue.c",
    "content": "// Queue.c: This file contains the queue entry points and callbacks.\n\n#include <driver.h>\n#include \"queue.tmh\"\n\nNTSTATUS\nAmtPtpDeviceQueueInitialize(\n\t_In_ WDFDEVICE Device\n)\n{\n\n\tWDFQUEUE queue;\n\tNTSTATUS status;\n\tWDF_IO_QUEUE_CONFIG    queueConfig;\n\tPDEVICE_CONTEXT\t       deviceContext;\n\n\tdeviceContext = DeviceGetContext(Device);\n\n\t//\n\t// Configure a default queue so that requests that are not\n\t// configure-fowarded using WdfDeviceConfigureRequestDispatching to goto\n\t// other queues get dispatched here.\n\t//\n\tWDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(\n\t\t&queueConfig,\n\t\tWdfIoQueueDispatchParallel\n\t);\n\n\tqueueConfig.EvtIoDeviceControl = AmtPtpDeviceEvtIoDeviceControl;\n\tqueueConfig.EvtIoStop = AmtPtpDeviceEvtIoStop;\n\n\tstatus = WdfIoQueueCreate(\n\t\tDevice,\n\t\t&queueConfig,\n\t\tWDF_NO_OBJECT_ATTRIBUTES,\n\t\t&queue\n\t);\n\n\tif (!NT_SUCCESS(status)) {\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_ERROR, \n\t\t\tTRACE_QUEUE, \n\t\t\t\"%!FUNC! WdfIoQueueCreate (Primary) failed %!STATUS!\", \n\t\t\tstatus\n\t\t);\n\t\treturn status;\n\t}\n\n\t//\n\t// Create secondary queues for touch and mouse read requests.\n\t// \n\n\tWDF_IO_QUEUE_CONFIG_INIT(&queueConfig, WdfIoQueueDispatchManual);\n\tqueueConfig.PowerManaged = WdfFalse;\n\n\tstatus = WdfIoQueueCreate(\n\t\tDevice,\n\t\t&queueConfig,\n\t\tWDF_NO_OBJECT_ATTRIBUTES,\n\t\t&deviceContext->InputQueue\n\t);\n\n\tif (!NT_SUCCESS(status)) {\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_ERROR, \n\t\t\tTRACE_QUEUE, \n\t\t\t\"%!FUNC! WdfIoQueueCreate (Input) failed %!STATUS!\", \n\t\t\tstatus\n\t\t);\n\t\treturn status;\n\t}\n\n\treturn status;\n\n}\n\n_IRQL_requires_(PASSIVE_LEVEL)\nPCHAR\nDbgIoControlGetString(\n\t_In_ ULONG IoControlCode\n)\n{\n\n\tswitch (IoControlCode)\n\t{\n\tcase IOCTL_HID_GET_DEVICE_DESCRIPTOR:\n\t\treturn \"IOCTL_HID_GET_DEVICE_DESCRIPTOR\";\n\tcase IOCTL_HID_GET_DEVICE_ATTRIBUTES:\n\t\treturn \"IOCTL_HID_GET_DEVICE_ATTRIBUTES\";\n\tcase IOCTL_HID_GET_REPORT_DESCRIPTOR:\n\t\treturn \"IOCTL_HID_GET_REPORT_DESCRIPTOR\";\n\tcase IOCTL_HID_GET_STRING:\n\t\treturn \"IOCTL_HID_GET_STRING\";\n\tcase IOCTL_HID_READ_REPORT:\n\t\treturn \"IOCTL_HID_READ_REPORT\";\n\tcase IOCTL_HID_WRITE_REPORT:\n\t\treturn \"IOCTL_HID_WRITE_REPORT\";\n\tcase IOCTL_UMDF_HID_GET_INPUT_REPORT:\n\t\treturn \"IOCTL_UMDF_HID_GET_INPUT_REPORT\";\n\tcase IOCTL_UMDF_HID_SET_OUTPUT_REPORT:\n\t\treturn \"IOCTL_UMDF_HID_SET_OUTPUT_REPORT\";\n\tcase IOCTL_UMDF_HID_GET_FEATURE:\n\t\treturn \"IOCTL_UMDF_HID_GET_FEATURE\";\n\tcase IOCTL_UMDF_HID_SET_FEATURE:\n\t\treturn \"IOCTL_UMDF_HID_SET_FEATURE\";\n\tcase IOCTL_HID_ACTIVATE_DEVICE:\n\t\treturn \"IOCTL_HID_ACTIVATE_DEVICE\";\n\tcase IOCTL_HID_DEACTIVATE_DEVICE:\n\t\treturn \"IOCTL_HID_DEACTIVATE_DEVICE\";\n\tcase IOCTL_HID_SEND_IDLE_NOTIFICATION_REQUEST:\n\t\treturn \"IOCTL_HID_SEND_IDLE_NOTIFICATION_REQUEST\";\n\tdefault:\n\t\treturn \"IOCTL_UNKNOWN\";\n\t}\n\n}\n\nVOID\nAmtPtpDeviceEvtIoDeviceControl(\n\t_In_ WDFQUEUE Queue,\n\t_In_ WDFREQUEST Request,\n\t_In_ size_t OutputBufferLength,\n\t_In_ size_t InputBufferLength,\n\t_In_ ULONG IoControlCode\n)\n{\n\t\n\tNTSTATUS status = STATUS_SUCCESS;\n\tWDFDEVICE device = WdfIoQueueGetDevice(Queue);\n\tBOOLEAN requestPending = FALSE;\n\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION,\n\t\tTRACE_QUEUE,\n\t\t\"%!FUNC!: Queue 0x%p, Request 0x%p OutputBufferLength %d InputBufferLength %d IoControlCode %d\",\n\t\tQueue, \n\t\tRequest, \n\t\t(int) OutputBufferLength, \n\t\t(int) InputBufferLength, \n\t\tIoControlCode\n\t);\n\n\tswitch (IoControlCode)\n\t{\n\t\tcase IOCTL_HID_GET_DEVICE_DESCRIPTOR:\n\t\t\tstatus = AmtPtpGetHidDescriptor(\n\t\t\t\tdevice, \n\t\t\t\tRequest\n\t\t\t);\n\t\t\tbreak;\n\t\tcase IOCTL_HID_GET_DEVICE_ATTRIBUTES:\n\t\t\tstatus = AmtPtpGetDeviceAttribs(\n\t\t\t\tdevice, \n\t\t\t\tRequest\n\t\t\t);\n\t\t\tbreak;\n\t\tcase IOCTL_HID_GET_REPORT_DESCRIPTOR:\n\t\t\tstatus = AmtPtpGetReportDescriptor(\n\t\t\t\tdevice, \n\t\t\t\tRequest\n\t\t\t);\n\t\t\tbreak;\n\t\tcase IOCTL_HID_GET_STRING:\n\t\t\tstatus = AmtPtpGetStrings(\n\t\t\t\tdevice, \n\t\t\t\tRequest\n\t\t\t);\n\t\t\tbreak;\n\t\tcase IOCTL_HID_READ_REPORT:\n\t\t\tstatus = AmtPtpDispatchReadReportRequests(\n\t\t\t\tdevice, \n\t\t\t\tRequest, \n\t\t\t\t&requestPending\n\t\t\t);\n\t\t\tbreak;\n\t\tcase IOCTL_UMDF_HID_GET_FEATURE:\n\t\t\tstatus = AmtPtpReportFeatures(\n\t\t\t\tdevice, \n\t\t\t\tRequest\n\t\t\t);\n\t\t\tbreak;\n\t\tcase IOCTL_UMDF_HID_SET_FEATURE:\n\t\t\tstatus = AmtPtpSetFeatures(\n\t\t\t\tdevice, \n\t\t\t\tRequest\n\t\t\t);\n\t\t\tbreak;\n\t\tcase IOCTL_HID_WRITE_REPORT:\n\t\tcase IOCTL_UMDF_HID_SET_OUTPUT_REPORT:\n\t\tcase IOCTL_UMDF_HID_GET_INPUT_REPORT:\n\t\tcase IOCTL_HID_ACTIVATE_DEVICE:\n\t\tcase IOCTL_HID_DEACTIVATE_DEVICE:\n\t\tcase IOCTL_HID_SEND_IDLE_NOTIFICATION_REQUEST:\n\t\tdefault:\n\t\t\tstatus = STATUS_NOT_SUPPORTED;\n\t\t\tTraceEvents(\n\t\t\t\tTRACE_LEVEL_WARNING, \n\t\t\t\tTRACE_QUEUE, \n\t\t\t\t\"%!FUNC!: %s is not yet implemented\", \n\t\t\t\tDbgIoControlGetString(IoControlCode)\n\t\t\t);\n\t\t\tbreak;\n\t}\n\n\tif (requestPending != TRUE) {\n\t\tWdfRequestComplete(\n\t\t\tRequest, \n\t\t\tstatus\n\t\t);\n\t}\n\n\treturn;\n}\n\nVOID\nAmtPtpDeviceEvtIoStop(\n\t_In_ WDFQUEUE Queue,\n\t_In_ WDFREQUEST Request,\n\t_In_ ULONG ActionFlags\n)\n{\n\n\tTraceEvents(\n\t\tTRACE_LEVEL_INFORMATION,\n\t\tTRACE_QUEUE,\n\t\t\"%!FUNC! Queue 0x%p, Request 0x%p ActionFlags %d\",\n\t\tQueue, \n\t\tRequest, \n\t\tActionFlags\n\t);\n\n\t//\n\t// In most cases, the EvtIoStop callback function completes, cancels, or postpones\n\t// further processing of the I/O request.\n\t//\n\t// Typically, the driver uses the following rules:\n\t//\n\t// - If the driver owns the I/O request, it either postpones further processing\n\t//   of the request and calls WdfRequestStopAcknowledge, or it calls WdfRequestComplete\n\t//   with a completion status value of STATUS_SUCCESS or STATUS_CANCELLED.\n\t//  \n\t//   The driver must call WdfRequestComplete only once, to either complete or cancel\n\t//   the request. To ensure that another thread does not call WdfRequestComplete\n\t//   for the same request, the EvtIoStop callback must synchronize with the driver's\n\t//   other event callback functions, for instance by using interlocked operations.\n\t//\n\t// - If the driver has forwarded the I/O request to an I/O target, it either calls\n\t//   WdfRequestCancelSentRequest to attempt to cancel the request, or it postpones\n\t//   further processing of the request and calls WdfRequestStopAcknowledge.\n\t//\n\t// A driver might choose to take no action in EvtIoStop for requests that are\n\t// guaranteed to complete in a small amount of time. For example, the driver might\n\t// take no action for requests that are completed in one of the drivers request handlers.\n\t//\n\n\treturn;\n\n}\n\nNTSTATUS\nAmtPtpDispatchReadReportRequests(\n\t_In_ WDFDEVICE Device,\n\t_In_ WDFREQUEST Request,\n\t_Out_ BOOLEAN *Pending\n)\n{\n\n\tNTSTATUS status;\n\tPDEVICE_CONTEXT devContext;\n\n\tstatus = STATUS_SUCCESS;\n\tdevContext = DeviceGetContext(Device);\n\n\tstatus = WdfRequestForwardToIoQueue(\n\t\tRequest, \n\t\tdevContext->InputQueue\n\t);\n\t\n\n\tif (!NT_SUCCESS(status)) {\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_ERROR, \n\t\t\tTRACE_DRIVER, \n\t\t\t\"%!FUNC! WdfRequestForwardToIoQueue failed with %!STATUS!\", \n\t\t\tstatus\n\t\t);\n\t\treturn status;\n\t} else {\n\t\tTraceEvents(\n\t\t\tTRACE_LEVEL_INFORMATION, \n\t\t\tTRACE_DRIVER,\n\t\t\t\"%!FUNC! A report has been forwarded to input queue\"\n\t\t);\n\t}\n\n\tif (NULL != Pending) {\n\t\t*Pending = TRUE;\n\t}\n\n\treturn status;\n\n}"
  },
  {
    "path": "src/AmtPtpDeviceUsbUm/include/AppleDefinition.h",
    "content": "#pragma once\n\n#define USB_VENDOR_ID_APPLE\t\t0x05ac\n\n/* MacbookAir, aka wellspring */\n#define USB_DEVICE_ID_APPLE_WELLSPRING_ANSI\t0x0223\n#define USB_DEVICE_ID_APPLE_WELLSPRING_ISO\t0x0224\n#define USB_DEVICE_ID_APPLE_WELLSPRING_JIS\t0x0225\n/* MacbookProPenryn, aka wellspring2 */\n#define USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI\t0x0230\n#define USB_DEVICE_ID_APPLE_WELLSPRING2_ISO\t0x0231\n#define USB_DEVICE_ID_APPLE_WELLSPRING2_JIS\t0x0232\n/* Macbook5,1 (unibody), aka wellspring3 */\n#define USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI\t0x0236\n#define USB_DEVICE_ID_APPLE_WELLSPRING3_ISO\t0x0237\n#define USB_DEVICE_ID_APPLE_WELLSPRING3_JIS\t0x0238\n/* MacbookAir3,2 (unibody), aka wellspring5 */\n#define USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI\t0x023f\n#define USB_DEVICE_ID_APPLE_WELLSPRING4_ISO\t0x0240\n#define USB_DEVICE_ID_APPLE_WELLSPRING4_JIS\t0x0241\n/* MacbookAir3,1 (unibody), aka wellspring4 */\n#define USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI\t0x0242\n#define USB_DEVICE_ID_APPLE_WELLSPRING4A_ISO\t0x0243\n#define USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS\t0x0244\n/* Macbook8 (unibody, March 2011) */\n#define USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI\t0x0245\n#define USB_DEVICE_ID_APPLE_WELLSPRING5_ISO\t0x0246\n#define USB_DEVICE_ID_APPLE_WELLSPRING5_JIS\t0x0247\n/* MacbookAir4,1 (unibody, July 2011) */\n#define USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI\t0x0249\n#define USB_DEVICE_ID_APPLE_WELLSPRING6A_ISO\t0x024a\n#define USB_DEVICE_ID_APPLE_WELLSPRING6A_JIS\t0x024b\n/* MacbookAir4,2 (unibody, July 2011) */\n#define USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI\t0x024c\n#define USB_DEVICE_ID_APPLE_WELLSPRING6_ISO\t0x024d\n#define USB_DEVICE_ID_APPLE_WELLSPRING6_JIS\t0x024e\n/* Macbook8,2 (unibody) */\n#define USB_DEVICE_ID_APPLE_WELLSPRING5A_ANSI\t0x0252\n#define USB_DEVICE_ID_APPLE_WELLSPRING5A_ISO\t0x0253\n#define USB_DEVICE_ID_APPLE_WELLSPRING5A_JIS\t0x0254\n/* MacbookPro10,1 (unibody, June 2012) */\n#define USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI\t0x0262\n#define USB_DEVICE_ID_APPLE_WELLSPRING7_ISO\t0x0263\n#define USB_DEVICE_ID_APPLE_WELLSPRING7_JIS\t0x0264\n/* MacbookPro10,2 (unibody, October 2012) */\n#define USB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI\t0x0259\n#define USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO\t0x025a\n#define USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS\t0x025b\n/* MacbookAir6,2 (unibody, June 2013) */\n#define USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI\t0x0290\n#define USB_DEVICE_ID_APPLE_WELLSPRING8_ISO\t0x0291\n#define USB_DEVICE_ID_APPLE_WELLSPRING8_JIS\t0x0292\n/* MacbookPro12,1 (2015) */\n#define USB_DEVICE_ID_APPLE_WELLSPRING9_ANSI\t0x0272\n#define USB_DEVICE_ID_APPLE_WELLSPRING9_ISO\t0x0273\n#define USB_DEVICE_ID_APPLE_WELLSPRING9_JIS\t0x0274\n/* MagicTrackpad2 (2015) */\n#define USB_DEVICE_ID_APPLE_MAGICTRACKPAD2\t0x0265\n/* Apple T2 USB trackpad */\n#define USB_DEVICE_ID_APPLE_T2 0x027d\n\n/* button data structure */\nstruct TRACKPAD_BUTTON_DATA {\n\tUCHAR unknown1;\t\t/* constant */\n\tUCHAR button;\t\t\t/* left button */\n\tUCHAR rel_x;\t\t\t/* relative x coordinate */\n\tUCHAR rel_y;\t\t\t/* relative y coordinate */\n};\n\n/* trackpad header types */\nenum TRACKPAD_TYPE {\n\tTYPE1,\t\t\t/* plain trackpad */\n\tTYPE2,\t\t\t/* button integrated in trackpad */\n\tTYPE3,\t\t\t/* additional header fields since June 2013 */\n\tTYPE4,\t\t\t/* additional header field for pressure data */\n\tTYPE5\t\t\t/* format for magic trackpad 2 */\n};\n\n/* Trackpad finger data offsets, le16-aligned */\n#define HEADER_TYPE1\t\t(13 * sizeof(USHORT))\n#define HEADER_TYPE2\t\t(15 * sizeof(USHORT))\n#define HEADER_TYPE3\t\t(19 * sizeof(USHORT))\n#define HEADER_TYPE4\t\t(23 * sizeof(USHORT))\n#define HEADER_TYPE5\t\t( 6 * sizeof(USHORT))\n\n/* Trackpad button data offsets */\n#define BUTTON_TYPE1\t\t0\n#define BUTTON_TYPE2\t\t15\n#define BUTTON_TYPE3\t\t23\n#define BUTTON_TYPE4\t\t31\n#define BUTTON_TYPE5\t\t1\n\n/* List of device capability bits */\n#define HAS_INTEGRATED_BUTTON\t1\n\n/* Trackpad finger data block size */\n#define FSIZE_TYPE1\t\t(14 * sizeof(USHORT))\n#define FSIZE_TYPE2\t\t(14 * sizeof(USHORT))\n#define FSIZE_TYPE3\t\t(14 * sizeof(USHORT))\n#define FSIZE_TYPE4\t\t(15 * sizeof(USHORT))\n#define FSIZE_TYPE5\t\t(9)\n\n/* Offset from header to finger struct */\n#define DELTA_TYPE1\t\t(0 * sizeof(USHORT))\n#define DELTA_TYPE2\t\t(0 * sizeof(USHORT))\n#define DELTA_TYPE3\t\t(0 * sizeof(USHORT))\n#define DELTA_TYPE4\t\t(1 * sizeof(USHORT))\n#define DELTA_TYPE5\t\t(0 * sizeof(USHORT))\n\n/* USB control message mode switch data */\n#define USBMSG_TYPE1\t8, 0x300, 0, 0, 0x1, 0x8\n#define USBMSG_TYPE2\t8, 0x300, 0, 0, 0x1, 0x8\n#define USBMSG_TYPE3\t8, 0x300, 0, 0, 0x1, 0x8\n#define USBMSG_TYPE4\t2, 0x302, 2, 1, 0x1, 0x0\n#define USBMSG_TYPE5\t2, 0x302, 1, 1, 0x1, 0x0\n\n/* Wellspring initialization constants */\n#define BCM5974_WELLSPRING_MODE_READ_REQUEST_ID\t\t1\n#define BCM5974_WELLSPRING_MODE_WRITE_REQUEST_ID\t9\n\n/* Trackpad finger data size, empirically at least ten fingers */\n#define MAX_FINGERS\t\t16\n#define MAX_FINGER_ORIENTATION\t16384\n\n#define BCM5974_MOUSE_SIZE 8\n\n/* trackpad finger structure, le16-aligned */\n__declspec(align(2)) struct TRACKPAD_FINGER {\n\tUSHORT origin;\t\t/* zero when switching track finger */\n\tUSHORT abs_x;\t\t/* absolute x coodinate */\n\tUSHORT abs_y;\t\t/* absolute y coodinate */\n\tUSHORT rel_x;\t\t/* relative x coodinate */\n\tUSHORT rel_y;\t\t/* relative y coodinate */\n\tUSHORT tool_major;\t/* tool area, major axis */\n\tUSHORT tool_minor;\t/* tool area, minor axis */\n\tUSHORT orientation;\t/* 16384 when point, else 15 bit angle */\n\tUSHORT touch_major;\t/* touch area, major axis */\n\tUSHORT touch_minor;\t/* touch area, minor axis */\n\tUSHORT unused[2];\t/* zeros */\n\tUSHORT pressure;\t/* pressure on forcetouch touchpad */\n\tUSHORT multi;\t\t/* one finger: varies, more fingers: constant */\n};\n\n/* Trackpad finger structure for type5 (magic trackpad), le16-aligned */\n__declspec(align(2)) struct TRACKPAD_FINGER_TYPE5 \n{\n\tUCHAR AbsoluteX;\t\t\t/* absolute x coodinate */\n\tUCHAR AbsoluteXY;\t\t\t/* absolute x,y coodinate */\n\tUCHAR AbsoluteY[2];\t\t\t/* absolute y coodinate */\n\tUCHAR TouchMajor;\t\t\t/* touch area, major axis */\n\tUCHAR TouchMinor;\t\t\t/* touch area, minor axis */\n\tUCHAR Size;\t\t\t\t\t/* tool area, size */\n\tUCHAR Pressure;\t\t\t\t/* pressure on forcetouch touchpad */\n\tunion \n\t{\n\t\tstruct \n\t\t{\n\t\t\tUCHAR Id : 4;\n\t\t\tUCHAR Orientation : 4;\n\t\t} ContactIdentifier;\n\t\tUCHAR RawOrientationAndOrigin;\n\t};\n};\n\n/* device-specific parameters */\nstruct BCM5974_PARAM {\n\tint snratio;\t\t/* signal-to-noise ratio */\n\tint min;\t\t\t/* device minimum reading */\n\tint max;\t\t\t/* device maximum reading */\n};\n\n/* device-specific configuration */\nstruct BCM5974_CONFIG {\n\tint ansi, iso, jis;\t\t\t\t/* the product id of this device */\n\tint caps;\t\t\t\t\t\t/* device capability bitmask */\n\tint bt_ep;\t\t\t\t\t\t/* the endpoint of the button interface */\n\tint bt_datalen;\t\t\t\t\t/* data length of the button interface */\n\tint tp_ep;\t\t\t\t\t\t/* the endpoint of the trackpad interface */\n\tenum TRACKPAD_TYPE tp_type;\t\t/* type of trackpad interface */\n\tint tp_header;\t\t\t\t\t/* bytes in header block */\n\tint tp_datalen;\t\t\t\t\t/* data length of the trackpad interface */\n\tint tp_button;\t\t\t\t\t/* offset to button data */\n\tint tp_fsize;\t\t\t\t\t/* bytes in single finger block */\n\tint tp_delta;\t\t\t\t\t/* offset from header to finger struct */\n\tint um_size;\t\t\t\t\t/* usb control message length */\n\tint um_req_val;\t\t\t\t\t/* usb control message value */\n\tint um_req_idx;\t\t\t\t\t/* usb control message index */\n\tint um_switch_idx;\t\t\t\t/* usb control message mode switch index */\n\tint um_switch_on;\t\t\t\t/* usb control message mode switch on */\n\tint um_switch_off;\t\t\t\t/* usb control message mode switch off */\n\tstruct BCM5974_PARAM p;\t\t\t/* finger pressure limits */\n\tstruct BCM5974_PARAM w;\t\t\t/* finger width limits */\n\tstruct BCM5974_PARAM x;\t\t\t/* horizontal limits */\n\tstruct BCM5974_PARAM y;\t\t\t/* vertical limits */\n\tstruct BCM5974_PARAM o;\t\t\t/* orientation limits */\n};\n\n#define DATAFORMAT(type)\t\t\t\t\\\n\ttype,\t\t\t\t\t\t\\\n\tHEADER_##type,\t\t\t\t\t\\\n\tHEADER_##type + (MAX_FINGERS) * (FSIZE_##type),\t\\\n\tBUTTON_##type,\t\t\t\t\t\\\n\tFSIZE_##type,\t\t\t\t\t\\\n\tDELTA_##type,\t\t\t\t\t\\\n\tUSBMSG_##type\n\n/* logical signal quality */\n#define SN_PRESSURE\t45\t\t/* pressure signal-to-noise ratio */\n#define SN_WIDTH\t25\t\t/* width signal-to-noise ratio */\n#define SN_COORD\t250\t\t/* coordinate signal-to-noise ratio */\n#define SN_ORIENT\t10\t\t/* orientation signal-to-noise ratio */\n\n#define PRESSURE_QUALIFICATION_THRESHOLD 2\n#define SIZE_QUALIFICATION_THRESHOLD 9\n#define SIZE_MU_LOWER_THRESHOLD 5\n\n#define PRESSURE_MU_QUALIFICATION_THRESHOLD_TOTAL 15\n#define SIZE_MU_QUALIFICATION_THRESHOLD_TOTAL 25\n\n/* device constants */\nstatic const struct BCM5974_CONFIG Bcm5974ConfigTable[] = {\n\t{\n\t\tUSB_DEVICE_ID_APPLE_WELLSPRING_ANSI,\n\t\tUSB_DEVICE_ID_APPLE_WELLSPRING_ISO,\n\t\tUSB_DEVICE_ID_APPLE_WELLSPRING_JIS,\n\t\t0,\n\t\t0x84, sizeof(struct TRACKPAD_BUTTON_DATA),\n\t\t0x81, DATAFORMAT(TYPE1),\n\t\t{ SN_PRESSURE, 0, 256 },\n\t\t{ SN_WIDTH, 0, 2048 },\n\t\t{ SN_COORD, -4824, 5342 },\n\t\t{ SN_COORD, -172, 5820 },\n\t\t{ SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }\n\t},\n\t{\n\t\tUSB_DEVICE_ID_APPLE_WELLSPRING2_ANSI,\n\t\tUSB_DEVICE_ID_APPLE_WELLSPRING2_ISO,\n\t\tUSB_DEVICE_ID_APPLE_WELLSPRING2_JIS,\n\t\t0,\n\t\t0x84, sizeof(struct TRACKPAD_BUTTON_DATA),\n\t\t0x81, DATAFORMAT(TYPE1),\n\t\t{ SN_PRESSURE, 0, 256 },\n\t\t{ SN_WIDTH, 0, 2048 },\n\t\t{ SN_COORD, -4824, 4824 },\n\t\t{ SN_COORD, -172, 4290 },\n\t\t{ SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }\n\t},\n\t{\n\t\tUSB_DEVICE_ID_APPLE_WELLSPRING3_ANSI,\n\t\tUSB_DEVICE_ID_APPLE_WELLSPRING3_ISO,\n\t\tUSB_DEVICE_ID_APPLE_WELLSPRING3_JIS,\n\t\tHAS_INTEGRATED_BUTTON,\n\t\t0x84, sizeof(struct TRACKPAD_BUTTON_DATA),\n\t\t0x81, DATAFORMAT(TYPE2),\n\t\t{ SN_PRESSURE, 0, 300 },\n\t\t{ SN_WIDTH, 0, 2048 },\n\t\t{ SN_COORD, -4460, 5166 },\n\t\t{ SN_COORD, -75, 6700 },\n\t\t{ SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }\n\t},\n\t{\n\t\tUSB_DEVICE_ID_APPLE_WELLSPRING4_ANSI,\n\t\tUSB_DEVICE_ID_APPLE_WELLSPRING4_ISO,\n\t\tUSB_DEVICE_ID_APPLE_WELLSPRING4_JIS,\n\t\tHAS_INTEGRATED_BUTTON,\n\t\t0x84, sizeof(struct TRACKPAD_BUTTON_DATA),\n\t\t0x81, DATAFORMAT(TYPE2),\n\t\t{ SN_PRESSURE, 0, 300 },\n\t\t{ SN_WIDTH, 0, 2048 },\n\t\t{ SN_COORD, -4620, 5140 },\n\t\t{ SN_COORD, -150, 6600 },\n\t\t{ SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }\n\t},\n\t{\n\t\tUSB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI,\n\t\tUSB_DEVICE_ID_APPLE_WELLSPRING4A_ISO,\n\t\tUSB_DEVICE_ID_APPLE_WELLSPRING4A_JIS,\n\t\tHAS_INTEGRATED_BUTTON,\n\t\t0x84, sizeof(struct TRACKPAD_BUTTON_DATA),\n\t\t0x81, DATAFORMAT(TYPE2),\n\t\t{ SN_PRESSURE, 0, 300 },\n\t\t{ SN_WIDTH, 0, 2048 },\n\t\t{ SN_COORD, -4616, 5112 },\n\t\t{ SN_COORD, -142, 5234 },\n\t\t{ SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }\n\t},\n\t{\n\t\tUSB_DEVICE_ID_APPLE_WELLSPRING5_ANSI,\n\t\tUSB_DEVICE_ID_APPLE_WELLSPRING5_ISO,\n\t\tUSB_DEVICE_ID_APPLE_WELLSPRING5_JIS,\n\t\tHAS_INTEGRATED_BUTTON,\n\t\t0x84, sizeof(struct TRACKPAD_BUTTON_DATA),\n\t\t0x81, DATAFORMAT(TYPE2),\n\t\t{ SN_PRESSURE, 0, 300 },\n\t\t{ SN_WIDTH, 0, 2048 },\n\t\t{ SN_COORD, -4415, 5050 },\n\t\t{ SN_COORD, -55, 6680 },\n\t\t{ SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }\n\t},\n\t{\n\t\tUSB_DEVICE_ID_APPLE_WELLSPRING6_ANSI,\n\t\tUSB_DEVICE_ID_APPLE_WELLSPRING6_ISO,\n\t\tUSB_DEVICE_ID_APPLE_WELLSPRING6_JIS,\n\t\tHAS_INTEGRATED_BUTTON,\n\t\t0x84, sizeof(struct TRACKPAD_BUTTON_DATA),\n\t\t0x81, DATAFORMAT(TYPE2),\n\t\t{ SN_PRESSURE, 0, 300 },\n\t\t{ SN_WIDTH, 0, 2048 },\n\t\t{ SN_COORD, -4620, 5140 },\n\t\t{ SN_COORD, -150, 6600 },\n\t\t{ SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }\n\t},\n\t{\n\t\tUSB_DEVICE_ID_APPLE_WELLSPRING5A_ANSI,\n\t\tUSB_DEVICE_ID_APPLE_WELLSPRING5A_ISO,\n\t\tUSB_DEVICE_ID_APPLE_WELLSPRING5A_JIS,\n\t\tHAS_INTEGRATED_BUTTON,\n\t\t0x84, sizeof(struct TRACKPAD_BUTTON_DATA),\n\t\t0x81, DATAFORMAT(TYPE2),\n\t\t{ SN_PRESSURE, 0, 300 },\n\t\t{ SN_WIDTH, 0, 2048 },\n\t\t{ SN_COORD, -4750, 5280 },\n\t\t{ SN_COORD, -150, 6730 },\n\t\t{ SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }\n\t},\n\t{\n\t\tUSB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI,\n\t\tUSB_DEVICE_ID_APPLE_WELLSPRING6A_ISO,\n\t\tUSB_DEVICE_ID_APPLE_WELLSPRING6A_JIS,\n\t\tHAS_INTEGRATED_BUTTON,\n\t\t0x84, sizeof(struct TRACKPAD_BUTTON_DATA),\n\t\t0x81, DATAFORMAT(TYPE2),\n\t\t{ SN_PRESSURE, 0, 300 },\n\t\t{ SN_WIDTH, 0, 2048 },\n\t\t{ SN_COORD, -4620, 5140 },\n\t\t{ SN_COORD, -150, 6600 },\n\t\t{ SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }\n\t},\n\t{\n\t\tUSB_DEVICE_ID_APPLE_WELLSPRING7_ANSI,\n\t\tUSB_DEVICE_ID_APPLE_WELLSPRING7_ISO,\n\t\tUSB_DEVICE_ID_APPLE_WELLSPRING7_JIS,\n\t\tHAS_INTEGRATED_BUTTON,\n\t\t0x84, sizeof(struct TRACKPAD_BUTTON_DATA),\n\t\t0x81, DATAFORMAT(TYPE2),\n\t\t{ SN_PRESSURE, 0, 300 },\n\t\t{ SN_WIDTH, 0, 2048 },\n\t\t{ SN_COORD, -4750, 5280 },\n\t\t{ SN_COORD, -150, 6730 },\n\t\t{ SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }\n\t},\n\t{\n\t\tUSB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI,\n\t\tUSB_DEVICE_ID_APPLE_WELLSPRING7A_ISO,\n\t\tUSB_DEVICE_ID_APPLE_WELLSPRING7A_JIS,\n\t\tHAS_INTEGRATED_BUTTON,\n\t\t0x84, sizeof(struct TRACKPAD_BUTTON_DATA),\n\t\t0x81, DATAFORMAT(TYPE2),\n\t\t{ SN_PRESSURE, 0, 300 },\n\t\t{ SN_WIDTH, 0, 2048 },\n\t\t{ SN_COORD, -4750, 5280 },\n\t\t{ SN_COORD, -150, 6730 },\n\t\t{ SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }\n\t},\n\t{\n\t\tUSB_DEVICE_ID_APPLE_WELLSPRING8_ANSI,\n\t\tUSB_DEVICE_ID_APPLE_WELLSPRING8_ISO,\n\t\tUSB_DEVICE_ID_APPLE_WELLSPRING8_JIS,\n\t\tHAS_INTEGRATED_BUTTON,\n\t\t0, sizeof(struct TRACKPAD_BUTTON_DATA),\n\t\t0x83, DATAFORMAT(TYPE3),\n\t\t{ SN_PRESSURE, 0, 300 },\n\t\t{ SN_WIDTH, 0, 2048 },\n\t\t{ SN_COORD, -4620, 5140 },\n\t\t{ SN_COORD, -150, 6600 },\n\t\t{ SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }\n\t},\n\t{\n\t\tUSB_DEVICE_ID_APPLE_WELLSPRING9_ANSI,\n\t\tUSB_DEVICE_ID_APPLE_WELLSPRING9_ISO,\n\t\tUSB_DEVICE_ID_APPLE_WELLSPRING9_JIS,\n\t\tHAS_INTEGRATED_BUTTON,\n\t\t0, sizeof(struct TRACKPAD_BUTTON_DATA),\n\t\t0x83, DATAFORMAT(TYPE4),\n\t\t{ SN_PRESSURE, 0, 300 },\n\t\t{ SN_WIDTH, 0, 2048 },\n\t\t{ SN_COORD, -4828, 5345 },\n\t\t{ SN_COORD, -203, 6803 },\n\t\t{ SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }\n\t},\n\t{\n\t\tUSB_DEVICE_ID_APPLE_MAGICTRACKPAD2,\n\t\tUSB_DEVICE_ID_APPLE_MAGICTRACKPAD2,\n\t\tUSB_DEVICE_ID_APPLE_MAGICTRACKPAD2,\n\t\tHAS_INTEGRATED_BUTTON,\n\t\t0, sizeof(struct TRACKPAD_BUTTON_DATA),\n\t\t0x83, DATAFORMAT(TYPE5),\n\t\t{ SN_PRESSURE, 0, 300 },\n\t\t{ SN_WIDTH, 0, 2048 },\n\t\t{ SN_COORD, -3678, 3934 },\n\t\t{ SN_COORD, -2479, 2586 },\n\t\t{ SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }\n\t},\n\t{\n\t\tUSB_DEVICE_ID_APPLE_T2,\n\t\tUSB_DEVICE_ID_APPLE_T2,\n\t\tUSB_DEVICE_ID_APPLE_T2,\n\t\tHAS_INTEGRATED_BUTTON,\n\t\t0, sizeof(struct TRACKPAD_BUTTON_DATA),\n\t\t0x83, DATAFORMAT(TYPE4),\n\t\t{ SN_PRESSURE, 0, 300 },\n\t\t/* This is incorrect; check actual data later */\n\t\t{ SN_WIDTH, 0, 2048 },\n\t\t{ SN_COORD, -4828, 5345 },\n\t\t{ SN_COORD, -203, 6803 },\n\t\t{ SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }\n\t},\n};"
  },
  {
    "path": "src/AmtPtpDeviceUsbUm/include/Device.h",
    "content": "// Device.h: Device definitions\n\nEXTERN_C_START\n\n// Device context struct\ntypedef struct _DEVICE_CONTEXT\n{\n\tWDFUSBDEVICE                UsbDevice;\n\tWDFUSBPIPE                  InterruptPipe;\n\tWDFUSBINTERFACE             UsbInterface;\n\tWDFQUEUE                    InputQueue;\n\n\tUSB_DEVICE_DESCRIPTOR       DeviceDescriptor;\n\n\tconst struct BCM5974_CONFIG *DeviceInfo;\n\n\tULONG                       UsbDeviceTraits;\n\n\tUCHAR\t\t\t\t\t\tPressureQualLevel;\n\tUCHAR\t\t\t\t\t\tSgContactSizeQualLevel;\n\tUCHAR\t\t\t\t\t\tMuContactSizeQualLevel;\n\n\tBOOL                        IsWellspringModeOn;\n\tBOOL                        IsSurfaceReportOn;\n\tBOOL                        IsButtonReportOn;\n\n\tLARGE_INTEGER\t\t\t\tPerfCounter;\n\n} DEVICE_CONTEXT, *PDEVICE_CONTEXT;\n\n//\n// This macro will generate an inline function called DeviceGetContext\n// which will be used to get a pointer to the device context memory\n// in a type safe manner.\n//\nWDF_DECLARE_CONTEXT_TYPE_WITH_NAME(DEVICE_CONTEXT, DeviceGetContext)\n\n//\n// Pool tags\n//\n#define POOL_TAG_PTP_CONTROL 'PTPC'\n\n//\n// Function to initialize the device's queues and callbacks\n//\nNTSTATUS\nAmtPtpCreateDevice(\n\t_In_    WDFDRIVER       Driver,\n\t_Inout_ PWDFDEVICE_INIT DeviceInit\n);\n\n//\n// Function to select the device's USB configuration and get a WDFUSBDEVICE\n// handle\n//\nEVT_WDF_DEVICE_PREPARE_HARDWARE AmtPtpEvtDevicePrepareHardware;\nEVT_WDF_DEVICE_D0_ENTRY AmtPtpEvtDeviceD0Entry;\nEVT_WDF_DEVICE_D0_EXIT AmtPtpEvtDeviceD0Exit;\n\n_IRQL_requires_(PASSIVE_LEVEL)\nNTSTATUS\nAmtPtpConfigContReaderForInterruptEndPoint(\n\t_In_ PDEVICE_CONTEXT DeviceContext\n);\n\n_IRQL_requires_(PASSIVE_LEVEL)\nNTSTATUS\nAmtPtpGetWellspringMode(\n\t_In_  PDEVICE_CONTEXT DeviceContext,\n\t_Out_ BOOL* IsWellspringModeOn\n);\n\n_IRQL_requires_(PASSIVE_LEVEL)\nNTSTATUS\nSelectInterruptInterface(\n\t_In_ WDFDEVICE Device\n);\n\n_IRQL_requires_(PASSIVE_LEVEL)\nNTSTATUS\nAmtPtpSetWellspringMode(\n\t_In_ PDEVICE_CONTEXT DeviceContext,\n\t_In_ BOOL IsWellspringModeOn\n);\n\n_IRQL_requires_(PASSIVE_LEVEL)\nPCHAR\nDbgDevicePowerString(\n\t_In_ WDF_POWER_DEVICE_STATE Type\n);\n\n_IRQL_requires_(PASSIVE_LEVEL)\nVOID\nAmtPtpEvtUsbInterruptPipeReadComplete(\n\t_In_ WDFUSBPIPE  Pipe,\n\t_In_ WDFMEMORY   Buffer,\n\t_In_ size_t      NumBytesTransferred,\n\t_In_ WDFCONTEXT  Context\n);\n\n_IRQL_requires_(PASSIVE_LEVEL)\nBOOLEAN\nAmtPtpEvtUsbInterruptReadersFailed(\n\t_In_ WDFUSBPIPE Pipe,\n\t_In_ NTSTATUS Status,\n\t_In_ USBD_STATUS UsbdStatus\n);\n\n_IRQL_requires_(PASSIVE_LEVEL)\nNTSTATUS\nAmtPtpServiceTouchInputInterrupt(\n\t_In_ PDEVICE_CONTEXT DeviceContext,\n\t_In_ UCHAR* Buffer,\n\t_In_ size_t NumBytesTransferred\n);\n\n_IRQL_requires_(PASSIVE_LEVEL)\nNTSTATUS\nAmtPtpServiceTouchInputInterruptType5(\n\t_In_ PDEVICE_CONTEXT DeviceContext,\n\t_In_ UCHAR* Buffer,\n\t_In_ size_t NumBytesTransferred\n);\n\n_IRQL_requires_(PASSIVE_LEVEL)\nNTSTATUS\nAmtPtpEmergResetDevice(\n\t_In_ PDEVICE_CONTEXT DeviceContext\n);\n\n///\n/// HID sections\n///\n\n_IRQL_requires_(PASSIVE_LEVEL)\nNTSTATUS\nAmtPtpGetHidDescriptor(\n\t_In_ WDFDEVICE Device,\n\t_In_ WDFREQUEST Request\n);\n\n_IRQL_requires_(PASSIVE_LEVEL)\nNTSTATUS\nAmtPtpGetDeviceAttribs(\n\t_In_ WDFDEVICE Device,\n\t_In_ WDFREQUEST Request\n);\n\n_IRQL_requires_(PASSIVE_LEVEL)\nNTSTATUS\nAmtPtpGetReportDescriptor(\n\t_In_ WDFDEVICE Device,\n\t_In_ WDFREQUEST Request\n);\n\n_IRQL_requires_(PASSIVE_LEVEL)\nNTSTATUS\nAmtPtpGetStrings(\n\t_In_ WDFDEVICE Device,\n\t_In_ WDFREQUEST Request\n);\n\n_IRQL_requires_(PASSIVE_LEVEL)\nNTSTATUS\nAmtPtpReportFeatures(\n\t_In_ WDFDEVICE Device,\n\t_In_ WDFREQUEST Request\n);\n\n_IRQL_requires_(PASSIVE_LEVEL)\nNTSTATUS\nAmtPtpSetFeatures(\n\t_In_ WDFDEVICE Device,\n\t_In_ WDFREQUEST Request\n);\n\n//\n// Utils\n//\n\n_IRQL_requires_(PASSIVE_LEVEL)\nNTSTATUS\nRequestGetHidXferPacketToReadFromDevice(\n\t_In_  WDFREQUEST        Request,\n\t_Out_ HID_XFER_PACKET  *Packet\n);\n\n_IRQL_requires_(PASSIVE_LEVEL)\nNTSTATUS\nRequestGetHidXferPacketToWriteToDevice(\n\t_In_  WDFREQUEST        Request,\n\t_Out_ HID_XFER_PACKET  *Packet\n);\n\n// Helper function for numberic operation\nstatic inline INT AmtRawToInteger(\n\t_In_ USHORT x\n);\n\nEXTERN_C_END\n"
  },
  {
    "path": "src/AmtPtpDeviceUsbUm/include/DeviceFamily/Wellspring3.h",
    "content": "#pragma once\n\n#include <HidCommon.h>\n\n#define AAPL_WELLSPRING_3_PTP_FINGER_COLLECTION_1 \\\n\tBEGIN_COLLECTION, 0x02, /* Begin Collection: Logical */ \\\n\t\t/* Begin a byte */ \\\n\t\tLOGICAL_MAXIMUM, 0x01, /* Logical Maximum: 1 */ \\\n\t\tUSAGE, 0x47, /* Usage: Confidence */ \\\n\t\tUSAGE, 0x42, /* Usage: Tip switch */ \\\n\t\tREPORT_COUNT, 0x02, /* Report Count: 2 */ \\\n\t\tREPORT_SIZE, 0x01, /* Report Size: 1 */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tREPORT_SIZE, 0x01, /* Report Size: 1 */ \\\n\t\tREPORT_COUNT, 0x06, /* Report Count: 6 */ \\\n\t\tINPUT, 0x03, /* Input: (Const, Var, Abs) */ \\\n\t\t/* End of a byte */ \\\n\t\t/* Begin of 4 bytes */ \\\n\t\tREPORT_COUNT, 0x01, /* Report Count: 1 */ \\\n\t\tREPORT_SIZE, 0x20, /* Report Size: 0x20 (4 bytes) */ \\\n\t\tLOGICAL_MAXIMUM_3, 0xff, 0xff, 0xff, 0xff, /* Logical Maximum: 0xffffffff */ \\\n\t\tUSAGE, 0x51, /* Usage: Contract Identifier */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\t/* End of 4 bytes */ \\\n\t\t/* Begin of 4 bytes */ \\\n\t\t/* Size is hard-coded at this moment */ \\\n\t\t/* This hard-coded size is designed for MacBookAir 7,2 */ \\\n\t\tUSAGE_PAGE, 0x01, /* Usage Page: Generic Desktop */ \\\n\t\tLOGICAL_MAXIMUM_2, 0x9a, 0x25, /* Logical Maximum: 9626 (See defintion) */ \\\n\t\tREPORT_SIZE, 0x10, /* Report Size: 0x10 (2 bytes) */ \\\n\t\tUNIT_EXPONENT, 0x0e, /* Unit exponent: -2 */ \\\n\t\tUNIT, 0x11, /* Unit: SI Length (cm) */ \\\n\t\tUSAGE, 0x30, /* Usage: X */ \\\n\t\tPHYSICAL_MAXIMUM_2, 0x1a, 0x04, /* Physical Maximum: 1050 (See Apple Spec) */ \\\n\t\tREPORT_COUNT, 0x01, /* Report count: 1 */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tPHYSICAL_MAXIMUM_2, 0xf8, 0x02, /* Physical Maximum: 760 (See Apple Spec) */ \\\n\t\tLOGICAL_MAXIMUM_2, 0x77, 0x1a, /* Logical Maximum: 6775 (See definition) */ \\\n\t\tUSAGE, 0x31, /* Usage: Y */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tPHYSICAL_MAXIMUM, 0x00, /* Physical Maximum: 0 */ \\\n\t\tUNIT_EXPONENT, 0x00, /* Unit exponent: 0 */ \\\n\t\tUNIT, 0x00, /* Unit: None */ \\\n\t\t/* End of 4 bytes */ \\\n\tEND_COLLECTION /* End Collection */ \\\n\n#define AAPL_WELLSPRING_3_PTP_FINGER_COLLECTION_2 \\\n\tBEGIN_COLLECTION, 0x02, /* Begin Collection: Logical */ \\\n\t\t/* Begin a byte */ \\\n\t\tLOGICAL_MAXIMUM, 0x01, /* Logical Maximum: 1 */ \\\n\t\tUSAGE, 0x47, /* Usage: Confidence */ \\\n\t\tUSAGE, 0x42, /* Usage: Tip switch */ \\\n\t\tREPORT_COUNT, 0x02, /* Report Count: 2 */ \\\n\t\tREPORT_SIZE, 0x01, /* Report Size: 1 */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tREPORT_SIZE, 0x01, /* Report Size: 1 */ \\\n\t\tREPORT_COUNT, 0x06, /* Report Count: 6 */ \\\n\t\tINPUT, 0x03, /* Input: (Const, Var, Abs) */ \\\n\t\t/* End of a byte */ \\\n\t\t/* Begin of 4 bytes */ \\\n\t\tREPORT_COUNT, 0x01, /* Report Count: 1 */ \\\n\t\tREPORT_SIZE, 0x20, /* Report Size: 0x20 (4 bytes) */ \\\n\t\tLOGICAL_MAXIMUM_3, 0xff, 0xff, 0xff, 0xff, /* Logical Maximum: 0xffffffff */ \\\n\t\tUSAGE, 0x51, /* Usage: Contract Identifier */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\t/* End of 4 bytes */ \\\n\t\t/* Begin of 4 bytes */ \\\n\t\t/* Size is hard-coded at this moment */ \\\n\t\tUSAGE_PAGE, 0x01, /* Usage Page: Generic Desktop */ \\\n\t\tLOGICAL_MAXIMUM_2, 0x9a, 0x25, /* Logical Maximum: 9626 (See defintion) */ \\\n\t\tREPORT_SIZE, 0x10, /* Report Size: 0x10 (2 bytes) */ \\\n\t\tUNIT_EXPONENT, 0x0e, /* Unit exponent: -2 */ \\\n\t\tUNIT, 0x11, /* Unit: SI Length (cm) */ \\\n\t\tUSAGE, 0x30, /* Usage: X */ \\\n\t\tPHYSICAL_MAXIMUM_2, 0x1a, 0x04, /* Physical Maximum: 1050 (See Apple Spec) */ \\\n\t\tREPORT_COUNT, 0x01, /* Report count: 1 */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tPHYSICAL_MAXIMUM_2, 0xf8, 0x02, /* Physical Maximum: 760 (See Apple Spec) */ \\\n\t\tLOGICAL_MAXIMUM_2, 0x77, 0x1a, /* Logical Maximum: 6775 (See definition) */ \\\n\t\tUSAGE, 0x31, /* Usage: Y */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\t/* End of 4 bytes */ \\\n\tEND_COLLECTION /* End Collection */ \\\n\n#define AAPL_WELLSPRING_3_PTP_TLC \\\n\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\tUSAGE, 0x05, /* Usage: Touch Pad */ \\\n\tBEGIN_COLLECTION, 0x01, /* Begin Collection: Application */ \\\n\t\tREPORT_ID, REPORTID_MULTITOUCH, /* Report ID: Multi-touch */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_WELLSPRING_3_PTP_FINGER_COLLECTION_1, /* 1 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_WELLSPRING_3_PTP_FINGER_COLLECTION_1, /* 2 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_WELLSPRING_3_PTP_FINGER_COLLECTION_2, /* 3 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_WELLSPRING_3_PTP_FINGER_COLLECTION_1, /* 4 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_WELLSPRING_3_PTP_FINGER_COLLECTION_2, /* 5 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUNIT_EXPONENT, 0x0c, /* Unit exponent: -4 */ \\\n\t\tUNIT_2, 0x01, 0x10, /* Time: Second */ \\\n\t\tPHYSICAL_MAXIMUM_3, 0xff, 0xff, 0x00, 0x00, \\\n\t\tLOGICAL_MAXIMUM_3, 0xff, 0xff, 0x00, 0x00, \\\n\t\tUSAGE, 0x56, /* Usage: Scan Time */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tUSAGE, 0x54, /* Usage: Contact Count */ \\\n\t\tLOGICAL_MAXIMUM, 0x7f, \\\n\t\tREPORT_SIZE, 0x08, \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tUSAGE_PAGE, 0x09, /* Usage Page: Button */ \\\n\t\tUSAGE, 0x01, /* Button 1 */ \\\n\t\tLOGICAL_MAXIMUM, 0x01, \\\n\t\tREPORT_SIZE, 0x01, \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tREPORT_COUNT, 0x07, \\\n\t\tINPUT, 0x03, /* Input: (Const, Var, Abs) */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tREPORT_ID, REPORTID_DEVICE_CAPS, \\\n\t\tUSAGE, 0x55, /* Usage: Maximum Contacts */ \\\n\t\tUSAGE, 0x59, /* Usage: Touchpad Button Type*/ \\\n\t\tLOGICAL_MINIMUM, 0x00, \\\n\t\tLOGICAL_MAXIMUM_2, 0xff, 0x00, \\\n\t\tREPORT_SIZE, 0x08, \\\n\t\tREPORT_COUNT, 0x02, \\\n\t\tFEATURE, 0x02, \\\n\t\tUSAGE_PAGE_1, 0x00, 0xff, \\\n\t\tREPORT_ID, REPORTID_PTPHQA, \\\n\t\tUSAGE, 0xc5, \\\n\t\tLOGICAL_MINIMUM, 0x00, \\\n\t\tLOGICAL_MAXIMUM_2, 0xff, 0x00, \\\n\t\tREPORT_SIZE, 0x08, \\\n\t\tREPORT_COUNT_2, 0x00, 0x01, \\\n\t\tFEATURE, 0x02, \\\n\tEND_COLLECTION /* End Collection */\n"
  },
  {
    "path": "src/AmtPtpDeviceUsbUm/include/DeviceFamily/Wellspring5.h",
    "content": "#pragma once\n\n#include <HidCommon.h>\n\n#define AAPL_WELLSPRING_5_PTP_FINGER_COLLECTION_1 \\\n\tBEGIN_COLLECTION, 0x02, /* Begin Collection: Logical */ \\\n\t\t/* Begin a byte */ \\\n\t\tLOGICAL_MAXIMUM, 0x01, /* Logical Maximum: 1 */ \\\n\t\tUSAGE, 0x47, /* Usage: Confidence */ \\\n\t\tUSAGE, 0x42, /* Usage: Tip switch */ \\\n\t\tREPORT_COUNT, 0x02, /* Report Count: 2 */ \\\n\t\tREPORT_SIZE, 0x01, /* Report Size: 1 */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tREPORT_SIZE, 0x01, /* Report Size: 1 */ \\\n\t\tREPORT_COUNT, 0x06, /* Report Count: 6 */ \\\n\t\tINPUT, 0x03, /* Input: (Const, Var, Abs) */ \\\n\t\t/* End of a byte */ \\\n\t\t/* Begin of 4 bytes */ \\\n\t\tREPORT_COUNT, 0x01, /* Report Count: 1 */ \\\n\t\tREPORT_SIZE, 0x20, /* Report Size: 0x20 (4 bytes) */ \\\n\t\tLOGICAL_MAXIMUM_3, 0xff, 0xff, 0xff, 0xff, /* Logical Maximum: 0xffffffff */ \\\n\t\tUSAGE, 0x51, /* Usage: Contract Identifier */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\t/* End of 4 bytes */ \\\n\t\t/* Begin of 4 bytes */ \\\n\t\t/* Size is hard-coded at this moment */ \\\n\t\t/* This hard-coded size is designed for MacBookAir 7,2 */ \\\n\t\tUSAGE_PAGE, 0x01, /* Usage Page: Generic Desktop */ \\\n\t\tLOGICAL_MAXIMUM_2, 0xf9, 0x24, /* Logical Maximum: 9465 (See defintion) */ \\\n\t\tREPORT_SIZE, 0x10, /* Report Size: 0x10 (2 bytes) */ \\\n\t\tUNIT_EXPONENT, 0x0e, /* Unit exponent: -2 */ \\\n\t\tUNIT, 0x11, /* Unit: SI Length (cm) */ \\\n\t\tUSAGE, 0x30, /* Usage: X */ \\\n\t\tPHYSICAL_MAXIMUM_2, 0x1a, 0x04, /* Physical Maximum: 1050 (See Apple Spec) */ \\\n\t\tREPORT_COUNT, 0x01, /* Report count: 1 */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tPHYSICAL_MAXIMUM_2, 0x2a, 0x03, /* Physical Maximum: 810 (See Apple Spec) */ \\\n\t\tLOGICAL_MAXIMUM_2, 0x4f, 0x1a, /* Logical Maximum: 6735 (See definition) */ \\\n\t\tUSAGE, 0x31, /* Usage: Y */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tPHYSICAL_MAXIMUM, 0x00, /* Physical Maximum: 0 */ \\\n\t\tUNIT_EXPONENT, 0x00, /* Unit exponent: 0 */ \\\n\t\tUNIT, 0x00, /* Unit: None */ \\\n\t\t/* End of 4 bytes */ \\\n\tEND_COLLECTION /* End Collection */ \\\n\n#define AAPL_WELLSPRING_5_PTP_FINGER_COLLECTION_2 \\\n\tBEGIN_COLLECTION, 0x02, /* Begin Collection: Logical */ \\\n\t\t/* Begin a byte */ \\\n\t\tLOGICAL_MAXIMUM, 0x01, /* Logical Maximum: 1 */ \\\n\t\tUSAGE, 0x47, /* Usage: Confidence */ \\\n\t\tUSAGE, 0x42, /* Usage: Tip switch */ \\\n\t\tREPORT_COUNT, 0x02, /* Report Count: 2 */ \\\n\t\tREPORT_SIZE, 0x01, /* Report Size: 1 */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tREPORT_SIZE, 0x01, /* Report Size: 1 */ \\\n\t\tREPORT_COUNT, 0x06, /* Report Count: 6 */ \\\n\t\tINPUT, 0x03, /* Input: (Const, Var, Abs) */ \\\n\t\t/* End of a byte */ \\\n\t\t/* Begin of 4 bytes */ \\\n\t\tREPORT_COUNT, 0x01, /* Report Count: 1 */ \\\n\t\tREPORT_SIZE, 0x20, /* Report Size: 0x20 (4 bytes) */ \\\n\t\tLOGICAL_MAXIMUM_3, 0xff, 0xff, 0xff, 0xff, /* Logical Maximum: 0xffffffff */ \\\n\t\tUSAGE, 0x51, /* Usage: Contract Identifier */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\t/* End of 4 bytes */ \\\n\t\t/* Begin of 4 bytes */ \\\n\t\t/* Size is hard-coded at this moment */ \\\n\t\tUSAGE_PAGE, 0x01, /* Usage Page: Generic Desktop */ \\\n\t\tLOGICAL_MAXIMUM_2, 0xf9, 0x24, /* Logical Maximum: 9465 (See defintion) */ \\\n\t\tREPORT_SIZE, 0x10, /* Report Size: 0x10 (2 bytes) */ \\\n\t\tUNIT_EXPONENT, 0x0e, /* Unit exponent: -2 */ \\\n\t\tUNIT, 0x11, /* Unit: SI Length (cm) */ \\\n\t\tUSAGE, 0x30, /* Usage: X */ \\\n\t\tPHYSICAL_MAXIMUM_2, 0x1a, 0x04, /* Physical Maximum: 1050 (See Apple Spec) */ \\\n\t\tREPORT_COUNT, 0x01, /* Report count: 1 */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tPHYSICAL_MAXIMUM_2, 0x2a, 0x03, /* Physical Maximum: 810 (See Apple Spec) */ \\\n\t\tLOGICAL_MAXIMUM_2, 0x4f, 0x1a, /* Logical Maximum: 6735 (See definition) */ \\\n\t\tUSAGE, 0x31, /* Usage: Y */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\t/* End of 4 bytes */ \\\n\tEND_COLLECTION /* End Collection */ \\\n\n#define AAPL_WELLSPRING_5_PTP_TLC \\\n\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\tUSAGE, 0x05, /* Usage: Touch Pad */ \\\n\tBEGIN_COLLECTION, 0x01, /* Begin Collection: Application */ \\\n\t\tREPORT_ID, REPORTID_MULTITOUCH, /* Report ID: Multi-touch */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_WELLSPRING_5_PTP_FINGER_COLLECTION_1, /* 1 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_WELLSPRING_5_PTP_FINGER_COLLECTION_1, /* 2 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_WELLSPRING_5_PTP_FINGER_COLLECTION_2, /* 3 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_WELLSPRING_5_PTP_FINGER_COLLECTION_1, /* 4 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_WELLSPRING_5_PTP_FINGER_COLLECTION_2, /* 5 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUNIT_EXPONENT, 0x0c, /* Unit exponent: -4 */ \\\n\t\tUNIT_2, 0x01, 0x10, /* Time: Second */ \\\n\t\tPHYSICAL_MAXIMUM_3, 0xff, 0xff, 0x00, 0x00, \\\n\t\tLOGICAL_MAXIMUM_3, 0xff, 0xff, 0x00, 0x00, \\\n\t\tUSAGE, 0x56, /* Usage: Scan Time */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tUSAGE, 0x54, /* Usage: Contact Count */ \\\n\t\tLOGICAL_MAXIMUM, 0x7f, \\\n\t\tREPORT_SIZE, 0x08, \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tUSAGE_PAGE, 0x09, /* Usage Page: Button */ \\\n\t\tUSAGE, 0x01, /* Button 1 */ \\\n\t\tLOGICAL_MAXIMUM, 0x01, \\\n\t\tREPORT_SIZE, 0x01, \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tREPORT_COUNT, 0x07, \\\n\t\tINPUT, 0x03, /* Input: (Const, Var, Abs) */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tREPORT_ID, REPORTID_DEVICE_CAPS, \\\n\t\tUSAGE, 0x55, /* Usage: Maximum Contacts */ \\\n\t\tUSAGE, 0x59, /* Usage: Touchpad Button Type*/ \\\n\t\tLOGICAL_MINIMUM, 0x00, \\\n\t\tLOGICAL_MAXIMUM_2, 0xff, 0x00, \\\n\t\tREPORT_SIZE, 0x08, \\\n\t\tREPORT_COUNT, 0x02, \\\n\t\tFEATURE, 0x02, \\\n\t\tUSAGE_PAGE_1, 0x00, 0xff, \\\n\t\tREPORT_ID, REPORTID_PTPHQA, \\\n\t\tUSAGE, 0xc5, \\\n\t\tLOGICAL_MINIMUM, 0x00, \\\n\t\tLOGICAL_MAXIMUM_2, 0xff, 0x00, \\\n\t\tREPORT_SIZE, 0x08, \\\n\t\tREPORT_COUNT_2, 0x00, 0x01, \\\n\t\tFEATURE, 0x02, \\\n\tEND_COLLECTION /* End Collection */\n"
  },
  {
    "path": "src/AmtPtpDeviceUsbUm/include/DeviceFamily/Wellspring6.h",
    "content": "#pragma once\n\n#include <HidCommon.h>\n\n#define AAPL_WELLSPRING_6_PTP_FINGER_COLLECTION_1 \\\n\tBEGIN_COLLECTION, 0x02, /* Begin Collection: Logical */ \\\n\t\t/* Begin a byte */ \\\n\t\tLOGICAL_MAXIMUM, 0x01, /* Logical Maximum: 1 */ \\\n\t\tUSAGE, 0x47, /* Usage: Confidence */ \\\n\t\tUSAGE, 0x42, /* Usage: Tip switch */ \\\n\t\tREPORT_COUNT, 0x02, /* Report Count: 2 */ \\\n\t\tREPORT_SIZE, 0x01, /* Report Size: 1 */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tREPORT_SIZE, 0x01, /* Report Size: 1 */ \\\n\t\tREPORT_COUNT, 0x06, /* Report Count: 6 */ \\\n\t\tINPUT, 0x03, /* Input: (Const, Var, Abs) */ \\\n\t\t/* End of a byte */ \\\n\t\t/* Begin of 4 bytes */ \\\n\t\tREPORT_COUNT, 0x01, /* Report Count: 1 */ \\\n\t\tREPORT_SIZE, 0x20, /* Report Size: 0x20 (4 bytes) */ \\\n\t\tLOGICAL_MAXIMUM_3, 0xff, 0xff, 0xff, 0xff, /* Logical Maximum: 0xffffffff */ \\\n\t\tUSAGE, 0x51, /* Usage: Contract Identifier */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\t/* End of 4 bytes */ \\\n\t\t/* Begin of 4 bytes */ \\\n\t\t/* Size is hard-coded at this moment */ \\\n\t\t/* This hard-coded size is designed for MacBookAir 7,2 */ \\\n\t\tUSAGE_PAGE, 0x01, /* Usage Page: Generic Desktop */ \\\n\t\tLOGICAL_MAXIMUM_2, 0x20, 0x26, /* Logical Maximum: 9760 (See defintion) */ \\\n\t\tREPORT_SIZE, 0x10, /* Report Size: 0x10 (2 bytes) */ \\\n\t\tUNIT_EXPONENT, 0x0e, /* Unit exponent: -2 */ \\\n\t\tUNIT, 0x11, /* Unit: SI Length (cm) */ \\\n\t\tUSAGE, 0x30, /* Usage: X */ \\\n\t\tPHYSICAL_MAXIMUM_2, 0x2b, 0x04, /* Physical Maximum: 1067 (See Apple Spec) */ \\\n\t\tREPORT_COUNT, 0x01, /* Report count: 1 */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tPHYSICAL_MAXIMUM_2, 0xfa, 0x02, /* Physical Maximum: 762 (See Apple Spec) */ \\\n\t\tLOGICAL_MAXIMUM_2, 0x5e, 0x1a, /* Logical Maximum: 6750 (See definition) */ \\\n\t\tUSAGE, 0x31, /* Usage: Y */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tPHYSICAL_MAXIMUM, 0x00, /* Physical Maximum: 0 */ \\\n\t\tUNIT_EXPONENT, 0x00, /* Unit exponent: 0 */ \\\n\t\tUNIT, 0x00, /* Unit: None */ \\\n\t\t/* End of 4 bytes */ \\\n\tEND_COLLECTION /* End Collection */ \\\n\n#define AAPL_WELLSPRING_6_PTP_FINGER_COLLECTION_2 \\\n\tBEGIN_COLLECTION, 0x02, /* Begin Collection: Logical */ \\\n\t\t/* Begin a byte */ \\\n\t\tLOGICAL_MAXIMUM, 0x01, /* Logical Maximum: 1 */ \\\n\t\tUSAGE, 0x47, /* Usage: Confidence */ \\\n\t\tUSAGE, 0x42, /* Usage: Tip switch */ \\\n\t\tREPORT_COUNT, 0x02, /* Report Count: 2 */ \\\n\t\tREPORT_SIZE, 0x01, /* Report Size: 1 */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tREPORT_SIZE, 0x01, /* Report Size: 1 */ \\\n\t\tREPORT_COUNT, 0x06, /* Report Count: 6 */ \\\n\t\tINPUT, 0x03, /* Input: (Const, Var, Abs) */ \\\n\t\t/* End of a byte */ \\\n\t\t/* Begin of 4 bytes */ \\\n\t\tREPORT_COUNT, 0x01, /* Report Count: 1 */ \\\n\t\tREPORT_SIZE, 0x20, /* Report Size: 0x20 (4 bytes) */ \\\n\t\tLOGICAL_MAXIMUM_3, 0xff, 0xff, 0xff, 0xff, /* Logical Maximum: 0xffffffff */ \\\n\t\tUSAGE, 0x51, /* Usage: Contract Identifier */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\t/* End of 4 bytes */ \\\n\t\t/* Begin of 4 bytes */ \\\n\t\t/* Size is hard-coded at this moment */ \\\n\t\tUSAGE_PAGE, 0x01, /* Usage Page: Generic Desktop */ \\\n\t\tLOGICAL_MAXIMUM_2, 0x20, 0x26, /* Logical Maximum: 9760 (See defintion) */ \\\n\t\tREPORT_SIZE, 0x10, /* Report Size: 0x10 (2 bytes) */ \\\n\t\tUNIT_EXPONENT, 0x0e, /* Unit exponent: -2 */ \\\n\t\tUNIT, 0x11, /* Unit: SI Length (cm) */ \\\n\t\tUSAGE, 0x30, /* Usage: X */ \\\n\t\tPHYSICAL_MAXIMUM_2, 0x2b, 0x04, /* Physical Maximum: 1067 (See Apple Spec) */ \\\n\t\tREPORT_COUNT, 0x01, /* Report count: 1 */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tPHYSICAL_MAXIMUM_2, 0xfa, 0x02, /* Physical Maximum: 762 (See Apple Spec) */ \\\n\t\tLOGICAL_MAXIMUM_2, 0x5e, 0x1a, /* Logical Maximum: 6750 (See definition) */ \\\n\t\tUSAGE, 0x31, /* Usage: Y */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\t/* End of 4 bytes */ \\\n\tEND_COLLECTION /* End Collection */ \\\n\n#define AAPL_WELLSPRING_6_PTP_TLC \\\n\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\tUSAGE, 0x05, /* Usage: Touch Pad */ \\\n\tBEGIN_COLLECTION, 0x01, /* Begin Collection: Application */ \\\n\t\tREPORT_ID, REPORTID_MULTITOUCH, /* Report ID: Multi-touch */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_WELLSPRING_6_PTP_FINGER_COLLECTION_1, /* 1 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_WELLSPRING_6_PTP_FINGER_COLLECTION_1, /* 2 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_WELLSPRING_6_PTP_FINGER_COLLECTION_2, /* 3 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_WELLSPRING_6_PTP_FINGER_COLLECTION_1, /* 4 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_WELLSPRING_6_PTP_FINGER_COLLECTION_2, /* 5 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUNIT_EXPONENT, 0x0c, /* Unit exponent: -4 */ \\\n\t\tUNIT_2, 0x01, 0x10, /* Time: Second */ \\\n\t\tPHYSICAL_MAXIMUM_3, 0xff, 0xff, 0x00, 0x00, \\\n\t\tLOGICAL_MAXIMUM_3, 0xff, 0xff, 0x00, 0x00, \\\n\t\tUSAGE, 0x56, /* Usage: Scan Time */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tUSAGE, 0x54, /* Usage: Contact Count */ \\\n\t\tLOGICAL_MAXIMUM, 0x7f, \\\n\t\tREPORT_SIZE, 0x08, \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tUSAGE_PAGE, 0x09, /* Usage Page: Button */ \\\n\t\tUSAGE, 0x01, /* Button 1 */ \\\n\t\tLOGICAL_MAXIMUM, 0x01, \\\n\t\tREPORT_SIZE, 0x01, \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tREPORT_COUNT, 0x07, \\\n\t\tINPUT, 0x03, /* Input: (Const, Var, Abs) */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tREPORT_ID, REPORTID_DEVICE_CAPS, \\\n\t\tUSAGE, 0x55, /* Usage: Maximum Contacts */ \\\n\t\tUSAGE, 0x59, /* Usage: Touchpad Button Type*/ \\\n\t\tLOGICAL_MINIMUM, 0x00, \\\n\t\tLOGICAL_MAXIMUM_2, 0xff, 0x00, \\\n\t\tREPORT_SIZE, 0x08, \\\n\t\tREPORT_COUNT, 0x02, \\\n\t\tFEATURE, 0x02, \\\n\t\tUSAGE_PAGE_1, 0x00, 0xff, \\\n\t\tREPORT_ID, REPORTID_PTPHQA, \\\n\t\tUSAGE, 0xc5, \\\n\t\tLOGICAL_MINIMUM, 0x00, \\\n\t\tLOGICAL_MAXIMUM_2, 0xff, 0x00, \\\n\t\tREPORT_SIZE, 0x08, \\\n\t\tREPORT_COUNT_2, 0x00, 0x01, \\\n\t\tFEATURE, 0x02, \\\n\tEND_COLLECTION /* End Collection */"
  },
  {
    "path": "src/AmtPtpDeviceUsbUm/include/DeviceFamily/Wellspring7A.h",
    "content": "#pragma once\n\n#include <HidCommon.h>\n\n#define AAPL_WELLSPRING_7A_PTP_FINGER_COLLECTION_1 \\\n\tBEGIN_COLLECTION, 0x02, /* Begin Collection: Logical */ \\\n\t\t/* Begin a byte */ \\\n\t\tLOGICAL_MAXIMUM, 0x01, /* Logical Maximum: 1 */ \\\n\t\tUSAGE, 0x47, /* Usage: Confidence */ \\\n\t\tUSAGE, 0x42, /* Usage: Tip switch */ \\\n\t\tREPORT_COUNT, 0x02, /* Report Count: 2 */ \\\n\t\tREPORT_SIZE, 0x01, /* Report Size: 1 */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tREPORT_SIZE, 0x01, /* Report Size: 1 */ \\\n\t\tREPORT_COUNT, 0x06, /* Report Count: 6 */ \\\n\t\tINPUT, 0x03, /* Input: (Const, Var, Abs) */ \\\n\t\t/* End of a byte */ \\\n\t\t/* Begin of 4 bytes */ \\\n\t\tREPORT_COUNT, 0x01, /* Report Count: 1 */ \\\n\t\tREPORT_SIZE, 0x20, /* Report Size: 0x20 (4 bytes) */ \\\n\t\tLOGICAL_MAXIMUM_3, 0xff, 0xff, 0xff, 0xff, /* Logical Maximum: 0xffffffff */ \\\n\t\tUSAGE, 0x51, /* Usage: Contract Identifier */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\t/* End of 4 bytes */ \\\n\t\t/* Begin of 4 bytes */ \\\n\t\t/* Size is hard-coded at this moment */ \\\n\t\t/* This hard-coded size is designed for MacBookPro 11,1 */ \\\n\t\tUSAGE_PAGE, 0x01, /* Usage Page: Generic Desktop */ \\\n\t\tLOGICAL_MAXIMUM_2, 0x2e, 0x27, /* Logical Maximum: 10030 (See defintion) */ \\\n\t\tREPORT_SIZE, 0x10, /* Report Size: 0x10 (2 bytes) */ \\\n\t\tUNIT_EXPONENT, 0x0e, /* Unit exponent: -2 */ \\\n\t\tUNIT, 0x11, /* Unit: SI Length (cm) */ \\\n\t\tUSAGE, 0x30, /* Usage: X */ \\\n\t\tPHYSICAL_MAXIMUM_2, 0x28, 0x04, /* Physical Maximum: 1064 (See Apple Spec) */ \\\n\t\tREPORT_COUNT, 0x01, /* Report count: 1 */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tPHYSICAL_MAXIMUM_2, 0x05, 0x03, /* Physical Maximum: 773 (See Apple Spec) */ \\\n\t\tLOGICAL_MAXIMUM_2, 0xe0, 0x1a, /* Logical Maximum: 6880 (See definition) */ \\\n\t\tUSAGE, 0x31, /* Usage: Y */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tPHYSICAL_MAXIMUM, 0x00, /* Physical Maximum: 0 */ \\\n\t\tUNIT_EXPONENT, 0x00, /* Unit exponent: 0 */ \\\n\t\tUNIT, 0x00, /* Unit: None */ \\\n\t\t/* End of 4 bytes */ \\\n\tEND_COLLECTION /* End Collection */ \\\n\n#define AAPL_WELLSPRING_7A_PTP_FINGER_COLLECTION_2 \\\n\tBEGIN_COLLECTION, 0x02, /* Begin Collection: Logical */ \\\n\t\t/* Begin a byte */ \\\n\t\tLOGICAL_MAXIMUM, 0x01, /* Logical Maximum: 1 */ \\\n\t\tUSAGE, 0x47, /* Usage: Confidence */ \\\n\t\tUSAGE, 0x42, /* Usage: Tip switch */ \\\n\t\tREPORT_COUNT, 0x02, /* Report Count: 2 */ \\\n\t\tREPORT_SIZE, 0x01, /* Report Size: 1 */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tREPORT_SIZE, 0x01, /* Report Size: 1 */ \\\n\t\tREPORT_COUNT, 0x06, /* Report Count: 6 */ \\\n\t\tINPUT, 0x03, /* Input: (Const, Var, Abs) */ \\\n\t\t/* End of a byte */ \\\n\t\t/* Begin of 4 bytes */ \\\n\t\tREPORT_COUNT, 0x01, /* Report Count: 1 */ \\\n\t\tREPORT_SIZE, 0x20, /* Report Size: 0x20 (4 bytes) */ \\\n\t\tLOGICAL_MAXIMUM_3, 0xff, 0xff, 0xff, 0xff, /* Logical Maximum: 0xffffffff */ \\\n\t\tUSAGE, 0x51, /* Usage: Contract Identifier */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\t/* End of 4 bytes */ \\\n\t\t/* Begin of 4 bytes */ \\\n\t\t/* Size is hard-coded at this moment */ \\\n\t\tUSAGE_PAGE, 0x01, /* Usage Page: Generic Desktop */ \\\n\t\tLOGICAL_MAXIMUM_2, 0x2e, 0x27, /* Logical Maximum: 10030 (See defintion) */ \\\n\t\tREPORT_SIZE, 0x10, /* Report Size: 0x10 (2 bytes) */ \\\n\t\tUNIT_EXPONENT, 0x0e, /* Unit exponent: -2 */ \\\n\t\tUNIT, 0x11, /* Unit: SI Length (cm) */ \\\n\t\tUSAGE, 0x30, /* Usage: X */ \\\n\t\tPHYSICAL_MAXIMUM_2, 0x28, 0x04, /* Physical Maximum: 1064 (See Apple Spec) */ \\\n\t\tREPORT_COUNT, 0x01, /* Report count: 1 */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tPHYSICAL_MAXIMUM_2, 0x05, 0x03, /* Physical Maximum: 773 (See Apple Spec) */ \\\n\t\tLOGICAL_MAXIMUM_2, 0xe0, 0x1a, /* Logical Maximum: 6880 (See definition) */ \\\n\t\tUSAGE, 0x31, /* Usage: Y */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\t/* End of 4 bytes */ \\\n\tEND_COLLECTION /* End Collection */ \\\n\n#define AAPL_WELLSPRING_7A_PTP_TLC \\\n\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\tUSAGE, 0x05, /* Usage: Touch Pad */ \\\n\tBEGIN_COLLECTION, 0x01, /* Begin Collection: Application */ \\\n\t\tREPORT_ID, REPORTID_MULTITOUCH, /* Report ID: Multi-touch */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_WELLSPRING_7A_PTP_FINGER_COLLECTION_1, /* 1 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_WELLSPRING_7A_PTP_FINGER_COLLECTION_1, /* 2 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_WELLSPRING_7A_PTP_FINGER_COLLECTION_2, /* 3 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_WELLSPRING_7A_PTP_FINGER_COLLECTION_1, /* 4 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_WELLSPRING_7A_PTP_FINGER_COLLECTION_2, /* 5 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUNIT_EXPONENT, 0x0c, /* Unit exponent: -4 */ \\\n\t\tUNIT_2, 0x01, 0x10, /* Time: Second */ \\\n\t\tPHYSICAL_MAXIMUM_3, 0xff, 0xff, 0x00, 0x00, \\\n\t\tLOGICAL_MAXIMUM_3, 0xff, 0xff, 0x00, 0x00, \\\n\t\tUSAGE, 0x56, /* Usage: Scan Time */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tUSAGE, 0x54, /* Usage: Contact Count */ \\\n\t\tLOGICAL_MAXIMUM, 0x7f, \\\n\t\tREPORT_SIZE, 0x08, \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tUSAGE_PAGE, 0x09, /* Usage Page: Button */ \\\n\t\tUSAGE, 0x01, /* Button 1 */ \\\n\t\tLOGICAL_MAXIMUM, 0x01, \\\n\t\tREPORT_SIZE, 0x01, \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tREPORT_COUNT, 0x07, \\\n\t\tINPUT, 0x03, /* Input: (Const, Var, Abs) */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tREPORT_ID, REPORTID_DEVICE_CAPS, \\\n\t\tUSAGE, 0x55, /* Usage: Maximum Contacts */ \\\n\t\tUSAGE, 0x59, /* Usage: Touchpad Button Type*/ \\\n\t\tLOGICAL_MINIMUM, 0x00, \\\n\t\tLOGICAL_MAXIMUM_2, 0xff, 0x00, \\\n\t\tREPORT_SIZE, 0x08, \\\n\t\tREPORT_COUNT, 0x02, \\\n\t\tFEATURE, 0x02, \\\n\t\tUSAGE_PAGE_1, 0x00, 0xff, \\\n\t\tREPORT_ID, REPORTID_PTPHQA, \\\n\t\tUSAGE, 0xc5, \\\n\t\tLOGICAL_MINIMUM, 0x00, \\\n\t\tLOGICAL_MAXIMUM_2, 0xff, 0x00, \\\n\t\tREPORT_SIZE, 0x08, \\\n\t\tREPORT_COUNT_2, 0x00, 0x01, \\\n\t\tFEATURE, 0x02, \\\n\tEND_COLLECTION /* End Collection */\n"
  },
  {
    "path": "src/AmtPtpDeviceUsbUm/include/DeviceFamily/Wellspring8.h",
    "content": "#pragma once\n\n#include <HidCommon.h>\n\n#define AAPL_WELLSPRING_8_PTP_FINGER_COLLECTION_1 \\\n\tBEGIN_COLLECTION, 0x02, /* Begin Collection: Logical */ \\\n\t\t/* Begin a byte */ \\\n\t\tLOGICAL_MAXIMUM, 0x01, /* Logical Maximum: 1 */ \\\n\t\tUSAGE, 0x47, /* Usage: Confidence */ \\\n\t\tUSAGE, 0x42, /* Usage: Tip switch */ \\\n\t\tREPORT_COUNT, 0x02, /* Report Count: 2 */ \\\n\t\tREPORT_SIZE, 0x01, /* Report Size: 1 */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tREPORT_SIZE, 0x01, /* Report Size: 1 */ \\\n\t\tREPORT_COUNT, 0x06, /* Report Count: 6 */ \\\n\t\tINPUT, 0x03, /* Input: (Const, Var, Abs) */ \\\n\t\t/* End of a byte */ \\\n\t\t/* Begin of 4 bytes */ \\\n\t\tREPORT_COUNT, 0x01, /* Report Count: 1 */ \\\n\t\tREPORT_SIZE, 0x20, /* Report Size: 0x20 (4 bytes) */ \\\n\t\tLOGICAL_MAXIMUM_3, 0xff, 0xff, 0xff, 0xff, /* Logical Maximum: 0xffffffff */ \\\n\t\tUSAGE, 0x51, /* Usage: Contract Identifier */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\t/* End of 4 bytes */ \\\n\t\t/* Begin of 4 bytes */ \\\n\t\t/* Size is hard-coded at this moment */ \\\n\t\t/* This hard-coded size is designed for MacBookAir 7,2 */ \\\n\t\tUSAGE_PAGE, 0x01, /* Usage Page: Generic Desktop */ \\\n\t\tLOGICAL_MAXIMUM_2, 0x20, 0x26, /* Logical Maximum: 9760 (See defintion) */ \\\n\t\tREPORT_SIZE, 0x10, /* Report Size: 0x10 (2 bytes) */ \\\n\t\tUNIT_EXPONENT, 0x0e, /* Unit exponent: -2 */ \\\n\t\tUNIT, 0x11, /* Unit: SI Length (cm) */ \\\n\t\tUSAGE, 0x30, /* Usage: X */ \\\n\t\tPHYSICAL_MAXIMUM_2, 0x15, 0x04, /* Physical Maximum: 1045 (See Apple Spec) */ \\\n\t\tREPORT_COUNT, 0x01, /* Report count: 1 */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tPHYSICAL_MAXIMUM_2, 0xee, 0x02, /* Physical Maximum: 750 (See Apple Spec) */ \\\n\t\tLOGICAL_MAXIMUM_2, 0x5e, 0x1a, /* Logical Maximum: 6750 (See definition) */ \\\n\t\tUSAGE, 0x31, /* Usage: Y */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tPHYSICAL_MAXIMUM, 0x00, /* Physical Maximum: 0 */ \\\n\t\tUNIT_EXPONENT, 0x00, /* Unit exponent: 0 */ \\\n\t\tUNIT, 0x00, /* Unit: None */ \\\n\t\t/* End of 4 bytes */ \\\n\tEND_COLLECTION /* End Collection */ \\\n\n#define AAPL_WELLSPRING_8_PTP_FINGER_COLLECTION_2 \\\n\tBEGIN_COLLECTION, 0x02, /* Begin Collection: Logical */ \\\n\t\t/* Begin a byte */ \\\n\t\tLOGICAL_MAXIMUM, 0x01, /* Logical Maximum: 1 */ \\\n\t\tUSAGE, 0x47, /* Usage: Confidence */ \\\n\t\tUSAGE, 0x42, /* Usage: Tip switch */ \\\n\t\tREPORT_COUNT, 0x02, /* Report Count: 2 */ \\\n\t\tREPORT_SIZE, 0x01, /* Report Size: 1 */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tREPORT_SIZE, 0x01, /* Report Size: 1 */ \\\n\t\tREPORT_COUNT, 0x06, /* Report Count: 6 */ \\\n\t\tINPUT, 0x03, /* Input: (Const, Var, Abs) */ \\\n\t\t/* End of a byte */ \\\n\t\t/* Begin of 4 bytes */ \\\n\t\tREPORT_COUNT, 0x01, /* Report Count: 1 */ \\\n\t\tREPORT_SIZE, 0x20, /* Report Size: 0x20 (4 bytes) */ \\\n\t\tLOGICAL_MAXIMUM_3, 0xff, 0xff, 0xff, 0xff, /* Logical Maximum: 0xffffffff */ \\\n\t\tUSAGE, 0x51, /* Usage: Contract Identifier */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\t/* End of 4 bytes */ \\\n\t\t/* Begin of 4 bytes */ \\\n\t\t/* Size is hard-coded at this moment */ \\\n\t\tUSAGE_PAGE, 0x01, /* Usage Page: Generic Desktop */ \\\n\t\tLOGICAL_MAXIMUM_2, 0x20, 0x26, /* Logical Maximum: 9760 (See defintion) */ \\\n\t\tREPORT_SIZE, 0x10, /* Report Size: 0x10 (2 bytes) */ \\\n\t\tUNIT_EXPONENT, 0x0e, /* Unit exponent: -2 */ \\\n\t\tUNIT, 0x11, /* Unit: SI Length (cm) */ \\\n\t\tUSAGE, 0x30, /* Usage: X */ \\\n\t\tPHYSICAL_MAXIMUM_2, 0x15, 0x04, /* Physical Maximum: 1045 (See Apple Spec) */ \\\n\t\tREPORT_COUNT, 0x01, /* Report count: 1 */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tPHYSICAL_MAXIMUM_2, 0xee, 0x02, /* Physical Maximum: 750 (See Apple Spec) */ \\\n\t\tLOGICAL_MAXIMUM_2, 0x5e, 0x1a, /* Logical Maximum: 6750 (See definition) */ \\\n\t\tUSAGE, 0x31, /* Usage: Y */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\t/* End of 4 bytes */ \\\n\tEND_COLLECTION /* End Collection */ \\\n\n#define AAPL_WELLSPRING_8_PTP_TLC \\\n\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\tUSAGE, 0x05, /* Usage: Touch Pad */ \\\n\tBEGIN_COLLECTION, 0x01, /* Begin Collection: Application */ \\\n\t\tREPORT_ID, REPORTID_MULTITOUCH, /* Report ID: Multi-touch */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_WELLSPRING_8_PTP_FINGER_COLLECTION_1, /* 1 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_WELLSPRING_8_PTP_FINGER_COLLECTION_1, /* 2 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_WELLSPRING_8_PTP_FINGER_COLLECTION_2, /* 3 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_WELLSPRING_8_PTP_FINGER_COLLECTION_1, /* 4 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_WELLSPRING_8_PTP_FINGER_COLLECTION_2, /* 5 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUNIT_EXPONENT, 0x0c, /* Unit exponent: -4 */ \\\n\t\tUNIT_2, 0x01, 0x10, /* Time: Second */ \\\n\t\tPHYSICAL_MAXIMUM_3, 0xff, 0xff, 0x00, 0x00, \\\n\t\tLOGICAL_MAXIMUM_3, 0xff, 0xff, 0x00, 0x00, \\\n\t\tUSAGE, 0x56, /* Usage: Scan Time */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tUSAGE, 0x54, /* Usage: Contact Count */ \\\n\t\tLOGICAL_MAXIMUM, 0x7f, \\\n\t\tREPORT_SIZE, 0x08, \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tUSAGE_PAGE, 0x09, /* Usage Page: Button */ \\\n\t\tUSAGE, 0x01, /* Button 1 */ \\\n\t\tLOGICAL_MAXIMUM, 0x01, \\\n\t\tREPORT_SIZE, 0x01, \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tREPORT_COUNT, 0x07, \\\n\t\tINPUT, 0x03, /* Input: (Const, Var, Abs) */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tREPORT_ID, REPORTID_DEVICE_CAPS, \\\n\t\tUSAGE, 0x55, /* Usage: Maximum Contacts */ \\\n\t\tUSAGE, 0x59, /* Usage: Touchpad Button Type*/ \\\n\t\tLOGICAL_MINIMUM, 0x00, \\\n\t\tLOGICAL_MAXIMUM_2, 0xff, 0x00, \\\n\t\tREPORT_SIZE, 0x08, \\\n\t\tREPORT_COUNT, 0x02, \\\n\t\tFEATURE, 0x02, \\\n\t\tUSAGE_PAGE_1, 0x00, 0xff, \\\n\t\tREPORT_ID, REPORTID_PTPHQA, \\\n\t\tUSAGE, 0xc5, \\\n\t\tLOGICAL_MINIMUM, 0x00, \\\n\t\tLOGICAL_MAXIMUM_2, 0xff, 0x00, \\\n\t\tREPORT_SIZE, 0x08, \\\n\t\tREPORT_COUNT_2, 0x00, 0x01, \\\n\t\tFEATURE, 0x02, \\\n\tEND_COLLECTION /* End Collection */\n"
  },
  {
    "path": "src/AmtPtpDeviceUsbUm/include/DeviceFamily/WellspringMt2.h",
    "content": "#pragma once\n\n#include <HidCommon.h>\n\n#define AAPL_MAGIC_TRACKPAD2_PTP_FINGER_COLLECTION_1 \\\n\tBEGIN_COLLECTION, 0x02, /* Begin Collection: Logical */ \\\n\t\t/* Begin a byte */ \\\n\t\tLOGICAL_MAXIMUM, 0x01, /* Logical Maximum: 1 */ \\\n\t\tUSAGE, 0x47, /* Usage: Confidence */ \\\n\t\tUSAGE, 0x42, /* Usage: Tip switch */ \\\n\t\tREPORT_COUNT, 0x02, /* Report Count: 2 */ \\\n\t\tREPORT_SIZE, 0x01, /* Report Size: 1 */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tREPORT_SIZE, 0x01, /* Report Size: 1 */ \\\n\t\tREPORT_COUNT, 0x06, /* Report Count: 6 */ \\\n\t\tINPUT, 0x03, /* Input: (Const, Var, Abs) */ \\\n\t\t/* End of a byte */ \\\n\t\t/* Begin of 4 bytes */ \\\n\t\tREPORT_COUNT, 0x01, /* Report Count: 1 */ \\\n\t\tREPORT_SIZE, 0x20, /* Report Size: 0x20 (4 bytes) */ \\\n\t\tLOGICAL_MAXIMUM_3, 0xff, 0xff, 0xff, 0xff, /* Logical Maximum: 0xffffffff */ \\\n\t\tUSAGE, 0x51, /* Usage: Contract Identifier */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\t/* End of 4 bytes */ \\\n\t\t/* Begin of 4 bytes */ \\\n\t\t/* Size is hard-coded at this moment */ \\\n\t\tUSAGE_PAGE, 0x01, /* Usage Page: Generic Desktop */ \\\n\t\tLOGICAL_MAXIMUM_2, 0xbc, 0x1d, /* Logical Maximum: 7612 (See defintion) */ \\\n\t\tREPORT_SIZE, 0x10, /* Report Size: 0x10 (2 bytes) */ \\\n\t\tUNIT_EXPONENT, 0x0e, /* Unit exponent: -2 */ \\\n\t\tUNIT, 0x11, /* Unit: SI Length (cm) */ \\\n\t\tUSAGE, 0x30, /* Usage: X */ \\\n\t\tPHYSICAL_MAXIMUM_2, 0x40, 0x06, /* Physical Maximum: 1600 (See Apple Spec) */ \\\n\t\tREPORT_COUNT, 0x01, /* Report count: 1 */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tPHYSICAL_MAXIMUM_2, 0x7d, 0x04, /* Physical Maximum: 1149 (See Apple Spec) */ \\\n\t\tLOGICAL_MAXIMUM_2, 0xc9, 0x13, /* Logical Maximum: 5065 (See definition) */ \\\n\t\tUSAGE, 0x31, /* Usage: Y */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tPHYSICAL_MAXIMUM, 0x00, /* Physical Maximum: 0 */ \\\n\t\tUNIT_EXPONENT, 0x00, /* Unit exponent: 0 */ \\\n\t\tUNIT, 0x00, /* Unit: None */ \\\n\t\t/* End of 4 bytes */ \\\n\tEND_COLLECTION /* End Collection */ \\\n\n#define AAPL_MAGIC_TRACKPAD2_PTP_FINGER_COLLECTION_2 \\\n\tBEGIN_COLLECTION, 0x02, /* Begin Collection: Logical */ \\\n\t\t/* Begin a byte */ \\\n\t\tLOGICAL_MAXIMUM, 0x01, /* Logical Maximum: 1 */ \\\n\t\tUSAGE, 0x47, /* Usage: Confidence */ \\\n\t\tUSAGE, 0x42, /* Usage: Tip switch */ \\\n\t\tREPORT_COUNT, 0x02, /* Report Count: 2 */ \\\n\t\tREPORT_SIZE, 0x01, /* Report Size: 1 */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tREPORT_SIZE, 0x01, /* Report Size: 1 */ \\\n\t\tREPORT_COUNT, 0x06, /* Report Count: 6 */ \\\n\t\tINPUT, 0x03, /* Input: (Const, Var, Abs) */ \\\n\t\t/* End of a byte */ \\\n\t\t/* Begin of 4 bytes */ \\\n\t\tREPORT_COUNT, 0x01, /* Report Count: 1 */ \\\n\t\tREPORT_SIZE, 0x20, /* Report Size: 0x20 (4 bytes) */ \\\n\t\tLOGICAL_MAXIMUM_3, 0xff, 0xff, 0xff, 0xff, /* Logical Maximum: 0xffffffff */ \\\n\t\tUSAGE, 0x51, /* Usage: Contract Identifier */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\t/* End of 4 bytes */ \\\n\t\t/* Begin of 4 bytes */ \\\n\t\t/* Size is hard-coded at this moment */ \\\n\t\tUSAGE_PAGE, 0x01, /* Usage Page: Generic Desktop */ \\\n\t\tLOGICAL_MAXIMUM_2, 0xbc, 0x1d, /* Logical Maximum: 7612 (See defintion) */ \\\n\t\tREPORT_SIZE, 0x10, /* Report Size: 0x10 (2 bytes) */ \\\n\t\tUNIT_EXPONENT, 0x0e, /* Unit exponent: -2 */ \\\n\t\tUNIT, 0x11, /* Unit: SI Length (cm) */ \\\n\t\tUSAGE, 0x30, /* Usage: X */ \\\n\t\tPHYSICAL_MAXIMUM_2, 0x40, 0x06, /* Physical Maximum: 1600 (See Apple Spec) */ \\\n\t\tREPORT_COUNT, 0x01, /* Report count: 1 */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tPHYSICAL_MAXIMUM_2, 0x7d, 0x04, /* Physical Maximum: 1149 (See Apple Spec) */ \\\n\t\tLOGICAL_MAXIMUM_2, 0xc9, 0x13, /* Logical Maximum: 5065 (See definition) */ \\\n\t\tUSAGE, 0x31, /* Usage: Y */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\t/* End of 4 bytes */ \\\n\tEND_COLLECTION /* End Collection */ \\\n\n#define AAPL_MAGIC_TRACKPAD2_PTP_TLC \\\n\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\tUSAGE, 0x05, /* Usage: Touch Pad */ \\\n\tBEGIN_COLLECTION, 0x01, /* Begin Collection: Application */ \\\n\t\tREPORT_ID, REPORTID_MULTITOUCH, /* Report ID: Multi-touch */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_MAGIC_TRACKPAD2_PTP_FINGER_COLLECTION_1, /* 1 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_MAGIC_TRACKPAD2_PTP_FINGER_COLLECTION_1, /* 2 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_MAGIC_TRACKPAD2_PTP_FINGER_COLLECTION_2, /* 3 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_MAGIC_TRACKPAD2_PTP_FINGER_COLLECTION_1, /* 4 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_MAGIC_TRACKPAD2_PTP_FINGER_COLLECTION_2, /* 5 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUNIT_EXPONENT, 0x0c, /* Unit exponent: -4 */ \\\n\t\tUNIT_2, 0x01, 0x10, /* Time: Second */ \\\n\t\tPHYSICAL_MAXIMUM_3, 0xff, 0xff, 0x00, 0x00, \\\n\t\tLOGICAL_MAXIMUM_3, 0xff, 0xff, 0x00, 0x00, \\\n\t\tUSAGE, 0x56, /* Usage: Scan Time */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tUSAGE, 0x54, /* Usage: Contact Count */ \\\n\t\tLOGICAL_MAXIMUM, 0x7f, \\\n\t\tREPORT_SIZE, 0x08, \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tUSAGE_PAGE, 0x09, /* Usage Page: Button */ \\\n\t\tUSAGE, 0x01, /* Button 1 */ \\\n\t\tLOGICAL_MAXIMUM, 0x01, \\\n\t\tREPORT_SIZE, 0x01, \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tREPORT_COUNT, 0x07, \\\n\t\tINPUT, 0x03, /* Input: (Const, Var, Abs) */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tREPORT_ID, REPORTID_DEVICE_CAPS, \\\n\t\tUSAGE, 0x55, /* Usage: Maximum Contacts */ \\\n\t\tUSAGE, 0x59, /* Usage: Touchpad Button Type*/ \\\n\t\tLOGICAL_MINIMUM, 0x00, \\\n\t\tLOGICAL_MAXIMUM_2, 0xff, 0x00, \\\n\t\tREPORT_SIZE, 0x08, \\\n\t\tREPORT_COUNT, 0x02, \\\n\t\tFEATURE, 0x02, \\\n\t\tUSAGE_PAGE_1, 0x00, 0xff, \\\n\t\tREPORT_ID, REPORTID_PTPHQA, \\\n\t\tUSAGE, 0xc5, \\\n\t\tLOGICAL_MINIMUM, 0x00, \\\n\t\tLOGICAL_MAXIMUM_2, 0xff, 0x00, \\\n\t\tREPORT_SIZE, 0x08, \\\n\t\tREPORT_COUNT_2, 0x00, 0x01, \\\n\t\tFEATURE, 0x02, \\\n\tEND_COLLECTION /* End Collection */\n"
  },
  {
    "path": "src/AmtPtpDeviceUsbUm/include/Driver.h",
    "content": "// Driver.h: Driver definitions\n\n#include <windows.h>\n#include <wdf.h>\n#include <usb.h>\n#include <wdfusb.h>\n#include <initguid.h>\n#include <hidport.h>\n\n// ModernTrace is for runtime debugging\n// Trace is WPP-based, development debugging\n#include <ModernTrace.h>\n#include <Trace.h>\n\n#include <AppleDefinition.h>\n#include <Hid.h>\n#include <Device.h>\n#include <Queue.h>\n\nEXTERN_C_START\n\n//\n// WDFDRIVER Events\n//\n\nDRIVER_INITIALIZE DriverEntry;\nEVT_WDF_DRIVER_DEVICE_ADD AmtPtpDeviceEvtDeviceAdd;\nEVT_WDF_OBJECT_CONTEXT_CLEANUP AmtPtpDeviceEvtDriverContextCleanup;\n\n\n//\n// Driver initialization routines\n//\n\nVOID\nDriverTraceInit(\n\t_In_ PDRIVER_OBJECT  DriverObject,\n\t_In_ PUNICODE_STRING RegistryPath\n);\n\nVOID \nDriverTraceCleanup(\n\t_In_ WDFOBJECT DriverObject\n);\n\nEXTERN_C_END\n"
  },
  {
    "path": "src/AmtPtpDeviceUsbUm/include/Hid.h",
    "content": "// Hid.h: Device-related HID definitions\n#pragma once\n\n#include <hidport.h>\n\n#include <AppleDefinition.h>\n#include <HidCommon.h>\n\n// Device family metadata\n#include \"DeviceFamily/Wellspring3.h\"\n#include \"DeviceFamily/Wellspring5.h\"\n#include \"DeviceFamily/Wellspring6.h\"\n#include \"DeviceFamily/Wellspring7A.h\"\n#include \"DeviceFamily/Wellspring8.h\"\n#include \"DeviceFamily/WellspringMt2.h\"\n\ntypedef UCHAR HID_REPORT_DESCRIPTOR, *PHID_REPORT_DESCRIPTOR;\n\n#define DEVICE_VERSION 0x01\n#define DEVICE_VID 0x8910\n\n#define AAPL_PTP_USERMODE_CONFIGURATION_APP_TLC \\\n\tUSAGE_PAGE_1, 0x00, 0xff, /* Usage Page: Vendor defined */ \\\n\tUSAGE, 0x01, /* Usage: Vendor Usage 0x01 */ \\\n\tBEGIN_COLLECTION, 0x01, /* Begin Collection: Application */ \\\n\t\tREPORT_ID, REPORTID_UMAPP_CONF, /* Report ID: User-mode Application configuration */ \\\n\t\tUSAGE, 0x01, /* Usage: Vendor Usage 0x01 */ \\\n\t\tLOGICAL_MINIMUM, 0x00, /* Logical Minimum 0 */ \\\n\t\tLOGICAL_MAXIMUM_2, 0xff, 0x00, /* Logical Maximum 255 */ \\\n\t\tREPORT_SIZE, 0x08, /* Report Size: 8 */ \\\n\t\tREPORT_COUNT, 0x03, /* Report Count: 3 */ \\\n\t\tFEATURE, 0x02, /* Feature: (Data, Var, Abs) */ \\\n\tEND_COLLECTION\n\n#define AAPL_PTP_WINDOWS_CONFIGURATION_TLC \\\n\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\tUSAGE, 0x0e, /* Usage: Configuration */ \\\n\tBEGIN_COLLECTION, 0x01, /* Begin Collection: Application */ \\\n\t\tREPORT_ID, REPORTID_REPORTMODE, /* Report ID: Mode Selection */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tBEGIN_COLLECTION, 0x02, /* Begin Collection: Logical */ \\\n\t\t\tUSAGE, 0x52, /* Usage: Input Mode */ \\\n\t\t\tLOGICAL_MINIMUM, 0x00, /* Logical Minumum: 0 finger */ \\\n\t\t\tLOGICAL_MAXIMUM, MAX_FINGERS, /* Logical Maximum: MAX_TOUCH_COUNT fingers */ \\\n\t\t\tREPORT_SIZE, 0x08, /* Report Size: 0x08 */ \\\n\t\t\tREPORT_COUNT, 0x01, /* Report Count: 0x01 */ \\\n\t\t\tFEATURE, 0x02, /* Feature: (Data, Var, Abs) */ \\\n\t\tEND_COLLECTION, /* End Collection */ \\\n\t\tBEGIN_COLLECTION, 0x00, /* Begin Collection: Physical */ \\\n\t\t\tREPORT_ID, REPORTID_FUNCSWITCH, /* Report ID: Function Switch */ \\\n\t\t\tUSAGE, BUTTON_SWITCH, /* Usage: Button Switch */ \\\n\t\t\tUSAGE, SURFACE_SWITCH, /* Usage: Surface Switch */ \\\n\t\t\tREPORT_SIZE, 0x01, /* Report Size: 0x01 */ \\\n\t\t\tREPORT_COUNT, 0x02, /* Report Count: 0x02 */ \\\n\t\t\tLOGICAL_MAXIMUM, 0x01, /* Logical Maximum: 0x01 */ \\\n\t\t\tFEATURE, 0x02, /* Feature: (Data, Var, Abs) */ \\\n\t\t\tREPORT_COUNT, 0x06, /* Report Count: 0x06 */ \\\n\t\t\tFEATURE, 0x03, /* Feature: (Const, Var, Abs) */ \\\n\t\tEND_COLLECTION, /* End Collection */ \\\n\tEND_COLLECTION /* End Collection */\n\n#define DEFAULT_PTP_HQA_BLOB \\\n\t0xfc, 0x28, 0xfe, 0x84, 0x40, 0xcb, 0x9a, 0x87, \\\n\t0x0d, 0xbe, 0x57, 0x3c, 0xb6, 0x70, 0x09, 0x88, \\\n\t0x07, 0x97, 0x2d, 0x2b, 0xe3, 0x38, 0x34, 0xb6, \\\n\t0x6c, 0xed, 0xb0, 0xf7, 0xe5, 0x9c, 0xf6, 0xc2, \\\n\t0x2e, 0x84, 0x1b, 0xe8, 0xb4, 0x51, 0x78, 0x43, \\\n\t0x1f, 0x28, 0x4b, 0x7c, 0x2d, 0x53, 0xaf, 0xfc, \\\n\t0x47, 0x70, 0x1b, 0x59, 0x6f, 0x74, 0x43, 0xc4, \\\n\t0xf3, 0x47, 0x18, 0x53, 0x1a, 0xa2, 0xa1, 0x71, \\\n\t0xc7, 0x95, 0x0e, 0x31, 0x55, 0x21, 0xd3, 0xb5, \\\n\t0x1e, 0xe9, 0x0c, 0xba, 0xec, 0xb8, 0x89, 0x19, \\\n\t0x3e, 0xb3, 0xaf, 0x75, 0x81, 0x9d, 0x53, 0xb9, \\\n\t0x41, 0x57, 0xf4, 0x6d, 0x39, 0x25, 0x29, 0x7c, \\\n\t0x87, 0xd9, 0xb4, 0x98, 0x45, 0x7d, 0xa7, 0x26, \\\n\t0x9c, 0x65, 0x3b, 0x85, 0x68, 0x89, 0xd7, 0x3b, \\\n\t0xbd, 0xff, 0x14, 0x67, 0xf2, 0x2b, 0xf0, 0x2a, \\\n\t0x41, 0x54, 0xf0, 0xfd, 0x2c, 0x66, 0x7c, 0xf8, \\\n\t0xc0, 0x8f, 0x33, 0x13, 0x03, 0xf1, 0xd3, 0xc1, \\\n\t0x0b, 0x89, 0xd9, 0x1b, 0x62, 0xcd, 0x51, 0xb7, \\\n\t0x80, 0xb8, 0xaf, 0x3a, 0x10, 0xc1, 0x8a, 0x5b, \\\n\t0xe8, 0x8a, 0x56, 0xf0, 0x8c, 0xaa, 0xfa, 0x35, \\\n\t0xe9, 0x42, 0xc4, 0xd8, 0x55, 0xc3, 0x38, 0xcc, \\\n\t0x2b, 0x53, 0x5c, 0x69, 0x52, 0xd5, 0xc8, 0x73, \\\n\t0x02, 0x38, 0x7c, 0x73, 0xb6, 0x41, 0xe7, 0xff, \\\n\t0x05, 0xd8, 0x2b, 0x79, 0x9a, 0xe2, 0x34, 0x60, \\\n\t0x8f, 0xa3, 0x32, 0x1f, 0x09, 0x78, 0x62, 0xbc, \\\n\t0x80, 0xe3, 0x0f, 0xbd, 0x65, 0x20, 0x08, 0x13, \\\n\t0xc1, 0xe2, 0xee, 0x53, 0x2d, 0x86, 0x7e, 0xa7, \\\n\t0x5a, 0xc5, 0xd3, 0x7d, 0x98, 0xbe, 0x31, 0x48, \\\n\t0x1f, 0xfb, 0xda, 0xaf, 0xa2, 0xa8, 0x6a, 0x89, \\\n\t0xd6, 0xbf, 0xf2, 0xd3, 0x32, 0x2a, 0x9a, 0xe4, \\\n\t0xcf, 0x17, 0xb7, 0xb8, 0xf4, 0xe1, 0x33, 0x08, \\\n\t0x24, 0x8b, 0xc4, 0x43, 0xa5, 0xe5, 0x24, 0xc2\n\n#define PTP_MAX_CONTACT_POINTS 5\n#define PTP_BUTTON_TYPE_CLICK_PAD 0\n#define PTP_BUTTON_TYPE_PRESSURE_PAD 1\n\n#define PTP_COLLECTION_MOUSE 0\n#define PTP_COLLECTION_WINDOWS 3\n\n#define PTP_CONTACT_CONFIDENCE_BIT   1\n#define PTP_CONTACT_TIPSWITCH_BIT    2\n\ntypedef struct _HID_AAPL_MOUSE_REPORT {\n\tstruct {\n\t\tUCHAR  bButtons;\n\t\tUCHAR  wXData;\n\t\tUCHAR  wYData;\n\t\tUINT   Padding;\n\t} InputReport;\n} HID_AAPL_MOUSE_REPORT, *PHID_AAPL_MOUSE_REPORT;\n\ntypedef struct _HID_INPUT_REPORT {\n\tUCHAR ReportID;\n\tHID_AAPL_MOUSE_REPORT MouseReport;\n} HID_INPUT_REPORT, *PHID_INPUT_REPORT;\n\ntypedef struct _PTP_DEVICE_CAPS_FEATURE_REPORT {\n\tUCHAR ReportID;\n\tUCHAR MaximumContactPoints;\n\tUCHAR ButtonType;\n} PTP_DEVICE_CAPS_FEATURE_REPORT, *PPTP_DEVICE_CAPS_FEATURE_REPORT;\n\ntypedef struct _PTP_DEVICE_HQA_CERTIFICATION_REPORT {\n\tUCHAR ReportID;\n\tUCHAR CertificationBlob[256];\n} PTP_DEVICE_HQA_CERTIFICATION_REPORT, *PPTP_DEVICE_HQA_CERTIFICATION_REPORT;\n\ntypedef struct _PTP_DEVICE_INPUT_MODE_REPORT {\n\tUCHAR ReportID;\n\tUCHAR Mode;\n} PTP_DEVICE_INPUT_MODE_REPORT, *PPTP_DEVICE_INPUT_MODE_REPORT;\n\n#pragma pack(1)\ntypedef struct _PTP_DEVICE_SELECTIVE_REPORT_MODE_REPORT {\n\tUCHAR ReportID;\n\tUCHAR ButtonReport : 1;\n\tUCHAR SurfaceReport : 1;\n\tUCHAR Padding : 6;\n} PTP_DEVICE_SELECTIVE_REPORT_MODE_REPORT, *PPTP_DEVICE_SELECTIVE_REPORT_MODE_REPORT;\n#pragma pack()\n\n#pragma pack(1)\ntypedef struct _PTP_CONTACT {\n\tUCHAR\t\tConfidence : 1;\n\tUCHAR\t\tTipSwitch  : 1;\n\tUCHAR\t\tPadding    : 6;\n\tULONG\t\tContactID;\n\tUSHORT\t\tX;\n\tUSHORT\t\tY;\n} PTP_CONTACT, *PPTP_CONTACT;\n#pragma pack()\n\ntypedef struct _PTP_REPORT {\n\tUCHAR       ReportID;\n\tPTP_CONTACT Contacts[5];\n\tUSHORT      ScanTime;\n\tUCHAR       ContactCount;\n\tUCHAR       IsButtonClicked;\n} PTP_REPORT, *PPTP_REPORT;\n\ntypedef struct _PTP_USERMODEAPP_CONF_REPORT {\n\tUCHAR\t\tReportID;\n\tUCHAR\t\tPressureQualificationLevel;\n\tUCHAR\t\tSingleContactSizeQualificationLevel;\n\tUCHAR\t\tMultipleContactSizeQualificationLevel;\n} PTP_USERMODEAPP_CONF_REPORT, *PPTP_USERMODEAPP_CONF_REPORT;\n"
  },
  {
    "path": "src/AmtPtpDeviceUsbUm/include/HidCommon.h",
    "content": "#pragma once\n\n#define REPORTID_STANDARDMOUSE 0x02\n#define REPORTID_MULTITOUCH 0x05\n#define REPORTID_REPORTMODE 0x04\n#define REPORTID_PTPHQA 0x08\n#define REPORTID_FUNCSWITCH 0x06\n#define REPORTID_DEVICE_CAPS 0x07\n#define REPORTID_UMAPP_CONF  0x09\n\n#define BUTTON_SWITCH 0x57\n#define SURFACE_SWITCH 0x58\n\n#define USAGE_PAGE 0x05\n#define USAGE_PAGE_1 0x06\n#define USAGE      0x09\n#define USAGE_MINIMUM 0x19\n#define USAGE_MAXIMUM 0x29\n#define LOGICAL_MINIMUM 0x15\n#define LOGICAL_MAXIMUM 0x25\n#define LOGICAL_MAXIMUM_2 0x26\n#define LOGICAL_MAXIMUM_3 0x27\n#define PHYSICAL_MINIMUM 0x35\n#define PHYSICAL_MAXIMUM 0x45\n#define PHYSICAL_MAXIMUM_2 0x46\n#define PHYSICAL_MAXIMUM_3 0x47\n#define UNIT_EXPONENT 0x55\n#define UNIT 0x65\n#define UNIT_2 0x66\n\n#define REPORT_ID       0x85\n#define REPORT_COUNT    0x95\n#define REPORT_COUNT_2\t0x96\n#define REPORT_SIZE     0x75\n#define INPUT           0x81\n#define FEATURE         0xb1\n\n#define BEGIN_COLLECTION 0xa1\n#define END_COLLECTION   0xc0\n"
  },
  {
    "path": "src/AmtPtpDeviceUsbUm/include/ModernTrace.h",
    "content": "#pragma once\n// This is the new Windows 10 trace logger provider\n#include <TraceLoggingProvider.h>\n\nEXTERN_C_START\n\n//\n// Declare TraceLogger Handler\n// TraceLogger GUID {871B1E2D-CC5A-4ADE-B74E-6CF1004EF149}\n// Do not confuse with WPP tracing\n//\nTRACELOGGING_DECLARE_PROVIDER(g_hAmtPtpDeviceTraceProvider);\n\nEXTERN_C_END\n\n//\n// Defines a set of events to use\n//\n\n#define EVENT_DRIVER_FUNCTIONAL\t\t\"DriverFunctionalEvent\"\n#define EVENT_DEVICE_IDENTIFICATION \"DeviceIdentificationEvent\"\n#define EVENT_DEVICE_USBOPERATION\t\"DeviceUsbOperationEvent\"\n#define EVENT_INPUT_DIAGNOSTICS\t\t\"InputDiagnosticsEvent\"\n\n#define EVENT_DRIVER_FUNC_SUBTYPE\t\t\t\"Subtype\"\n#define EVENT_DRIVER_FUNC_SUBTYPE_CRITFAIL\t\"CriticalFailure\"\n#define EVENT_DEVICE_ID_SUBTYPE_NOTFOUND\t\"DeviceNotFoundInRegistry\"\n#define EVENT_DEVICE_ID_SUBTYPE_HIDREG_NOTFOUND\t\t\"DeviceDescriptorNotFoundInRegistry\"\n"
  },
  {
    "path": "src/AmtPtpDeviceUsbUm/include/Queue.h",
    "content": "// Queue.h: This file contains the queue definitions.\n\nEXTERN_C_START\n\n//\n// This is the context that can be placed per queue\n// and would contain per queue information.\n//\ntypedef struct _QUEUE_CONTEXT {\n\n\tULONG placeholder;\n\n} QUEUE_CONTEXT, *PQUEUE_CONTEXT;\n\nWDF_DECLARE_CONTEXT_TYPE_WITH_NAME(QUEUE_CONTEXT, QueueGetContext)\n\n_IRQL_requires_(PASSIVE_LEVEL)\nPCHAR\nDbgIoControlGetString(\n\t_In_ ULONG IoControlCode\n);\n\nNTSTATUS\nAmtPtpDeviceQueueInitialize(\n\t_In_ WDFDEVICE Device\n);\n\nNTSTATUS\nAmtPtpDispatchReadReportRequests(\n\t_In_ WDFDEVICE Device,\n\t_In_ WDFREQUEST Request,\n\t_Out_ BOOLEAN *Pending\n);\n\n//\n// Events from the IoQueue object\n//\nEVT_WDF_IO_QUEUE_IO_DEVICE_CONTROL AmtPtpDeviceEvtIoDeviceControl;\nEVT_WDF_IO_QUEUE_IO_STOP AmtPtpDeviceEvtIoStop;\n\nEXTERN_C_END\n"
  },
  {
    "path": "src/AmtPtpDeviceUsbUm/include/StaticHidRegistry.h",
    "content": "#pragma once\n\n#ifndef _AAPL_HID_DESCRIPTOR_H_\n#define _AAPL_HID_DESCRIPTOR_H_\n\nHID_REPORT_DESCRIPTOR AmtPtp3ReportDescriptor[] = {\n\tAAPL_WELLSPRING_3_PTP_TLC,\n\tAAPL_PTP_WINDOWS_CONFIGURATION_TLC,\n\tAAPL_PTP_USERMODE_CONFIGURATION_APP_TLC\n};\n\nHID_REPORT_DESCRIPTOR AmtPtp5ReportDescriptor[] = {\n\tAAPL_WELLSPRING_5_PTP_TLC,\n\tAAPL_PTP_WINDOWS_CONFIGURATION_TLC,\n\tAAPL_PTP_USERMODE_CONFIGURATION_APP_TLC\n};\n\nHID_REPORT_DESCRIPTOR AmtPtp6ReportDescriptor[] = {\n\tAAPL_WELLSPRING_6_PTP_TLC,\n\tAAPL_PTP_WINDOWS_CONFIGURATION_TLC,\n\tAAPL_PTP_USERMODE_CONFIGURATION_APP_TLC\n};\n\nHID_REPORT_DESCRIPTOR AmtPtp7aReportDescriptor[] = {\n\tAAPL_WELLSPRING_7A_PTP_TLC,\n\tAAPL_PTP_WINDOWS_CONFIGURATION_TLC,\n\tAAPL_PTP_USERMODE_CONFIGURATION_APP_TLC\n};\n\nHID_REPORT_DESCRIPTOR AmtPtp8ReportDescriptor[] = {\n\tAAPL_WELLSPRING_8_PTP_TLC,\n\tAAPL_PTP_WINDOWS_CONFIGURATION_TLC,\n\tAAPL_PTP_USERMODE_CONFIGURATION_APP_TLC\n};\n\nHID_REPORT_DESCRIPTOR AmtPtpMt2ReportDescriptor[] = {\n\tAAPL_MAGIC_TRACKPAD2_PTP_TLC,\n\tAAPL_PTP_WINDOWS_CONFIGURATION_TLC,\n\tAAPL_PTP_USERMODE_CONFIGURATION_APP_TLC\n};\n\nHID_DESCRIPTOR AmtPtp3DefaultHidDescriptor = {\n\t0x09,   // bLength\n\t0x21,   // bDescriptorType\n\t0x0100, // bcdHID\n\t0x00,   // bCountryCode\n\t0x01,   // bNumDescriptors\n\t{\n\t\t0x22,                               // bDescriptorType\n\t\tsizeof(AmtPtp3ReportDescriptor)    // bDescriptorLength\n\t},\n};\n\nHID_DESCRIPTOR AmtPtp5DefaultHidDescriptor = {\n\t0x09,   // bLength\n\t0x21,   // bDescriptorType\n\t0x0100, // bcdHID\n\t0x00,   // bCountryCode\n\t0x01,   // bNumDescriptors\n\t{\n\t\t0x22,                               // bDescriptorType\n\t\tsizeof(AmtPtp5ReportDescriptor)    // bDescriptorLength\n\t},\n};\n\nHID_DESCRIPTOR AmtPtp6DefaultHidDescriptor = {\n\t0x09,   // bLength\n\t0x21,   // bDescriptorType\n\t0x0100, // bcdHID\n\t0x00,   // bCountryCode\n\t0x01,   // bNumDescriptors\n\t{\n\t\t0x22,                               // bDescriptorType\n\t\tsizeof(AmtPtp6ReportDescriptor)    // bDescriptorLength\n\t},\n};\n\nHID_DESCRIPTOR AmtPtp7aDefaultHidDescriptor = {\n\t0x09,   // bLength\n\t0x21,   // bDescriptorType\n\t0x0100, // bcdHID\n\t0x00,   // bCountryCode\n\t0x01,   // bNumDescriptors\n\t{\n\t\t0x22,                               // bDescriptorType\n\t\tsizeof(AmtPtp7aReportDescriptor)    // bDescriptorLength\n\t},\n};\n\nHID_DESCRIPTOR AmtPtp8DefaultHidDescriptor = {\n\t0x09,   // bLength\n\t0x21,   // bDescriptorType\n\t0x0100, // bcdHID\n\t0x00,   // bCountryCode\n\t0x01,   // bNumDescriptors\n\t{\n\t\t0x22,                               // bDescriptorType\n\t\tsizeof(AmtPtp8ReportDescriptor)    // bDescriptorLength\n\t},\n};\n\nHID_DESCRIPTOR AmtPtpMt2DefaultHidDescriptor = {\n\t0x09,   // bLength\n\t0x21,   // bDescriptorType\n\t0x0100, // bcdHID\n\t0x00,   // bCountryCode\n\t0x01,   // bNumDescriptors\n\t{\n\t\t0x22,                               // bDescriptorType\n\t\tsizeof(AmtPtpMt2ReportDescriptor)    // bDescriptorLength\n\t},\n};\n\n#endif\n"
  },
  {
    "path": "src/AmtPtpDeviceUsbUm/include/Trace.h",
    "content": "// Trace.h: Local type definitions for tracing\n\n//\n// Device Interface GUID\n// 4a5064e5-7d39-41d1-a0e4-81097edce967\n//\nDEFINE_GUID(GUID_DEVINTERFACE_AmtPtpDevice,\n\t0x4a5064e5, 0x7d39, 0x41d1, 0xa0, 0xe4, 0x81, 0x09, 0x7e, 0xdc, 0xe9, 0x67);\n\n//\n// Define the tracing flags.\n//\n// Tracing GUID - efc3ce99-43ff-4b59-afe4-c856e1afd8b0\n//\n\n#define WPP_CONTROL_GUIDS\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n    WPP_DEFINE_CONTROL_GUID(\t\t\t\t\t\t\t\t\t\t\t\t\\\n        AmtPtpDriverTraceGuid, (efc3ce99,43ff,4b59,afe4,c856e1afd8b0),\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n        WPP_DEFINE_BIT(AMTPTPDRIVER_ALL_INFO)\t\t\t\t\t\t\t\t\\\n        WPP_DEFINE_BIT(TRACE_DRIVER)\t\t\t\t\t\t\t\t\t\t\\\n        WPP_DEFINE_BIT(TRACE_DEVICE)\t\t\t\t\t\t\t\t\t\t\\\n        WPP_DEFINE_BIT(TRACE_QUEUE)\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tWPP_DEFINE_BIT(TRACE_INPUT)\t\t\t\t\t\t\t\t\t\t\t\\\n        )                             \n\n#define WPP_FLAG_LEVEL_LOGGER(flag, level)                                  \\\n    WPP_LEVEL_LOGGER(flag)\n\n#define WPP_FLAG_LEVEL_ENABLED(flag, level)                                 \\\n    (WPP_LEVEL_ENABLED(flag) &&                                             \\\n     WPP_CONTROL(WPP_BIT_ ## flag).Level >= level)\n\n#define WPP_LEVEL_FLAGS_LOGGER(lvl,flags) \\\n           WPP_LEVEL_LOGGER(flags)\n\n#define WPP_LEVEL_FLAGS_ENABLED(lvl, flags) \\\n           (WPP_LEVEL_ENABLED(flags) && WPP_CONTROL(WPP_BIT_ ## flags).Level >= lvl)\n\n//\n// This comment block is scanned by the trace preprocessor to define our\n// Trace function.\n//\n// begin_wpp config\n// FUNC Trace{FLAG=MYDRIVER_ALL_INFO}(LEVEL, MSG, ...);\n// FUNC TraceEvents(LEVEL, FLAGS, MSG, ...);\n// end_wpp\n//"
  },
  {
    "path": "src/AmtPtpDeviceUsbUm/include/resource.h",
    "content": "//{{NO_DEPENDENCIES}}\n// Microsoft Visual C++ generated include file.\n// Used by Resource.rc\n\n#define IDS_APP_TITLE           103\n\n// Next default values for new objects\n// \n#ifdef APSTUDIO_INVOKED\n#ifndef APSTUDIO_READONLY_SYMBOLS\n#define _APS_NEXT_RESOURCE_VALUE        101\n#define _APS_NEXT_COMMAND_VALUE         40001\n#define _APS_NEXT_CONTROL_VALUE         1001\n#define _APS_NEXT_SYMED_VALUE           101\n#endif\n#endif\n"
  },
  {
    "path": "src/AmtPtpHidFilter/AmtPtpHidFilter.inf",
    "content": ";\n; AmtPtpHidFilter.inf\n;\n\n[Version]\nSignature=\"$WINDOWS NT$\"\nClass = HIDClass\nClassGuid = {745a17a0-74d3-11d0-b6fe-00a0c90f57da}\nProvider=%ManufacturerName%\nCatalogFile=AmtPtpHidFilter.cat\nDriverVer= ; TODO: set DriverVer in stampinf property pages\nPnpLockdown=1\n\n[DestinationDirs]\nDefaultDestDir = 13\n\n[ControlFlags]\n; We don't want our device to be installable via the non-PnP hardware dialogs\nExcludeFromSelect = *\n\n[SourceDisksNames]\n1 = %DiskName%,,,\"\"\n\n[SourceDisksFiles]\nAmtPtpHidFilter.sys  = 1,,\n\n;*****************************************\n; Install Section\n;*****************************************\n\n[Manufacturer]\n%ManufacturerName%=Standard,NT$ARCH$.10.0\n\n[Standard.NT$ARCH$.10.0]\n; Driver migration: if this user installed the old Precision Touch Driver, install the generic HID USB driver for them\n%AmtPtpHidRootDevice.DeviceDesc%=StandardUsbHid_Device, USB\\Vid_05ac&Pid_0265&MI_01\n\n; The fact is, you can't filter HIDUSB or friends directly, because they load the export driver called\n; HIDCLASS which overrides their IO Major Function pointers. Therefore we still implement our own HID miniport \n; transport, but in fact reusing the underlying HID transport (either Bluetooth or USB).\n; Some high-level patches involved to modify the underlying driver IO handlers.\n%AmtPtpHidFilter.DeviceDesc%=AmtPtpHidFilter_MiniPortDevice, HID\\VID_05AC&PID_0265&REV_0855&MI_01&Col01\n%AmtPtpHidFilter.DeviceDesc%=AmtPtpHidFilter_MiniPortDevice, HID\\{00001124-0000-1000-8000-00805f9b34fb}_VID&0001004c_PID&0265&Col01\n; To avoid confusions to OS, disable any other collections.\n%AmtPtpHidFilter.NullDeviceDesc%=AmtPtpHidFilter_NullDevice, HID\\VID_05AC&PID_0265&REV_0855&MI_01&Col02\n%AmtPtpHidFilter.NullDeviceDesc%=AmtPtpHidFilter_NullDevice, HID\\VID_05AC&PID_0265&REV_0855&MI_01&Col03\n%AmtPtpHidFilter.NullDeviceDesc%=AmtPtpHidFilter_NullDevice, HID\\{00001124-0000-1000-8000-00805f9b34fb}_VID&0001004c_PID&0265&Col02\n\n[FilterDriver_Payload]\nAmtPtpHidFilter.sys\n\n[StandardUsbHid_Device.NT]\nInclude = input.inf\nNeeds = HID_Inst.NT\n\n[StandardUsbHid_Device.NT.HW]\nInclude = input.inf\nNeeds = HID_Inst.NT.HW\n\n[StandardUsbHid_Device.NT.Services]\nInclude = input.inf\nNeeds = HID_Inst.NT.Services\n\n[AmtPtpHidFilter_MiniPortDevice.NT]\nCopyFiles=FilterDriver_Payload\n\n[AmtPtpHidFilter_NullDevice]\n; Nothing!\n\n[AmtPtpHidFilter_NullDevice.Services]\nAddService = ,2    ; no value for the service name\n\n;-------------- Service installation\n[AmtPtpHidFilter_MiniPortDevice.NT.Services]\nAddService = AmtPtpHidFilter,, AmtPtpHidFilter_Service_Inst\nAddService = mshidkmdf, %SPSVCINST_ASSOCSERVICE%, mshidkmdf_Service_Inst\n\n[AmtPtpHidFilter_MiniPortDevice.NT.HW]\nAddReg=AmtPtpHidFilter_AddReg\n\n[AmtPtpHidFilter_AddReg]\nHKR,,FriendlyName,,%AmtPtpHidFilter.DeviceDesc%\nHKR,,\"LowerFilters\",0x00010008,\"AmtPtpHidFilter\"\n\n[AmtPtpHidFilter_MiniPortDevice.NT.Wdf]\nKmdfService = AmtPtpHidFilter, AmtPtpHidFilter_wdfsect\n\n; -------------- Microsoft HID KMDF driver install sections\n[mshidkmdf_Service_Inst]\nServiceType    = 1                  ; SERVICE_KERNEL_DRIVER\nStartType      = 3                  ; SERVICE_DEMAND_START\nErrorControl   = 1                  ; SERVICE_ERROR_NORMAL\nServiceBinary  = %10%\\System32\\Drivers\\mshidkmdf.sys\n\n; -------------- AmtPtpHidFilter driver install sections\n[AmtPtpHidFilter_Service_Inst]\nDisplayName    = %AmtPtpHidFilter.SVCDESC%\nServiceType    = 1               ; SERVICE_KERNEL_DRIVER\nStartType      = 3               ; SERVICE_DEMAND_START\nErrorControl   = 1               ; SERVICE_ERROR_NORMAL\nServiceBinary  = %13%\\AmtPtpHidFilter.sys\n\n[AmtPtpHidFilter_wdfsect]\nKmdfLibraryVersion = $KMDFVERSION$\n\n[Strings]\nSPSVCINST_ASSOCSERVICE= 0x00000002\nManufacturerName = \"Bingxing Wang\"\nDiskName = \"Precision Touchpad for Apple Trackpad Installation Disk\"\nAmtPtpHidRootDevice.DeviceDesc = \"Apple Multi-touch Trackpad HID Device\"\nAmtPtpHidFilter.DeviceDesc = \"Apple Multi-touch Trackpad HID Filter\"\nAmtPtpHidFilter.NullDeviceDesc = \"Apple Multi-touch Auxiliary Services\"\nAmtPtpHidFilter.SVCDESC = \"Apple Multi-touch Trackpad HID Filter Service\"\n"
  },
  {
    "path": "src/AmtPtpHidFilter/AmtPtpHidFilter.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"12.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"ReleaseSigned|ARM64\">\n      <Configuration>ReleaseSigned</Configuration>\n      <Platform>ARM64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"ReleaseSigned|x64\">\n      <Configuration>ReleaseSigned</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|ARM64\">\n      <Configuration>Debug</Configuration>\n      <Platform>ARM64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|ARM64\">\n      <Configuration>Release</Configuration>\n      <Platform>ARM64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{EE63C42B-F401-4F55-ADBB-14C16BD3B18C}</ProjectGuid>\n    <TemplateGuid>{1bc93793-694f-48fe-9372-81e2b05556fd}</TemplateGuid>\n    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>\n    <MinimumVisualStudioVersion>12.0</MinimumVisualStudioVersion>\n    <Configuration>Debug</Configuration>\n    <Platform Condition=\"'$(Platform)' == ''\">Win32</Platform>\n    <RootNamespace>AmtPtpHidFilter</RootNamespace>\n    <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <TargetVersion>Windows10</TargetVersion>\n    <UseDebugLibraries>true</UseDebugLibraries>\n    <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>\n    <ConfigurationType>Driver</ConfigurationType>\n    <DriverType>KMDF</DriverType>\n    <DriverTargetPlatform>Universal</DriverTargetPlatform>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <TargetVersion>Windows10</TargetVersion>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>\n    <ConfigurationType>Driver</ConfigurationType>\n    <DriverType>KMDF</DriverType>\n    <DriverTargetPlatform>Universal</DriverTargetPlatform>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseSigned|x64'\" Label=\"Configuration\">\n    <TargetVersion>Windows10</TargetVersion>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>\n    <ConfigurationType>Driver</ConfigurationType>\n    <DriverType>KMDF</DriverType>\n    <DriverTargetPlatform>Universal</DriverTargetPlatform>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\" Label=\"Configuration\">\n    <TargetVersion>Windows10</TargetVersion>\n    <UseDebugLibraries>true</UseDebugLibraries>\n    <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>\n    <ConfigurationType>Driver</ConfigurationType>\n    <DriverType>KMDF</DriverType>\n    <DriverTargetPlatform>Universal</DriverTargetPlatform>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\" Label=\"Configuration\">\n    <TargetVersion>Windows10</TargetVersion>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>\n    <ConfigurationType>Driver</ConfigurationType>\n    <DriverType>KMDF</DriverType>\n    <DriverTargetPlatform>Universal</DriverTargetPlatform>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseSigned|ARM64'\" Label=\"Configuration\">\n    <TargetVersion>Windows10</TargetVersion>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>\n    <ConfigurationType>Driver</ConfigurationType>\n    <DriverType>KMDF</DriverType>\n    <DriverTargetPlatform>Universal</DriverTargetPlatform>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>\n    <IncludePath>$(ProjectDir)include;$(SolutionDir)intermediate\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\;$(IncludePath)</IncludePath>\n    <OutDir>$(SolutionDir)build\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\</OutDir>\n    <IntDir>$(SolutionDir)intermediate\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\</IntDir>\n    <TimeStampServer>http://timestamp.digicert.com</TimeStampServer>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>\n    <IncludePath>$(ProjectDir)include;$(SolutionDir)intermediate\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\;$(IncludePath)</IncludePath>\n    <OutDir>$(SolutionDir)build\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\</OutDir>\n    <IntDir>$(SolutionDir)intermediate\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\</IntDir>\n    <TimeStampServer>http://timestamp.digicert.com</TimeStampServer>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseSigned|x64'\">\n    <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>\n    <IncludePath>$(ProjectDir)include;$(SolutionDir)intermediate\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\;$(IncludePath)</IncludePath>\n    <OutDir>$(SolutionDir)build\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\</OutDir>\n    <IntDir>$(SolutionDir)intermediate\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\</IntDir>\n    <TimeStampServer>http://timestamp.digicert.com</TimeStampServer>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">\n    <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>\n    <IncludePath>$(ProjectDir)include;$(SolutionDir)intermediate\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\;$(IncludePath)</IncludePath>\n    <OutDir>$(SolutionDir)build\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\</OutDir>\n    <IntDir>$(SolutionDir)intermediate\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\</IntDir>\n    <TimeStampServer>http://timestamp.digicert.com</TimeStampServer>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">\n    <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>\n    <IncludePath>$(ProjectDir)include;$(SolutionDir)intermediate\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\;$(IncludePath)</IncludePath>\n    <OutDir>$(SolutionDir)build\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\</OutDir>\n    <IntDir>$(SolutionDir)intermediate\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\</IntDir>\n    <TimeStampServer>http://timestamp.digicert.com</TimeStampServer>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseSigned|ARM64'\">\n    <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>\n    <IncludePath>$(ProjectDir)include;$(SolutionDir)intermediate\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\;$(IncludePath)</IncludePath>\n    <OutDir>$(SolutionDir)build\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\</OutDir>\n    <IntDir>$(SolutionDir)intermediate\\$(ProjectName)\\$(Platform)\\$(ConfigurationName)\\</IntDir>\n    <TimeStampServer>http://timestamp.digicert.com</TimeStampServer>\n  </PropertyGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">\n    <ClCompile>\n      <WppEnabled>true</WppEnabled>\n      <WppPreprocessorDefinitions>\n      </WppPreprocessorDefinitions>\n      <WppRecorderEnabled>true</WppRecorderEnabled>\n      <WppScanConfigurationData>$(ProjectDir)include\\Trace.h</WppScanConfigurationData>\n      <LanguageStandard>stdcpplatest</LanguageStandard>\n      <LanguageStandard_C>stdc17</LanguageStandard_C>\n    </ClCompile>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">\n    <ClCompile>\n      <WppEnabled>true</WppEnabled>\n      <WppPreprocessorDefinitions>\n      </WppPreprocessorDefinitions>\n      <WppRecorderEnabled>true</WppRecorderEnabled>\n      <WppScanConfigurationData>$(ProjectDir)include\\Trace.h</WppScanConfigurationData>\n      <LanguageStandard>stdcpplatest</LanguageStandard>\n      <LanguageStandard_C>stdc17</LanguageStandard_C>\n    </ClCompile>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseSigned|ARM64'\">\n    <ClCompile>\n      <WppEnabled>true</WppEnabled>\n      <WppPreprocessorDefinitions>\n      </WppPreprocessorDefinitions>\n      <WppRecorderEnabled>true</WppRecorderEnabled>\n      <WppScanConfigurationData>$(ProjectDir)include\\Trace.h</WppScanConfigurationData>\n      <LanguageStandard>stdcpplatest</LanguageStandard>\n      <LanguageStandard_C>stdc17</LanguageStandard_C>\n    </ClCompile>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <ClCompile>\n      <WppEnabled>true</WppEnabled>\n      <WppPreprocessorDefinitions>\n      </WppPreprocessorDefinitions>\n      <WppRecorderEnabled>true</WppRecorderEnabled>\n      <WppScanConfigurationData>$(ProjectDir)include\\Trace.h</WppScanConfigurationData>\n      <LanguageStandard>stdcpplatest</LanguageStandard>\n      <LanguageStandard_C>stdc17</LanguageStandard_C>\n    </ClCompile>\n    <DriverSign>\n      <FileDigestAlgorithm>sha256</FileDigestAlgorithm>\n    </DriverSign>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <ClCompile>\n      <WppEnabled>true</WppEnabled>\n      <WppPreprocessorDefinitions>\n      </WppPreprocessorDefinitions>\n      <WppRecorderEnabled>true</WppRecorderEnabled>\n      <WppScanConfigurationData>$(ProjectDir)include\\Trace.h</WppScanConfigurationData>\n      <LanguageStandard>stdcpplatest</LanguageStandard>\n      <LanguageStandard_C>stdc17</LanguageStandard_C>\n    </ClCompile>\n    <DriverSign>\n      <FileDigestAlgorithm>sha256</FileDigestAlgorithm>\n    </DriverSign>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseSigned|x64'\">\n    <ClCompile>\n      <WppEnabled>true</WppEnabled>\n      <WppPreprocessorDefinitions>\n      </WppPreprocessorDefinitions>\n      <WppRecorderEnabled>true</WppRecorderEnabled>\n      <WppScanConfigurationData>$(ProjectDir)include\\Trace.h</WppScanConfigurationData>\n      <LanguageStandard>stdcpplatest</LanguageStandard>\n      <LanguageStandard_C>stdc17</LanguageStandard_C>\n    </ClCompile>\n    <DriverSign>\n      <FileDigestAlgorithm>sha256</FileDigestAlgorithm>\n    </DriverSign>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <Inf Include=\"AmtPtpHidFilter.inf\" />\n  </ItemGroup>\n  <ItemGroup>\n    <FilesToPackage Include=\"$(TargetPath)\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ClCompile Include=\"Detour.c\" />\n    <ClCompile Include=\"Device.c\" />\n    <ClCompile Include=\"Diagnostics.c\" />\n    <ClCompile Include=\"Driver.c\" />\n    <ClCompile Include=\"Hid.c\" />\n    <ClCompile Include=\"Input.c\" />\n    <ClCompile Include=\"Queue.c\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"include\\Driver.h\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"include\\Device.h\" />\n    <ClInclude Include=\"include\\Diagnostics.h\" />\n    <ClInclude Include=\"include\\Hac.h\" />\n    <ClInclude Include=\"include\\HidCommon.h\" />\n    <ClInclude Include=\"include\\HidDevice.h\" />\n    <ClInclude Include=\"include\\HidMiniport.h\" />\n    <ClInclude Include=\"include\\Input.h\" />\n    <ClInclude Include=\"include\\Metadata\\MagicTrackpad2.h\" />\n    <ClInclude Include=\"include\\Metadata\\StaticHidRegistry.h\" />\n    <ClInclude Include=\"include\\Metadata\\WindowsHID.h\" />\n    <ClInclude Include=\"include\\Queue.h\" />\n    <ClInclude Include=\"include\\Trace.h\" />\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "src/AmtPtpHidFilter/AmtPtpHidFilter.vcxproj.filters",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup>\n    <Filter Include=\"Source Files\">\n      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>\n      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>\n    </Filter>\n    <Filter Include=\"Header Files\">\n      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>\n      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>\n    </Filter>\n    <Filter Include=\"Resource Files\">\n      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>\n      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>\n    </Filter>\n    <Filter Include=\"Driver Files\">\n      <UniqueIdentifier>{8E41214B-6785-4CFE-B992-037D68949A14}</UniqueIdentifier>\n      <Extensions>inf;inv;inx;mof;mc;</Extensions>\n    </Filter>\n    <Filter Include=\"Device Specific Metadata Files\">\n      <UniqueIdentifier>{cccbe0e8-fadd-4a3c-bd83-cbd350127d11}</UniqueIdentifier>\n    </Filter>\n  </ItemGroup>\n  <ItemGroup>\n    <Inf Include=\"AmtPtpHidFilter.inf\">\n      <Filter>Driver Files</Filter>\n    </Inf>\n  </ItemGroup>\n  <ItemGroup>\n    <ClCompile Include=\"Driver.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"Device.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"Queue.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"Detour.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"Diagnostics.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"Input.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"Hid.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"include\\Driver.h\">\n      <Filter>Header Files</Filter>\n    </None>\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"include\\Trace.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"include\\Device.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"include\\Queue.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"include\\Hac.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"include\\Diagnostics.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"include\\Metadata\\MagicTrackpad2.h\">\n      <Filter>Device Specific Metadata Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"include\\HidCommon.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"include\\Metadata\\StaticHidRegistry.h\">\n      <Filter>Device Specific Metadata Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"include\\Metadata\\WindowsHID.h\">\n      <Filter>Device Specific Metadata Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"include\\HidMiniport.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"include\\Input.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"include\\HidDevice.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "src/AmtPtpHidFilter/Detour.c",
    "content": "// Detour.c: Windows HID detour facilities\n\n#include <Driver.h>\n#include \"Detour.tmh\"\n\nNTSTATUS\nPtpFilterDetourWindowsHIDStack(\n    _In_ WDFDEVICE Device\n)\n{\n    NTSTATUS status = STATUS_SUCCESS;\n    PDEVICE_CONTEXT deviceContext;\n    PDEVICE_OBJECT  hidTransportWdmDeviceObject = NULL;\n    PDRIVER_OBJECT  hidTransportWdmDriverObject = NULL;\n    PIO_CLIENT_EXTENSION hidTransportIoClientExtension = NULL;\n    PHIDCLASS_DRIVER_EXTENSION hidTransportClassExtension = NULL;\n\n    PAGED_CODE();\n    TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DEVICE, \"%!FUNC! Entry\");\n    deviceContext = PtpFilterGetContext(Device);\n\n    if (deviceContext->WdmDeviceObject == NULL || deviceContext->WdmDeviceObject->DriverObject == NULL) {\n        TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE, \"%!FUNC! WDM Device Object or Driver Object is null, can't continue\");\n        status = STATUS_UNSUCCESSFUL;\n        goto exit;\n    }\n\n    // Access the driver object to find next low-level device (in our case, we expect it to be HID transport driver)\n    hidTransportWdmDeviceObject = IoGetLowerDeviceObject(deviceContext->WdmDeviceObject);\n    if (hidTransportWdmDeviceObject == NULL) {\n        TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE, \"%!FUNC! IoGetLowerDeviceObject returns null, can't continue\");\n        status = STATUS_UNSUCCESSFUL;\n        goto exit;\n    }\n\n    hidTransportWdmDriverObject = hidTransportWdmDeviceObject->DriverObject;\n    if (hidTransportWdmDriverObject == NULL) {\n        TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE, \"%!FUNC! DriverObject of HID transport Device Object is null, can't continue\");\n        status = STATUS_UNSUCCESSFUL;\n        goto cleanup;\n    }\n\n    // Verify if the driver extension is what we expected.\n    if (hidTransportWdmDriverObject->DriverExtension == NULL) {\n        TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE, \"%!FUNC! DriverExtension of HID transport Driver Object is null, can't continue\");\n        status = STATUS_UNSUCCESSFUL;\n        goto cleanup;\n    }\n\n    // Just two more check...\n    hidTransportIoClientExtension = ((PDRIVER_EXTENSION_EXT)hidTransportWdmDriverObject->DriverExtension)->IoClientExtension;\n    if (hidTransportIoClientExtension == NULL) {\n        TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE, \"%!FUNC! IO Extension is NULL, can't continue\");\n        status = STATUS_UNSUCCESSFUL;\n        goto cleanup;\n    }\n\n    if (strncmp(HID_CLASS_EXTENSION_LITERAL_ID, hidTransportIoClientExtension->ClientIdentificationAddress, sizeof(HID_CLASS_EXTENSION_LITERAL_ID)) != 0) {\n        TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE, \"%!FUNC! IO Extension mistmatch, can't continue\");\n        status = STATUS_UNSUCCESSFUL;\n        goto cleanup;\n    }\n\n    hidTransportClassExtension = (PHIDCLASS_DRIVER_EXTENSION)(hidTransportIoClientExtension + 1);\n    TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DEVICE, \"%!FUNC! Sanity check seems okay, safe to patch IO handler routines\");\n\n    // HIDClass overrides:\n    // IRP_MJ_SYSTEM_CONTROL, IRP_MJ_WRITE, IRP_MJ_READ, IRP_MJ_POWER, IRP_MJ_PNP, IRP_MJ_INTERNAL_DEVICE_CONTROL, IRP_MJ_DEVICE_CONTROL\n    // IRP_MJ_CREATE, IRP_MJ_CLOSE\n    // For us, overriding IRP_MJ_DEVICE_CONTROL and IRP_MJ_INTERNAL_DEVICE_CONTROL might be sufficient.\n    // Details: https://ligstd.visualstudio.com/Apple%20PTP%20Trackpad/_wiki/wikis/Apple-PTP-Trackpad.wiki/47/Hijack-HIDCLASS\n    hidTransportWdmDriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = hidTransportClassExtension->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL];\n    TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DEVICE, \"%!FUNC! IRP_MJ_INTERNAL_DEVICE_CONTROL patched\");\n\n    // Mark detour as completed.\n    deviceContext->IsHidIoDetourCompleted = TRUE;\n    deviceContext->HidIoTarget = WdfDeviceGetIoTarget(Device);\n\ncleanup:\n    if (hidTransportWdmDeviceObject != NULL) {\n        ObDereferenceObject(hidTransportWdmDeviceObject);\n    }\nexit:\n    TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DEVICE, \"%!FUNC! Exit, Status = %!STATUS!\", status);\n    return status;\n}\n"
  },
  {
    "path": "src/AmtPtpHidFilter/Device.c",
    "content": "// Device.c: Device-specific D0<->D3 handler and other misc procedures\n\n#include <Driver.h>\n#include \"Device.tmh\"\n\n#ifdef ALLOC_PRAGMA\n#pragma alloc_text (PAGE, PtpFilterCreateDevice)\n#endif\n\nNTSTATUS\nPtpFilterCreateDevice(\n    _Inout_ PWDFDEVICE_INIT DeviceInit\n)\n{\n    WDF_OBJECT_ATTRIBUTES deviceAttributes;\n    WDF_PNPPOWER_EVENT_CALLBACKS pnpPowerCallbacks;\n    WDF_TIMER_CONFIG timerConfig;\n    WDF_WORKITEM_CONFIG workitemConfig;\n    WDFDEVICE device;\n    PDEVICE_CONTEXT deviceContext;\n    NTSTATUS status;\n\n    PAGED_CODE();\n    TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DEVICE, \"%!FUNC! Entry\");\n\n    // Initialize Power Callback\n    WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpPowerCallbacks);\n    pnpPowerCallbacks.EvtDevicePrepareHardware = PtpFilterPrepareHardware;\n    pnpPowerCallbacks.EvtDeviceD0Entry = PtpFilterDeviceD0Entry;\n    pnpPowerCallbacks.EvtDeviceD0Exit = PtpFilterDeviceD0Exit;\n    pnpPowerCallbacks.EvtDeviceSelfManagedIoInit = PtpFilterSelfManagedIoInit;\n    pnpPowerCallbacks.EvtDeviceSelfManagedIoRestart = PtpFilterSelfManagedIoRestart;\n    WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpPowerCallbacks);\n\n    // Create WDF device object\n    WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&deviceAttributes, DEVICE_CONTEXT);\n    status = WdfDeviceCreate(&DeviceInit, &deviceAttributes, &device);\n    if (!NT_SUCCESS(status)) {\n        TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE, \"WdfDeviceCreate failed: %!STATUS!\", status);\n        goto exit;\n    }\n\n    // Initialize context and interface\n    deviceContext = PtpFilterGetContext(device);\n    deviceContext->Device = device;\n    deviceContext->WdmDeviceObject = WdfDeviceWdmGetDeviceObject(device);\n    if (deviceContext->WdmDeviceObject == NULL) {\n        TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE, \"WdfDeviceWdmGetDeviceObject failed\");\n        goto exit;\n    }\n\n    status = WdfDeviceCreateDeviceInterface(device,&GUID_DEVICEINTERFACE_AmtPtpHidFilter, NULL);\n    if (!NT_SUCCESS(status)) {\n        TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE, \"WdfDeviceCreateDeviceInterface failed: %!STATUS!\", status);\n        goto exit;\n    }\n\n    // Initialize read buffer\n    status = WdfLookasideListCreate(WDF_NO_OBJECT_ATTRIBUTES, REPORT_BUFFER_SIZE,\n        NonPagedPoolNx, WDF_NO_OBJECT_ATTRIBUTES, PTP_LIST_POOL_TAG,\n        &deviceContext->HidReadBufferLookaside\n    );\n    if (!NT_SUCCESS(status)) {\n        TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE, \"WdfLookasideListCreate failed: %!STATUS!\", status);\n    }\n\n    // Initialize HID recovery timer\n    WDF_TIMER_CONFIG_INIT(&timerConfig, PtpFilterRecoveryTimerCallback);\n    timerConfig.AutomaticSerialization = TRUE;\n    WDF_OBJECT_ATTRIBUTES_INIT(&deviceAttributes);\n    deviceAttributes.ParentObject = device;\n    deviceAttributes.ExecutionLevel = WdfExecutionLevelPassive;\n    status = WdfTimerCreate(&timerConfig, &deviceAttributes, &deviceContext->HidTransportRecoveryTimer);\n    if (!NT_SUCCESS(status)) {\n        TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE, \"WdfTimerCreate failed: %!STATUS!\", status);\n    }\n\n    // Initialize HID recovery workitem\n    WDF_WORKITEM_CONFIG_INIT(&workitemConfig, PtpFilterWorkItemCallback);\n    WDF_OBJECT_ATTRIBUTES_INIT(&deviceAttributes);\n    deviceAttributes.ParentObject = device;\n    status = WdfWorkItemCreate(&workitemConfig, &deviceAttributes, &deviceContext->HidTransportRecoveryWorkItem);\n    if (!NT_SUCCESS(status)) {\n        TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE, \"HidTransportRecoveryWorkItem failed: %!STATUS!\", status);\n    }\n\n    // Set initial state\n    deviceContext->VendorID = 0;\n    deviceContext->ProductID = 0;\n    deviceContext->VersionNumber = 0;\n    deviceContext->DeviceConfigured = FALSE;\n\n    // Initialize IO queue\n    status = PtpFilterIoQueueInitialize(device);\n    if (!NT_SUCCESS(status)) {\n        TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE, \"PtpFilterIoQueueInitialize failed: %!STATUS!\", status);\n    }\n\nexit:\n    TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DEVICE, \"%!FUNC! Exit, Status = %!STATUS!\", status);\n    return status;\n}\n\nNTSTATUS\nPtpFilterPrepareHardware(\n    _In_ WDFDEVICE Device,\n    _In_ WDFCMRESLIST ResourceList,\n    _In_ WDFCMRESLIST ResourceListTranslated\n)\n{\n    PDEVICE_CONTEXT deviceContext;\n    NTSTATUS status = STATUS_SUCCESS;\n    \n    // We don't need to retrieve resources since this works as a filter now\n    UNREFERENCED_PARAMETER(ResourceList);\n    UNREFERENCED_PARAMETER(ResourceListTranslated);\n\n    PAGED_CODE();\n    TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DEVICE, \"%!FUNC! Entry\");\n    deviceContext = PtpFilterGetContext(Device);\n\n    // Initialize IDs, set to zero\n    deviceContext->VendorID = 0;\n    deviceContext->ProductID = 0;\n    deviceContext->VersionNumber = 0;\n    deviceContext->DeviceConfigured = FALSE;\n\n    TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DEVICE, \"%!FUNC! Exit, Status = %!STATUS!\", status);\n    return status;\n}\n\nNTSTATUS\nPtpFilterDeviceD0Entry(\n    _In_ WDFDEVICE Device,\n    _In_ WDF_POWER_DEVICE_STATE PreviousState\n)\n{\n    NTSTATUS status = STATUS_SUCCESS;\n\n    PAGED_CODE();\n    UNREFERENCED_PARAMETER(Device);\n    UNREFERENCED_PARAMETER(PreviousState);\n    TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DEVICE, \"%!FUNC! Entry\");\n\n    TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DEVICE, \"%!FUNC! Exit, Status = %!STATUS!\", status);\n    return status;\n}\n\nNTSTATUS\nPtpFilterDeviceD0Exit(\n    _In_ WDFDEVICE Device,\n    _In_ WDF_POWER_DEVICE_STATE TargetState\n)\n{\n    PDEVICE_CONTEXT deviceContext;\n    NTSTATUS status = STATUS_SUCCESS;\n    WDFREQUEST outstandingRequest;\n\n    UNREFERENCED_PARAMETER(TargetState);\n\n    PAGED_CODE();\n    TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DEVICE, \"%!FUNC! Entry\");\n    deviceContext = PtpFilterGetContext(Device);\n\n    // Reset device state\n    deviceContext->DeviceConfigured = FALSE;\n\n    // Cancelling all outstanding requests\n    while (NT_SUCCESS(status)) {\n        status = WdfIoQueueRetrieveNextRequest(\n            deviceContext->HidReadQueue,\n            &outstandingRequest\n        );\n\n        if (NT_SUCCESS(status)) {\n            WdfRequestComplete(outstandingRequest, STATUS_CANCELLED);\n        }\n    }\n\n    TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DEVICE, \"%!FUNC! Exit, Status = %!STATUS!\", STATUS_SUCCESS);\n    return STATUS_SUCCESS;\n}\n\nNTSTATUS\nPtpFilterSelfManagedIoInit(\n    _In_ WDFDEVICE Device\n)\n{\n    NTSTATUS status;\n    PDEVICE_CONTEXT deviceContext;\n    WDF_MEMORY_DESCRIPTOR hidAttributeMemoryDescriptor;\n    HID_DEVICE_ATTRIBUTES deviceAttributes;\n\n    PAGED_CODE();\n    TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DEVICE, \"%!FUNC! Entry\");\n\n    deviceContext = PtpFilterGetContext(Device);\n    status = PtpFilterDetourWindowsHIDStack(Device);\n    if (!NT_SUCCESS(status)) {\n        TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE, \"%!FUNC! PtpFilterDetourWindowsHIDStack failed, Status = %!STATUS!\", status);\n        goto exit;\n    }\n\n    // Request device attribute descriptor for self-identification.\n    RtlZeroMemory(&deviceAttributes, sizeof(deviceAttributes));\n    WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(\n        &hidAttributeMemoryDescriptor,\n        (PVOID)&deviceAttributes,\n        sizeof(deviceAttributes)\n    );\n\n    status = WdfIoTargetSendInternalIoctlSynchronously(\n        deviceContext->HidIoTarget, NULL,\n        IOCTL_HID_GET_DEVICE_ATTRIBUTES,\n        NULL, &hidAttributeMemoryDescriptor, NULL, NULL);\n    if (!NT_SUCCESS(status)) {\n        TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE, \"%!FUNC! WdfIoTargetSendInternalIoctlSynchronously failed, Status = %!STATUS!\", status);\n        goto exit;\n    }\n\n    deviceContext->VendorID = deviceAttributes.VendorID;\n    deviceContext->ProductID = deviceAttributes.ProductID;\n    deviceContext->VersionNumber = deviceAttributes.VersionNumber;\n    TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DEVICE, \"%!FUNC! Device %x:%x, Version 0x%x\", deviceContext->VendorID,\n        deviceContext->ProductID, deviceContext->VersionNumber);\n\n    status = PtpFilterConfigureMultiTouch(Device);\n    if (!NT_SUCCESS(status)) {\n        // If this failed, we will retry after 2 seconds (and pretend nothing happens)\n        TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE, \"%!FUNC! PtpFilterConfigureMultiTouch failed, Status = %!STATUS!\", status);\n        status = STATUS_SUCCESS;\n        WdfTimerStart(deviceContext->HidTransportRecoveryTimer, WDF_REL_TIMEOUT_IN_SEC(2));\n        goto exit;\n    }\n\n    // Stamp last query performance counter\n    KeQueryPerformanceCounter(&deviceContext->LastReportTime);\n\n    // Set device state\n    deviceContext->DeviceConfigured = TRUE;\n\nexit:\n    TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DEVICE, \"%!FUNC! Exit, Status = %!STATUS!\", status);\n    return status;\n}\n\nNTSTATUS\nPtpFilterSelfManagedIoRestart(\n    _In_ WDFDEVICE Device\n)\n{\n    NTSTATUS status = STATUS_SUCCESS;\n    PDEVICE_CONTEXT deviceContext;\n\n    PAGED_CODE();\n    TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DEVICE, \"%!FUNC! Entry\");\n    deviceContext = PtpFilterGetContext(Device);\n\n    // If this is first D0, it will be done in self-managed IO init.\n    if (deviceContext->IsHidIoDetourCompleted) {\n        status = PtpFilterConfigureMultiTouch(Device);\n        if (!NT_SUCCESS(status)) {\n            TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE, \"%!FUNC! PtpFilterConfigureMultiTouch failed, Status = %!STATUS!\", status);\n            // If this failed, we will retry after 2 seconds (and pretend nothing happens)\n            status = STATUS_SUCCESS;\n            WdfTimerStart(deviceContext->HidTransportRecoveryTimer, WDF_REL_TIMEOUT_IN_SEC(2));\n            goto exit;\n        }\n    }\n    else {\n        TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE, \"%!FUNC! HID detour should already complete here\");\n        status = STATUS_INVALID_STATE_TRANSITION;\n    }\n\n    // Stamp last query performance counter\n    KeQueryPerformanceCounter(&deviceContext->LastReportTime);\n\n    // Set device state\n    deviceContext->DeviceConfigured = TRUE;\n\nexit:\n    TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DEVICE, \"%!FUNC! Exit, Status = %!STATUS!\", status);\n    return status;\n}\n\nNTSTATUS\nPtpFilterConfigureMultiTouch(\n    _In_ WDFDEVICE Device\n)\n{\n    NTSTATUS status = STATUS_SUCCESS;\n    PDEVICE_CONTEXT deviceContext;\n\n    UCHAR hidPacketBuffer[HID_XFER_PACKET_SIZE];\n    PHID_XFER_PACKET pHidPacket;\n    WDFMEMORY hidMemory;\n    WDF_OBJECT_ATTRIBUTES attributes;\n    WDF_REQUEST_SEND_OPTIONS configRequestSendOptions;\n    WDFREQUEST configRequest;\n    PIRP pConfigIrp = NULL;\n\n    PAGED_CODE();\n    TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DEVICE, \"%!FUNC! Entry\");\n    deviceContext = PtpFilterGetContext(Device); \n    \n    // Check if this device is supported for configuration.\n    // So far in this prototype, we support Magic Trackpad 2 in USB (05AC:0265) or Bluetooth mode (004c:0265)\n    if (deviceContext->VendorID != HID_VID_APPLE_USB && deviceContext->VendorID != HID_VID_APPLE_BT) {\n        TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE, \"%!FUNC! Vendor not supported: 0x%x\", deviceContext->VendorID);\n        status = STATUS_NOT_SUPPORTED;\n        goto exit;\n    }\n    if (deviceContext->ProductID != HID_PID_MAGIC_TRACKPAD_2) {\n        TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE, \"%!FUNC! Product not supported: 0x%x\", deviceContext->ProductID);\n        status = STATUS_NOT_SUPPORTED;\n        goto exit;\n    }\n\n    RtlZeroMemory(hidPacketBuffer, sizeof(hidPacketBuffer));\n    pHidPacket = (PHID_XFER_PACKET) &hidPacketBuffer;\n\n    if (deviceContext->VendorID == HID_VID_APPLE_USB) {\n        deviceContext->InputFingerSize = FSIZE_TYPE5;\n        deviceContext->InputHeaderSize = HOFFSET_TYPE_USB_5;\n        deviceContext->InputFingerDelta = FDELTA_TYPE5;\n        deviceContext->InputButtonDelta = BOFFSET_TYPE5;\n\n        deviceContext->X.snratio = 250;\n        deviceContext->X.min = -3678;\n        deviceContext->X.max = 3934;\n        deviceContext->Y.snratio = 250;\n        deviceContext->Y.min = -2479;\n        deviceContext->Y.max = 2586;\n\n        pHidPacket->reportId = 0x02;\n        pHidPacket->reportBufferLen = 0x04;\n        pHidPacket->reportBuffer = (PUCHAR)pHidPacket + sizeof(HID_XFER_PACKET);\n        pHidPacket->reportBuffer[0] = 0x02;\n        pHidPacket->reportBuffer[1] = 0x01;\n        pHidPacket->reportBuffer[2] = 0x00;\n        pHidPacket->reportBuffer[3] = 0x00;\n    }\n    else if (deviceContext->VendorID == HID_VID_APPLE_BT) {\n        deviceContext->InputFingerSize = FSIZE_TYPE5;\n        deviceContext->InputHeaderSize = HOFFSET_TYPE_BTH_5;\n        deviceContext->InputFingerDelta = FDELTA_TYPE5;\n        deviceContext->InputButtonDelta = BOFFSET_TYPE5;\n\n        deviceContext->X.snratio = 250;\n        deviceContext->X.min = -3678;\n        deviceContext->X.max = 3934;\n        deviceContext->Y.snratio = 250;\n        deviceContext->Y.min = -2479;\n        deviceContext->Y.max = 2586;\n\n        pHidPacket->reportId = 0xF1;\n        pHidPacket->reportBufferLen = 0x03;\n        pHidPacket->reportBuffer = (PUCHAR)pHidPacket + sizeof(HID_XFER_PACKET);\n        pHidPacket->reportBuffer[0] = 0xF1;\n        pHidPacket->reportBuffer[1] = 0x02;\n        pHidPacket->reportBuffer[2] = 0x01;\n    }\n    else {\n        // Something we don't support yet.\n        TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE, \"%!FUNC! Unrecognized device detected\");\n        status = STATUS_NOT_SUPPORTED;\n        goto exit;\n    }\n\n    // Init a request entity.\n    // Because we bypassed HIDCLASS driver, there's a few things that we need to manually take care of.\n    status = WdfRequestCreate(WDF_NO_OBJECT_ATTRIBUTES, deviceContext->HidIoTarget, &configRequest);\n    if (!NT_SUCCESS(status)) {\n        TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE, \"%!FUNC! WdfRequestCreate failed, Status = %!STATUS!\", status);\n        goto exit;\n    }\n\n    WDF_OBJECT_ATTRIBUTES_INIT(&attributes);\n    attributes.ParentObject = configRequest;\n    status = WdfMemoryCreatePreallocated(&attributes, (PVOID) pHidPacket, HID_XFER_PACKET_SIZE, &hidMemory);\n    if (!NT_SUCCESS(status)) {\n        TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE, \"%!FUNC! WdfMemoryCreatePreallocated failed, Status = %!STATUS!\", status);\n        goto cleanup;\n    }\n\n    status = WdfIoTargetFormatRequestForInternalIoctl(deviceContext->HidIoTarget,\n        configRequest, IOCTL_HID_SET_FEATURE,\n        hidMemory, NULL, NULL, NULL);\n    if (!NT_SUCCESS(status)) {\n        TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE, \"%!FUNC! WdfIoTargetFormatRequestForInternalIoctl failed, Status = %!STATUS!\", status);\n        goto cleanup;\n    }\n    \n    // Manually take care of IRP to meet requirements of mini drivers.\n    pConfigIrp = WdfRequestWdmGetIrp(configRequest);\n    if (pConfigIrp == NULL) {\n        TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE, \"%!FUNC! WdfRequestWdmGetIrp failed\");\n        status = STATUS_UNSUCCESSFUL;\n        goto cleanup;\n    }\n\n    // God-damn-it we have to configure it by ourselves :)\n    pConfigIrp->UserBuffer = pHidPacket;\n\n    WDF_REQUEST_SEND_OPTIONS_INIT(&configRequestSendOptions, WDF_REQUEST_SEND_OPTION_SYNCHRONOUS);\n    if (WdfRequestSend(configRequest, deviceContext->HidIoTarget, &configRequestSendOptions) == FALSE) {\n        status = WdfRequestGetStatus(configRequest);\n        TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE, \"%!FUNC! WdfRequestSend failed, Status = %!STATUS!\", status);\n        goto cleanup;\n    } else {\n        TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DEVICE, \"%!FUNC! Changed trackpad status to multitouch mode\");\n        status = STATUS_SUCCESS;\n    }\n\ncleanup:\n    if (configRequest != NULL) {\n        WdfObjectDelete(configRequest);\n    }\nexit:\n    TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DEVICE, \"%!FUNC! Exit, Status = %!STATUS!\", status);\n    return status;\n}\n\nVOID\nPtpFilterRecoveryTimerCallback(\n    WDFTIMER Timer\n)\n{\n    WDFDEVICE device;\n    PDEVICE_CONTEXT deviceContext;\n    NTSTATUS status;\n\n    device = WdfTimerGetParentObject(Timer);\n    deviceContext = PtpFilterGetContext(device);\n\n    // We will try to reinitialize the device\n    status = PtpFilterSelfManagedIoRestart(device);\n    if (NT_SUCCESS(status)) {\n        // If succeeded, proceed to reissue the request.\n        // Otherwise it will retry the process after a few seconds.\n        PtpFilterInputIssueTransportRequest(device);\n    }\n}\n"
  },
  {
    "path": "src/AmtPtpHidFilter/Diagnostics.c",
    "content": "// Diagnostics.c: Debug and diagnostics facilities\n\n#include <Driver.h>\n#include \"Diagnostics.tmh\"\n\nVOID PtpFilterDiagnosticsInitializeContinuousRead(\n\t_In_ WDFDEVICE Device\n)\n{\n\tNTSTATUS status = STATUS_SUCCESS;\n\n\tTraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DEVICE, \"%!FUNC! Entry\");\n\t\n\t// Issue a request to underlying HID target. Then start to have a continus stream reading it\n\tPtpFilterDiagnosticsInputIssueRequest(Device);\n\n\tTraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DEVICE, \"%!FUNC! Exit, Status = %!STATUS!\", status);\n}\n\nVOID\nPtpFilterDiagnosticsInputIssueRequest(\n\t_In_ WDFDEVICE Device\n)\n{\n\tNTSTATUS status;\n\tPDEVICE_CONTEXT deviceContext;\n\tWDF_OBJECT_ATTRIBUTES attributes;\n\tBOOLEAN requestStatus = FALSE;\n\tWDFREQUEST hidReadRequest;\n\tWDFMEMORY hidReadOutputMemory;\n\tPWORKER_REQUEST_CONTEXT requestContext;\n\n\tdeviceContext = PtpFilterGetContext(Device);\n\n\tWDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, WORKER_REQUEST_CONTEXT);\n\tattributes.ParentObject = Device;\n\n\tstatus = WdfRequestCreate(&attributes, deviceContext->HidIoTarget, &hidReadRequest);\n\tif (!NT_SUCCESS(status))\n\t{\n\t\tTraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE, \"%!FUNC! WdfRequestCreate fails, status = %!STATUS!\",status);\n\t\tWdfTimerStart(deviceContext->HidTransportRecoveryTimer, WDF_REL_TIMEOUT_IN_US(200));\n\t\treturn;\n\t}\n\n\tstatus = WdfMemoryCreateFromLookaside(deviceContext->HidReadBufferLookaside, &hidReadOutputMemory);\n\tif (!NT_SUCCESS(status))\n\t{\n\t\tTraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE, \"%!FUNC! WdfMemoryCreateFromLookaside fails, status = %!STATUS!\", status);\n\t\tWdfObjectDelete(hidReadRequest);\n\t\tWdfTimerStart(deviceContext->HidTransportRecoveryTimer, WDF_REL_TIMEOUT_IN_US(200));\n\t\treturn;\n\t}\n\n\t// Assign context information\n\trequestContext = WorkerRequestGetContext(hidReadRequest);\n\trequestContext->DeviceContext = deviceContext;\n\trequestContext->RequestMemory = hidReadOutputMemory;\n\n\t// Invoke HID read request to the device.\n\tstatus = WdfIoTargetFormatRequestForInternalIoctl(deviceContext->HidIoTarget, hidReadRequest,\n\t\tIOCTL_HID_READ_REPORT, NULL, 0, hidReadOutputMemory, 0);\n\n\tif (!NT_SUCCESS(status))\n\t{\n\t\tTraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE, \"%!FUNC! WdfIoTargetFormatRequestForInternalIoctl fails, status = %!STATUS!\", status);\n\n\t\tif (hidReadOutputMemory != NULL) {\n\t\t\tWdfObjectDelete(hidReadOutputMemory);\n\t\t}\n\n\t\tif (hidReadRequest != NULL) {\n\t\t\tWdfObjectDelete(hidReadRequest);\n\t\t}\n\n\t\treturn;\n\t}\n\n\tWdfRequestSetCompletionRoutine(\n\t\thidReadRequest,\n\t\tPtpFilterDiagnosticsRequestCompletionRoutine,\n\t\trequestContext\n\t);\n\n\trequestStatus = WdfRequestSend(\n\t\thidReadRequest,\n\t\tdeviceContext->HidIoTarget,\n\t\tNULL\n\t);\n\n\tif (!requestStatus)\n\t{\n\t\tTraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE, \"%!FUNC! AmtPtpSpiInputRoutineWorker request failed to sent\");\n\t\tWdfTimerStart(deviceContext->HidTransportRecoveryTimer, WDF_REL_TIMEOUT_IN_US(50));\n\n\t\tif (hidReadOutputMemory != NULL) {\n\t\t\tWdfObjectDelete(hidReadOutputMemory);\n\t\t}\n\n\t\tif (hidReadRequest != NULL) {\n\t\t\tWdfObjectDelete(hidReadRequest);\n\t\t}\n\t}\n}\n\nVOID\nPtpFilterDiagnosticsRequestCompletionRoutine(\n\t_In_ WDFREQUEST Request,\n\t_In_ WDFIOTARGET Target,\n\t_In_ PWDF_REQUEST_COMPLETION_PARAMS Params,\n\t_In_ WDFCONTEXT Context\n)\n{\n\tPWORKER_REQUEST_CONTEXT requestContext;\n\tPDEVICE_CONTEXT deviceContext;\n\tLONG responseLength;\n\n\tUNREFERENCED_PARAMETER(Request);\n\tUNREFERENCED_PARAMETER(Target);\n\tUNREFERENCED_PARAMETER(Params);\n\n\trequestContext = (PWORKER_REQUEST_CONTEXT)Context;\n\tdeviceContext = requestContext->DeviceContext;\n\n\t// Decode request\n\tresponseLength = (LONG) WdfRequestGetInformation(Request);\n\tif (responseLength > 0) {\n\t\tTraceEvents(TRACE_LEVEL_INFORMATION, TRACE_INPUT, \"Request received with size %d\", responseLength);\n\t}\n\n\t// Cleanup\n\tWdfObjectDelete(Request);\n\tif (requestContext->RequestMemory != NULL) {\n\t\tWdfObjectDelete(requestContext->RequestMemory);\n\t}\n\n\t// Issue next request\n\tPtpFilterDiagnosticsInputIssueRequest(requestContext->DeviceContext->Device);\n}\n\nPCHAR\nPtpFilterDiagnosticsIoControlGetString(\n\t_In_ ULONG IoControlCode\n)\n{\n\tswitch (IoControlCode)\n\t{\n\tcase IOCTL_HID_GET_DEVICE_DESCRIPTOR:\n\t\treturn \"IOCTL_HID_GET_DEVICE_DESCRIPTOR\";\n\tcase IOCTL_HID_GET_DEVICE_ATTRIBUTES:\n\t\treturn \"IOCTL_HID_GET_DEVICE_ATTRIBUTES\";\n\tcase IOCTL_HID_GET_REPORT_DESCRIPTOR:\n\t\treturn \"IOCTL_HID_GET_REPORT_DESCRIPTOR\";\n\tcase IOCTL_HID_GET_STRING:\n\t\treturn \"IOCTL_HID_GET_STRING\";\n\tcase IOCTL_HID_READ_REPORT:\n\t\treturn \"IOCTL_HID_READ_REPORT\";\n\tcase IOCTL_HID_WRITE_REPORT:\n\t\treturn \"IOCTL_HID_WRITE_REPORT\";\n\tcase IOCTL_UMDF_HID_GET_INPUT_REPORT:\n\t\treturn \"IOCTL_UMDF_HID_GET_INPUT_REPORT\";\n\tcase IOCTL_UMDF_HID_SET_OUTPUT_REPORT:\n\t\treturn \"IOCTL_UMDF_HID_SET_OUTPUT_REPORT\";\n\tcase IOCTL_UMDF_HID_GET_FEATURE:\n\t\treturn \"IOCTL_UMDF_HID_GET_FEATURE\";\n\tcase IOCTL_UMDF_HID_SET_FEATURE:\n\t\treturn \"IOCTL_UMDF_HID_SET_FEATURE\";\n\tcase IOCTL_HID_ACTIVATE_DEVICE:\n\t\treturn \"IOCTL_HID_ACTIVATE_DEVICE\";\n\tcase IOCTL_HID_DEACTIVATE_DEVICE:\n\t\treturn \"IOCTL_HID_DEACTIVATE_DEVICE\";\n\tcase IOCTL_HID_SEND_IDLE_NOTIFICATION_REQUEST:\n\t\treturn \"IOCTL_HID_SEND_IDLE_NOTIFICATION_REQUEST\";\n\tcase IOCTL_HID_GET_FEATURE:\n\t\treturn \"IOCTL_HID_GET_FEATURE\";\n\tcase IOCTL_HID_SET_FEATURE:\n\t\treturn \"IOCTL_HID_SET_FEATURE\";\n\tdefault:\n\t\treturn \"IOCTL_UNKNOWN\";\n\t}\n}\n"
  },
  {
    "path": "src/AmtPtpHidFilter/Driver.c",
    "content": "// Driver.c: Common entry point and WPP trace filter handler\n\n#include <Driver.h>\n#include \"Driver.tmh\"\n\n#ifdef ALLOC_PRAGMA\n#pragma alloc_text (INIT, DriverEntry)\n#pragma alloc_text (PAGE, PtpFilterEvtDeviceAdd)\n#pragma alloc_text (PAGE, PtpFilterEvtDriverContextCleanup)\n#endif\n\nNTSTATUS\nDriverEntry(\n    _In_ PDRIVER_OBJECT  DriverObject,\n    _In_ PUNICODE_STRING RegistryPath\n)\n{\n    NTSTATUS status;\n    WDF_DRIVER_CONFIG config;\n    WDF_OBJECT_ATTRIBUTES attributes;\n\n    PAGED_CODE();\n\n    // Initialize WPP\n    WPP_INIT_TRACING(DriverObject, RegistryPath);\n\n    // Register a cleanup callback\n    WDF_OBJECT_ATTRIBUTES_INIT(&attributes);\n    attributes.EvtCleanupCallback = PtpFilterEvtDriverContextCleanup;\n\n    // Register WDF driver\n    WDF_DRIVER_CONFIG_INIT(&config, PtpFilterEvtDeviceAdd);\n    status = WdfDriverCreate(DriverObject, RegistryPath, &attributes, &config, WDF_NO_HANDLE);\n\n    if (!NT_SUCCESS(status)) {\n        TraceEvents(TRACE_LEVEL_ERROR, TRACE_DRIVER, \"WdfDriverCreate failed %!STATUS!\", status);\n        WPP_CLEANUP(DriverObject);\n        return status;\n    }\n\n    TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, \"%!FUNC! Driver Initialized\");\n    return STATUS_SUCCESS;\n}\n\nNTSTATUS\nPtpFilterEvtDeviceAdd(\n    _In_    WDFDRIVER       Driver,\n    _Inout_ PWDFDEVICE_INIT DeviceInit\n)\n{\n    NTSTATUS status;\n\n    UNREFERENCED_PARAMETER(Driver);\n    PAGED_CODE();\n    TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, \"%!FUNC! Entry\");\n\n    // We do not own power control.\n    // In addition we do not own every I/O request.\n    WdfFdoInitSetFilter(DeviceInit);\n\n    // Create the device.\n    status = PtpFilterCreateDevice(DeviceInit);\n\n    TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, \"%!FUNC! Exit\");\n    return status;\n}\n\nVOID\nPtpFilterEvtDriverContextCleanup(\n    _In_ WDFOBJECT DriverObject\n)\n{\n    PAGED_CODE();\n    TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, \"%!FUNC! Cleanup\");\n\n    //\n    // Stop WPP Tracing\n    //\n    WPP_CLEANUP(WdfDriverWdmGetDriverObject((WDFDRIVER)DriverObject));\n}\n"
  },
  {
    "path": "src/AmtPtpHidFilter/Hid.c",
    "content": "// Hid.c: HID specific routines\n\n#include <Driver.h>\n#include \"Hid.tmh\"\n\nNTSTATUS\nPtpFilterGetHidDescriptor(\n\t_In_ WDFDEVICE Device,\n\t_In_ WDFREQUEST Request\n)\n{\n\n\tNTSTATUS        status = STATUS_SUCCESS;\n\tPDEVICE_CONTEXT deviceContext;\n\tsize_t\t\t\thidDescriptorSize = 0;\n\tWDFMEMORY       requestMemory;\n\tPHID_DESCRIPTOR pSelectedHidDescriptor = NULL;\n\n\tTraceEvents(TRACE_LEVEL_INFORMATION, TRACE_HID, \"%!FUNC! Entry\");\n\tdeviceContext = PtpFilterGetContext(Device);\n\n\tstatus = WdfRequestRetrieveOutputMemory(Request, &requestMemory);\n\tif (!NT_SUCCESS(status)) {\n\t\tTraceEvents(TRACE_LEVEL_ERROR, TRACE_HID, \"%!FUNC! WdfRequestRetrieveOutputBuffer failed with %!STATUS!\", status);\n\t\tgoto exit;\n\t}\n\n\tswitch (deviceContext->ProductID) {\n\t\tcase HID_PID_MAGIC_TRACKPAD_2:\n\t\t{\n\t\t\tTraceEvents(TRACE_LEVEL_INFORMATION, TRACE_HID, \"%!FUNC! Request HID Report Descriptor for Apple Magic Trackpad 2 Family\");\n\t\t\thidDescriptorSize = PtpDefaultHidDescriptorMagicTrackpad2.bLength;\n\t\t\tpSelectedHidDescriptor = &PtpDefaultHidDescriptorMagicTrackpad2;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (pSelectedHidDescriptor != NULL && hidDescriptorSize > 0) {\n\t\tstatus = WdfMemoryCopyFromBuffer(requestMemory, 0, (PVOID)pSelectedHidDescriptor, hidDescriptorSize);\n\t\tif (!NT_SUCCESS(status)) {\n\t\t\tTraceEvents(TRACE_LEVEL_ERROR, TRACE_HID, \"%!FUNC! WdfMemoryCopyFromBuffer failed with %!STATUS!\", status);\n\t\t\tgoto exit;\n\t\t}\n\n\t\tWdfRequestSetInformation(Request, hidDescriptorSize);\n\t}\n\telse {\n\t\tTraceEvents(TRACE_LEVEL_WARNING, TRACE_HID, \"%!FUNC! Device HID registry is not found\");\n\t\tstatus = STATUS_NOT_SUPPORTED;\n\t\tgoto exit;\n\t}\n\nexit:\n\tTraceEvents(TRACE_LEVEL_INFORMATION, TRACE_HID, \"%!FUNC! Exit\");\n\treturn status;\n}\n\nNTSTATUS\nPtpFilterGetDeviceAttribs(\n\t_In_ WDFDEVICE Device,\n\t_In_ WDFREQUEST Request\n)\n{\n\n\tNTSTATUS               status = STATUS_SUCCESS;\n\tPDEVICE_CONTEXT        deviceContext;\n\tPHID_DEVICE_ATTRIBUTES pDeviceAttributes = NULL;\n\n\tTraceEvents(TRACE_LEVEL_INFORMATION, TRACE_HID, \"%!FUNC! Entry\");\n\tdeviceContext = PtpFilterGetContext(Device);\n\n\tstatus = WdfRequestRetrieveOutputBuffer(Request, sizeof(HID_DEVICE_ATTRIBUTES), &pDeviceAttributes, NULL);\n\tif (!NT_SUCCESS(status)) {\n\t\tTraceEvents(TRACE_LEVEL_ERROR, TRACE_HID, \"%!FUNC! WdfRequestRetrieveOutputBuffer failed with %!STATUS!\", status);\n\t\tgoto exit;\n\t}\n\n\tpDeviceAttributes->Size = sizeof(HID_DEVICE_ATTRIBUTES);\n\t// Okay here's one thing: we cannot report the real ID here, otherwise there's will be some great conflict with the USB/BT driver.\n\t// Therefore Vendor ID is changed to a hardcoded number\n\tpDeviceAttributes->ProductID = deviceContext->ProductID;\n\tpDeviceAttributes->VendorID = DEVICE_VID;\n\tpDeviceAttributes->VersionNumber = DEVICE_VERSION;\n\tWdfRequestSetInformation(Request, sizeof(HID_DEVICE_ATTRIBUTES));\n\nexit:\n\tTraceEvents(TRACE_LEVEL_INFORMATION, TRACE_HID, \"%!FUNC! Exit\");\n\treturn status;\n}\n\nNTSTATUS\nPtpFilterGetReportDescriptor(\n\t_In_ WDFDEVICE Device,\n\t_In_ WDFREQUEST Request\n)\n{\n\n\tNTSTATUS               status = STATUS_SUCCESS;\n\tPDEVICE_CONTEXT        deviceContext;\n\tsize_t\t\t\t       hidDescriptorSize = 0;\n\tWDFMEMORY              requestMemory;\n\tPHID_REPORT_DESCRIPTOR selectedHidDescriptor = NULL;\n\n\tTraceEvents(TRACE_LEVEL_INFORMATION, TRACE_HID, \"%!FUNC! Entry\");\n\tdeviceContext = PtpFilterGetContext(Device);\n\n\tstatus = WdfRequestRetrieveOutputMemory(Request, &requestMemory);\n\tif (!NT_SUCCESS(status)) {\n\t\tTraceEvents(TRACE_LEVEL_ERROR, TRACE_HID, \"%!FUNC! WdfRequestRetrieveOutputBuffer failed with %!STATUS!\", status);\n\t\tgoto exit;\n\t}\n\n\tswitch (deviceContext->ProductID) {\n\t\tcase HID_PID_MAGIC_TRACKPAD_2:\n\t\t{\n\t\t\thidDescriptorSize = PtpDefaultHidDescriptorMagicTrackpad2.DescriptorList[0].wReportLength;\n\t\t\tselectedHidDescriptor = PtpReportDescriptorMagicTrackpad2;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (selectedHidDescriptor != NULL && hidDescriptorSize > 0) {\n\t\tstatus = WdfMemoryCopyFromBuffer(requestMemory, 0, (PVOID)selectedHidDescriptor, hidDescriptorSize);\n\t\tif (!NT_SUCCESS(status)) {\n\t\t\tTraceEvents(TRACE_LEVEL_ERROR, TRACE_HID, \"%!FUNC! WdfMemoryCopyFromBuffer failed with %!STATUS!\", status);\n\t\t\tgoto exit;\n\t\t}\n\n\t\tWdfRequestSetInformation(Request, hidDescriptorSize);\n\t}\n\telse {\n\t\tTraceEvents(TRACE_LEVEL_WARNING, TRACE_HID, \"%!FUNC! Device HID registry is not found\");\n\t\tstatus = STATUS_NOT_SUPPORTED;\n\t\tgoto exit;\n\t}\n\nexit:\n\tTraceEvents(TRACE_LEVEL_INFORMATION, TRACE_HID, \"%!FUNC! Exit\");\n\treturn status;\n}\n\nNTSTATUS\nPtpFilterGetStrings(\n\t_In_ WDFDEVICE Device,\n\t_In_ WDFREQUEST Request,\n\t_Out_ BOOLEAN* Pending\n)\n{\n\tNTSTATUS status = STATUS_SUCCESS;\n\tPDEVICE_CONTEXT deviceContext;\n\tBOOLEAN requestSent;\n\tWDF_REQUEST_SEND_OPTIONS sendOptions;\n\n\tTraceEvents(TRACE_LEVEL_INFORMATION, TRACE_HID, \"%!FUNC! Entry\");\n\tdeviceContext = PtpFilterGetContext(Device);\n\n\t// Forward the IRP to our upstream IO target\n\t// We don't really care about the content\n\tWdfRequestFormatRequestUsingCurrentType(Request);\n\tWDF_REQUEST_SEND_OPTIONS_INIT(&sendOptions, WDF_REQUEST_SEND_OPTION_SEND_AND_FORGET);\n\n\t// This IOCTL is METHOD_NEITHER, so we just send it without IRP modification\n\trequestSent = WdfRequestSend(Request, deviceContext->HidIoTarget, &sendOptions);\n\t*Pending = TRUE;\n\n\tif (!requestSent)\n\t{\n\t\tstatus = WdfRequestGetStatus(Request);\n\t\t*Pending = FALSE;\n\t}\n\n\tTraceEvents(TRACE_LEVEL_INFORMATION, TRACE_HID, \"%!FUNC! Exit\");\n\treturn status;\n}\n\nNTSTATUS\nPtpFilterGetHidFeatures(\n\t_In_ WDFDEVICE Device,\n\t_In_ WDFREQUEST Request\n)\n{\n\tNTSTATUS status = STATUS_SUCCESS;\n\tPDEVICE_CONTEXT deviceContext;\n\t\n\tWDF_REQUEST_PARAMETERS requestParameters;\n\tsize_t reportSize;\n\tPHID_XFER_PACKET hidContent;\n\n\tTraceEvents(TRACE_LEVEL_INFORMATION, TRACE_HID, \"%!FUNC! Entry\");\n\tdeviceContext = PtpFilterGetContext(Device);\n\n\tWDF_REQUEST_PARAMETERS_INIT(&requestParameters);\n\tWdfRequestGetParameters(Request, &requestParameters);\n\tif (requestParameters.Parameters.DeviceIoControl.OutputBufferLength < sizeof(HID_XFER_PACKET))\n\t{\n\t\tstatus = STATUS_BUFFER_TOO_SMALL;\n\t\tgoto exit;\n\t}\n\n\thidContent = (PHID_XFER_PACKET)WdfRequestWdmGetIrp(Request)->UserBuffer;\n\tif (hidContent == NULL)\n\t{\n\t\tstatus = STATUS_INVALID_DEVICE_REQUEST;\n\t\tgoto exit;\n\t}\n\n\tswitch (hidContent->reportId)\n\t{\n\tcase REPORTID_DEVICE_CAPS:\n\t{\n\t\tTraceEvents(TRACE_LEVEL_INFORMATION, TRACE_HID, \"%!FUNC! Report REPORTID_DEVICE_CAPS is requested\");\n\n\t\t// Size sanity check\n\t\treportSize = sizeof(PTP_DEVICE_CAPS_FEATURE_REPORT);\n\t\tif (hidContent->reportBufferLen < reportSize) {\n\t\t\tstatus = STATUS_INVALID_BUFFER_SIZE;\n\t\t\tTraceEvents(TRACE_LEVEL_ERROR, TRACE_HID, \"%!FUNC! Report buffer is too small\");\n\t\t\tgoto exit;\n\t\t}\n\n\t\tPPTP_DEVICE_CAPS_FEATURE_REPORT capsReport = (PPTP_DEVICE_CAPS_FEATURE_REPORT)hidContent->reportBuffer;\n\t\tcapsReport->MaximumContactPoints = PTP_MAX_CONTACT_POINTS;\n\t\tcapsReport->ButtonType = PTP_BUTTON_TYPE_CLICK_PAD;\n\t\tcapsReport->ReportID = REPORTID_DEVICE_CAPS;\n\n\t\tTraceEvents(TRACE_LEVEL_INFORMATION, TRACE_HID, \"%!FUNC! Report REPORTID_DEVICE_CAPS has maximum contact points of %d\", capsReport->MaximumContactPoints);\n\t\tTraceEvents(TRACE_LEVEL_INFORMATION, TRACE_HID, \"%!FUNC! Report REPORTID_DEVICE_CAPS has touchpad type %d\", capsReport->ButtonType);\n\t\tTraceEvents(TRACE_LEVEL_INFORMATION, TRACE_HID, \"%!FUNC! Report REPORTID_DEVICE_CAPS is fulfilled\");\n\t\tbreak;\n\t}\n\tcase REPORTID_PTPHQA:\n\t{\n\t\tTraceEvents(TRACE_LEVEL_INFORMATION, TRACE_HID, \"%!FUNC! Report REPORTID_PTPHQA is requested\");\n\n\t\t// Size sanity check\n\t\treportSize = sizeof(PTP_DEVICE_HQA_CERTIFICATION_REPORT);\n\t\tif (hidContent->reportBufferLen < reportSize)\n\t\t{\n\t\t\tstatus = STATUS_INVALID_BUFFER_SIZE;\n\t\t\tTraceEvents(TRACE_LEVEL_ERROR, TRACE_HID, \"%!FUNC! Report buffer is too small.\");\n\t\t\tgoto exit;\n\t\t}\n\n\t\tPPTP_DEVICE_HQA_CERTIFICATION_REPORT certReport = (PPTP_DEVICE_HQA_CERTIFICATION_REPORT)hidContent->reportBuffer;\n\t\t*certReport->CertificationBlob = DEFAULT_PTP_HQA_BLOB;\n\t\tcertReport->ReportID = REPORTID_PTPHQA;\n\n\t\tTraceEvents(TRACE_LEVEL_INFORMATION, TRACE_HID, \"%!FUNC! Report REPORTID_PTPHQA is fulfilled\");\n\t\tbreak;\n\t}\n\tdefault:\n\t{\n\t\tTraceEvents(TRACE_LEVEL_INFORMATION, TRACE_HID, \"%!FUNC! Unsupported type %d is requested\", hidContent->reportId);\n\t\tstatus = STATUS_NOT_SUPPORTED;\n\t\tgoto exit;\n\t}\n\t}\n\nexit:\n\tTraceEvents(TRACE_LEVEL_INFORMATION, TRACE_HID, \"%!FUNC! Exit\");\n\treturn status;\n}\n\nNTSTATUS\nPtpFilterSetHidFeatures(\n\t_In_ WDFDEVICE Device,\n\t_In_ WDFREQUEST Request\n)\n{\n\tNTSTATUS status = STATUS_SUCCESS;\n\tPDEVICE_CONTEXT deviceContext;\n\n\tPHID_XFER_PACKET hidPacket;\n\tWDF_REQUEST_PARAMETERS requestParameters;\n\n\tTraceEvents(TRACE_LEVEL_INFORMATION, TRACE_HID, \"%!FUNC! Entry\");\n\tdeviceContext = PtpFilterGetContext(Device);\n\n\tWDF_REQUEST_PARAMETERS_INIT(&requestParameters);\n\tWdfRequestGetParameters(Request, &requestParameters);\n\tif (requestParameters.Parameters.DeviceIoControl.InputBufferLength < sizeof(HID_XFER_PACKET))\n\t{\n\t\tstatus = STATUS_BUFFER_TOO_SMALL;\n\t\tgoto exit;\n\t}\n\n\thidPacket = (PHID_XFER_PACKET)WdfRequestWdmGetIrp(Request)->UserBuffer;\n\tif (hidPacket == NULL)\n\t{\n\t\tstatus = STATUS_INVALID_DEVICE_REQUEST;\n\t\tgoto exit;\n\t}\n\n\tswitch (hidPacket->reportId)\n\t{\n\tcase REPORTID_REPORTMODE:\n\t{\n\t\tTraceEvents(TRACE_LEVEL_INFORMATION, TRACE_HID, \"%!FUNC! Report REPORTID_REPORTMODE is requested\");\n\n\t\tPPTP_DEVICE_INPUT_MODE_REPORT DeviceInputMode = (PPTP_DEVICE_INPUT_MODE_REPORT)hidPacket->reportBuffer;\n\t\tswitch (DeviceInputMode->Mode)\n\t\t{\n\t\tcase PTP_COLLECTION_MOUSE:\n\t\t{\n\t\t\tTraceEvents(TRACE_LEVEL_INFORMATION, TRACE_HID, \"%!FUNC! Report REPORTID_REPORTMODE requested Mouse Input\");\n\t\t\tdeviceContext->PtpInputOn = FALSE;\n\t\t\tbreak;\n\t\t}\n\t\tcase PTP_COLLECTION_WINDOWS:\n\t\t{\n\n\t\t\tTraceEvents(TRACE_LEVEL_INFORMATION, TRACE_HID, \"%!FUNC! Report REPORTID_REPORTMODE requested Windows PTP Input\");\n\t\t\tdeviceContext->PtpInputOn = TRUE;\n\t\t\tbreak;\n\t\t}\n\t\t}\n\n\t\tTraceEvents(TRACE_LEVEL_INFORMATION, TRACE_HID, \"%!FUNC! Report REPORTID_REPORTMODE is fulfilled\");\n\t\tbreak;\n\t}\n\tcase REPORTID_FUNCSWITCH:\n\t{\n\t\tTraceEvents(TRACE_LEVEL_INFORMATION, TRACE_HID, \"%!FUNC! Report REPORTID_FUNCSWITCH is requested\");\n\n\t\tPPTP_DEVICE_SELECTIVE_REPORT_MODE_REPORT InputSelection = (PPTP_DEVICE_SELECTIVE_REPORT_MODE_REPORT)hidPacket->reportBuffer;\n\t\tdeviceContext->PtpReportButton = InputSelection->ButtonReport;\n\t\tdeviceContext->PtpReportTouch = InputSelection->SurfaceReport;\n\n\t\tTraceEvents(TRACE_LEVEL_INFORMATION, TRACE_HID, \"%!FUNC! Report REPORTID_FUNCSWITCH requested Button = %d, Surface = %d\",\n\t\t\tInputSelection->ButtonReport, InputSelection->SurfaceReport);\n\t\tTraceEvents(TRACE_LEVEL_INFORMATION, TRACE_HID, \"%!FUNC! Report REPORTID_FUNCSWITCH is fulfilled\");\n\t\tbreak;\n\t}\n\tdefault:\n\t{\n\t\tTraceEvents(TRACE_LEVEL_INFORMATION, TRACE_HID, \"%!FUNC! Unsupported type %d is requested\", hidPacket->reportId);\n\t\tstatus = STATUS_NOT_SUPPORTED;\n\t\tgoto exit;\n\t}\n\t}\n\nexit:\n\tTraceEvents(TRACE_LEVEL_INFORMATION, TRACE_HID, \"%!FUNC! Exit\");\n\treturn status;\n}\n"
  },
  {
    "path": "src/AmtPtpHidFilter/Input.c",
    "content": "// Input.c: Input handler routines\n\n#include <Driver.h>\n#include \"Input.tmh\"\n\nVOID\nPtpFilterInputProcessRequest(\n\t_In_ WDFDEVICE Device,\n\t_In_ WDFREQUEST Request\n)\n{\n\tNTSTATUS status;\n\tPDEVICE_CONTEXT deviceContext;\n\n\tdeviceContext = PtpFilterGetContext(Device);\n\tstatus = WdfRequestForwardToIoQueue(Request, deviceContext->HidReadQueue);\n\tif (!NT_SUCCESS(status)) {\n\t\tTraceEvents(TRACE_LEVEL_ERROR, TRACE_INPUT, \"%!FUNC! WdfRequestForwardToIoQueue fails, status = %!STATUS!\", status);\n\t\tWdfRequestComplete(Request, status);\n\t\treturn;\n\t}\n\n\t// Only issue request when fully configured.\n\t// Otherwise we will let power recovery process to triage it\n\tif (deviceContext->DeviceConfigured == TRUE) {\n\t\tPtpFilterInputIssueTransportRequest(Device);\n\t}\n}\n\nVOID\nPtpFilterWorkItemCallback(\n\t_In_ WDFWORKITEM WorkItem\n)\n{\n\tWDFDEVICE Device = WdfWorkItemGetParentObject(WorkItem);\n\tPtpFilterInputIssueTransportRequest(Device);\n}\n\nVOID\nPtpFilterInputIssueTransportRequest(\n\t_In_ WDFDEVICE Device\n)\n{\n\tNTSTATUS status;\n\tPDEVICE_CONTEXT deviceContext;\n\n\tWDF_OBJECT_ATTRIBUTES attributes;\n\tWDFREQUEST hidReadRequest;\n\tWDFMEMORY hidReadOutputMemory;\n\tPWORKER_REQUEST_CONTEXT requestContext;\n\tBOOLEAN requestStatus = FALSE;\n\n\tdeviceContext = PtpFilterGetContext(Device);\n\n\tWDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, WORKER_REQUEST_CONTEXT);\n\tattributes.ParentObject = Device;\n\tstatus = WdfRequestCreate(&attributes, deviceContext->HidIoTarget, &hidReadRequest);\n\tif (!NT_SUCCESS(status)) {\n\t\t// This can fail for Bluetooth devices. We will set up a 3 second timer for retry triage.\n\t\t// Typically this should not fail for USB transport.\n\t\tTraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE, \"%!FUNC! WdfRequestCreate fails, status = %!STATUS!\", status);\n\t\tdeviceContext->DeviceConfigured = FALSE;\n\t\tWdfTimerStart(deviceContext->HidTransportRecoveryTimer, WDF_REL_TIMEOUT_IN_SEC(3));\n\t\treturn;\n\t}\n\n\tstatus = WdfMemoryCreateFromLookaside(deviceContext->HidReadBufferLookaside, &hidReadOutputMemory);\n\tif (!NT_SUCCESS(status)) {\n\t\t// tbh if you fail here, something seriously went wrong...request a restart.\n\t\tTraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE, \"%!FUNC! WdfMemoryCreateFromLookaside fails, status = %!STATUS!\", status);\n\t\tWdfObjectDelete(hidReadRequest);\n\t\tWdfDeviceSetFailed(deviceContext->Device, WdfDeviceFailedAttemptRestart);\n\t\treturn;\n\t}\n\n\t// Assign context information\n\t// And format HID read request.\n\trequestContext = WorkerRequestGetContext(hidReadRequest);\n\trequestContext->DeviceContext = deviceContext;\n\trequestContext->RequestMemory = hidReadOutputMemory;\n\tstatus = WdfIoTargetFormatRequestForInternalIoctl(deviceContext->HidIoTarget, hidReadRequest,\n\t\tIOCTL_HID_READ_REPORT, NULL, 0, hidReadOutputMemory, 0);\n\tif (!NT_SUCCESS(status)) {\n\t\t// tbh if you fail here, something seriously went wrong...request a restart.\n\t\tTraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE, \"%!FUNC! WdfIoTargetFormatRequestForInternalIoctl fails, status = %!STATUS!\", status);\n\n\t\tif (hidReadOutputMemory != NULL) {\n\t\t\tWdfObjectDelete(hidReadOutputMemory);\n\t\t}\n\n\t\tif (hidReadRequest != NULL) {\n\t\t\tWdfObjectDelete(hidReadRequest);\n\t\t}\n\n\t\tWdfDeviceSetFailed(deviceContext->Device, WdfDeviceFailedAttemptRestart);\n\t\treturn;\n\t}\n\n\t// Set callback\n\tWdfRequestSetCompletionRoutine(hidReadRequest, PtpFilterInputRequestCompletionCallback, requestContext);\n\n\trequestStatus = WdfRequestSend(hidReadRequest, deviceContext->HidIoTarget, NULL);\n\tif (!requestStatus) {\n\t\t// Retry after 3 seconds, in case this is a transportation issue.\n\t\tTraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE, \"%!FUNC! PtpFilterInputIssueTransportRequest request failed to sent\");\n\t\tdeviceContext->DeviceConfigured = FALSE;\n\t\tWdfTimerStart(deviceContext->HidTransportRecoveryTimer, WDF_REL_TIMEOUT_IN_SEC(3));\n\n\t\tif (hidReadOutputMemory != NULL) {\n\t\t\tWdfObjectDelete(hidReadOutputMemory);\n\t\t}\n\n\t\tif (hidReadRequest != NULL) {\n\t\t\tWdfObjectDelete(hidReadRequest);\n\t\t}\n\t}\n}\n\nVOID\nPtpFilterInputRequestCompletionCallback(\n\t_In_ WDFREQUEST Request,\n\t_In_ WDFIOTARGET Target,\n\t_In_ PWDF_REQUEST_COMPLETION_PARAMS Params,\n\t_In_ WDFCONTEXT Context\n)\n{\n\tPWORKER_REQUEST_CONTEXT requestContext;\n\tPDEVICE_CONTEXT deviceContext;\n\tNTSTATUS status;\n\n\tWDFREQUEST ptpRequest;\n\tPTP_REPORT ptpOutputReport;\n\tWDFMEMORY  ptpRequestMemory;\n\n\tsize_t responseLength;\n\tPUCHAR responseBuffer;\n\n\tLARGE_INTEGER currentTSC;\n\tLONGLONG tSCDelta;\n\n\tconst TRACKPAD_FINGER* f;\n\tconst TRACKPAD_FINGER_TYPE5* f_type5;\n\tsize_t raw_n, headerSize, fingerprintSize = 0;\n\tINT x, y = 0;\n\n\tUNREFERENCED_PARAMETER(Target);\n\t\n\trequestContext = (PWORKER_REQUEST_CONTEXT)Context;\n\tdeviceContext = requestContext->DeviceContext;\n\tresponseLength = (size_t)(LONG)WdfRequestGetInformation(Request);\n\tresponseBuffer = WdfMemoryGetBuffer(Params->Parameters.Ioctl.Output.Buffer, NULL);\n\theaderSize = deviceContext->InputHeaderSize;\n\tfingerprintSize = deviceContext->InputFingerSize;\n\n\t// Pre-flight check 0: Right now we only have Magic Trackpad 2 (BT and USB)\n\tif (deviceContext->VendorID != HID_VID_APPLE_USB && deviceContext->VendorID != HID_VID_APPLE_BT) {\n\t\tTraceEvents(TRACE_LEVEL_ERROR, TRACE_INPUT, \"%!FUNC! Unsupported device entered this routine\");\n\t\tWdfDeviceSetFailed(deviceContext->Device, WdfDeviceFailedNoRestart);\n\t\tgoto cleanup;\n\t}\n\n\t// Pre-flight check 1: if size is 0, this is not something we need. Ignore the read, and issue next request.\n\tif (responseLength <= 0) {\n\t\tWdfWorkItemEnqueue(requestContext->DeviceContext->HidTransportRecoveryWorkItem);\n\t\tgoto cleanup;\n\t}\n\n\t// Pre-flight check 2: the response size should be sane\n\tif (responseLength < deviceContext->InputHeaderSize || (responseLength - deviceContext->InputHeaderSize) % deviceContext->InputFingerSize != 0) {\n\t\tTraceEvents(TRACE_LEVEL_INFORMATION, TRACE_INPUT, \"%!FUNC! Malformed input received. Length = %llu. Attempt to reconfigure the device.\", responseLength);\n\t\tWdfTimerStart(deviceContext->HidTransportRecoveryTimer, WDF_REL_TIMEOUT_IN_SEC(3));\n\t\tgoto cleanup;\n\t}\n\n\t// Read report and fulfill PTP request. If no report is found, just exit.\n\tstatus = WdfIoQueueRetrieveNextRequest(deviceContext->HidReadQueue, &ptpRequest);\n\tif (!NT_SUCCESS(status)) {\n\t\tTraceEvents(TRACE_LEVEL_ERROR, TRACE_INPUT, \"%!FUNC! WdfIoQueueRetrieveNextRequest failed with %!STATUS!\", status);\n\t\tgoto cleanup;\n\t}\n\n\t// Report header\n\tptpOutputReport.ReportID = REPORTID_MULTITOUCH;\n\tptpOutputReport.IsButtonClicked = 0;\n\n\t// Capture current timestamp and get input delta in 100us unit\n\tKeQueryPerformanceCounter(&currentTSC);\n\ttSCDelta = (currentTSC.QuadPart - deviceContext->LastReportTime.QuadPart) / 100;\n\tptpOutputReport.ScanTime = (tSCDelta >= 0xFF) ? 0xFF : (USHORT)tSCDelta;\n\tdeviceContext->LastReportTime.QuadPart = currentTSC.QuadPart;\n\n\t// Report required content\n\t// Touch\n\traw_n = (responseLength - headerSize) / fingerprintSize;\n\tif (raw_n >= PTP_MAX_CONTACT_POINTS) raw_n = PTP_MAX_CONTACT_POINTS;\n\tptpOutputReport.ContactCount = (UCHAR) raw_n;\n\tfor (size_t i = 0; i < raw_n; i++) {\n\t\tPUCHAR f_base = responseBuffer + headerSize + deviceContext->InputFingerDelta;\n\t\tf = (const TRACKPAD_FINGER*)(f_base + i * fingerprintSize);\n\t\tf_type5 = (const TRACKPAD_FINGER_TYPE5*)f;\n\t\t\n\t\tUSHORT tmp_x = (*((USHORT*)f_type5)) & 0x1fff;\n\t\tunsigned int tmp_y = (INT)(*((unsigned int*) f_type5));\n\n\t\tx = (SHORT)(tmp_x << 3) >> 3;\n\t\ty = -(INT)(tmp_y << 6) >> 19;\n\t\tx = (x - deviceContext->X.min) > 0 ? (x - deviceContext->X.min) : 0;\n\t\ty = (y - deviceContext->Y.min) > 0 ? (y - deviceContext->Y.min) : 0;\n\n\t\tptpOutputReport.Contacts[i].ContactID = f_type5->OrientationAndOrigin.ContactIdentifier.Id;\n\t\tptpOutputReport.Contacts[i].X = (USHORT)x;\n\t\tptpOutputReport.Contacts[i].Y = (USHORT)y;\n\t\tptpOutputReport.Contacts[i].TipSwitch = ((signed short) (f_type5->TouchMajor) << 1) > 0;\n\t\t// The Microsoft spec says reject any input larger than 25mm. This is not ideal\n\t\t// for Magic Trackpad 2 - so we raised the threshold a bit higher.\n\t\t// Or maybe I used the wrong unit? IDK\n\t\tptpOutputReport.Contacts[i].Confidence = ((signed short) (f_type5->TouchMinor) << 1) < 345 && ((signed short) (f_type5->TouchMinor) << 1) < 345;\n\t}\n\n\t// Button\n\tif ((responseBuffer[deviceContext->InputButtonDelta] & 1) != 0) {\n\t\tptpOutputReport.IsButtonClicked = TRUE;\n\t}\n\n\tstatus = WdfRequestRetrieveOutputMemory(ptpRequest, &ptpRequestMemory);\n\tif (!NT_SUCCESS(status))\n\t{\n\t\tTraceEvents(TRACE_LEVEL_ERROR, TRACE_INPUT, \"%!FUNC! WdfRequestRetrieveOutputBuffer failed with %!STATUS!\", status);\n\t\tWdfDeviceSetFailed(deviceContext->Device, WdfDeviceFailedAttemptRestart);\n\t\tgoto cleanup;\n\t}\n\n\tstatus = WdfMemoryCopyFromBuffer(ptpRequestMemory, 0, (PVOID) &ptpOutputReport, sizeof(PTP_REPORT));\n\tif (!NT_SUCCESS(status))\n\t{\n\t\tTraceEvents(TRACE_LEVEL_ERROR, TRACE_INPUT, \"%!FUNC! WdfMemoryCopyFromBuffer failed with %!STATUS!\", status);\n\t\tWdfDeviceSetFailed(deviceContext->Device, WdfDeviceFailedAttemptRestart);\n\t\tgoto cleanup;\n\t}\n\n\tWdfRequestSetInformation(ptpRequest, sizeof(PTP_REPORT));\n\tWdfRequestComplete(ptpRequest, status);\n\ncleanup:\n\t// Cleanup\n\tWdfObjectDelete(Request);\n\tif (requestContext->RequestMemory != NULL) {\n\t\tWdfObjectDelete(requestContext->RequestMemory);\n\t}\n\n\t// We don't issue new request here (unless it's a spurious request - which is handled earlier) to\n\t// keep the request pipe go through one-way.\n}\n"
  },
  {
    "path": "src/AmtPtpHidFilter/Queue.c",
    "content": "// Queue.c: IO-queue related operations\n\n#include <Driver.h>\n#include \"Queue.tmh\"\n\n#ifdef ALLOC_PRAGMA\n#pragma alloc_text (PAGE, PtpFilterIoQueueInitialize)\n#endif\n\nNTSTATUS\nPtpFilterIoQueueInitialize(\n    _In_ WDFDEVICE Device\n)\n{\n    WDFQUEUE queue;\n    WDF_IO_QUEUE_CONFIG queueConfig;\n    WDF_OBJECT_ATTRIBUTES queueAttributes;\n    PDEVICE_CONTEXT deviceContext;\n    PQUEUE_CONTEXT queueContext;\n    NTSTATUS status;\n\n    PAGED_CODE();\n    TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, \"%!FUNC! Entry\");\n\n    deviceContext = PtpFilterGetContext(Device);\n\n    // First queue for system-wide HID controls\n    WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&queueConfig, WdfIoQueueDispatchParallel);\n    WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&queueAttributes, QUEUE_CONTEXT);\n    queueConfig.EvtIoInternalDeviceControl = FilterEvtIoIntDeviceControl;\n    queueConfig.EvtIoStop = FilterEvtIoStop;\n    status = WdfIoQueueCreate(Device, &queueConfig, &queueAttributes, &queue);\n    if (!NT_SUCCESS(status))\n    {\n        TraceEvents(TRACE_LEVEL_ERROR, TRACE_QUEUE, \"%!FUNC! WdfIoQueueCreate failed %!STATUS!\", status);\n        goto exit;\n    }\n\n    queueContext = PtpFilterQueueGetContext(queue);\n    queueContext->Device = deviceContext->Device;\n    queueContext->DeviceIoTarget = deviceContext->HidIoTarget;\n\n    // Second queue for HID read requests\n    WDF_IO_QUEUE_CONFIG_INIT(&queueConfig, WdfIoQueueDispatchManual);\n    queueConfig.PowerManaged = WdfFalse;\n    status = WdfIoQueueCreate(Device, &queueConfig, WDF_NO_OBJECT_ATTRIBUTES, &deviceContext->HidReadQueue);\n    if (!NT_SUCCESS(status)) {\n        TraceEvents(TRACE_LEVEL_ERROR, TRACE_QUEUE, \"%!FUNC! WdfIoQueueCreate (Input) failed %!STATUS!\", status);\n    }\n\nexit:\n    TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, \"%!FUNC! Exit, Status = %!STATUS!\", status);\n    return status;\n}\n\nVOID\nFilterEvtIoIntDeviceControl(\n    _In_ WDFQUEUE Queue,\n    _In_ WDFREQUEST Request,\n    _In_ size_t OutputBufferLength,\n    _In_ size_t InputBufferLength,\n    _In_ ULONG IoControlCode\n)\n{\n    PQUEUE_CONTEXT queueContext;\n    PDEVICE_CONTEXT deviceContext;\n    BOOLEAN requestPending = FALSE;\n\tNTSTATUS status = STATUS_UNSUCCESSFUL;\n    \n    UNREFERENCED_PARAMETER(InputBufferLength);\n    UNREFERENCED_PARAMETER(OutputBufferLength);\n\n    queueContext = PtpFilterQueueGetContext(Queue);\n    deviceContext = PtpFilterGetContext(queueContext->Device);\n\n\tswitch (IoControlCode)\n\t{\n\tcase IOCTL_HID_GET_DEVICE_DESCRIPTOR:\n\t\tstatus = PtpFilterGetHidDescriptor(queueContext->Device, Request);\n\t\tbreak;\n\tcase IOCTL_HID_GET_DEVICE_ATTRIBUTES:\n\t\tstatus = PtpFilterGetDeviceAttribs(queueContext->Device, Request);\n\t\tbreak;\n\tcase IOCTL_HID_GET_REPORT_DESCRIPTOR:\n\t\tstatus = PtpFilterGetReportDescriptor(queueContext->Device, Request);\n\t\tbreak;\n\tcase IOCTL_HID_GET_STRING:\n\t\tstatus = PtpFilterGetStrings(queueContext->Device, Request, &requestPending);\n\t\tbreak;\n\tcase IOCTL_HID_READ_REPORT:\n        PtpFilterInputProcessRequest(queueContext->Device, Request);\n\t\trequestPending = TRUE;\n\t\tbreak;\n\tcase IOCTL_HID_GET_FEATURE:\n\t\tstatus = PtpFilterGetHidFeatures(queueContext->Device, Request);\n\t\tbreak;\n\tcase IOCTL_HID_SET_FEATURE:\n\t\tstatus = PtpFilterSetHidFeatures(queueContext->Device, Request);\n\t\tbreak;\n\tcase IOCTL_HID_WRITE_REPORT:\n\tcase IOCTL_UMDF_HID_SET_OUTPUT_REPORT:\n\tcase IOCTL_UMDF_HID_GET_INPUT_REPORT:\n\tcase IOCTL_HID_ACTIVATE_DEVICE:\n\tcase IOCTL_HID_DEACTIVATE_DEVICE:\n\tcase IOCTL_HID_SEND_IDLE_NOTIFICATION_REQUEST:\n\tdefault:\n\t\tstatus = STATUS_NOT_SUPPORTED;\n\t\tTraceEvents(TRACE_LEVEL_WARNING, TRACE_QUEUE, \"%!FUNC!: %s is not yet implemented\", PtpFilterDiagnosticsIoControlGetString(IoControlCode));\n\t\tbreak;\n\t}\n\n    if (requestPending != TRUE)\n    {\n        TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_QUEUE, \"%!FUNC!: %s, Status = %!STATUS!\", PtpFilterDiagnosticsIoControlGetString(IoControlCode), status);\n        WdfRequestComplete(Request, status);\n    }\n}\n\nVOID\nFilterEvtIoStop(\n    _In_ WDFQUEUE Queue,\n    _In_ WDFREQUEST Request,\n    _In_ ULONG ActionFlags\n)\n{\n    UNREFERENCED_PARAMETER(Queue);\n    UNREFERENCED_PARAMETER(Request);\n    UNREFERENCED_PARAMETER(ActionFlags);\n}\n"
  },
  {
    "path": "src/AmtPtpHidFilter/include/Device.h",
    "content": "// Device.h: Device-specific struct and routines\n\n#pragma once\n\nEXTERN_C_START\n\n// {FF969022-3111-4441-8F88-875440172C2E} for the device interface\nDEFINE_GUID(GUID_DEVICEINTERFACE_AmtPtpHidFilter,\n    0xff969022, 0x3111, 0x4441, 0x8f, 0x88, 0x87, 0x54, 0x40, 0x17, 0x2c, 0x2e);\n\n// Definition\n#define HID_XFER_PACKET_SIZE 32\n\n#define HID_VID_APPLE_USB 0x05ac\n#define HID_VID_APPLE_BT  0x004c\n#define HID_PID_MAGIC_TRACKPAD_2 0x0265\n\n/* device-specific parameters */\ntypedef struct _BCM5974_PARAM {\n    int snratio;\t\t/* signal-to-noise ratio */\n    int min;\t\t\t/* device minimum reading */\n    int max;\t\t\t/* device maximum reading */\n} BCM5974_PARAM, *PBCM5974_PARAM;\n\n// Device Context\ntypedef struct _DEVICE_CONTEXT\n{\n    PDEVICE_OBJECT  WdmDeviceObject;\n    WDFDEVICE       Device;\n    WDFQUEUE        HidReadQueue;\n\n    // Device identification\n    USHORT VendorID;\n    USHORT ProductID;\n    USHORT VersionNumber;\n    size_t InputHeaderSize;\n    size_t InputFingerSize;\n    size_t InputFingerDelta;\n    size_t InputButtonDelta;\n    BCM5974_PARAM X;\n    BCM5974_PARAM Y;\n\n    // List of buffers\n    WDFLOOKASIDE HidReadBufferLookaside;\n\n    // System HID transport\n    WDFIOTARGET HidIoTarget;\n    BOOLEAN     IsHidIoDetourCompleted;\n    WDFTIMER    HidTransportRecoveryTimer;\n    WDFWORKITEM HidTransportRecoveryWorkItem;\n\n    // Device State\n    BOOLEAN DeviceConfigured;\n\n    // PTP report specific\n    LARGE_INTEGER   LastReportTime;\n    BOOLEAN         PtpInputOn;\n    BOOLEAN         PtpReportTouch;\n    BOOLEAN         PtpReportButton;\n} DEVICE_CONTEXT, *PDEVICE_CONTEXT;\n\nWDF_DECLARE_CONTEXT_TYPE_WITH_NAME(DEVICE_CONTEXT, PtpFilterGetContext)\n\n// Request context\ntypedef struct _WORKER_REQUEST_CONTEXT {\n    PDEVICE_CONTEXT DeviceContext;\n    WDFMEMORY RequestMemory;\n} WORKER_REQUEST_CONTEXT, * PWORKER_REQUEST_CONTEXT;\n\nWDF_DECLARE_CONTEXT_TYPE_WITH_NAME(WORKER_REQUEST_CONTEXT, WorkerRequestGetContext)\n\n// Initialization routines\nNTSTATUS\nPtpFilterCreateDevice(\n    _Inout_ PWDFDEVICE_INIT DeviceInit\n);\n\n// Power Management Handlers\nEVT_WDF_DEVICE_PREPARE_HARDWARE PtpFilterPrepareHardware;\nEVT_WDF_DEVICE_D0_ENTRY PtpFilterDeviceD0Entry;\nEVT_WDF_DEVICE_D0_EXIT PtpFilterDeviceD0Exit;\nEVT_WDF_DEVICE_SELF_MANAGED_IO_INIT PtpFilterSelfManagedIoInit;\nEVT_WDF_DEVICE_SELF_MANAGED_IO_RESTART PtpFilterSelfManagedIoRestart;\n\n// Device Management routines\nNTSTATUS\nPtpFilterConfigureMultiTouch(\n    _In_ WDFDEVICE Device\n);\n\nVOID\nPtpFilterRecoveryTimerCallback(\n    WDFTIMER Timer\n);\n\nEXTERN_C_END\n"
  },
  {
    "path": "src/AmtPtpHidFilter/include/Diagnostics.h",
    "content": "#pragma once\n\nEXTERN_C_START\n\nVOID PtpFilterDiagnosticsInitializeContinuousRead(\n\t_In_ WDFDEVICE Device\n);\n\nVOID\nPtpFilterDiagnosticsInputIssueRequest(\n\t_In_ WDFDEVICE Device\n);\n\nVOID\nPtpFilterDiagnosticsRequestCompletionRoutine(\n\t_In_ WDFREQUEST Request,\n\t_In_ WDFIOTARGET Target,\n\t_In_ PWDF_REQUEST_COMPLETION_PARAMS Params,\n\t_In_ WDFCONTEXT Context\n);\n\nPCHAR\nPtpFilterDiagnosticsIoControlGetString(\n\t_In_ ULONG IoControlCode\n);\n\nEXTERN_C_END\n"
  },
  {
    "path": "src/AmtPtpHidFilter/include/Driver.h",
    "content": "// Driver.h: common definition\n#pragma once\n\n#include <ntddk.h>\n#include <wdf.h>\n#include <usb.h>\n#include <usbdlib.h>\n#include <wdfusb.h>\n#include <initguid.h>\n#include <hidport.h>\n\n#include \"Trace.h\"\n\nEXTERN_C_START\n\n// Common entry points\nDRIVER_INITIALIZE DriverEntry;\nEVT_WDF_DRIVER_DEVICE_ADD PtpFilterEvtDeviceAdd;\nEVT_WDF_OBJECT_CONTEXT_CLEANUP PtpFilterEvtDriverContextCleanup;\n\n// Device specific routines\n#include \"Device.h\"\n#include \"Queue.h\"\n#include \"Hac.h\"\n#include \"Diagnostics.h\"\n#include \"Metadata/StaticHidRegistry.h\"\n#include \"HidMiniport.h\"\n#include \"HidDevice.h\"\n#include \"Input.h\"\n\n// Pool Tag\n#define PTP_LIST_POOL_TAG 'LTPA'\n#define REPORT_BUFFER_SIZE   1024\n\nEXTERN_C_END\n"
  },
  {
    "path": "src/AmtPtpHidFilter/include/Hac.h",
    "content": "// Hac.h: Yes, we have to hack Windows HID stack on the fly...\n#pragma once\n\nEXTERN_C_START\n\n// HACK: detour the HIDClass extension\ntypedef struct _HIDCLASS_DRIVER_EXTENSION {\n    PDRIVER_OBJECT      MinidriverObject;\n    UNICODE_STRING      RegistryPath;\n    ULONG               DeviceExtensionSize;\n    PDRIVER_DISPATCH    MajorFunction[IRP_MJ_MAXIMUM_FUNCTION + 1];\n    PDRIVER_ADD_DEVICE  AddDevice;\n    PDRIVER_UNLOAD      DriverUnload;\n    LONG                ReferenceCount;\n    LIST_ENTRY          ListEntry;\n    BOOLEAN             DevicesArePolled;\n} HIDCLASS_DRIVER_EXTENSION, * PHIDCLASS_DRIVER_EXTENSION;\n\ntypedef struct _IO_CLIENT_EXTENSION\n{\n    struct _IO_CLIENT_EXTENSION* NextExtension;\n    PVOID\tClientIdentificationAddress;\n} IO_CLIENT_EXTENSION, * PIO_CLIENT_EXTENSION, ** PPIO_CLIENT_EXTENSION;\n\ntypedef struct _DRIVER_EXTENSION_EXT {\n    struct _DRIVER_OBJECT* DriverObject;\n    PDRIVER_ADD_DEVICE AddDevice;\n    ULONG Count;\n    UNICODE_STRING ServiceKeyName;\n    PIO_CLIENT_EXTENSION IoClientExtension;\n} DRIVER_EXTENSION_EXT, * PDRIVER_EXTENSION_EXT;\n\n#define HID_CLASS_EXTENSION_LITERAL_ID \"HIDCLASS\"\n#define HID_USB_SERVICE_NAME L\"HidUsb\"\n\n// Hack: import from ntifs.h\nextern NTKERNELAPI\nPDEVICE_OBJECT\nIoGetLowerDeviceObject(\n    _In_  PDEVICE_OBJECT  DeviceObject\n);\n\n// Detour routines\nNTSTATUS\nPtpFilterDetourWindowsHIDStack(\n    _In_ WDFDEVICE Device\n);\n\n\nEXTERN_C_END\n"
  },
  {
    "path": "src/AmtPtpHidFilter/include/HidCommon.h",
    "content": "// HidCommon.h: HID common definition\n#pragma once\n\n#define REPORTID_STANDARDMOUSE 0x02\n#define REPORTID_MULTITOUCH 0x05\n#define REPORTID_REPORTMODE 0x04\n#define REPORTID_PTPHQA 0x08\n#define REPORTID_FUNCSWITCH 0x06\n#define REPORTID_DEVICE_CAPS 0x07\n#define REPORTID_UMAPP_CONF  0x09\n\n#define BUTTON_SWITCH 0x57\n#define SURFACE_SWITCH 0x58\n\n#define USAGE_PAGE 0x05\n#define USAGE_PAGE_1 0x06\n#define USAGE      0x09\n#define USAGE_MINIMUM 0x19\n#define USAGE_MAXIMUM 0x29\n#define LOGICAL_MINIMUM 0x15\n#define LOGICAL_MAXIMUM 0x25\n#define LOGICAL_MAXIMUM_2 0x26\n#define LOGICAL_MAXIMUM_3 0x27\n#define PHYSICAL_MINIMUM 0x35\n#define PHYSICAL_MAXIMUM 0x45\n#define PHYSICAL_MAXIMUM_2 0x46\n#define PHYSICAL_MAXIMUM_3 0x47\n#define UNIT_EXPONENT 0x55\n#define UNIT 0x65\n#define UNIT_2 0x66\n\n#define REPORT_ID       0x85\n#define REPORT_COUNT    0x95\n#define REPORT_COUNT_2\t0x96\n#define REPORT_SIZE     0x75\n#define INPUT           0x81\n#define FEATURE         0xb1\n\n#define BEGIN_COLLECTION 0xa1\n#define END_COLLECTION   0xc0\n\n#define DEVICE_VID 0x8910\n#define DEVICE_VERSION 0x100"
  },
  {
    "path": "src/AmtPtpHidFilter/include/HidDevice.h",
    "content": "// HidDevice.h: devicei-specific HID structures\n#pragma once\n\n/* Trackpad finger data offsets, le16-aligned */\n#define HOFFSET_TYPE_USB_1\t\t(13 * sizeof(USHORT))\n#define HOFFSET_TYPE_USB_2\t\t(15 * sizeof(USHORT))\n#define HOFFSET_TYPE_USB_3\t\t(19 * sizeof(USHORT))\n#define HOFFSET_TYPE_USB_4\t\t(23 * sizeof(USHORT))\n#define HOFFSET_TYPE_USB_5\t\t( 6 * sizeof(USHORT))\n#define HOFFSET_TYPE_BTH_5\t\t( 2 * sizeof(USHORT))\n\n/* Trackpad button data offsets */\n#define BOFFSET_TYPE1\t\t0\n#define BOFFSET_TYPE2\t\t15\n#define BOFFSET_TYPE3\t\t23\n#define BOFFSET_TYPE4\t\t31\n#define BOFFSET_TYPE5\t\t1\n\n/* Trackpad finger data block size */\n#define FSIZE_TYPE1\t\t(14 * sizeof(USHORT))\n#define FSIZE_TYPE2\t\t(14 * sizeof(USHORT))\n#define FSIZE_TYPE3\t\t(14 * sizeof(USHORT))\n#define FSIZE_TYPE4\t\t(15 * sizeof(USHORT))\n#define FSIZE_TYPE5\t\t(9)\n\n/* List of device capability bits */\n#define HAS_INTEGRATED_BUTTON\t1\n\n/* Offset from header to finger struct */\n#define FDELTA_TYPE1\t\t(0 * sizeof(USHORT))\n#define FDELTA_TYPE2\t\t(0 * sizeof(USHORT))\n#define FDELTA_TYPE3\t\t(0 * sizeof(USHORT))\n#define FDELTA_TYPE4\t\t(1 * sizeof(USHORT))\n#define FDELTA_TYPE5\t\t(0 * sizeof(USHORT))\n\n/* Trackpad finger data size, empirically at least ten fingers */\n#define MAX_FINGERS\t\t16\n#define MAX_FINGER_ORIENTATION\t16384\n\n/* button data structure */\ntypedef struct _TRACKPAD_BUTTON_DATA {\n\tUCHAR unknown1;\t\t\t/* constant */\n\tUCHAR button;\t\t\t/* left button */\n\tUCHAR rel_x;\t\t\t/* relative x coordinate */\n\tUCHAR rel_y;\t\t\t/* relative y coordinate */\n} TRACKPAD_BUTTON_DATA, *PTRACKPAD_BUTTON_DATA;\n\n#include <pshpack2.h>\n/* trackpad finger structure, le16-aligned */\ntypedef struct _TRACKPAD_FINGER {\n\tUSHORT origin;\t\t/* zero when switching track finger */\n\tUSHORT abs_x;\t\t/* absolute x coodinate */\n\tUSHORT abs_y;\t\t/* absolute y coodinate */\n\tUSHORT rel_x;\t\t/* relative x coodinate */\n\tUSHORT rel_y;\t\t/* relative y coodinate */\n\tUSHORT tool_major;\t/* tool area, major axis */\n\tUSHORT tool_minor;\t/* tool area, minor axis */\n\tUSHORT orientation;\t/* 16384 when point, else 15 bit angle */\n\tUSHORT touch_major;\t/* touch area, major axis */\n\tUSHORT touch_minor;\t/* touch area, minor axis */\n\tUSHORT unused[2];\t/* zeros */\n\tUSHORT pressure;\t/* pressure on forcetouch touchpad */\n\tUSHORT multi;\t\t/* one finger: varies, more fingers: constant */\n} TRACKPAD_FINGER, *PTRACKPAD_FINGER;\n\n/* Trackpad finger structure for type5 (magic trackpad), le16-aligned */\ntypedef struct _TRACKPAD_FINGER_TYPE5\n{\n\tUCHAR AbsoluteX;\t\t\t/* absolute x coodinate */\n\tUCHAR AbsoluteXY;\t\t\t/* absolute x,y coodinate */\n\tUCHAR AbsoluteY[2];\t\t\t/* absolute y coodinate */\n\tUCHAR TouchMajor;\t\t\t/* touch area, major axis */\n\tUCHAR TouchMinor;\t\t\t/* touch area, minor axis */\n\tUCHAR Size;\t\t\t\t\t/* tool area, size */\n\tUCHAR Pressure;\t\t\t\t/* pressure on forcetouch touchpad */\n\tunion _ORIDENTATION_AND_ORIGIN\n\t{\n\t\tstruct _CONTACT_IDENTIFIER\n\t\t{\n\t\t\tUCHAR Id : 4;\n\t\t\tUCHAR Orientation : 4;\n\t\t} ContactIdentifier;\n\t\tUCHAR RawValue;\n\t} OrientationAndOrigin;\n} TRACKPAD_FINGER_TYPE5, *PTRACKPAD_FINGER_TYPE5;\n#include <poppack.h>\n"
  },
  {
    "path": "src/AmtPtpHidFilter/include/HidMiniport.h",
    "content": "// Hidminiport.h: HID miniport communication structures\n#pragma once\n\n#include <pshpack1.h>\n\n// PTP device capabilites Feature Report\ntypedef struct _PTP_DEVICE_CAPS_FEATURE_REPORT {\n\tUCHAR ReportID;\n\tUCHAR MaximumContactPoints;\n\tUCHAR ButtonType;\n} PTP_DEVICE_CAPS_FEATURE_REPORT, * PPTP_DEVICE_CAPS_FEATURE_REPORT;\n\n// PTP device certification Feature Report\ntypedef struct _PTP_DEVICE_HQA_CERTIFICATION_REPORT {\n\tUCHAR ReportID;\n\tUCHAR CertificationBlob[256];\n} PTP_DEVICE_HQA_CERTIFICATION_REPORT, * PPTP_DEVICE_HQA_CERTIFICATION_REPORT;\n\n// PTP input mode Feature Report\ntypedef struct _PTP_DEVICE_INPUT_MODE_REPORT {\n\tUCHAR ReportID;\n\tUCHAR Mode;\n} PTP_DEVICE_INPUT_MODE_REPORT, * PPTP_DEVICE_INPUT_MODE_REPORT;\n\n// PTP input selection Feature Report\ntypedef struct _PTP_DEVICE_SELECTIVE_REPORT_MODE_REPORT {\n\tUCHAR ReportID;\n\tUCHAR ButtonReport : 1;\n\tUCHAR SurfaceReport : 1;\n\tUCHAR Padding : 6;\n} PTP_DEVICE_SELECTIVE_REPORT_MODE_REPORT, * PPTP_DEVICE_SELECTIVE_REPORT_MODE_REPORT;\n\n// PTP single finger\ntypedef struct _PTP_CONTACT {\n\tUCHAR\t\tConfidence : 1;\n\tUCHAR\t\tTipSwitch : 1;\n\tUCHAR\t\tPadding : 6;\n\tULONG\t\tContactID;\n\tUSHORT\t\tX;\n\tUSHORT\t\tY;\n} PTP_CONTACT, * PPTP_CONTACT;\n\n// PTP single scan frame Input Report\ntypedef struct _PTP_REPORT {\n\tUCHAR       ReportID;\n\tPTP_CONTACT Contacts[5];\n\tUSHORT      ScanTime;\n\tUCHAR       ContactCount;\n\tUCHAR       IsButtonClicked;\n} PTP_REPORT, * PPTP_REPORT;\n\n#include <poppack.h>\n\n// HID routines\nNTSTATUS\nPtpFilterGetHidDescriptor(\n\t_In_ WDFDEVICE Device,\n\t_In_ WDFREQUEST Request\n);\n\nNTSTATUS\nPtpFilterGetDeviceAttribs(\n\t_In_ WDFDEVICE Device,\n\t_In_ WDFREQUEST Request\n);\n\nNTSTATUS\nPtpFilterGetReportDescriptor(\n\t_In_ WDFDEVICE Device,\n\t_In_ WDFREQUEST Request\n);\n\nNTSTATUS\nPtpFilterGetStrings(\n\t_In_ WDFDEVICE Device,\n\t_In_ WDFREQUEST Request,\n\t_Out_ BOOLEAN* Pending\n);\n\nNTSTATUS\nPtpFilterGetHidFeatures(\n\t_In_ WDFDEVICE Device,\n\t_In_ WDFREQUEST Request\n);\n\nNTSTATUS\nPtpFilterSetHidFeatures(\n\t_In_ WDFDEVICE Device,\n\t_In_ WDFREQUEST Request\n);\n"
  },
  {
    "path": "src/AmtPtpHidFilter/include/Input.h",
    "content": "// Input.h: Input processing and device definitions\n#pragma once\n\nVOID\nPtpFilterInputProcessRequest(\n\t_In_ WDFDEVICE Device,\n\t_In_ WDFREQUEST Request\n);\n\nVOID\nPtpFilterWorkItemCallback(\n\t_In_ WDFWORKITEM WorkItem\n);\n\nVOID\nPtpFilterInputIssueTransportRequest(\n\t_In_ WDFDEVICE Device\n);\n\nVOID\nPtpFilterInputRequestCompletionCallback(\n\t_In_ WDFREQUEST Request,\n\t_In_ WDFIOTARGET Target,\n\t_In_ PWDF_REQUEST_COMPLETION_PARAMS Params,\n\t_In_ WDFCONTEXT Context\n);\n"
  },
  {
    "path": "src/AmtPtpHidFilter/include/Metadata/MagicTrackpad2.h",
    "content": "// MagicTrackpad2.h: Magic Trackpad 2 specific HID information\n#pragma once\n\n#define AAPL_MAGIC_TRACKPAD2_PTP_FINGER_COLLECTION_1 \\\n\tBEGIN_COLLECTION, 0x02, /* Begin Collection: Logical */ \\\n\t\t/* Begin a byte */ \\\n\t\tLOGICAL_MAXIMUM, 0x01, /* Logical Maximum: 1 */ \\\n\t\tUSAGE, 0x47, /* Usage: Confidence */ \\\n\t\tUSAGE, 0x42, /* Usage: Tip switch */ \\\n\t\tREPORT_COUNT, 0x02, /* Report Count: 2 */ \\\n\t\tREPORT_SIZE, 0x01, /* Report Size: 1 */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tREPORT_SIZE, 0x01, /* Report Size: 1 */ \\\n\t\tREPORT_COUNT, 0x06, /* Report Count: 6 */ \\\n\t\tINPUT, 0x03, /* Input: (Const, Var, Abs) */ \\\n\t\t/* End of a byte */ \\\n\t\t/* Begin of 4 bytes */ \\\n\t\tREPORT_COUNT, 0x01, /* Report Count: 1 */ \\\n\t\tREPORT_SIZE, 0x20, /* Report Size: 0x20 (4 bytes) */ \\\n\t\tLOGICAL_MAXIMUM_3, 0xff, 0xff, 0xff, 0xff, /* Logical Maximum: 0xffffffff */ \\\n\t\tUSAGE, 0x51, /* Usage: Contract Identifier */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\t/* End of 4 bytes */ \\\n\t\t/* Begin of 4 bytes */ \\\n\t\t/* Size is hard-coded at this moment */ \\\n\t\tUSAGE_PAGE, 0x01, /* Usage Page: Generic Desktop */ \\\n\t\tLOGICAL_MAXIMUM_2, 0xbc, 0x1d, /* Logical Maximum: 7612 (See defintion) */ \\\n\t\tREPORT_SIZE, 0x10, /* Report Size: 0x10 (2 bytes) */ \\\n\t\tUNIT_EXPONENT, 0x0e, /* Unit exponent: -2 */ \\\n\t\tUNIT, 0x11, /* Unit: SI Length (cm) */ \\\n\t\tUSAGE, 0x30, /* Usage: X */ \\\n\t\tPHYSICAL_MAXIMUM_2, 0x40, 0x06, /* Physical Maximum: 1600 (See Apple Spec) */ \\\n\t\tREPORT_COUNT, 0x01, /* Report count: 1 */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tPHYSICAL_MAXIMUM_2, 0x7d, 0x04, /* Physical Maximum: 1149 (See Apple Spec) */ \\\n\t\tLOGICAL_MAXIMUM_2, 0xc9, 0x13, /* Logical Maximum: 5065 (See definition) */ \\\n\t\tUSAGE, 0x31, /* Usage: Y */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tPHYSICAL_MAXIMUM, 0x00, /* Physical Maximum: 0 */ \\\n\t\tUNIT_EXPONENT, 0x00, /* Unit exponent: 0 */ \\\n\t\tUNIT, 0x00, /* Unit: None */ \\\n\t\t/* End of 4 bytes */ \\\n\tEND_COLLECTION /* End Collection */ \\\n\n#define AAPL_MAGIC_TRACKPAD2_PTP_FINGER_COLLECTION_2 \\\n\tBEGIN_COLLECTION, 0x02, /* Begin Collection: Logical */ \\\n\t\t/* Begin a byte */ \\\n\t\tLOGICAL_MAXIMUM, 0x01, /* Logical Maximum: 1 */ \\\n\t\tUSAGE, 0x47, /* Usage: Confidence */ \\\n\t\tUSAGE, 0x42, /* Usage: Tip switch */ \\\n\t\tREPORT_COUNT, 0x02, /* Report Count: 2 */ \\\n\t\tREPORT_SIZE, 0x01, /* Report Size: 1 */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tREPORT_SIZE, 0x01, /* Report Size: 1 */ \\\n\t\tREPORT_COUNT, 0x06, /* Report Count: 6 */ \\\n\t\tINPUT, 0x03, /* Input: (Const, Var, Abs) */ \\\n\t\t/* End of a byte */ \\\n\t\t/* Begin of 4 bytes */ \\\n\t\tREPORT_COUNT, 0x01, /* Report Count: 1 */ \\\n\t\tREPORT_SIZE, 0x20, /* Report Size: 0x20 (4 bytes) */ \\\n\t\tLOGICAL_MAXIMUM_3, 0xff, 0xff, 0xff, 0xff, /* Logical Maximum: 0xffffffff */ \\\n\t\tUSAGE, 0x51, /* Usage: Contract Identifier */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\t/* End of 4 bytes */ \\\n\t\t/* Begin of 4 bytes */ \\\n\t\t/* Size is hard-coded at this moment */ \\\n\t\tUSAGE_PAGE, 0x01, /* Usage Page: Generic Desktop */ \\\n\t\tLOGICAL_MAXIMUM_2, 0xbc, 0x1d, /* Logical Maximum: 7612 (See defintion) */ \\\n\t\tREPORT_SIZE, 0x10, /* Report Size: 0x10 (2 bytes) */ \\\n\t\tUNIT_EXPONENT, 0x0e, /* Unit exponent: -2 */ \\\n\t\tUNIT, 0x11, /* Unit: SI Length (cm) */ \\\n\t\tUSAGE, 0x30, /* Usage: X */ \\\n\t\tPHYSICAL_MAXIMUM_2, 0x40, 0x06, /* Physical Maximum: 1600 (See Apple Spec) */ \\\n\t\tREPORT_COUNT, 0x01, /* Report count: 1 */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tPHYSICAL_MAXIMUM_2, 0x7d, 0x04, /* Physical Maximum: 1149 (See Apple Spec) */ \\\n\t\tLOGICAL_MAXIMUM_2, 0xc9, 0x13, /* Logical Maximum: 5065 (See definition) */ \\\n\t\tUSAGE, 0x31, /* Usage: Y */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\t/* End of 4 bytes */ \\\n\tEND_COLLECTION /* End Collection */ \\\n\n#define AAPL_MAGIC_TRACKPAD2_PTP_TLC \\\n\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\tUSAGE, 0x05, /* Usage: Touch Pad */ \\\n\tBEGIN_COLLECTION, 0x01, /* Begin Collection: Application */ \\\n\t\tREPORT_ID, REPORTID_MULTITOUCH, /* Report ID: Multi-touch */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_MAGIC_TRACKPAD2_PTP_FINGER_COLLECTION_1, /* 1 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_MAGIC_TRACKPAD2_PTP_FINGER_COLLECTION_1, /* 2 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_MAGIC_TRACKPAD2_PTP_FINGER_COLLECTION_2, /* 3 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_MAGIC_TRACKPAD2_PTP_FINGER_COLLECTION_1, /* 4 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tAAPL_MAGIC_TRACKPAD2_PTP_FINGER_COLLECTION_2, /* 5 */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tUNIT_EXPONENT, 0x0c, /* Unit exponent: -4 */ \\\n\t\tUNIT_2, 0x01, 0x10, /* Time: Second */ \\\n\t\tPHYSICAL_MAXIMUM_3, 0xff, 0xff, 0x00, 0x00, \\\n\t\tLOGICAL_MAXIMUM_3, 0xff, 0xff, 0x00, 0x00, \\\n\t\tUSAGE, 0x56, /* Usage: Scan Time */ \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tUSAGE, 0x54, /* Usage: Contact Count */ \\\n\t\tLOGICAL_MAXIMUM, 0x7f, \\\n\t\tREPORT_SIZE, 0x08, \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tUSAGE_PAGE, 0x09, /* Usage Page: Button */ \\\n\t\tUSAGE, 0x01, /* Button 1 */ \\\n\t\tLOGICAL_MAXIMUM, 0x01, \\\n\t\tREPORT_SIZE, 0x01, \\\n\t\tINPUT, 0x02, /* Input: (Data, Var, Abs) */ \\\n\t\tREPORT_COUNT, 0x07, \\\n\t\tINPUT, 0x03, /* Input: (Const, Var, Abs) */ \\\n\t\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\t\tREPORT_ID, REPORTID_DEVICE_CAPS, \\\n\t\tUSAGE, 0x55, /* Usage: Maximum Contacts */ \\\n\t\tUSAGE, 0x59, /* Usage: Touchpad Button Type*/ \\\n\t\tLOGICAL_MINIMUM, 0x00, \\\n\t\tLOGICAL_MAXIMUM_2, 0xff, 0x00, \\\n\t\tREPORT_SIZE, 0x08, \\\n\t\tREPORT_COUNT, 0x02, \\\n\t\tFEATURE, 0x02, \\\n\t\tUSAGE_PAGE_1, 0x00, 0xff, \\\n\t\tREPORT_ID, REPORTID_PTPHQA, \\\n\t\tUSAGE, 0xc5, \\\n\t\tLOGICAL_MINIMUM, 0x00, \\\n\t\tLOGICAL_MAXIMUM_2, 0xff, 0x00, \\\n\t\tREPORT_SIZE, 0x08, \\\n\t\tREPORT_COUNT_2, 0x00, 0x01, \\\n\t\tFEATURE, 0x02, \\\n\tEND_COLLECTION /* End Collection */\n"
  },
  {
    "path": "src/AmtPtpHidFilter/include/Metadata/StaticHidRegistry.h",
    "content": "// StaticHidRegistry.h: Static HID collection information\n#pragma once\n\n#include <hidport.h>\n\n#include <HidCommon.h>\n#include <Metadata/WindowsHID.h>\n#include <Metadata/MagicTrackpad2.h>\n\ntypedef UCHAR HID_REPORT_DESCRIPTOR, *PHID_REPORT_DESCRIPTOR;\n\n#ifndef _STATIC_HID_REGISTRY_H_\n#define _STATIC_HID_REGISTRY_H_\n\nstatic HID_REPORT_DESCRIPTOR PtpReportDescriptorMagicTrackpad2[] = {\n\tAAPL_MAGIC_TRACKPAD2_PTP_TLC,\n\tAAPL_PTP_WINDOWS_CONFIGURATION_TLC,\n};\n\nstatic HID_DESCRIPTOR PtpDefaultHidDescriptorMagicTrackpad2 = {\n\t0x09,   // bLength\n\t0x21,   // bDescriptorType\n\t0x0100, // bcdHID\n\t0x00,   // bCountryCode\n\t0x01,   // bNumDescriptors\n\t{\n\t\t0x22,\t\t\t\t\t\t\t\t\t\t\t// bDescriptorType\n\t\tsizeof(PtpReportDescriptorMagicTrackpad2),\t\t// bDescriptorLength\n\t},\n};\n\n#endif\n"
  },
  {
    "path": "src/AmtPtpHidFilter/include/Metadata/WindowsHID.h",
    "content": "// WindowsHID.h: Windows specific HID Top Level Collections\n#pragma once\n\n#define MAX_FINGERS 16\n\n#define PTP_MAX_CONTACT_POINTS 5\n#define PTP_BUTTON_TYPE_CLICK_PAD 0\n#define PTP_BUTTON_TYPE_PRESSURE_PAD 1\n\n#define PTP_COLLECTION_MOUSE 0\n#define PTP_COLLECTION_WINDOWS 3\n\n#define PTP_CONTACT_CONFIDENCE_BIT   1\n#define PTP_CONTACT_TIPSWITCH_BIT    2\n\n#define AAPL_PTP_USERMODE_CONFIGURATION_APP_TLC \\\n\tUSAGE_PAGE_1, 0x00, 0xff, /* Usage Page: Vendor defined */ \\\n\tUSAGE, 0x01, /* Usage: Vendor Usage 0x01 */ \\\n\tBEGIN_COLLECTION, 0x01, /* Begin Collection: Application */ \\\n\t\tREPORT_ID, REPORTID_UMAPP_CONF, /* Report ID: User-mode Application configuration */ \\\n\t\tUSAGE, 0x01, /* Usage: Vendor Usage 0x01 */ \\\n\t\tLOGICAL_MINIMUM, 0x00, /* Logical Minimum 0 */ \\\n\t\tLOGICAL_MAXIMUM_2, 0xff, 0x00, /* Logical Maximum 255 */ \\\n\t\tREPORT_SIZE, 0x08, /* Report Size: 8 */ \\\n\t\tREPORT_COUNT, 0x03, /* Report Count: 3 */ \\\n\t\tFEATURE, 0x02, /* Feature: (Data, Var, Abs) */ \\\n\tEND_COLLECTION\n\n#define AAPL_PTP_WINDOWS_CONFIGURATION_TLC \\\n\tUSAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \\\n\tUSAGE, 0x0e, /* Usage: Configuration */ \\\n\tBEGIN_COLLECTION, 0x01, /* Begin Collection: Application */ \\\n\t\tREPORT_ID, REPORTID_REPORTMODE, /* Report ID: Mode Selection */ \\\n\t\tUSAGE, 0x22, /* Usage: Finger */ \\\n\t\tBEGIN_COLLECTION, 0x02, /* Begin Collection: Logical */ \\\n\t\t\tUSAGE, 0x52, /* Usage: Input Mode */ \\\n\t\t\tLOGICAL_MINIMUM, 0x00, /* Logical Minumum: 0 finger */ \\\n\t\t\tLOGICAL_MAXIMUM, MAX_FINGERS, /* Logical Maximum: MAX_TOUCH_COUNT fingers */ \\\n\t\t\tREPORT_SIZE, 0x08, /* Report Size: 0x08 */ \\\n\t\t\tREPORT_COUNT, 0x01, /* Report Count: 0x01 */ \\\n\t\t\tFEATURE, 0x02, /* Feature: (Data, Var, Abs) */ \\\n\t\tEND_COLLECTION, /* End Collection */ \\\n\t\tBEGIN_COLLECTION, 0x00, /* Begin Collection: Physical */ \\\n\t\t\tREPORT_ID, REPORTID_FUNCSWITCH, /* Report ID: Function Switch */ \\\n\t\t\tUSAGE, BUTTON_SWITCH, /* Usage: Button Switch */ \\\n\t\t\tUSAGE, SURFACE_SWITCH, /* Usage: Surface Switch */ \\\n\t\t\tREPORT_SIZE, 0x01, /* Report Size: 0x01 */ \\\n\t\t\tREPORT_COUNT, 0x02, /* Report Count: 0x02 */ \\\n\t\t\tLOGICAL_MAXIMUM, 0x01, /* Logical Maximum: 0x01 */ \\\n\t\t\tFEATURE, 0x02, /* Feature: (Data, Var, Abs) */ \\\n\t\t\tREPORT_COUNT, 0x06, /* Report Count: 0x06 */ \\\n\t\t\tFEATURE, 0x03, /* Feature: (Const, Var, Abs) */ \\\n\t\tEND_COLLECTION, /* End Collection */ \\\n\tEND_COLLECTION /* End Collection */\n\n#define DEFAULT_PTP_HQA_BLOB \\\n\t0xfc, 0x28, 0xfe, 0x84, 0x40, 0xcb, 0x9a, 0x87, \\\n\t0x0d, 0xbe, 0x57, 0x3c, 0xb6, 0x70, 0x09, 0x88, \\\n\t0x07, 0x97, 0x2d, 0x2b, 0xe3, 0x38, 0x34, 0xb6, \\\n\t0x6c, 0xed, 0xb0, 0xf7, 0xe5, 0x9c, 0xf6, 0xc2, \\\n\t0x2e, 0x84, 0x1b, 0xe8, 0xb4, 0x51, 0x78, 0x43, \\\n\t0x1f, 0x28, 0x4b, 0x7c, 0x2d, 0x53, 0xaf, 0xfc, \\\n\t0x47, 0x70, 0x1b, 0x59, 0x6f, 0x74, 0x43, 0xc4, \\\n\t0xf3, 0x47, 0x18, 0x53, 0x1a, 0xa2, 0xa1, 0x71, \\\n\t0xc7, 0x95, 0x0e, 0x31, 0x55, 0x21, 0xd3, 0xb5, \\\n\t0x1e, 0xe9, 0x0c, 0xba, 0xec, 0xb8, 0x89, 0x19, \\\n\t0x3e, 0xb3, 0xaf, 0x75, 0x81, 0x9d, 0x53, 0xb9, \\\n\t0x41, 0x57, 0xf4, 0x6d, 0x39, 0x25, 0x29, 0x7c, \\\n\t0x87, 0xd9, 0xb4, 0x98, 0x45, 0x7d, 0xa7, 0x26, \\\n\t0x9c, 0x65, 0x3b, 0x85, 0x68, 0x89, 0xd7, 0x3b, \\\n\t0xbd, 0xff, 0x14, 0x67, 0xf2, 0x2b, 0xf0, 0x2a, \\\n\t0x41, 0x54, 0xf0, 0xfd, 0x2c, 0x66, 0x7c, 0xf8, \\\n\t0xc0, 0x8f, 0x33, 0x13, 0x03, 0xf1, 0xd3, 0xc1, \\\n\t0x0b, 0x89, 0xd9, 0x1b, 0x62, 0xcd, 0x51, 0xb7, \\\n\t0x80, 0xb8, 0xaf, 0x3a, 0x10, 0xc1, 0x8a, 0x5b, \\\n\t0xe8, 0x8a, 0x56, 0xf0, 0x8c, 0xaa, 0xfa, 0x35, \\\n\t0xe9, 0x42, 0xc4, 0xd8, 0x55, 0xc3, 0x38, 0xcc, \\\n\t0x2b, 0x53, 0x5c, 0x69, 0x52, 0xd5, 0xc8, 0x73, \\\n\t0x02, 0x38, 0x7c, 0x73, 0xb6, 0x41, 0xe7, 0xff, \\\n\t0x05, 0xd8, 0x2b, 0x79, 0x9a, 0xe2, 0x34, 0x60, \\\n\t0x8f, 0xa3, 0x32, 0x1f, 0x09, 0x78, 0x62, 0xbc, \\\n\t0x80, 0xe3, 0x0f, 0xbd, 0x65, 0x20, 0x08, 0x13, \\\n\t0xc1, 0xe2, 0xee, 0x53, 0x2d, 0x86, 0x7e, 0xa7, \\\n\t0x5a, 0xc5, 0xd3, 0x7d, 0x98, 0xbe, 0x31, 0x48, \\\n\t0x1f, 0xfb, 0xda, 0xaf, 0xa2, 0xa8, 0x6a, 0x89, \\\n\t0xd6, 0xbf, 0xf2, 0xd3, 0x32, 0x2a, 0x9a, 0xe4, \\\n\t0xcf, 0x17, 0xb7, 0xb8, 0xf4, 0xe1, 0x33, 0x08, \\\n\t0x24, 0x8b, 0xc4, 0x43, 0xa5, 0xe5, 0x24, 0xc2\n"
  },
  {
    "path": "src/AmtPtpHidFilter/include/Queue.h",
    "content": "// Queue.h: IO queue bits\n#pragma once\n\nEXTERN_C_START\n\n// Initialization\nNTSTATUS\nPtpFilterIoQueueInitialize(\n    _In_ WDFDEVICE Device\n);\n\n// Queue context\ntypedef struct _QUEUE_CONTEXT {\n    WDFDEVICE   Device;\n    WDFIOTARGET DeviceIoTarget;\n} QUEUE_CONTEXT, *PQUEUE_CONTEXT;\n\nWDF_DECLARE_CONTEXT_TYPE_WITH_NAME(QUEUE_CONTEXT, PtpFilterQueueGetContext)\n\n// Event handlers\nEVT_WDF_IO_QUEUE_IO_INTERNAL_DEVICE_CONTROL FilterEvtIoIntDeviceControl;\nEVT_WDF_IO_QUEUE_IO_STOP FilterEvtIoStop;\n\nEXTERN_C_END\n"
  },
  {
    "path": "src/AmtPtpHidFilter/include/Trace.h",
    "content": "// Trace.h: Defines WPP tracing control bits.\n\n#pragma once\n\n//\n// Define the tracing flags.\n//\n// Tracing GUID - eeb34803-f3ec-4bb1-97ce-b42405d7f3c2\n//\n\n#define WPP_CONTROL_GUIDS                                                   \\\n    WPP_DEFINE_CONTROL_GUID(                                                \\\n        AmtPtpHidFilterTraceGuid, (eeb34803,f3ec,4bb1,97ce,b42405d7f3c2),   \\\n                                                                            \\\n        WPP_DEFINE_BIT(TRACE_DRIVER)                                        \\\n        WPP_DEFINE_BIT(TRACE_DEVICE)                                        \\\n        WPP_DEFINE_BIT(TRACE_QUEUE)                                         \\\n        WPP_DEFINE_BIT(TRACE_HID)                                           \\\n\t\tWPP_DEFINE_BIT(TRACE_INPUT)\t\t\t\t\t\t\t\t\t        \\\n        )\n\n#define WPP_FLAG_LEVEL_LOGGER(flag, level)                                  \\\n    WPP_LEVEL_LOGGER(flag)\n\n#define WPP_FLAG_LEVEL_ENABLED(flag, level)                                 \\\n    (WPP_LEVEL_ENABLED(flag) &&                                             \\\n     WPP_CONTROL(WPP_BIT_ ## flag).Level >= level)\n\n#define WPP_LEVEL_FLAGS_LOGGER(lvl,flags) \\\n    WPP_LEVEL_LOGGER(flags)\n\n#define WPP_LEVEL_FLAGS_ENABLED(lvl, flags) \\\n    (WPP_LEVEL_ENABLED(flags) && WPP_CONTROL(WPP_BIT_ ## flags).Level >= lvl)\n\n//           \n// WPP orders static parameters before dynamic parameters. To support the Trace function\n// defined below which sets FLAGS=MYDRIVER_ALL_INFO, a custom macro must be defined to\n// reorder the arguments to what the .tpl configuration file expects.\n//\n#define WPP_RECORDER_FLAGS_LEVEL_ARGS(flags, lvl) WPP_RECORDER_LEVEL_FLAGS_ARGS(lvl, flags)\n#define WPP_RECORDER_FLAGS_LEVEL_FILTER(flags, lvl) WPP_RECORDER_LEVEL_FLAGS_FILTER(lvl, flags)\n\n//\n// This comment block is scanned by the trace preprocessor to define our\n// Trace function.\n//\n// begin_wpp config\n// FUNC Trace{FLAGS=TRACE_DRIVER}(LEVEL, MSG, ...);\n// FUNC TraceEvents(LEVEL, FLAGS, MSG, ...);\n// end_wpp\n//\n"
  }
]