summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSanjeev Reddy <[email protected]>2019-02-06 13:12:11 -0800
committerGitHub <[email protected]>2019-02-06 13:12:11 -0800
commit27302e1d522bc16e1cc18232602f7eca1b79db0f (patch)
tree1035100a803e4e52abbda93288091bb50f4f5073
parent46da8a0d4f0de180dd15b6ca088e095b5e2c0b96 (diff)
parent39d39e7485faddf601d51c897863ff2f876e391e (diff)
Merge pull request #1 from Microsoft/master
Updating to latest
-rw-r--r--general/SimpleMediaSource/MediaSource/MediaSource.vcxproj331
-rw-r--r--general/SimpleMediaSource/MediaSource/MediaSource.vcxproj.filters47
-rw-r--r--general/SimpleMediaSource/MediaSource/SimpleMediaSource.cpp526
-rw-r--r--general/SimpleMediaSource/MediaSource/SimpleMediaSource.h81
-rw-r--r--general/SimpleMediaSource/MediaSource/SimpleMediaStream.cpp391
-rw-r--r--general/SimpleMediaSource/MediaSource/SimpleMediaStream.h54
-rw-r--r--general/SimpleMediaSource/MediaSource/dllMain.cpp35
-rw-r--r--general/SimpleMediaSource/MediaSource/module.def6
-rw-r--r--general/SimpleMediaSource/MediaSource/stdafx.cpp11
-rw-r--r--general/SimpleMediaSource/MediaSource/stdafx.h76
-rw-r--r--general/SimpleMediaSource/README.md33
-rw-r--r--general/SimpleMediaSource/SimpleMediaSource.sln67
-rw-r--r--general/SimpleMediaSource/SimpleMediaSourceDriver/Device.c109
-rw-r--r--general/SimpleMediaSource/SimpleMediaSourceDriver/Device.h46
-rw-r--r--general/SimpleMediaSource/SimpleMediaSourceDriver/Driver.c167
-rw-r--r--general/SimpleMediaSource/SimpleMediaSourceDriver/Driver.h37
-rw-r--r--general/SimpleMediaSource/SimpleMediaSourceDriver/Public.h24
-rw-r--r--general/SimpleMediaSource/SimpleMediaSourceDriver/Queue.c193
-rw-r--r--general/SimpleMediaSource/SimpleMediaSourceDriver/Queue.h42
-rw-r--r--general/SimpleMediaSource/SimpleMediaSourceDriver/ReadMe.txt33
-rw-r--r--general/SimpleMediaSource/SimpleMediaSourceDriver/SimpleMediaSourceDriver.infbin0 -> 8500 bytes
-rw-r--r--general/SimpleMediaSource/SimpleMediaSourceDriver/SimpleMediaSourceDriver.vcxproj282
-rw-r--r--general/SimpleMediaSource/SimpleMediaSourceDriver/SimpleMediaSourceDriver.vcxproj.filters57
-rw-r--r--general/SimpleMediaSource/SimpleMediaSourceDriver/Trace.h62
-rw-r--r--general/SimpleMediaSource/general-SimpleMediaSource.yaml10
-rw-r--r--general/ioctl/kmdf/exe/testapp.c2
-rw-r--r--general/ioctl/wdm/exe/testapp.c2
-rw-r--r--general/pcidrv/kmdf/trace.h6
-rw-r--r--gnss/GnssUmdfSampleDriver.wprp32
-rw-r--r--gnss/ReadMe.md97
-rw-r--r--gnss/gnss.yaml10
-rw-r--r--gnss/gnssUmdf.sln59
-rw-r--r--gnss/gnssUmdf/Defaults.h59
-rw-r--r--gnss/gnssUmdf/Device.cpp163
-rw-r--r--gnss/gnssUmdf/Device.h44
-rw-r--r--gnss/gnssUmdf/Driver.cpp107
-rw-r--r--gnss/gnssUmdf/Driver.h22
-rw-r--r--gnss/gnssUmdf/FixHandler.cpp228
-rw-r--r--gnss/gnssUmdf/FixHandler.h39
-rw-r--r--gnss/gnssUmdf/FixSession.cpp512
-rw-r--r--gnss/gnssUmdf/FixSession.h60
-rw-r--r--gnss/gnssUmdf/Queue.cpp482
-rw-r--r--gnss/gnssUmdf/Queue.h78
-rw-r--r--gnss/gnssUmdf/Trace.h64
-rw-r--r--gnss/gnssUmdf/gnssUmdf.infbin0 -> 3592 bytes
-rw-r--r--gnss/gnssUmdf/gnssUmdf.vcxproj301
-rw-r--r--gnss/gnssUmdf/gnssUmdf.vcxproj.filters69
-rw-r--r--gnss/gnssUmdf/precomp.h29
-rw-r--r--nfc/NfcCxSample/README.md49
-rw-r--r--nfc/NfcCxSample/windows-drivertemplate-nfc.sln51
-rw-r--r--nfc/NfcCxSample/windows-drivertemplate-nfc/Device.cpp343
-rw-r--r--nfc/NfcCxSample/windows-drivertemplate-nfc/Device.h74
-rw-r--r--nfc/NfcCxSample/windows-drivertemplate-nfc/Driver.cpp41
-rw-r--r--nfc/NfcCxSample/windows-drivertemplate-nfc/windows-drivertemplate-nfc.infbin0 -> 3832 bytes
-rw-r--r--nfc/NfcCxSample/windows-drivertemplate-nfc/windows-drivertemplate-nfc.vcxproj95
-rw-r--r--nfc/NfcCxSample/windows-drivertemplate-nfc/windows-drivertemplate-nfc.vcxproj.filters13
-rw-r--r--print/XPSDrvSmpl/README.md6
-rw-r--r--serial/serial/trace.h2
58 files changed, 5850 insertions, 9 deletions
diff --git a/general/SimpleMediaSource/MediaSource/MediaSource.vcxproj b/general/SimpleMediaSource/MediaSource/MediaSource.vcxproj
new file mode 100644
index 00000000..47562ff7
--- /dev/null
+++ b/general/SimpleMediaSource/MediaSource/MediaSource.vcxproj
@@ -0,0 +1,331 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|ARM">
+ <Configuration>Debug</Configuration>
+ <Platform>ARM</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|ARM64">
+ <Configuration>Debug</Configuration>
+ <Platform>ARM64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|ARM">
+ <Configuration>Release</Configuration>
+ <Platform>ARM</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|ARM64">
+ <Configuration>Release</Configuration>
+ <Platform>ARM64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <VCProjectVersion>15.0</VCProjectVersion>
+ <ProjectGuid>{43AD9BF7-E765-48FE-9826-71A8F2CB12DD}</ProjectGuid>
+ <RootNamespace>MediaSource</RootNamespace>
+ <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
+ <ProjectName>SimpleMediaSource</ProjectName>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
+ <CharacterSet>MultiByte</CharacterSet>
+ <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
+ <CharacterSet>MultiByte</CharacterSet>
+ <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>MultiByte</CharacterSet>
+ <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>MultiByte</CharacterSet>
+ <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
+ <CharacterSet>MultiByte</CharacterSet>
+ <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
+ <CharacterSet>MultiByte</CharacterSet>
+ <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>MultiByte</CharacterSet>
+ <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>MultiByte</CharacterSet>
+ <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="Shared">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <CodeAnalysisRuleSet>NativeRecommendedRules.ruleset</CodeAnalysisRuleSet>
+ <RunCodeAnalysis>false</RunCodeAnalysis>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
+ <CodeAnalysisRuleSet>NativeRecommendedRules.ruleset</CodeAnalysisRuleSet>
+ <RunCodeAnalysis>false</RunCodeAnalysis>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <CodeAnalysisRuleSet>NativeRecommendedRules.ruleset</CodeAnalysisRuleSet>
+ <RunCodeAnalysis>false</RunCodeAnalysis>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
+ <CodeAnalysisRuleSet>NativeRecommendedRules.ruleset</CodeAnalysisRuleSet>
+ <RunCodeAnalysis>false</RunCodeAnalysis>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <CodeAnalysisRuleSet>NativeRecommendedRules.ruleset</CodeAnalysisRuleSet>
+ <RunCodeAnalysis>false</RunCodeAnalysis>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
+ <CodeAnalysisRuleSet>NativeRecommendedRules.ruleset</CodeAnalysisRuleSet>
+ <RunCodeAnalysis>false</RunCodeAnalysis>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <CodeAnalysisRuleSet>NativeRecommendedRules.ruleset</CodeAnalysisRuleSet>
+ <RunCodeAnalysis>false</RunCodeAnalysis>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
+ <CodeAnalysisRuleSet>NativeRecommendedRules.ruleset</CodeAnalysisRuleSet>
+ <RunCodeAnalysis>false</RunCodeAnalysis>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <SDLCheck>true</SDLCheck>
+ <ConformanceMode>true</ConformanceMode>
+ <EnablePREfast>false</EnablePREfast>
+ <ExceptionHandling>false</ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>mfplat.lib;Mfsensorgroup.lib;%(AdditionalDependencies);OneCoreUAP.lib</AdditionalDependencies>
+ <IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+ <ModuleDefinitionFile>$(SolutionDir)MediaSource\module.def</ModuleDefinitionFile>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <SDLCheck>true</SDLCheck>
+ <ConformanceMode>true</ConformanceMode>
+ <EnablePREfast>false</EnablePREfast>
+ <ExceptionHandling>false</ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>mfplat.lib;Mfsensorgroup.lib;%(AdditionalDependencies);OneCoreUAP.lib</AdditionalDependencies>
+ <IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+ <ModuleDefinitionFile>$(SolutionDir)MediaSource\module.def</ModuleDefinitionFile>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <SDLCheck>true</SDLCheck>
+ <ConformanceMode>true</ConformanceMode>
+ <EnablePREfast>false</EnablePREfast>
+ <ExceptionHandling>false</ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>mfplat.lib;Mfsensorgroup.lib;%(AdditionalDependencies);OneCoreUAP.lib</AdditionalDependencies>
+ <ModuleDefinitionFile>$(SolutionDir)MediaSource\module.def</ModuleDefinitionFile>
+ <IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <SDLCheck>true</SDLCheck>
+ <ConformanceMode>true</ConformanceMode>
+ <EnablePREfast>false</EnablePREfast>
+ <ExceptionHandling>false</ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>mfplat.lib;Mfsensorgroup.lib;%(AdditionalDependencies);OneCoreUAP.lib</AdditionalDependencies>
+ <ModuleDefinitionFile>$(SolutionDir)MediaSource\module.def</ModuleDefinitionFile>
+ <IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <SDLCheck>true</SDLCheck>
+ <ConformanceMode>true</ConformanceMode>
+ <EnablePREfast>false</EnablePREfast>
+ <ExceptionHandling>false</ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ </ClCompile>
+ <Link>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <AdditionalDependencies>mfplat.lib;Mfsensorgroup.lib;%(AdditionalDependencies);OneCoreUAP.lib</AdditionalDependencies>
+ <IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+ <ModuleDefinitionFile>$(SolutionDir)MediaSource\module.def</ModuleDefinitionFile>
+ <ImageHasSafeExceptionHandlers />
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <SDLCheck>true</SDLCheck>
+ <ConformanceMode>true</ConformanceMode>
+ <EnablePREfast>false</EnablePREfast>
+ <ExceptionHandling>false</ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ </ClCompile>
+ <Link>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <AdditionalDependencies>mfplat.lib;Mfsensorgroup.lib;%(AdditionalDependencies);OneCoreUAP.lib</AdditionalDependencies>
+ <IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+ <ModuleDefinitionFile>$(SolutionDir)MediaSource\module.def</ModuleDefinitionFile>
+ <ImageHasSafeExceptionHandlers>
+ </ImageHasSafeExceptionHandlers>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <SDLCheck>true</SDLCheck>
+ <ConformanceMode>true</ConformanceMode>
+ <EnablePREfast>false</EnablePREfast>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <ExceptionHandling>false</ExceptionHandling>
+ </ClCompile>
+ <Link>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <AdditionalDependencies>mfplat.lib;Mfsensorgroup.lib;%(AdditionalDependencies);OneCoreUAP.lib</AdditionalDependencies>
+ <IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+ <ModuleDefinitionFile>$(SolutionDir)MediaSource\module.def</ModuleDefinitionFile>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <SDLCheck>true</SDLCheck>
+ <ConformanceMode>true</ConformanceMode>
+ <EnablePREfast>false</EnablePREfast>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <ExceptionHandling>false</ExceptionHandling>
+ </ClCompile>
+ <Link>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <AdditionalDependencies>mfplat.lib;Mfsensorgroup.lib;%(AdditionalDependencies);OneCoreUAP.lib</AdditionalDependencies>
+ <IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+ <ModuleDefinitionFile>$(SolutionDir)MediaSource\module.def</ModuleDefinitionFile>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <None Include="module.def" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="dllMain.cpp" />
+ <ClCompile Include="SimpleMediaSource.cpp" />
+ <ClCompile Include="SimpleMediaStream.cpp" />
+ <ClCompile Include="stdafx.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="SimpleMediaSource.h" />
+ <ClInclude Include="SimpleMediaStream.h" />
+ <ClInclude Include="stdafx.h" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/general/SimpleMediaSource/MediaSource/MediaSource.vcxproj.filters b/general/SimpleMediaSource/MediaSource/MediaSource.vcxproj.filters
new file mode 100644
index 00000000..ffcc9853
--- /dev/null
+++ b/general/SimpleMediaSource/MediaSource/MediaSource.vcxproj.filters
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+ <Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="module.def">
+ <Filter>Source Files</Filter>
+ </None>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="SimpleMediaSource.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="SimpleMediaStream.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="stdafx.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="dllMain.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="SimpleMediaSource.h">
+ <Filter>Source Files</Filter>
+ </ClInclude>
+ <ClInclude Include="SimpleMediaStream.h">
+ <Filter>Source Files</Filter>
+ </ClInclude>
+ <ClInclude Include="stdafx.h">
+ <Filter>Source Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/general/SimpleMediaSource/MediaSource/SimpleMediaSource.cpp b/general/SimpleMediaSource/MediaSource/SimpleMediaSource.cpp
new file mode 100644
index 00000000..162fb1d8
--- /dev/null
+++ b/general/SimpleMediaSource/MediaSource/SimpleMediaSource.cpp
@@ -0,0 +1,526 @@
+#include "stdafx.h"
+
+///////////////////////////////////////////////////////////////////////////////
+HRESULT
+SimpleMediaSource::RuntimeClassInitialize(
+ )
+{
+ HRESULT hr = S_OK;
+
+ RETURN_IF_FAILED (MFCreateAttributes(&_spAttributes, 10));
+ RETURN_IF_FAILED (MFCreateEventQueue(&_spEventQueue));
+ RETURN_IF_FAILED (MakeAndInitialize<SimpleMediaStream>(&_stream, this));
+ {
+ ComPtr<IMFStreamDescriptor> streamDescriptor(_stream.Get()->_spStreamDesc.Get());
+ RETURN_IF_FAILED (MFCreatePresentationDescriptor(NUM_STREAMS, streamDescriptor.GetAddressOf(), &_spPresentationDescriptor));
+ }
+
+ _wasStreamPreviouslySelected = false;
+ _sourceState = SourceState::Stopped;
+
+ return hr;
+}
+
+// IMFMediaEventGenerator methods.
+IFACEMETHODIMP
+SimpleMediaSource::BeginGetEvent(
+ _In_ IMFAsyncCallback *pCallback,
+ _In_ IUnknown *punkState
+ )
+{
+ HRESULT hr = S_OK;
+ auto lock = _critSec.Lock();
+
+ RETURN_IF_FAILED (_CheckShutdownRequiresLock());
+ RETURN_IF_FAILED (_spEventQueue->BeginGetEvent(pCallback, punkState));
+
+ return hr;
+}
+
+IFACEMETHODIMP
+SimpleMediaSource::EndGetEvent(
+ _In_ IMFAsyncResult *pResult,
+ _COM_Outptr_ IMFMediaEvent **ppEvent
+ )
+{
+ HRESULT hr = S_OK;
+ auto lock = _critSec.Lock();
+
+ RETURN_IF_FAILED (_CheckShutdownRequiresLock());
+ RETURN_IF_FAILED (_spEventQueue->EndGetEvent(pResult, ppEvent));
+
+ return hr;
+}
+
+IFACEMETHODIMP
+SimpleMediaSource::GetEvent(
+ DWORD dwFlags,
+ _COM_Outptr_ IMFMediaEvent **ppEvent
+ )
+{
+ // NOTE:
+ // GetEvent can block indefinitely, so we don't hold the lock.
+ // This requires some juggling with the event queue pointer.
+
+ HRESULT hr = S_OK;
+
+ ComPtr<IMFMediaEventQueue> spQueue;
+
+ {
+ auto lock = _critSec.Lock();
+
+ RETURN_IF_FAILED (_CheckShutdownRequiresLock());
+ spQueue = _spEventQueue;
+ }
+
+ // Now get the event.
+ RETURN_IF_FAILED (_spEventQueue->GetEvent(dwFlags, ppEvent));
+
+ return hr;
+}
+
+IFACEMETHODIMP
+SimpleMediaSource::QueueEvent(
+ MediaEventType eventType,
+ REFGUID guidExtendedType,
+ HRESULT hrStatus,
+ _In_opt_ PROPVARIANT const *pvValue
+ )
+{
+ HRESULT hr = S_OK;
+ auto lock = _critSec.Lock();
+
+ RETURN_IF_FAILED (_CheckShutdownRequiresLock());
+ RETURN_IF_FAILED (_spEventQueue->QueueEventParamVar(eventType, guidExtendedType, hrStatus, pvValue));
+
+ return hr;
+}
+
+// IMFMediaSource methods
+IFACEMETHODIMP
+SimpleMediaSource::CreatePresentationDescriptor(
+ _COM_Outptr_ IMFPresentationDescriptor **ppPresentationDescriptor
+ )
+{
+ HRESULT hr = S_OK;
+ auto lock = _critSec.Lock();
+
+ if (ppPresentationDescriptor == nullptr)
+ {
+ return E_POINTER;
+ }
+ *ppPresentationDescriptor = nullptr;
+
+ RETURN_IF_FAILED (_CheckShutdownRequiresLock());
+ RETURN_IF_FAILED (_spPresentationDescriptor->Clone(ppPresentationDescriptor));
+
+ return hr;
+}
+
+IFACEMETHODIMP
+SimpleMediaSource::GetCharacteristics(
+ _Out_ DWORD *pdwCharacteristics
+ )
+{
+ HRESULT hr = S_OK;
+ auto lock = _critSec.Lock();
+
+ if (nullptr == pdwCharacteristics)
+ {
+ return E_POINTER;
+ }
+ *pdwCharacteristics = 0;
+
+ RETURN_IF_FAILED (_CheckShutdownRequiresLock());
+ *pdwCharacteristics = MFMEDIASOURCE_IS_LIVE;
+
+ return hr;
+}
+
+IFACEMETHODIMP
+SimpleMediaSource::Pause(
+ )
+{
+ // Pause() not required/needed
+ return MF_E_INVALID_STATE_TRANSITION;
+}
+
+
+IFACEMETHODIMP
+SimpleMediaSource::Shutdown(
+ )
+{
+ HRESULT hr = S_OK;
+ auto lock = _critSec.Lock();
+
+ _sourceState = SourceState::Shutdown;
+
+ _spAttributes.Reset();
+ _spPresentationDescriptor.Reset();
+
+ if (_spEventQueue != nullptr)
+ {
+ _spEventQueue->Shutdown();
+ _spEventQueue.Reset();
+ }
+
+ if (_stream != nullptr)
+ {
+ _stream.Get()->Shutdown();
+ _stream.Reset();
+ }
+
+ return hr;
+}
+
+IFACEMETHODIMP
+SimpleMediaSource::Start(
+ _In_ IMFPresentationDescriptor *pPresentationDescriptor,
+ _In_opt_ const GUID *pguidTimeFormat,
+ _In_ const PROPVARIANT *pvarStartPos
+ )
+{
+ HRESULT hr = S_OK;
+ auto lock = _critSec.Lock();
+ DWORD count = 0;
+ PROPVARIANT startTime;
+ BOOL selected = false;
+ ComPtr<IMFStreamDescriptor> streamDesc;
+ DWORD streamIndex = 0;
+
+ if (pPresentationDescriptor == nullptr || pvarStartPos == nullptr)
+ {
+ return E_INVALIDARG;
+ }
+ else if (pguidTimeFormat != nullptr && *pguidTimeFormat != GUID_NULL)
+ {
+ return MF_E_UNSUPPORTED_TIME_FORMAT;
+ }
+
+ RETURN_IF_FAILED (_CheckShutdownRequiresLock());
+
+ if (!(_sourceState != SourceState::Stopped || _sourceState != SourceState::Shutdown))
+ {
+ return MF_E_INVALID_STATE_TRANSITION;
+ }
+
+ _sourceState = SourceState::Started;
+
+ // This checks the passed in PresentationDescriptor matches the member of streams we
+ // have defined internally and that at least one stream is selected
+ RETURN_IF_FAILED (_ValidatePresentationDescriptor(pPresentationDescriptor));
+ RETURN_IF_FAILED (pPresentationDescriptor->GetStreamDescriptorCount(&count));
+ RETURN_IF_FAILED (InitPropVariantFromInt64(MFGetSystemTime(), &startTime));
+
+ // Send event that the source started. Include error code in case it failed.
+ RETURN_IF_FAILED (_spEventQueue->QueueEventParamVar(MESourceStarted,
+ GUID_NULL,
+ hr,
+ &startTime));
+
+ // We're hardcoding this to the first descriptor
+ // since this sample is a single stream sample. For
+ // multiple streams, we need to walk the list of streams
+ // and for each selected stream, send the MEUpdatedStream
+ // or MENewStream event along with the MEStreamStarted
+ // event.
+ RETURN_IF_FAILED (pPresentationDescriptor->GetStreamDescriptorByIndex(0,
+ &selected,
+ &streamDesc));
+ RETURN_IF_FAILED (streamDesc->GetStreamIdentifier(&streamIndex));
+ if (streamIndex >= NUM_STREAMS)
+ {
+ return MF_E_INVALIDSTREAMNUMBER;
+ }
+
+ if (selected)
+ {
+ ComPtr<IUnknown> spunkStream;
+ MediaEventType met = (_wasStreamPreviouslySelected ? MEUpdatedStream : MENewStream);
+
+ // Update our internal PresentationDescriptor
+ RETURN_IF_FAILED (_spPresentationDescriptor->SelectStream(streamIndex));
+ RETURN_IF_FAILED (_stream.Get()->SetStreamState(MF_STREAM_STATE_RUNNING));
+ RETURN_IF_FAILED (_stream.As(&spunkStream));
+
+ // Send the MEUpdatedStream/MENewStream to our source event
+ // queue.
+ RETURN_IF_FAILED (_spEventQueue->QueueEventParamUnk(met,
+ GUID_NULL,
+ S_OK,
+ spunkStream.Get()));
+
+ // But for our stream started (MEStreamStarted), we post to our
+ // stream event queue.
+ RETURN_IF_FAILED (_stream.Get()->QueueEvent(MEStreamStarted,
+ GUID_NULL,
+ S_OK,
+ &startTime));
+ }
+ _wasStreamPreviouslySelected = selected;
+
+ return hr;
+}
+
+IFACEMETHODIMP
+SimpleMediaSource::Stop(
+ )
+{
+ HRESULT hr = S_OK;
+ auto lock = _critSec.Lock();
+ PROPVARIANT stopTime;
+ DWORD count = 0;
+ MF_STREAM_STATE state;
+
+ if (_sourceState != SourceState::Started)
+ {
+ return MF_E_INVALID_STATE_TRANSITION;
+ }
+
+ _sourceState = SourceState::Stopped;
+
+ RETURN_IF_FAILED (_CheckShutdownRequiresLock());
+ RETURN_IF_FAILED (InitPropVariantFromInt64(MFGetSystemTime(), &stopTime));
+ RETURN_IF_FAILED (_spPresentationDescriptor->GetStreamDescriptorCount(&count));
+
+ // Deselect the streams and send the stream stopped events.
+ RETURN_IF_FAILED (_stream.Get()->GetStreamState(&state));
+ _wasStreamPreviouslySelected = (state == MF_STREAM_STATE_RUNNING);
+ RETURN_IF_FAILED (_stream.Get()->SetStreamState(MF_STREAM_STATE_STOPPED));
+ _spPresentationDescriptor->DeselectStream(0);
+ RETURN_IF_FAILED (_stream.Get()->QueueEvent(MEStreamStopped, GUID_NULL, hr, &stopTime));
+ RETURN_IF_FAILED (_spEventQueue->QueueEventParamVar(MESourceStopped, GUID_NULL, hr, &stopTime));
+
+ return hr;
+}
+
+// IMFMediaSourceEx
+IFACEMETHODIMP
+SimpleMediaSource::GetSourceAttributes(
+ _COM_Outptr_ IMFAttributes** sourceAttributes
+ )
+{
+ HRESULT hr = S_OK;
+ auto lock = _critSec.Lock();
+
+ if (nullptr == sourceAttributes)
+ {
+ return E_POINTER;
+ }
+
+ RETURN_IF_FAILED (_CheckShutdownRequiresLock());
+
+ *sourceAttributes = nullptr;
+ if (_spAttributes.Get() == nullptr)
+ {
+ ComPtr<IMFSensorProfileCollection> profileCollection;
+ ComPtr<IMFSensorProfile> profile;
+
+ // Create our source attribute store.
+ RETURN_IF_FAILED (MFCreateAttributes(_spAttributes.GetAddressOf(), 1));
+
+ // Create an empty profile collection...
+ RETURN_IF_FAILED (MFCreateSensorProfileCollection(&profileCollection));
+
+ // In this example since we have just one stream, we only have one
+ // pin to add: Pin0.
+
+ // Legacy profile is mandatory. This is to ensure non-profile
+ // aware applications can still function, but with degraded
+ // feature sets.
+ RETURN_IF_FAILED (MFCreateSensorProfile(KSCAMERAPROFILE_Legacy, 0, nullptr,
+ profile.ReleaseAndGetAddressOf()));
+ RETURN_IF_FAILED (profile->AddProfileFilter(0, L"((RES==;FRT<=30,1;SUT==))"));
+ RETURN_IF_FAILED (profileCollection->AddProfile(profile.Get()));
+
+ // High Frame Rate profile will only allow >=60fps.
+ RETURN_IF_FAILED (MFCreateSensorProfile(KSCAMERAPROFILE_HighFrameRate, 0, nullptr,
+ profile.ReleaseAndGetAddressOf()));
+ RETURN_IF_FAILED (profile->AddProfileFilter(0, L"((RES==;FRT>=60,1;SUT==))"));
+ RETURN_IF_FAILED (profileCollection->AddProfile(profile.Get()));
+
+
+ // Se the profile collection to the attribute store of the IMFTransform.
+ RETURN_IF_FAILED (_spAttributes->SetUnknown(MF_DEVICEMFT_SENSORPROFILE_COLLECTION,
+ profileCollection.Get()));
+ }
+
+ return _spAttributes.CopyTo(sourceAttributes);
+}
+
+
+IFACEMETHODIMP
+SimpleMediaSource::GetStreamAttributes(
+ DWORD dwStreamIdentifier,
+ _COM_Outptr_ IMFAttributes **ppAttributes
+ )
+{
+ HRESULT hr = S_OK;
+ auto lock = _critSec.Lock();
+
+ if (ppAttributes == nullptr)
+ {
+ return E_POINTER;
+ }
+ *ppAttributes = nullptr;
+
+ RETURN_IF_FAILED (_CheckShutdownRequiresLock());
+ if (dwStreamIdentifier >= NUM_STREAMS)
+ {
+ return MF_E_INVALIDSTREAMNUMBER;
+ }
+ else
+ {
+ *ppAttributes = _stream.Get()->_spAttributes.Get();
+ (*ppAttributes)->AddRef();
+ }
+
+ return hr;
+}
+
+IFACEMETHODIMP
+SimpleMediaSource::SetD3DManager(
+ _In_opt_ IUnknown* /*pManager*/
+ )
+{
+ // Return code is ignored by the frame work, this is a
+ // best effort attempt to inform the media source of the
+ // DXGI manager to use if DX surface support is available.
+
+ return E_NOTIMPL;
+}
+
+// IMFGetService methods
+_Use_decl_annotations_
+IFACEMETHODIMP
+SimpleMediaSource::GetService(
+ _In_ REFGUID guidService,
+ _In_ REFIID riid,
+ _Out_ LPVOID * ppvObject
+ )
+{
+ HRESULT hr = S_OK;
+ auto lock = _critSec.Lock();
+
+ RETURN_IF_FAILED (_CheckShutdownRequiresLock());
+
+ if (!ppvObject)
+ {
+ return E_POINTER;
+ }
+ *ppvObject = NULL;
+
+ // We have no supported service, just return
+ // MF_E_UNSUPPORTED_SERVICE for all calls.
+
+ return MF_E_UNSUPPORTED_SERVICE;
+}
+
+// IKsControl methods
+_Use_decl_annotations_
+IFACEMETHODIMP
+SimpleMediaSource::KsProperty(
+ _In_reads_bytes_(ulPropertyLength) PKSPROPERTY pProperty,
+ _In_ ULONG ulPropertyLength,
+ _Inout_updates_to_(ulDataLength, *pBytesReturned) LPVOID pPropertyData,
+ _In_ ULONG ulDataLength,
+ _Out_ ULONG* pBytesReturned
+ )
+{
+ // ERROR_SET_NOT_FOUND is the standard error code returned
+ // by the AV Stream driver framework when a miniport
+ // driver does not register a handler for a KS operation.
+ // We want to mimic the driver behavior here if we don't
+ // support controls.
+ return HRESULT_FROM_WIN32(ERROR_SET_NOT_FOUND);
+}
+
+_Use_decl_annotations_
+IFACEMETHODIMP SimpleMediaSource::KsMethod(
+ _In_reads_bytes_(ulMethodLength) PKSMETHOD pMethod,
+ _In_ ULONG ulMethodLength,
+ _Inout_updates_to_(ulDataLength, *pBytesReturned) LPVOID pMethodData,
+ _In_ ULONG ulDataLength,
+ _Out_ ULONG* pBytesReturned
+ )
+{
+ return HRESULT_FROM_WIN32(ERROR_SET_NOT_FOUND);
+}
+
+_Use_decl_annotations_
+IFACEMETHODIMP SimpleMediaSource::KsEvent(
+ _In_reads_bytes_opt_(ulEventLength) PKSEVENT pEvent,
+ _In_ ULONG ulEventLength,
+ _Inout_updates_to_(ulDataLength, *pBytesReturned) LPVOID pEventData,
+ _In_ ULONG ulDataLength,
+ _Out_opt_ ULONG* pBytesReturned
+ )
+{
+ return HRESULT_FROM_WIN32(ERROR_SET_NOT_FOUND);
+}
+
+/// Internal methods.
+HRESULT
+SimpleMediaSource::_CheckShutdownRequiresLock(
+ )
+{
+ if (_sourceState == SourceState::Shutdown)
+ {
+ return MF_E_SHUTDOWN;
+ }
+
+ if (_spEventQueue == nullptr || _stream == nullptr)
+ {
+ return E_UNEXPECTED;
+ }
+
+ return S_OK;
+}
+
+HRESULT
+SimpleMediaSource::_ValidatePresentationDescriptor(
+ _In_ IMFPresentationDescriptor *pPD
+ )
+{
+ HRESULT hr = S_OK;
+ DWORD cStreams = 0;
+ bool anySelected = false;
+
+ if (pPD == nullptr)
+ {
+ return E_INVALIDARG;
+ }
+
+ // The caller's PD must have the same number of streams as ours.
+ RETURN_IF_FAILED (pPD->GetStreamDescriptorCount(&cStreams));
+ if (SUCCEEDED(hr) && (cStreams != NUM_STREAMS))
+ {
+ return E_INVALIDARG;
+ }
+
+ // The caller must select at least one stream.
+ for (UINT32 i = 0; i < cStreams; ++i)
+ {
+ ComPtr<IMFStreamDescriptor> spSD;
+ BOOL fSelected = FALSE;
+ DWORD dwId = 0;
+
+ RETURN_IF_FAILED (pPD->GetStreamDescriptorByIndex(i, &fSelected, &spSD));
+
+ anySelected |= !!fSelected;
+
+ RETURN_IF_FAILED (spSD->GetStreamIdentifier(&dwId));
+ if (dwId >= NUM_STREAMS)
+ {
+ return E_INVALIDARG;
+ }
+ }
+
+ if (!anySelected)
+ {
+ return E_INVALIDARG;
+ }
+
+ return hr;
+}
+
diff --git a/general/SimpleMediaSource/MediaSource/SimpleMediaSource.h b/general/SimpleMediaSource/MediaSource/SimpleMediaSource.h
new file mode 100644
index 00000000..019926c8
--- /dev/null
+++ b/general/SimpleMediaSource/MediaSource/SimpleMediaSource.h
@@ -0,0 +1,81 @@
+#pragma once
+
+// Represents a simple media source that only has one stream and outputs a static image
+
+#include "stdafx.h"
+
+class SimpleMediaStream;
+
+class __declspec(uuid("{9812588D-5CE9-4E4C-ABC1-049138D10DCE}"))
+SimpleMediaSource : public RuntimeClass<
+ RuntimeClassFlags<WinRtClassicComMix>,
+ IMFMediaEventGenerator,
+ IMFMediaSource,
+ IMFMediaSourceEx,
+ IMFGetService,
+ IKsControl>
+{
+
+ enum class SourceState
+ {
+ Invalid, Stopped, Started, Shutdown
+ };
+
+public:
+ // IMFMediaEventGenerator
+ IFACEMETHOD(BeginGetEvent)(_In_ IMFAsyncCallback *pCallback, _In_ IUnknown *punkState);
+ IFACEMETHOD(EndGetEvent)(_In_ IMFAsyncResult *pResult, _Out_ IMFMediaEvent **ppEvent);
+ IFACEMETHOD(GetEvent)(DWORD dwFlags, _Out_ IMFMediaEvent **ppEvent);
+ IFACEMETHOD(QueueEvent)(MediaEventType met, REFGUID guidExtendedType, HRESULT hrStatus, _In_ const PROPVARIANT *pvValue);
+
+ // IMFMediaSource
+ IFACEMETHOD(CreatePresentationDescriptor)(_Out_ IMFPresentationDescriptor **ppPresentationDescriptor);
+ IFACEMETHOD(GetCharacteristics)(_Out_ DWORD *pdwCharacteristics);
+ IFACEMETHOD(Pause)();
+ IFACEMETHOD(Shutdown)();
+ IFACEMETHOD(Start)(_In_ IMFPresentationDescriptor *pPresentationDescriptor, _In_ const GUID *pguidTimeFormat, _In_ const PROPVARIANT *pvarStartPosition);
+ IFACEMETHOD(Stop)();
+
+ // IMFMediaSourceEx
+ IFACEMETHOD(GetSourceAttributes)(_COM_Outptr_ IMFAttributes **ppAttributes);
+ IFACEMETHOD(GetStreamAttributes)(DWORD dwStreamIdentifier, _COM_Outptr_ IMFAttributes **ppAttributes);
+ IFACEMETHOD(SetD3DManager)(_In_opt_ IUnknown *pManager);
+
+ // IMFGetService
+ IFACEMETHOD(GetService)(_In_ REFGUID guidService, _In_ REFIID riid, _Out_ LPVOID *ppvObject);
+
+ // IKsControl
+ IFACEMETHOD(KsProperty)(_In_reads_bytes_(ulPropertyLength) PKSPROPERTY pProperty,
+ _In_ ULONG ulPropertyLength,
+ _Inout_updates_to_(ulDataLength, *pBytesReturned) LPVOID pPropertyData,
+ _In_ ULONG ulDataLength,
+ _Out_ ULONG* pBytesReturned);
+ IFACEMETHOD(KsMethod)(_In_reads_bytes_(ulMethodLength) PKSMETHOD pMethod,
+ _In_ ULONG ulMethodLength,
+ _Inout_updates_to_(ulDataLength, *pBytesReturned) LPVOID pMethodData,
+ _In_ ULONG ulDataLength,
+ _Out_ ULONG* pBytesReturned);
+ IFACEMETHOD(KsEvent)(_In_reads_bytes_opt_(ulEventLength) PKSEVENT pEvent,
+ _In_ ULONG ulEventLength,
+ _Inout_updates_to_(ulDataLength, *pBytesReturned) LPVOID pEventData,
+ _In_ ULONG ulDataLength,
+ _Out_opt_ ULONG* pBytesReturned);
+public:
+ HRESULT RuntimeClassInitialize();
+
+private:
+ HRESULT _CheckShutdownRequiresLock();
+ HRESULT _ValidatePresentationDescriptor(_In_ IMFPresentationDescriptor *pPresentationDescriptor);
+
+ CriticalSection _critSec;
+ SourceState _sourceState{ SourceState::Invalid };
+ ComPtr<IMFMediaEventQueue> _spEventQueue;
+ ComPtr<IMFPresentationDescriptor> _spPresentationDescriptor;
+ ComPtr<IMFAttributes> _spAttributes;
+
+ bool _wasStreamPreviouslySelected; // maybe makes more sense as a property of the stream
+ const DWORD NUM_STREAMS = 1;
+ ComPtr<SimpleMediaStream> _stream;
+};
+
+CoCreatableClass(SimpleMediaSource);
diff --git a/general/SimpleMediaSource/MediaSource/SimpleMediaStream.cpp b/general/SimpleMediaSource/MediaSource/SimpleMediaStream.cpp
new file mode 100644
index 00000000..7685b12e
--- /dev/null
+++ b/general/SimpleMediaSource/MediaSource/SimpleMediaStream.cpp
@@ -0,0 +1,391 @@
+#include "stdafx.h"
+
+#define NUM_IMAGE_ROWS 240
+#define NUM_IMAGE_COLS 320
+#define BYTES_PER_PIXEL 4
+#define IMAGE_BUFFER_SIZE_BYTES (NUM_IMAGE_ROWS * NUM_IMAGE_COLS * BYTES_PER_PIXEL)
+#define IMAGE_ROW_SIZE_BYTES (NUM_IMAGE_COLS * BYTES_PER_PIXEL)
+
+HRESULT
+SimpleMediaStream::RuntimeClassInitialize(
+ _In_ SimpleMediaSource *pSource
+ )
+{
+ HRESULT hr = S_OK;
+ ComPtr<IMFMediaTypeHandler> spTypeHandler;
+ ComPtr<IMFAttributes> attrs;
+
+ if (nullptr == pSource)
+ {
+ return E_INVALIDARG;
+ }
+ RETURN_IF_FAILED (pSource->QueryInterface(IID_PPV_ARGS(&_parent)));
+
+ // Initialize media type and set the video output media type.
+ RETURN_IF_FAILED (MFCreateMediaType(&_spMediaType));
+ _spMediaType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video);
+ _spMediaType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_RGB32);
+ _spMediaType->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive);
+ _spMediaType->SetUINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE);
+ MFSetAttributeSize(_spMediaType.Get(), MF_MT_FRAME_SIZE, NUM_IMAGE_COLS, NUM_IMAGE_ROWS);
+ MFSetAttributeRatio(_spMediaType.Get(), MF_MT_FRAME_RATE, 30, 1);
+ MFSetAttributeRatio(_spMediaType.Get(), MF_MT_PIXEL_ASPECT_RATIO, 1, 1);
+
+ RETURN_IF_FAILED (MFCreateAttributes(&_spAttributes, 10));
+ RETURN_IF_FAILED (this->_SetStreamAttributes(_spAttributes.Get()));
+ RETURN_IF_FAILED (MFCreateEventQueue(&_spEventQueue));
+
+ // Initialize stream descriptors
+ RETURN_IF_FAILED (MFCreateStreamDescriptor(0, 1, _spMediaType.GetAddressOf(), &_spStreamDesc));
+
+ RETURN_IF_FAILED (_spStreamDesc->GetMediaTypeHandler(&spTypeHandler));
+ RETURN_IF_FAILED (spTypeHandler->SetCurrentMediaType(_spMediaType.Get()));
+ RETURN_IF_FAILED (this->_SetStreamDescriptorAttributes(_spStreamDesc.Get()));
+
+ return hr;
+}
+
+// IMFMediaEventGenerator
+IFACEMETHODIMP
+SimpleMediaStream::BeginGetEvent(
+ _In_ IMFAsyncCallback *pCallback,
+ _In_ IUnknown *punkState
+ )
+{
+ HRESULT hr = S_OK;
+ auto lock = _critSec.Lock();
+
+ RETURN_IF_FAILED (_CheckShutdownRequiresLock());
+ RETURN_IF_FAILED (_spEventQueue->BeginGetEvent(pCallback, punkState));
+
+ return hr;
+}
+
+IFACEMETHODIMP
+SimpleMediaStream::EndGetEvent(
+ _In_ IMFAsyncResult *pResult,
+ _COM_Outptr_ IMFMediaEvent **ppEvent
+ )
+{
+ HRESULT hr = S_OK;
+ auto lock = _critSec.Lock();
+
+ RETURN_IF_FAILED (_CheckShutdownRequiresLock());
+ RETURN_IF_FAILED (_spEventQueue->EndGetEvent(pResult, ppEvent));
+
+ return hr;
+}
+
+IFACEMETHODIMP
+SimpleMediaStream::GetEvent(
+ DWORD dwFlags,
+ _COM_Outptr_ IMFMediaEvent **ppEvent
+ )
+{
+ // NOTE:
+ // GetEvent can block indefinitely, so we don't hold the lock.
+ // This requires some juggling with the event queue pointer.
+
+ HRESULT hr = S_OK;
+
+ ComPtr<IMFMediaEventQueue> spQueue;
+
+ {
+ auto lock = _critSec.Lock();
+
+ RETURN_IF_FAILED (_CheckShutdownRequiresLock());
+ spQueue = _spEventQueue;
+ }
+
+ // Now get the event.
+ RETURN_IF_FAILED (_spEventQueue->GetEvent(dwFlags, ppEvent));
+
+ return hr;
+}
+
+IFACEMETHODIMP
+SimpleMediaStream::QueueEvent(
+ MediaEventType eventType,
+ REFGUID guidExtendedType,
+ HRESULT hrStatus,
+ _In_opt_ PROPVARIANT const *pvValue
+ )
+{
+ HRESULT hr = S_OK;
+ auto lock = _critSec.Lock();
+
+ RETURN_IF_FAILED (_CheckShutdownRequiresLock());
+ RETURN_IF_FAILED (_spEventQueue->QueueEventParamVar(eventType, guidExtendedType, hrStatus, pvValue));
+
+ return hr;
+}
+
+// IMFMediaStream
+IFACEMETHODIMP
+SimpleMediaStream::GetMediaSource(
+ _COM_Outptr_ IMFMediaSource **ppMediaSource
+ )
+{
+ HRESULT hr = S_OK;
+ auto lock = _critSec.Lock();
+
+ if (ppMediaSource == nullptr)
+ {
+ return E_POINTER;
+ }
+ *ppMediaSource = nullptr;
+
+ RETURN_IF_FAILED (_CheckShutdownRequiresLock());
+
+ *ppMediaSource = _parent.Get();
+ (*ppMediaSource)->AddRef();
+
+ return hr;
+}
+
+IFACEMETHODIMP
+SimpleMediaStream::GetStreamDescriptor(
+ _COM_Outptr_ IMFStreamDescriptor **ppStreamDescriptor
+ )
+{
+ HRESULT hr = S_OK;
+ auto lock = _critSec.Lock();
+
+ if (ppStreamDescriptor == nullptr)
+ {
+ return E_POINTER;
+ }
+ *ppStreamDescriptor = nullptr;
+
+ RETURN_IF_FAILED (_CheckShutdownRequiresLock());
+
+ if (_spStreamDesc != nullptr)
+ {
+ *ppStreamDescriptor = _spStreamDesc.Get();
+ (*ppStreamDescriptor)->AddRef();
+ }
+ else
+ {
+ return E_UNEXPECTED;
+ }
+
+ return hr;
+}
+
+/*
+ Writes to a buffer representing a 2D image.
+ Writes a different constant to each line based on row number and current time.
+
+ Assumes top down image, no negative stride and pBuf points to the begnning of the buffer of length len.
+
+ Param:
+ pBuf - pointer to beginning of buffer
+ pitch - line length in bytes
+ len - length of buffer in bytes
+*/
+HRESULT
+WriteSampleData(
+ _Inout_updates_bytes_(len) BYTE *pBuf,
+ _In_ LONG pitch,
+ _In_ DWORD len
+ )
+{
+ if (pBuf == nullptr)
+ {
+ return E_INVALIDARG;
+ }
+
+ const int NUM_ROWS = len / abs(pitch);
+
+ LONGLONG curSysTimeInS = MFGetSystemTime() / (MFTIME)10000000;
+ int offset = curSysTimeInS % NUM_ROWS;
+
+ for (int r = 0; r < NUM_ROWS; r++)
+ {
+ int grayColor = r + offset;
+ memset(pBuf + (pitch * r), (BYTE)(grayColor % NUM_ROWS), pitch);
+ }
+
+ return S_OK;
+}
+
+IFACEMETHODIMP
+SimpleMediaStream::RequestSample(
+ _In_ IUnknown *pToken
+ )
+{
+ HRESULT hr = S_OK;
+ auto lock = _critSec.Lock();
+ ComPtr<IMFSample> sample;
+ ComPtr<IMFMediaBuffer> outputBuffer;
+ LONG pitch = IMAGE_ROW_SIZE_BYTES;
+ BYTE *bufferStart = nullptr; // not used
+ DWORD bufferLength = 0;
+ BYTE *pbuf = nullptr;
+ ComPtr<IMF2DBuffer2> buffer2D;
+
+ RETURN_IF_FAILED (_CheckShutdownRequiresLock());
+ RETURN_IF_FAILED (MFCreateSample(&sample));
+ RETURN_IF_FAILED (MFCreate2DMediaBuffer(NUM_IMAGE_COLS,
+ NUM_IMAGE_ROWS,
+ D3DFMT_X8R8G8B8,
+ false,
+ &outputBuffer));
+ RETURN_IF_FAILED (outputBuffer.As(&buffer2D));
+ RETURN_IF_FAILED (buffer2D->Lock2DSize(MF2DBuffer_LockFlags_Write,
+ &pbuf,
+ &pitch,
+ &bufferStart,
+ &bufferLength));
+ RETURN_IF_FAILED (WriteSampleData(pbuf, pitch, bufferLength));
+ RETURN_IF_FAILED (buffer2D->Unlock2D());
+ RETURN_IF_FAILED (sample->AddBuffer(outputBuffer.Get()));
+ RETURN_IF_FAILED (sample->SetSampleTime(MFGetSystemTime()));
+ RETURN_IF_FAILED (sample->SetSampleDuration(333333));
+ if (pToken != nullptr)
+ {
+ RETURN_IF_FAILED (sample->SetUnknown(MFSampleExtension_Token, pToken));
+ }
+ RETURN_IF_FAILED (_spEventQueue->QueueEventParamUnk(MEMediaSample,
+ GUID_NULL,
+ S_OK,
+ sample.Get()));
+
+ return hr;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+// IMFMediaStream2
+IFACEMETHODIMP
+SimpleMediaStream::SetStreamState(
+ MF_STREAM_STATE state
+ )
+{
+ HRESULT hr = S_OK;
+ auto lock = _critSec.Lock();
+ bool runningState = false;
+
+ RETURN_IF_FAILED (_CheckShutdownRequiresLock());
+
+ switch (state)
+ {
+ case MF_STREAM_STATE_PAUSED:
+ goto done; // because not supported
+ case MF_STREAM_STATE_RUNNING:
+ runningState = true;
+ break;
+ case MF_STREAM_STATE_STOPPED:
+ runningState = false;
+ break;
+ default:
+ hr = MF_E_INVALID_STATE_TRANSITION;
+ break;
+ }
+
+ _isSelected = runningState;
+
+done:
+ return hr;
+}
+
+IFACEMETHODIMP
+SimpleMediaStream::GetStreamState(
+ _Out_ MF_STREAM_STATE *pState
+ )
+{
+ HRESULT hr = S_OK;
+ auto lock = _critSec.Lock();
+ BOOLEAN pauseState = false;
+
+ RETURN_IF_FAILED (_CheckShutdownRequiresLock());
+
+ if (SUCCEEDED(hr))
+ {
+ *pState = (_isSelected ? MF_STREAM_STATE_RUNNING : MF_STREAM_STATE_STOPPED);
+ }
+
+ return hr;
+}
+
+HRESULT
+SimpleMediaStream::Shutdown(
+ )
+{
+ HRESULT hr = S_OK;
+ auto lock = _critSec.Lock();
+
+ _isShutdown = true;
+ _parent.Reset();
+
+ if (_spEventQueue != nullptr)
+ {
+ hr = _spEventQueue->Shutdown();
+ _spEventQueue.Reset();
+ }
+
+ _spAttributes.Reset();
+ _spMediaType.Reset();
+ _spStreamDesc.Reset();
+
+ _isSelected = false;
+
+ return hr;
+}
+
+HRESULT
+SimpleMediaStream::_CheckShutdownRequiresLock(
+ )
+{
+ if (_isShutdown)
+ {
+ return MF_E_SHUTDOWN;
+ }
+
+ if (_spEventQueue == nullptr)
+ {
+ return E_UNEXPECTED;
+
+ }
+ return S_OK;
+}
+
+HRESULT
+SimpleMediaStream::_SetStreamAttributes(
+ _In_ IMFAttributes *pAttributeStore
+ )
+{
+ HRESULT hr = S_OK;
+
+ if (nullptr == pAttributeStore)
+ {
+ return E_INVALIDARG;
+ }
+
+ RETURN_IF_FAILED (pAttributeStore->SetGUID(MF_DEVICESTREAM_STREAM_CATEGORY, PINNAME_VIDEO_CAPTURE));
+ RETURN_IF_FAILED (pAttributeStore->SetUINT32(MF_DEVICESTREAM_STREAM_ID, STREAMINDEX));
+ RETURN_IF_FAILED (pAttributeStore->SetUINT32(MF_DEVICESTREAM_FRAMESERVER_SHARED, 1));
+ RETURN_IF_FAILED (pAttributeStore->SetUINT32(MF_DEVICESTREAM_ATTRIBUTE_FRAMESOURCE_TYPES, _MFFrameSourceTypes::MFFrameSourceTypes_Color));
+
+ return hr;
+}
+
+HRESULT
+SimpleMediaStream::_SetStreamDescriptorAttributes(
+ _In_ IMFAttributes *pAttributeStore
+ )
+{
+ HRESULT hr = S_OK;
+
+ if (nullptr == pAttributeStore)
+ {
+ return E_INVALIDARG;
+ }
+
+ RETURN_IF_FAILED (pAttributeStore->SetGUID(MF_DEVICESTREAM_STREAM_CATEGORY, PINNAME_VIDEO_CAPTURE));
+ RETURN_IF_FAILED (pAttributeStore->SetUINT32(MF_DEVICESTREAM_STREAM_ID, STREAMINDEX));
+ RETURN_IF_FAILED (pAttributeStore->SetUINT32(MF_DEVICESTREAM_FRAMESERVER_SHARED, 1));
+ RETURN_IF_FAILED (pAttributeStore->SetUINT32(MF_DEVICESTREAM_ATTRIBUTE_FRAMESOURCE_TYPES, _MFFrameSourceTypes::MFFrameSourceTypes_Color));
+
+ return hr;
+}
+
diff --git a/general/SimpleMediaSource/MediaSource/SimpleMediaStream.h b/general/SimpleMediaSource/MediaSource/SimpleMediaStream.h
new file mode 100644
index 00000000..56351f47
--- /dev/null
+++ b/general/SimpleMediaSource/MediaSource/SimpleMediaStream.h
@@ -0,0 +1,54 @@
+#pragma once
+
+#include "stdafx.h"
+
+class SimpleMediaSource;
+
+class SimpleMediaStream : public RuntimeClass<
+ RuntimeClassFlags<ClassicCom>,
+ IMFMediaEventGenerator,
+ IMFMediaStream,
+ IMFMediaStream2>
+{
+ friend class SimpleMediaSource;
+
+public:
+ // IMFMediaEventGenerator
+ IFACEMETHOD(BeginGetEvent)(IMFAsyncCallback *pCallback, IUnknown *punkState);
+ IFACEMETHOD(EndGetEvent)(IMFAsyncResult *pResult, IMFMediaEvent **ppEvent);
+ IFACEMETHOD(GetEvent)(DWORD dwFlags, IMFMediaEvent **ppEvent);
+ IFACEMETHOD(QueueEvent)(MediaEventType met, REFGUID guidExtendedType, HRESULT hrStatus, const PROPVARIANT *pvValue);
+
+ // IMFMediaStream
+ IFACEMETHOD(GetMediaSource)(IMFMediaSource **ppMediaSource);
+ IFACEMETHOD(GetStreamDescriptor)(IMFStreamDescriptor **ppStreamDescriptor);
+ IFACEMETHOD(RequestSample)(IUnknown *pToken);
+
+ // IMFMediaStream2
+ IFACEMETHOD(SetStreamState)(MF_STREAM_STATE state);
+ IFACEMETHOD(GetStreamState)(_Out_ MF_STREAM_STATE *pState);
+
+ // Non-interface methods.
+ HRESULT RuntimeClassInitialize(_In_ SimpleMediaSource* pSource);
+ HRESULT Shutdown();
+
+
+protected:
+ HRESULT _CheckShutdownRequiresLock();
+ HRESULT _SetStreamAttributes(IMFAttributes* pAttributeStore);
+ HRESULT _SetStreamDescriptorAttributes(IMFAttributes* pAttributeStore);
+
+
+ CriticalSection _critSec;
+
+ ComPtr<IMFMediaSource> _parent;
+ ComPtr<IMFMediaEventQueue> _spEventQueue;
+ ComPtr<IMFAttributes> _spAttributes;
+ ComPtr<IMFMediaType> _spMediaType;
+ ComPtr<IMFStreamDescriptor> _spStreamDesc;
+ bool _isShutdown = false;
+ bool _isSelected = false;
+
+ const DWORD STREAMINDEX = 0; // since there is only one stream
+};
+
diff --git a/general/SimpleMediaSource/MediaSource/dllMain.cpp b/general/SimpleMediaSource/MediaSource/dllMain.cpp
new file mode 100644
index 00000000..aed44eb0
--- /dev/null
+++ b/general/SimpleMediaSource/MediaSource/dllMain.cpp
@@ -0,0 +1,35 @@
+/// <copyright file="dllmain.cpp" company="Microsoft">
+/// Copyright (c) Microsoft Corporation. All rights reserved.
+/// </copyright>
+// dllmain.cpp : Defines the entry point for the DLL application.
+#include "stdafx.h"
+
+#include <wrl\module.h>
+
+#if !defined(__WRL_CLASSIC_COM__)
+STDAPI DllGetActivationFactory(_In_ HSTRING activatibleClassId, _COM_Outptr_ IActivationFactory** factory)
+{
+ return Module<InProc>::GetModule().GetActivationFactory(activatibleClassId, factory);
+}
+#endif
+
+#if !defined(__WRL_WINRT_STRICT__)
+STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, _COM_Outptr_ void** ppv)
+{
+ return Module<InProc>::GetModule().GetClassObject(rclsid, riid, ppv);
+}
+#endif
+
+STDAPI DllCanUnloadNow()
+{
+ return Module<InProc>::GetModule().Terminate() ? S_OK : S_FALSE;
+}
+
+STDAPI_(BOOL) DllMain(_In_opt_ HINSTANCE hinst, DWORD reason, _In_opt_ void*)
+{
+ if (reason == DLL_PROCESS_ATTACH)
+ {
+ DisableThreadLibraryCalls(hinst);
+ }
+ return TRUE;
+}
diff --git a/general/SimpleMediaSource/MediaSource/module.def b/general/SimpleMediaSource/MediaSource/module.def
new file mode 100644
index 00000000..ddeb3eac
--- /dev/null
+++ b/general/SimpleMediaSource/MediaSource/module.def
@@ -0,0 +1,6 @@
+LIBRARY
+
+EXPORTS
+ DllGetActivationFactory PRIVATE
+ DllGetClassObject PRIVATE
+ DllCanUnloadNow PRIVATE
diff --git a/general/SimpleMediaSource/MediaSource/stdafx.cpp b/general/SimpleMediaSource/MediaSource/stdafx.cpp
new file mode 100644
index 00000000..dc97a45b
--- /dev/null
+++ b/general/SimpleMediaSource/MediaSource/stdafx.cpp
@@ -0,0 +1,11 @@
+/// <copyright file="stdafx.cpp" company="Microsoft">
+/// Copyright (c) Microsoft Corporation. All rights reserved.
+/// </copyright>
+// stdafx.cpp : source file that includes just the standard includes
+// KinectMFMediaSource.pch will be the pre-compiled header
+// stdafx.obj will contain the pre-compiled type information
+
+#include "stdafx.h"
+
+// TODO: reference any additional headers you need in STDAFX.H
+// and not in this file
diff --git a/general/SimpleMediaSource/MediaSource/stdafx.h b/general/SimpleMediaSource/MediaSource/stdafx.h
new file mode 100644
index 00000000..73bec0b4
--- /dev/null
+++ b/general/SimpleMediaSource/MediaSource/stdafx.h
@@ -0,0 +1,76 @@
+// stdafx.h : include file for standard system include files,
+// or project specific include files that are used frequently, but
+// are changed infrequently
+//
+
+#pragma once
+
+// Windows Header Files:
+#include <windows.h>
+#include <propvarutil.h>
+//#include <mfstd.h> // Must be included before <initguid.h>, or else DirectDraw GUIDs will be defined twice. See the comment in <uuids.h>.
+#include <ole2.h>
+#include <initguid.h>
+#include <ks.h>
+#include <ksmedia.h>
+#include <mfapi.h>
+#include <mferror.h>
+#include <mfidl.h>
+#include <mfreadwrite.h>
+#include <nserror.h>
+#include <winmeta.h>
+#include <wrl.h>
+#include <d3d9types.h>
+
+using namespace Microsoft::WRL;
+using namespace Microsoft::WRL::Wrappers;
+
+#if !defined(_IKsControl_)
+#define _IKsControl_
+interface DECLSPEC_UUID("28F54685-06FD-11D2-B27A-00A0C9223196") IKsControl;
+#undef INTERFACE
+#define INTERFACE IKsControl
+DECLARE_INTERFACE_(IKsControl, IUnknown)
+{
+ STDMETHOD(KsProperty)(
+ THIS_
+ IN PKSPROPERTY Property,
+ IN ULONG PropertyLength,
+ IN OUT LPVOID PropertyData,
+ IN ULONG DataLength,
+ OUT ULONG* BytesReturned
+ ) PURE;
+ STDMETHOD(KsMethod)(
+ THIS_
+ IN PKSMETHOD Method,
+ IN ULONG MethodLength,
+ IN OUT LPVOID MethodData,
+ IN ULONG DataLength,
+ OUT ULONG* BytesReturned
+ ) PURE;
+ STDMETHOD(KsEvent)(
+ THIS_
+ IN PKSEVENT Event OPTIONAL,
+ IN ULONG EventLength,
+ IN OUT LPVOID EventData,
+ IN ULONG DataLength,
+ OUT ULONG* BytesReturned
+ ) PURE;
+};
+#endif // _IKsControl_
+
+#include "SimpleMediaStream.h"
+#include "SimpleMediaSource.h"
+
+
+// Basic macros to handle HRESULT checks.
+// Recommend adding implementation specific logging within the failure case.
+#ifndef RETURN_IF_FAILED
+#define RETURN_IF_FAILED( val ) \
+ hr = (val); \
+ if ( FAILED( hr ) ) \
+ { \
+ return hr; \
+ }
+#endif
+
diff --git a/general/SimpleMediaSource/README.md b/general/SimpleMediaSource/README.md
new file mode 100644
index 00000000..ca8e85da
--- /dev/null
+++ b/general/SimpleMediaSource/README.md
@@ -0,0 +1,33 @@
+<!---
+ name: SimpleMediaSource Sample
+ platform: UMDF2
+ language: cpp
+ category: general
+ description: Demonstrates how to write a custom media source and driver package.
+ samplefwlink:
+--->
+
+SimpleMediaSource Sample
+========================
+This sample demonstrates how to create a custom media source and driver package that can be installed as a Camera and produce frames.
+
+This sample has accompanying documentation here: https://docs.microsoft.com/en-us/windows-hardware/drivers/stream/frame-server-custom-media-source
+
+
+Contents
+--------
+MediaSource - COM DLL project for the custom media source
+SimpleMediaSourceDriver - UMDF driver install package
+
+Installation
+------------------
+
+1. Build the solution.
+
+2. Navigate to the output folder, e.g. Windows-driver-samples\general\SimpleMediaSource\x64\Release, and the driver package will be in a directory also called SimpleMediaSourceDriver. Check that the folder has `SimpleMediaSource.dll`, `simplemediasourcedriver.cat`, `SimpleMediaSourceDriver.dll`, and `SimpleMediaSourceDriver.inf`.
+
+3. Deploy the driver package with
+
+`devcon dp_add SimpleMediaSourceDriver.inf`
+
+4. In Device Manager, locate **SimpleMediaSource Capture Source**, under the Camera category. Open the Microsoft Camera App, switch cameras if necessary until the camera is streaming from the SimpleMediaSource. You should see a scrolling black and white gradient. \ No newline at end of file
diff --git a/general/SimpleMediaSource/SimpleMediaSource.sln b/general/SimpleMediaSource/SimpleMediaSource.sln
new file mode 100644
index 00000000..c93b8c42
--- /dev/null
+++ b/general/SimpleMediaSource/SimpleMediaSource.sln
@@ -0,0 +1,67 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.27703.2026
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SimpleMediaSource", "MediaSource\MediaSource.vcxproj", "{43AD9BF7-E765-48FE-9826-71A8F2CB12DD}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SimpleMediaSourceDriver", "SimpleMediaSourceDriver\SimpleMediaSourceDriver.vcxproj", "{3098C6BF-E96E-4793-A70E-FB09B741580A}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|ARM = Debug|ARM
+ Debug|ARM64 = Debug|ARM64
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|ARM = Release|ARM
+ Release|ARM64 = Release|ARM64
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {43AD9BF7-E765-48FE-9826-71A8F2CB12DD}.Debug|ARM.ActiveCfg = Debug|Win32
+ {43AD9BF7-E765-48FE-9826-71A8F2CB12DD}.Debug|ARM64.ActiveCfg = Debug|Win32
+ {43AD9BF7-E765-48FE-9826-71A8F2CB12DD}.Debug|x64.ActiveCfg = Debug|x64
+ {43AD9BF7-E765-48FE-9826-71A8F2CB12DD}.Debug|x64.Build.0 = Debug|x64
+ {43AD9BF7-E765-48FE-9826-71A8F2CB12DD}.Debug|x86.ActiveCfg = Debug|Win32
+ {43AD9BF7-E765-48FE-9826-71A8F2CB12DD}.Debug|x86.Build.0 = Debug|Win32
+ {43AD9BF7-E765-48FE-9826-71A8F2CB12DD}.Release|ARM.ActiveCfg = Release|ARM
+ {43AD9BF7-E765-48FE-9826-71A8F2CB12DD}.Release|ARM.Build.0 = Release|ARM
+ {43AD9BF7-E765-48FE-9826-71A8F2CB12DD}.Release|ARM64.ActiveCfg = Release|ARM64
+ {43AD9BF7-E765-48FE-9826-71A8F2CB12DD}.Release|ARM64.Build.0 = Release|ARM64
+ {43AD9BF7-E765-48FE-9826-71A8F2CB12DD}.Release|x64.ActiveCfg = Release|x64
+ {43AD9BF7-E765-48FE-9826-71A8F2CB12DD}.Release|x64.Build.0 = Release|x64
+ {43AD9BF7-E765-48FE-9826-71A8F2CB12DD}.Release|x86.ActiveCfg = Release|Win32
+ {43AD9BF7-E765-48FE-9826-71A8F2CB12DD}.Release|x86.Build.0 = Release|Win32
+ {3098C6BF-E96E-4793-A70E-FB09B741580A}.Debug|ARM.ActiveCfg = Debug|ARM
+ {3098C6BF-E96E-4793-A70E-FB09B741580A}.Debug|ARM.Build.0 = Debug|ARM
+ {3098C6BF-E96E-4793-A70E-FB09B741580A}.Debug|ARM.Deploy.0 = Debug|ARM
+ {3098C6BF-E96E-4793-A70E-FB09B741580A}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {3098C6BF-E96E-4793-A70E-FB09B741580A}.Debug|ARM64.Build.0 = Debug|ARM64
+ {3098C6BF-E96E-4793-A70E-FB09B741580A}.Debug|ARM64.Deploy.0 = Debug|ARM64
+ {3098C6BF-E96E-4793-A70E-FB09B741580A}.Debug|x64.ActiveCfg = Debug|x64
+ {3098C6BF-E96E-4793-A70E-FB09B741580A}.Debug|x64.Build.0 = Debug|x64
+ {3098C6BF-E96E-4793-A70E-FB09B741580A}.Debug|x64.Deploy.0 = Debug|x64
+ {3098C6BF-E96E-4793-A70E-FB09B741580A}.Debug|x86.ActiveCfg = Debug|Win32
+ {3098C6BF-E96E-4793-A70E-FB09B741580A}.Debug|x86.Build.0 = Debug|Win32
+ {3098C6BF-E96E-4793-A70E-FB09B741580A}.Debug|x86.Deploy.0 = Debug|Win32
+ {3098C6BF-E96E-4793-A70E-FB09B741580A}.Release|ARM.ActiveCfg = Release|ARM
+ {3098C6BF-E96E-4793-A70E-FB09B741580A}.Release|ARM.Build.0 = Release|ARM
+ {3098C6BF-E96E-4793-A70E-FB09B741580A}.Release|ARM.Deploy.0 = Release|ARM
+ {3098C6BF-E96E-4793-A70E-FB09B741580A}.Release|ARM64.ActiveCfg = Release|ARM64
+ {3098C6BF-E96E-4793-A70E-FB09B741580A}.Release|ARM64.Build.0 = Release|ARM64
+ {3098C6BF-E96E-4793-A70E-FB09B741580A}.Release|ARM64.Deploy.0 = Release|ARM64
+ {3098C6BF-E96E-4793-A70E-FB09B741580A}.Release|x64.ActiveCfg = Release|x64
+ {3098C6BF-E96E-4793-A70E-FB09B741580A}.Release|x64.Build.0 = Release|x64
+ {3098C6BF-E96E-4793-A70E-FB09B741580A}.Release|x64.Deploy.0 = Release|x64
+ {3098C6BF-E96E-4793-A70E-FB09B741580A}.Release|x86.ActiveCfg = Release|Win32
+ {3098C6BF-E96E-4793-A70E-FB09B741580A}.Release|x86.Build.0 = Release|Win32
+ {3098C6BF-E96E-4793-A70E-FB09B741580A}.Release|x86.Deploy.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {2205BF4A-ACC2-4A73-8C1E-C3D9AF0F8B24}
+ EndGlobalSection
+EndGlobal
diff --git a/general/SimpleMediaSource/SimpleMediaSourceDriver/Device.c b/general/SimpleMediaSource/SimpleMediaSourceDriver/Device.c
new file mode 100644
index 00000000..083cf3c7
--- /dev/null
+++ b/general/SimpleMediaSource/SimpleMediaSourceDriver/Device.c
@@ -0,0 +1,109 @@
+/*++
+
+Module Name:
+
+ device.c - Device handling events for example driver.
+
+Abstract:
+
+ This file contains the device entry points and callbacks.
+
+Environment:
+
+ User-mode Driver Framework 2
+
+--*/
+
+#include "driver.h"
+#include "device.tmh"
+
+GUID CAMERA_CATEGORY = { STATIC_KSCATEGORY_VIDEO_CAMERA };
+GUID CAPTURE_CATEGORY = { STATIC_KSCATEGORY_CAPTURE };
+GUID VIDEO_CATEGORY = { STATIC_KSCATEGORY_VIDEO };
+
+NTSTATUS
+SimpleMediaSourceDriverCreateDevice(
+ _Inout_ PWDFDEVICE_INIT DeviceInit
+ )
+/*++
+
+Routine Description:
+
+ Worker routine called to create a device and its software resources.
+
+Arguments:
+
+ DeviceInit - Pointer to an opaque init structure. Memory for this
+ structure will be freed by the framework when the WdfDeviceCreate
+ succeeds. So don't access the structure after that point.
+
+Return Value:
+
+ NTSTATUS
+
+--*/
+{
+ WDF_OBJECT_ATTRIBUTES deviceAttributes;
+ PDEVICE_CONTEXT deviceContext;
+ WDFDEVICE device;
+ NTSTATUS status;
+ UNICODE_STRING szReference;
+ RtlInitUnicodeString(&szReference, L"CustomCameraSource"); // Needs to match the ReferenceString in INF
+
+ WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&deviceAttributes, DEVICE_CONTEXT);
+
+ status = WdfDeviceCreate(&DeviceInit, &deviceAttributes, &device);
+
+ if (NT_SUCCESS(status)) {
+ //
+ // Get a pointer to the device context structure that we just associated
+ // with the device object. We define this structure in the device.h
+ // header file. DeviceGetContext is an inline function generated by
+ // using the WDF_DECLARE_CONTEXT_TYPE_WITH_NAME macro in device.h.
+ // This function will do the type checking and return the device context.
+ // If you pass a wrong object handle it will return NULL and assert if
+ // run under framework verifier mode.
+ //
+ deviceContext = DeviceGetContext(device);
+
+ //
+ // Initialize the context.
+ //
+ deviceContext->PrivateDeviceData = 0;
+
+ //
+ // Create a device interface so that applications can find and talk
+ // to us.
+ //
+ status = WdfDeviceCreateDeviceInterface(
+ device,
+ &CAMERA_CATEGORY,
+ &szReference // ReferenceString
+ );
+
+ if (NT_SUCCESS(status)) {
+ status = WdfDeviceCreateDeviceInterface(
+ device,
+ &CAPTURE_CATEGORY,
+ &szReference // ReferenceString
+ );
+ }
+
+ if (NT_SUCCESS(status)) {
+ status = WdfDeviceCreateDeviceInterface(
+ device,
+ &VIDEO_CATEGORY,
+ &szReference // ReferenceString
+ );
+ }
+
+ if (NT_SUCCESS(status)) {
+ //
+ // Initialize the I/O Package and any Queues
+ //
+ status = SimpleMediaSourceDriverQueueInitialize(device);
+ }
+ }
+
+ return status;
+}
diff --git a/general/SimpleMediaSource/SimpleMediaSourceDriver/Device.h b/general/SimpleMediaSource/SimpleMediaSourceDriver/Device.h
new file mode 100644
index 00000000..6c2da5e4
--- /dev/null
+++ b/general/SimpleMediaSource/SimpleMediaSourceDriver/Device.h
@@ -0,0 +1,46 @@
+/*++
+
+Module Name:
+
+ device.h
+
+Abstract:
+
+ This file contains the device definitions.
+
+Environment:
+
+ User-mode Driver Framework 2
+
+--*/
+
+#include "public.h"
+
+EXTERN_C_START
+
+//
+// The device context performs the same job as
+// a WDM device extension in the driver frameworks
+//
+typedef struct _DEVICE_CONTEXT
+{
+ ULONG PrivateDeviceData; // just a placeholder
+
+} DEVICE_CONTEXT, *PDEVICE_CONTEXT;
+
+//
+// This macro will generate an inline function called DeviceGetContext
+// which will be used to get a pointer to the device context memory
+// in a type safe manner.
+//
+WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(DEVICE_CONTEXT, DeviceGetContext)
+
+//
+// Function to initialize the device and its callbacks
+//
+NTSTATUS
+SimpleMediaSourceDriverCreateDevice(
+ _Inout_ PWDFDEVICE_INIT DeviceInit
+ );
+
+EXTERN_C_END
diff --git a/general/SimpleMediaSource/SimpleMediaSourceDriver/Driver.c b/general/SimpleMediaSource/SimpleMediaSourceDriver/Driver.c
new file mode 100644
index 00000000..94ee0fa9
--- /dev/null
+++ b/general/SimpleMediaSource/SimpleMediaSourceDriver/Driver.c
@@ -0,0 +1,167 @@
+/*++
+
+Module Name:
+
+ driver.c
+
+Abstract:
+
+ This file contains the driver entry points and callbacks.
+
+Environment:
+
+ User-mode Driver Framework 2
+
+--*/
+
+#include "driver.h"
+#include "driver.tmh"
+
+NTSTATUS
+DriverEntry(
+ _In_ PDRIVER_OBJECT DriverObject,
+ _In_ PUNICODE_STRING RegistryPath
+ )
+/*++
+
+Routine Description:
+ DriverEntry initializes the driver and is the first routine called by the
+ system after the driver is loaded. DriverEntry specifies the other entry
+ points in the function driver, such as EvtDevice and DriverUnload.
+
+Parameters Description:
+
+ DriverObject - represents the instance of the function driver that is loaded
+ into memory. DriverEntry must initialize members of DriverObject before it
+ returns to the caller. DriverObject is allocated by the system before the
+ driver is loaded, and it is released by the system after the system unloads
+ the function driver from memory.
+
+ RegistryPath - represents the driver specific path in the Registry.
+ The function driver can use the path to store driver related data between
+ reboots. The path does not store hardware instance specific data.
+
+Return Value:
+
+ STATUS_SUCCESS if successful,
+ STATUS_UNSUCCESSFUL otherwise.
+
+--*/
+{
+ WDF_DRIVER_CONFIG config;
+ NTSTATUS status;
+ WDF_OBJECT_ATTRIBUTES attributes;
+
+ //
+ // Initialize WPP Tracing
+ //
+#if UMDF_VERSION_MAJOR == 2 && UMDF_VERSION_MINOR == 0
+ WPP_INIT_TRACING(MYDRIVER_TRACING_ID);
+#else
+ WPP_INIT_TRACING( DriverObject, RegistryPath );
+#endif
+
+ TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Entry");
+
+ //
+ // Register a cleanup callback so that we can call WPP_CLEANUP when
+ // the framework driver object is deleted during driver unload.
+ //
+ WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
+ attributes.EvtCleanupCallback = SimpleMediaSourceDriverEvtDriverContextCleanup;
+
+ WDF_DRIVER_CONFIG_INIT(&config,
+ SimpleMediaSourceDriverEvtDeviceAdd
+ );
+
+ status = WdfDriverCreate(DriverObject,
+ RegistryPath,
+ &attributes,
+ &config,
+ WDF_NO_HANDLE
+ );
+
+ if (!NT_SUCCESS(status)) {
+ TraceEvents(TRACE_LEVEL_ERROR, TRACE_DRIVER, "WdfDriverCreate failed %!STATUS!", status);
+#if UMDF_VERSION_MAJOR == 2 && UMDF_VERSION_MINOR == 0
+ WPP_CLEANUP();
+#else
+ WPP_CLEANUP(DriverObject);
+#endif
+ return status;
+ }
+
+ TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Exit");
+
+ return status;
+}
+
+NTSTATUS
+SimpleMediaSourceDriverEvtDeviceAdd(
+ _In_ WDFDRIVER Driver,
+ _Inout_ PWDFDEVICE_INIT DeviceInit
+ )
+/*++
+Routine Description:
+
+ EvtDeviceAdd is called by the framework in response to AddDevice
+ call from the PnP manager. We create and initialize a device object to
+ represent a new instance of the device.
+
+Arguments:
+
+ Driver - Handle to a framework driver object created in DriverEntry
+
+ DeviceInit - Pointer to a framework-allocated WDFDEVICE_INIT structure.
+
+Return Value:
+
+ NTSTATUS
+
+--*/
+{
+ NTSTATUS status;
+
+ UNREFERENCED_PARAMETER(Driver);
+
+ TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Entry");
+
+ status = SimpleMediaSourceDriverCreateDevice(DeviceInit);
+
+ TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Exit");
+
+ return status;
+}
+
+VOID
+SimpleMediaSourceDriverEvtDriverContextCleanup(
+ _In_ WDFOBJECT DriverObject
+ )
+/*++
+Routine Description:
+
+ Free all the resources allocated in DriverEntry.
+
+Arguments:
+
+ DriverObject - handle to a WDF Driver object.
+
+Return Value:
+
+ VOID.
+
+--*/
+{
+ UNREFERENCED_PARAMETER(DriverObject);
+
+ TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Entry");
+
+ //
+ // Stop WPP Tracing
+ //
+#if UMDF_VERSION_MAJOR == 2 && UMDF_VERSION_MINOR == 0
+ WPP_CLEANUP();
+#else
+ WPP_CLEANUP(WdfDriverWdmGetDriverObject((WDFDRIVER)DriverObject));
+#endif
+}
diff --git a/general/SimpleMediaSource/SimpleMediaSourceDriver/Driver.h b/general/SimpleMediaSource/SimpleMediaSourceDriver/Driver.h
new file mode 100644
index 00000000..1e19eec9
--- /dev/null
+++ b/general/SimpleMediaSource/SimpleMediaSourceDriver/Driver.h
@@ -0,0 +1,37 @@
+/*++
+
+Module Name:
+
+ driver.h
+
+Abstract:
+
+ This file contains the driver definitions.
+
+Environment:
+
+ User-mode Driver Framework 2
+
+--*/
+
+#include <windows.h>
+#include <wdf.h>
+#include <initguid.h>
+#include <ks.h>
+#include <ksmedia.h>
+
+#include "device.h"
+#include "queue.h"
+#include "trace.h"
+
+EXTERN_C_START
+
+//
+// WDFDRIVER Events
+//
+
+DRIVER_INITIALIZE DriverEntry;
+EVT_WDF_DRIVER_DEVICE_ADD SimpleMediaSourceDriverEvtDeviceAdd;
+EVT_WDF_OBJECT_CONTEXT_CLEANUP SimpleMediaSourceDriverEvtDriverContextCleanup;
+
+EXTERN_C_END
diff --git a/general/SimpleMediaSource/SimpleMediaSourceDriver/Public.h b/general/SimpleMediaSource/SimpleMediaSourceDriver/Public.h
new file mode 100644
index 00000000..f3d4964b
--- /dev/null
+++ b/general/SimpleMediaSource/SimpleMediaSourceDriver/Public.h
@@ -0,0 +1,24 @@
+/*++
+
+Module Name:
+
+ public.h
+
+Abstract:
+
+ This module contains the common declarations shared by driver
+ and user applications.
+
+Environment:
+
+ driver and application
+
+--*/
+
+//
+// Define an Interface Guid so that apps can find the device and talk to it.
+//
+
+DEFINE_GUID (GUID_DEVINTERFACE_SimpleMediaSourceDriver,
+ 0xb5036295,0xf041,0x4506,0x88,0xdc,0xcb,0x16,0x5c,0x4d,0x67,0x8c);
+// {b5036295-f041-4506-88dc-cb165c4d678c}
diff --git a/general/SimpleMediaSource/SimpleMediaSourceDriver/Queue.c b/general/SimpleMediaSource/SimpleMediaSourceDriver/Queue.c
new file mode 100644
index 00000000..6ea51781
--- /dev/null
+++ b/general/SimpleMediaSource/SimpleMediaSourceDriver/Queue.c
@@ -0,0 +1,193 @@
+/*++
+
+Module Name:
+
+ queue.c
+
+Abstract:
+
+ This file contains the queue entry points and callbacks.
+
+Environment:
+
+ User-mode Driver Framework 2
+
+--*/
+
+#include "driver.h"
+#include "queue.tmh"
+
+NTSTATUS
+SimpleMediaSourceDriverQueueInitialize(
+ _In_ WDFDEVICE Device
+ )
+/*++
+
+Routine Description:
+
+ The I/O dispatch callbacks for the frameworks device object
+ are configured in this function.
+
+ A single default I/O Queue is configured for parallel request
+ processing, and a driver context memory allocation is created
+ to hold our structure QUEUE_CONTEXT.
+
+Arguments:
+
+ Device - Handle to a framework device object.
+
+Return Value:
+
+ VOID
+
+--*/
+{
+ WDFQUEUE queue;
+ NTSTATUS status;
+ WDF_IO_QUEUE_CONFIG queueConfig;
+
+ //
+ // Configure a default queue so that requests that are not
+ // configure-fowarded using WdfDeviceConfigureRequestDispatching to goto
+ // other queues get dispatched here.
+ //
+ WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(
+ &queueConfig,
+ WdfIoQueueDispatchParallel
+ );
+
+ queueConfig.EvtIoDeviceControl = SimpleMediaSourceDriverEvtIoDeviceControl;
+ queueConfig.EvtIoStop = SimpleMediaSourceDriverEvtIoStop;
+
+ status = WdfIoQueueCreate(
+ Device,
+ &queueConfig,
+ WDF_NO_OBJECT_ATTRIBUTES,
+ &queue
+ );
+
+ if(!NT_SUCCESS(status)) {
+ TraceEvents(TRACE_LEVEL_ERROR, TRACE_QUEUE, "WdfIoQueueCreate failed %!STATUS!", status);
+ return status;
+ }
+
+ return status;
+}
+
+VOID
+SimpleMediaSourceDriverEvtIoDeviceControl(
+ _In_ WDFQUEUE Queue,
+ _In_ WDFREQUEST Request,
+ _In_ size_t OutputBufferLength,
+ _In_ size_t InputBufferLength,
+ _In_ ULONG IoControlCode
+ )
+/*++
+
+Routine Description:
+
+ This event is invoked when the framework receives IRP_MJ_DEVICE_CONTROL request.
+
+Arguments:
+
+ Queue - Handle to the framework queue object that is associated with the
+ I/O request.
+
+ Request - Handle to a framework request object.
+
+ OutputBufferLength - Size of the output buffer in bytes
+
+ InputBufferLength - Size of the input buffer in bytes
+
+ IoControlCode - I/O control code.
+
+Return Value:
+
+ VOID
+
+--*/
+{
+ TraceEvents(TRACE_LEVEL_INFORMATION,
+ TRACE_QUEUE,
+ "%!FUNC! Queue 0x%p, Request 0x%p OutputBufferLength %d InputBufferLength %d IoControlCode %d",
+ Queue, Request, (int) OutputBufferLength, (int) InputBufferLength, IoControlCode);
+
+ WdfRequestComplete(Request, STATUS_SUCCESS);
+
+ return;
+}
+
+VOID
+SimpleMediaSourceDriverEvtIoStop(
+ _In_ WDFQUEUE Queue,
+ _In_ WDFREQUEST Request,
+ _In_ ULONG ActionFlags
+)
+/*++
+
+Routine Description:
+
+ This event is invoked for a power-managed queue before the device leaves the working state (D0).
+
+Arguments:
+
+ Queue - Handle to the framework queue object that is associated with the
+ I/O request.
+
+ Request - Handle to a framework request object.
+
+ ActionFlags - A bitwise OR of one or more WDF_REQUEST_STOP_ACTION_FLAGS-typed flags
+ that identify the reason that the callback function is being called
+ and whether the request is cancelable.
+
+Return Value:
+
+ VOID
+
+--*/
+{
+ TraceEvents(TRACE_LEVEL_INFORMATION,
+ TRACE_QUEUE,
+ "%!FUNC! Queue 0x%p, Request 0x%p ActionFlags %d",
+ Queue, Request, ActionFlags);
+
+ //
+ // In most cases, the EvtIoStop callback function completes, cancels, or postpones
+ // further processing of the I/O request.
+ //
+ // Typically, the driver uses the following rules:
+ //
+ // - If the driver owns the I/O request, it calls WdfRequestUnmarkCancelable
+ // (if the request is cancelable) and either calls WdfRequestStopAcknowledge
+ // with a Requeue value of TRUE, or it calls WdfRequestComplete with a
+ // completion status value of STATUS_SUCCESS or STATUS_CANCELLED.
+ //
+ // Before it can call these methods safely, the driver must make sure that
+ // its implementation of EvtIoStop has exclusive access to the request.
+ //
+ // In order to do that, the driver must synchronize access to the request
+ // to prevent other threads from manipulating the request concurrently.
+ // The synchronization method you choose will depend on your driver's design.
+ //
+ // For example, if the request is held in a shared context, the EvtIoStop callback
+ // might acquire an internal driver lock, take the request from the shared context,
+ // and then release the lock. At this point, the EvtIoStop callback owns the request
+ // and can safely complete or requeue the request.
+ //
+ // - If the driver has forwarded the I/O request to an I/O target, it either calls
+ // WdfRequestCancelSentRequest to attempt to cancel the request, or it postpones
+ // further processing of the request and calls WdfRequestStopAcknowledge with
+ // a Requeue value of FALSE.
+ //
+ // A driver might choose to take no action in EvtIoStop for requests that are
+ // guaranteed to complete in a small amount of time.
+ //
+ // In this case, the framework waits until the specified request is complete
+ // before moving the device (or system) to a lower power state or removing the device.
+ // Potentially, this inaction can prevent a system from entering its hibernation state
+ // or another low system power state. In extreme cases, it can cause the system
+ // to crash with bugcheck code 9F.
+ //
+
+ return;
+}
diff --git a/general/SimpleMediaSource/SimpleMediaSourceDriver/Queue.h b/general/SimpleMediaSource/SimpleMediaSourceDriver/Queue.h
new file mode 100644
index 00000000..e0c01283
--- /dev/null
+++ b/general/SimpleMediaSource/SimpleMediaSourceDriver/Queue.h
@@ -0,0 +1,42 @@
+/*++
+
+Module Name:
+
+ queue.h
+
+Abstract:
+
+ This file contains the queue definitions.
+
+Environment:
+
+ User-mode Driver Framework 2
+
+--*/
+
+EXTERN_C_START
+
+//
+// This is the context that can be placed per queue
+// and would contain per queue information.
+//
+typedef struct _QUEUE_CONTEXT {
+
+ ULONG PrivateDeviceData; // just a placeholder
+
+} QUEUE_CONTEXT, *PQUEUE_CONTEXT;
+
+WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(QUEUE_CONTEXT, QueueGetContext)
+
+NTSTATUS
+SimpleMediaSourceDriverQueueInitialize(
+ _In_ WDFDEVICE Device
+ );
+
+//
+// Events from the IoQueue object
+//
+EVT_WDF_IO_QUEUE_IO_DEVICE_CONTROL SimpleMediaSourceDriverEvtIoDeviceControl;
+EVT_WDF_IO_QUEUE_IO_STOP SimpleMediaSourceDriverEvtIoStop;
+
+EXTERN_C_END
diff --git a/general/SimpleMediaSource/SimpleMediaSourceDriver/ReadMe.txt b/general/SimpleMediaSource/SimpleMediaSourceDriver/ReadMe.txt
new file mode 100644
index 00000000..55d9dadd
--- /dev/null
+++ b/general/SimpleMediaSource/SimpleMediaSourceDriver/ReadMe.txt
@@ -0,0 +1,33 @@
+========================================================================
+ SimpleMediaSourceDriver Project Overview
+========================================================================
+
+This file contains a summary of what you will find in each of the files that make up your project.
+
+SimpleMediaSourceDriver.vcxproj
+ This is the main project file for projects generated using an Application Wizard.
+ It contains information about the version of the product that generated the file, and
+ information about the platforms, configurations, and project features selected with the
+ Application Wizard.
+
+SimpleMediaSourceDriver.vcxproj.filters
+ This is the filters file for VC++ projects generated using an Application Wizard.
+ It contains information about the association between the files in your project
+ and the filters. This association is used in the IDE to show grouping of files with
+ similar extensions under a specific node (for e.g. ".cpp" files are associated with the
+ "Source Files" filter).
+
+Public.h
+ Header file to be shared with applications.
+
+Driver.c & Driver.h
+ DriverEntry and WDFDRIVER related functionality and callbacks.
+
+Device.c & Device.h
+ WDFDEVICE related functionality and callbacks.
+
+Queue.c & Queue.h
+ WDFQUEUE related functionality and callbacks.
+
+Trace.h
+ Definitions for WPP tracing.
diff --git a/general/SimpleMediaSource/SimpleMediaSourceDriver/SimpleMediaSourceDriver.inf b/general/SimpleMediaSource/SimpleMediaSourceDriver/SimpleMediaSourceDriver.inf
new file mode 100644
index 00000000..dabb3237
--- /dev/null
+++ b/general/SimpleMediaSource/SimpleMediaSourceDriver/SimpleMediaSourceDriver.inf
Binary files differ
diff --git a/general/SimpleMediaSource/SimpleMediaSourceDriver/SimpleMediaSourceDriver.vcxproj b/general/SimpleMediaSource/SimpleMediaSourceDriver/SimpleMediaSourceDriver.vcxproj
new file mode 100644
index 00000000..38e21ccd
--- /dev/null
+++ b/general/SimpleMediaSource/SimpleMediaSourceDriver/SimpleMediaSourceDriver.vcxproj
@@ -0,0 +1,282 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|ARM">
+ <Configuration>Debug</Configuration>
+ <Platform>ARM</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|ARM">
+ <Configuration>Release</Configuration>
+ <Platform>ARM</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|ARM64">
+ <Configuration>Debug</Configuration>
+ <Platform>ARM64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|ARM64">
+ <Configuration>Release</Configuration>
+ <Platform>ARM64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="ReadMe.txt" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="Device.c" />
+ <ClCompile Include="Driver.c" />
+ <ClCompile Include="Queue.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="Device.h" />
+ <ClInclude Include="Driver.h" />
+ <ClInclude Include="Public.h" />
+ <ClInclude Include="Queue.h" />
+ <ClInclude Include="Trace.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <Inf Include="SimpleMediaSourceDriver.inf" />
+ </ItemGroup>
+ <ItemGroup>
+ <FilesToPackage Include="$(OutDir)\SimpleMediaSource.dll">
+ <PackageRelativeDirectory>
+ </PackageRelativeDirectory>
+ </FilesToPackage>
+ <FilesToPackage Include="$(OutDir)\SimpleMediaSourceDriver.dll">
+ <PackageRelativeDirectory>
+ </PackageRelativeDirectory>
+ </FilesToPackage>
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\MediaSource\MediaSource.vcxproj">
+ <Project>{43ad9bf7-e765-48fe-9826-71a8f2cb12dd}</Project>
+ </ProjectReference>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{3098C6BF-E96E-4793-A70E-FB09B741580A}</ProjectGuid>
+ <TemplateGuid>{32909489-7be5-497b-aafa-db6669d9b44b}</TemplateGuid>
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+ <MinimumVisualStudioVersion>12.0</MinimumVisualStudioVersion>
+ <Configuration>Debug</Configuration>
+ <Platform Condition="'$(Platform)' == ''">Win32</Platform>
+ <RootNamespace>SimpleMediaSourceDriver</RootNamespace>
+ </PropertyGroup>
+ <PropertyGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset>
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ </PropertyGroup>
+ <PropertyGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset>
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ </PropertyGroup>
+ <PropertyGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset>
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ </PropertyGroup>
+ <PropertyGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset>
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ </PropertyGroup>
+ <PropertyGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
+ <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset>
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ </PropertyGroup>
+ <PropertyGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
+ <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset>
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ </PropertyGroup>
+ <PropertyGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
+ <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset>
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ </PropertyGroup>
+ <PropertyGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
+ <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset>
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <UMDF_VERSION_MAJOR>2</UMDF_VERSION_MAJOR>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <UMDF_VERSION_MAJOR>2</UMDF_VERSION_MAJOR>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <UMDF_VERSION_MAJOR>2</UMDF_VERSION_MAJOR>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <UMDF_VERSION_MAJOR>2</UMDF_VERSION_MAJOR>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <UMDF_VERSION_MAJOR>2</UMDF_VERSION_MAJOR>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <UMDF_VERSION_MAJOR>2</UMDF_VERSION_MAJOR>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <UMDF_VERSION_MAJOR>2</UMDF_VERSION_MAJOR>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <UMDF_VERSION_MAJOR>2</UMDF_VERSION_MAJOR>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <DebuggerFlavor>DbgengRemoteDebugger</DebuggerFlavor>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <DebuggerFlavor>DbgengRemoteDebugger</DebuggerFlavor>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <DebuggerFlavor>DbgengRemoteDebugger</DebuggerFlavor>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <DebuggerFlavor>DbgengRemoteDebugger</DebuggerFlavor>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
+ <DebuggerFlavor>DbgengRemoteDebugger</DebuggerFlavor>
+ <EnableInf2cat>false</EnableInf2cat>
+ <Inf2CatWindowsVersionList>
+ </Inf2CatWindowsVersionList>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
+ <DebuggerFlavor>DbgengRemoteDebugger</DebuggerFlavor>
+ <EnableInf2cat>false</EnableInf2cat>
+ <Inf2CatWindowsVersionList>
+ </Inf2CatWindowsVersionList>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
+ <DebuggerFlavor>DbgengRemoteDebugger</DebuggerFlavor>
+ <Inf2CatWindowsVersionList>Server10_$(DDKPlatform)</Inf2CatWindowsVersionList>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
+ <DebuggerFlavor>DbgengRemoteDebugger</DebuggerFlavor>
+ <Inf2CatWindowsVersionList>Server10_$(DDKPlatform)</Inf2CatWindowsVersionList>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <WppEnabled>true</WppEnabled>
+ <WppRecorderEnabled>true</WppRecorderEnabled>
+ <WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">trace.h</WppScanConfigurationData>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\OneCoreUAP.lib</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <WppEnabled>true</WppEnabled>
+ <WppRecorderEnabled>true</WppRecorderEnabled>
+ <WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">trace.h</WppScanConfigurationData>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\OneCoreUAP.lib</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <WppEnabled>true</WppEnabled>
+ <WppRecorderEnabled>true</WppRecorderEnabled>
+ <WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">trace.h</WppScanConfigurationData>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\OneCoreUAP.lib</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <WppEnabled>true</WppEnabled>
+ <WppRecorderEnabled>true</WppRecorderEnabled>
+ <WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">trace.h</WppScanConfigurationData>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\OneCoreUAP.lib</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
+ <ClCompile>
+ <WppEnabled>true</WppEnabled>
+ <WppRecorderEnabled>true</WppRecorderEnabled>
+ <WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">trace.h</WppScanConfigurationData>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\OneCoreUAP.lib</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
+ <ClCompile>
+ <WppEnabled>true</WppEnabled>
+ <WppRecorderEnabled>true</WppRecorderEnabled>
+ <WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">trace.h</WppScanConfigurationData>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\OneCoreUAP.lib</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
+ <ClCompile>
+ <WppEnabled>true</WppEnabled>
+ <WppRecorderEnabled>true</WppRecorderEnabled>
+ <WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">trace.h</WppScanConfigurationData>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\OneCoreUAP.lib</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
+ <ClCompile>
+ <WppEnabled>true</WppEnabled>
+ <WppRecorderEnabled>true</WppRecorderEnabled>
+ <WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">trace.h</WppScanConfigurationData>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\OneCoreUAP.lib</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/general/SimpleMediaSource/SimpleMediaSourceDriver/SimpleMediaSourceDriver.vcxproj.filters b/general/SimpleMediaSource/SimpleMediaSourceDriver/SimpleMediaSourceDriver.vcxproj.filters
new file mode 100644
index 00000000..6f2263ef
--- /dev/null
+++ b/general/SimpleMediaSource/SimpleMediaSourceDriver/SimpleMediaSourceDriver.vcxproj.filters
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
+ </Filter>
+ <Filter Include="Driver Files">
+ <UniqueIdentifier>{8E41214B-6785-4CFE-B992-037D68949A14}</UniqueIdentifier>
+ <Extensions>inf;inv;inx;mof;mc;</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="ReadMe.txt" />
+ </ItemGroup>
+ <ItemGroup>
+ <Inf Include="SimpleMediaSourceDriver.inf">
+ <Filter>Driver Files</Filter>
+ </Inf>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="Device.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="Driver.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="Public.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="Queue.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="Trace.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="Device.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="Driver.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="Queue.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/general/SimpleMediaSource/SimpleMediaSourceDriver/Trace.h b/general/SimpleMediaSource/SimpleMediaSourceDriver/Trace.h
new file mode 100644
index 00000000..0180b817
--- /dev/null
+++ b/general/SimpleMediaSource/SimpleMediaSourceDriver/Trace.h
@@ -0,0 +1,62 @@
+/*++
+
+Module Name:
+
+ Internal.h
+
+Abstract:
+
+ This module contains the local type definitions for the
+ driver.
+
+Environment:
+
+ Windows User-Mode Driver Framework 2
+
+--*/
+
+//
+// Define the tracing flags.
+//
+// Tracing GUID - a9ae54d8-0a84-4b05-b9ae-faff98267b7e
+//
+
+#define WPP_CONTROL_GUIDS \
+ WPP_DEFINE_CONTROL_GUID( \
+ MyDriver1TraceGuid, (a9ae54d8,0a84,4b05,b9ae,faff98267b7e), \
+ \
+ WPP_DEFINE_BIT(MYDRIVER_ALL_INFO) \
+ WPP_DEFINE_BIT(TRACE_DRIVER) \
+ WPP_DEFINE_BIT(TRACE_DEVICE) \
+ WPP_DEFINE_BIT(TRACE_QUEUE) \
+ )
+
+#define WPP_FLAG_LEVEL_LOGGER(flag, level) \
+ WPP_LEVEL_LOGGER(flag)
+
+#define WPP_FLAG_LEVEL_ENABLED(flag, level) \
+ (WPP_LEVEL_ENABLED(flag) && \
+ WPP_CONTROL(WPP_BIT_ ## flag).Level >= level)
+
+#define WPP_LEVEL_FLAGS_LOGGER(lvl,flags) \
+ WPP_LEVEL_LOGGER(flags)
+
+#define WPP_LEVEL_FLAGS_ENABLED(lvl, flags) \
+ (WPP_LEVEL_ENABLED(flags) && WPP_CONTROL(WPP_BIT_ ## flags).Level >= lvl)
+
+//
+// This comment block is scanned by the trace preprocessor to define our
+// Trace function.
+//
+// begin_wpp config
+// FUNC Trace{FLAG=MYDRIVER_ALL_INFO}(LEVEL, MSG, ...);
+// FUNC TraceEvents(LEVEL, FLAGS, MSG, ...);
+// end_wpp
+
+//
+//
+// Driver specific #defines
+//
+#if UMDF_VERSION_MAJOR == 2 && UMDF_VERSION_MINOR == 0
+ #define MYDRIVER_TRACING_ID L"Microsoft\\UMDF2.0\\SimpleMediaSourceDriver V1.0"
+#endif \ No newline at end of file
diff --git a/general/SimpleMediaSource/general-SimpleMediaSource.yaml b/general/SimpleMediaSource/general-SimpleMediaSource.yaml
new file mode 100644
index 00000000..88e2d839
--- /dev/null
+++ b/general/SimpleMediaSource/general-SimpleMediaSource.yaml
@@ -0,0 +1,10 @@
+### YamlMime:Sample
+sample:
+- name: SimpleMediaSource Sample
+ description: Demonstrates how to write a custom media source and driver package.
+ generateZip: true
+ author: windows-driver-samples
+ languages:
+ - cpp
+ technologies:
+ - windows
diff --git a/general/ioctl/kmdf/exe/testapp.c b/general/ioctl/kmdf/exe/testapp.c
index 6626f00c..6586401e 100644
--- a/general/ioctl/kmdf/exe/testapp.c
+++ b/general/ioctl/kmdf/exe/testapp.c
@@ -412,7 +412,7 @@ DoIoctls(
//
- // Performing METHOD_NIETHER
+ // Performing METHOD_NEITHER
//
printf("\nCalling DeviceIoControl METHOD_NEITHER\n");
diff --git a/general/ioctl/wdm/exe/testapp.c b/general/ioctl/wdm/exe/testapp.c
index 507fc4f0..7652b5a2 100644
--- a/general/ioctl/wdm/exe/testapp.c
+++ b/general/ioctl/wdm/exe/testapp.c
@@ -156,7 +156,7 @@ main(
printf(" OutBuffer (%d): %s\n", bytesReturned, OutputBuffer);
//
- // Performing METHOD_NIETHER
+ // Performing METHOD_NEITHER
//
printf("\nCalling DeviceIoControl METHOD_NEITHER\n");
diff --git a/general/pcidrv/kmdf/trace.h b/general/pcidrv/kmdf/trace.h
index 2c041319..e4f7afd5 100644
--- a/general/pcidrv/kmdf/trace.h
+++ b/general/pcidrv/kmdf/trace.h
@@ -86,14 +86,14 @@ TraceEvents (
// specified.
//
// Name of the logger is PciDrv and the guid is
-// {BC6C9364-FC67-42c5-ACF7-ABED3B12ECC6}
-// (0xbc6c9364, 0xfc67, 0x42c5, 0xac, 0xf7, 0xab, 0xed, 0x3b, 0x12, 0xec, 0xc6);
+// {B4011D96-E169-49FF-A7D7-05FA9DBF6082}
+// (0xb4011d96, 0xe169, 0x49ff, 0xa7, 0xd7, 0x05, 0xfa, 0x9d, 0xbf, 0x60, 0x82);
//
#define WPP_CHECK_FOR_NULL_STRING //to prevent exceptions due to NULL strings
#define WPP_CONTROL_GUIDS \
- WPP_DEFINE_CONTROL_GUID(PciDrvTraceGuid,(bc6c9364,fc67,42c5,acf7,abed3b12ecc6), \
+ WPP_DEFINE_CONTROL_GUID(PciDrvTraceGuid,(b4011d96,e169,49ff,a7d7,05fa9dbf6082), \
WPP_DEFINE_BIT(DBG_INIT) /* bit 0 = 0x00000001 */ \
WPP_DEFINE_BIT(DBG_PNP) /* bit 1 = 0x00000002 */ \
WPP_DEFINE_BIT(DBG_POWER) /* bit 2 = 0x00000004 */ \
diff --git a/gnss/GnssUmdfSampleDriver.wprp b/gnss/GnssUmdfSampleDriver.wprp
new file mode 100644
index 00000000..7bb78452
--- /dev/null
+++ b/gnss/GnssUmdfSampleDriver.wprp
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8" standalone='yes'?>
+
+<WindowsPerformanceRecorder Version="1.0" Author="Location Dev" Team="Location Dev" Comments="ETW profiles" Company="Microsoft Corporation" Copyright="Microsoft Corporation">
+ <Profiles>
+ <!-- Event Collectors -->
+ <EventCollector Id="EventCollector_SampleGNSS" Name="SampleGNSS Category Event Collector" Private="false" ProcessPrivate="false" Secure="false" Realtime="false">
+ <BufferSize Value="128"/>
+ <Buffers Value="40"/>
+ <MaximumFileSize Value="5" FileMode="Circular"/>
+ <FileMax Value="3"/>
+ </EventCollector>
+
+ <!-- Umdf Gnss Sample Driver providers -->
+ <EventProvider Id="GnssUmdfTraceGuid" Name="CEB3BF01-80E4-4DC7-B3BF-F6B5279EB8C4" Level="5">
+ <Keywords>
+ <Keyword Value="0xFFFFFFFF"/> <!-- Provider is enabled with these keywords throughout the tracing session. -->
+ </Keywords>
+ </EventProvider>
+
+ <!-- Profiles -->
+ <Profile Id="SampleGNSSCategory.Verbose.File" LoggingMode="File" Name="SampleGNSSCategory" DetailLevel="Verbose" Description="Sample GNSS category profile">
+ <Collectors>
+ <EventCollectorId Value="EventCollector_SampleGNSS">
+ <EventProviders>
+ <EventProviderId Value="GnssUmdfTraceGuid"/>
+ </EventProviders>
+ </EventCollectorId>
+ </Collectors>
+ </Profile>
+ </Profiles>
+
+</WindowsPerformanceRecorder>
diff --git a/gnss/ReadMe.md b/gnss/ReadMe.md
new file mode 100644
index 00000000..deaca7a6
--- /dev/null
+++ b/gnss/ReadMe.md
@@ -0,0 +1,97 @@
+<!---
+ name: GPS/GNSS UMDF Sample Driver (UMDF Version 2)
+ platform: UMDF2
+ language: cpp
+ category: GPS/GNSS
+ description: Provides base sample driver that IHVs and partners can use to extend to build their custom Windows GPS/GNSS drivers
+ samplefwlink: https://go.microsoft.com/fwlink/?linkid=2045369
+--->
+
+
+GNSS UMDF Sample Driver (UMDF Version 2)
+==============================================================================
+
+# Overview
+
+## What is covered?
+
+* This is a sample that adheres to GNSS driver design for Windows 10 with this MSDN link: https://docs.microsoft.com/en-us/windows-hardware/drivers/gnss/gnss-driver-design-guide-for-windows-10
+* Serves as base sample driver that IHVs and partners can use as a template and guidance to extend to build their custom Windows GNSS drivers.
+* Follows the WDF guidelines and best practices around PnP device arrival/removal, power management and driver installation/uninstallation.
+* Supports the GNSS DDI mandatory requirements.
+* This driver successfully passes HLK tests and WDF tests provided by Visual studio.
+
+## What is not covered?
+
+* This sample currently doesn't support Geofence, SUPL, and AGNSS, as this is not mandatory GNSS DDI functionality.
+* SUPL and AGNSS are mandatory only if required by mobile operator, and the sample does not support them currently.
+* Not a production driver.
+
+## What Partner needs to do?
+
+* Customer can install WDK and run Location HLK tests to validate their driver. All test cases should be either pass or skip without failure.
+* Partner owns the following:
+ - Installing the driver.
+ - Adding certificate and driver signing.
+ - Updating manufacturer name driver version etc. (the code has comments to update).
+* The GNSS sample code has "FIX ME" comments. Partner should update them accordingly.
+
+
+# Design
+
+* The sample demonstrates a very basic software only driver that meets the minimum requirements from the GNSS DDI.
+* The sample currently always returns a fake hardcoded location. Driver developers can extend this to fetch fake positions from a file or inject through a custom IOCTL or instead implement getting real positions from GNSS hardware.
+* Driver developer can extend this to pull the fake positions from a file or through custom IOCTLs if needed.
+
+
+# Trace Logging
+
+* The sample code provides Trace logging WPRP file.
+* To capture trace log, copy GnssUmdfSampleDriver.wprp in the solution folder into the device under test. On command line (MyLog.etl is an example file name below):
+ ```sh
+ wpr -start GnssUmdfSampleDriver.wprp -filemode
+ <Reproduce the issue>
+ wpr -stop MyLog.etl
+ ```
+* Inspect MyLog.etl with trace file analyzer. Note that corresponding PDB file is needed to decode the logging information.
+
+
+# Test Plan
+
+Customer should validate their driver after customizing it.
+
+#### Test method 1
+
+* This tests WDF fundamental functionality (PnP etc.), rather than Location-specific features.
+* Run Visual studio built-in run-time test for WDF.
+* General information: https://docs.microsoft.com/en-us/windows-hardware/drivers/develop/testing-a-driver-at-runtime
+* Expected result / Pass criteria: Pass rate 100%
+
+#### Test method 2
+
+* This tests Location-specific functionality (Getting fix etc.).
+* Run HLK tests with existing and standard GNSS driver tests.
+* General information: https://docs.microsoft.com/en-us/windows-hardware/test/hlk/windows-hardware-lab-kit
+* Run "TE.exe GNSSDriverTest.dll".
+* Expected result / Pass criteria: Pass rate 100%
+* Note that this sample does not support AGNSS, SUPL and Geofencing currently. Based on the capability of driver, HLK skips them automatically.
+
+#### Test method 3
+
+* This tests from Windows Geolocation API (https://docs.microsoft.com/en-us/windows/desktop/locationapi/windows-location-api-portal) layer on real apps.
+* Get current location by clicking on "Show my location" from the In-box Windows Maps app.
+* Run tracking scenario from Geolocation Sample app (Download from https://github.com/Microsoft/Windows-universal-samples/tree/master/Samples/Geolocation).
+* Get current location by clicking on "Start" from GPS Satellite app in Windows Store.
+
+
+# Resources
+
+* GNSS DDI reference
+ - https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/content/gnssdriver/index
+* Getting started with Windows drivers
+ - https://docs.microsoft.com/en-us/windows-hardware/drivers/gettingstarted/
+* Windows Driver Kit documentation
+ - https://docs.microsoft.com/en-us/windows-hardware/drivers/
+* NMEA format documentation
+ - http://navspark.mybigcommerce.com/content/NMEA_Format_v0.1.pdf
+ \ No newline at end of file
diff --git a/gnss/gnss.yaml b/gnss/gnss.yaml
new file mode 100644
index 00000000..e53b2045
--- /dev/null
+++ b/gnss/gnss.yaml
@@ -0,0 +1,10 @@
+### YamlMime:Sample
+sample:
+- name: GPS/GNSS UMDF V2 Device Driver Sample
+ description: Demonstrates how to write a device driver that IHVs and partners can use to extend to build their custom drivers
+ generateZip: true
+ author: windows-driver-samples
+ languages:
+ - cpp
+ technologies:
+ - windows
diff --git a/gnss/gnssUmdf.sln b/gnss/gnssUmdf.sln
new file mode 100644
index 00000000..46b81091
--- /dev/null
+++ b/gnss/gnssUmdf.sln
@@ -0,0 +1,59 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.27703.2042
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gnssUmdf", "gnssUmdf\gnssUmdf.vcxproj", "{AC97DD9E-781F-4FCE-8AC7-ADE57C633A13}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{79D3FD2A-EEAE-4C86-90AF-39B7FFD6D27D}"
+ ProjectSection(SolutionItems) = preProject
+ gnss.yaml = gnss.yaml
+ GnssUmdfSampleDriver.wprp = GnssUmdfSampleDriver.wprp
+ ReadMe.md = ReadMe.md
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|ARM = Debug|ARM
+ Debug|ARM64 = Debug|ARM64
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|ARM = Release|ARM
+ Release|ARM64 = Release|ARM64
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {AC97DD9E-781F-4FCE-8AC7-ADE57C633A13}.Debug|ARM.ActiveCfg = Debug|ARM
+ {AC97DD9E-781F-4FCE-8AC7-ADE57C633A13}.Debug|ARM.Build.0 = Debug|ARM
+ {AC97DD9E-781F-4FCE-8AC7-ADE57C633A13}.Debug|ARM.Deploy.0 = Debug|ARM
+ {AC97DD9E-781F-4FCE-8AC7-ADE57C633A13}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {AC97DD9E-781F-4FCE-8AC7-ADE57C633A13}.Debug|ARM64.Build.0 = Debug|ARM64
+ {AC97DD9E-781F-4FCE-8AC7-ADE57C633A13}.Debug|ARM64.Deploy.0 = Debug|ARM64
+ {AC97DD9E-781F-4FCE-8AC7-ADE57C633A13}.Debug|x64.ActiveCfg = Debug|x64
+ {AC97DD9E-781F-4FCE-8AC7-ADE57C633A13}.Debug|x64.Build.0 = Debug|x64
+ {AC97DD9E-781F-4FCE-8AC7-ADE57C633A13}.Debug|x64.Deploy.0 = Debug|x64
+ {AC97DD9E-781F-4FCE-8AC7-ADE57C633A13}.Debug|x86.ActiveCfg = Debug|Win32
+ {AC97DD9E-781F-4FCE-8AC7-ADE57C633A13}.Debug|x86.Build.0 = Debug|Win32
+ {AC97DD9E-781F-4FCE-8AC7-ADE57C633A13}.Debug|x86.Deploy.0 = Debug|Win32
+ {AC97DD9E-781F-4FCE-8AC7-ADE57C633A13}.Release|ARM.ActiveCfg = Release|ARM
+ {AC97DD9E-781F-4FCE-8AC7-ADE57C633A13}.Release|ARM.Build.0 = Release|ARM
+ {AC97DD9E-781F-4FCE-8AC7-ADE57C633A13}.Release|ARM.Deploy.0 = Release|ARM
+ {AC97DD9E-781F-4FCE-8AC7-ADE57C633A13}.Release|ARM64.ActiveCfg = Release|ARM64
+ {AC97DD9E-781F-4FCE-8AC7-ADE57C633A13}.Release|ARM64.Build.0 = Release|ARM64
+ {AC97DD9E-781F-4FCE-8AC7-ADE57C633A13}.Release|ARM64.Deploy.0 = Release|ARM64
+ {AC97DD9E-781F-4FCE-8AC7-ADE57C633A13}.Release|x64.ActiveCfg = Release|x64
+ {AC97DD9E-781F-4FCE-8AC7-ADE57C633A13}.Release|x64.Build.0 = Release|x64
+ {AC97DD9E-781F-4FCE-8AC7-ADE57C633A13}.Release|x64.Deploy.0 = Release|x64
+ {AC97DD9E-781F-4FCE-8AC7-ADE57C633A13}.Release|x86.ActiveCfg = Release|Win32
+ {AC97DD9E-781F-4FCE-8AC7-ADE57C633A13}.Release|x86.Build.0 = Release|Win32
+ {AC97DD9E-781F-4FCE-8AC7-ADE57C633A13}.Release|x86.Deploy.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {C0D84930-F293-4CFC-ACFB-2A71C4CADDFD}
+ SolutionGuid = {E7531486-DB0B-43B1-AC4A-AFDE26BDED47}
+ EndGlobalSection
+EndGlobal
diff --git a/gnss/gnssUmdf/Defaults.h b/gnss/gnssUmdf/Defaults.h
new file mode 100644
index 00000000..bf78238e
--- /dev/null
+++ b/gnss/gnssUmdf/Defaults.h
@@ -0,0 +1,59 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+Module Name:
+
+ defaults.h
+
+Abstract:
+
+ This module contains the defaults used within the Umdf Gnss Driver.
+
+Environment:
+
+ driver and application
+
+--*/
+
+#pragma once
+
+#define GNSS_DRIVER_DDK_VERSION GNSS_DRIVER_VERSION_4
+#define INVALID_SESSION_ID (0xFFFFFFFF)
+#define DEFAULT_FIX_INTERVAL_SECONDS 1
+
+static const double c_MaximumLatitude = 90.0;
+static const double c_MinimumLatitude = -90.0;
+static const double c_MaximumLongitude = 180.0;
+static const double c_MinimumLongitude = -180.0;
+
+#define INIT_POD_GNSS_STRUCT(pName) \
+ memset((pName), 0, sizeof(*(pName))); \
+ (pName)->Size = sizeof(*(pName)); \
+ (pName)->Version = GNSS_DRIVER_DDK_VERSION
+
+const GNSS_FIXDATA g_DefaultGnssFixData =
+{
+ sizeof(GNSS_FIXDATA),
+ GNSS_DRIVER_DDK_VERSION,
+ INVALID_SESSION_ID,
+ { 0xCD700000, 0x1D48908 }, // an example date/time, Dec/01/2018
+ TRUE,
+ STATUS_SUCCESS,
+ GNSS_FIXDETAIL_BASIC | GNSS_FIXDETAIL_ACCURACY,
+ {
+ sizeof(GNSS_FIXDATA_BASIC),
+ GNSS_DRIVER_DDK_VERSION,
+ // Location: Mount Rainier National Park
+ 46.852273,
+ -121.757468,
+ 0.0,
+ 0.0,
+ 0.0
+ },
+ {
+ sizeof(GNSS_FIXDATA_ACCURACY),
+ GNSS_DRIVER_DDK_VERSION,
+ 10 // Meters accuracy
+ }
+};
diff --git a/gnss/gnssUmdf/Device.cpp b/gnss/gnssUmdf/Device.cpp
new file mode 100644
index 00000000..905b3e94
--- /dev/null
+++ b/gnss/gnssUmdf/Device.cpp
@@ -0,0 +1,163 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+Module Name:
+
+ device.c
+
+Abstract:
+
+ This file contains the device entry points and callbacks.
+
+Environment:
+
+ Windows User-Mode Driver Framework
+
+--*/
+
+#include "precomp.h"
+#include "Trace.h"
+#include "Defaults.h"
+#include "Device.h"
+#include "FixSession.h"
+#include "FixHandler.h"
+#include "Queue.h"
+
+#include "Device.tmh"
+
+
+CDevice::CDevice(
+ _In_ WDFDEVICE Device
+) :
+ _Device(Device),
+ _Queue(nullptr)
+{
+}
+
+CDevice::~CDevice()
+{
+ if (_Queue != nullptr)
+ {
+ _Queue = nullptr;
+ }
+}
+
+CQueue*
+CDevice::GetQueue()
+{
+ return _Queue;
+}
+
+NTSTATUS
+CDevice::OnDeviceAdd(
+ _In_ WDFDRIVER /*Driver*/,
+ _Inout_ PWDFDEVICE_INIT DeviceInit
+)
+{
+ NTSTATUS status = STATUS_SUCCESS;
+
+ WDF_PNPPOWER_EVENT_CALLBACKS powerCallbacks;
+ WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&powerCallbacks);
+
+ powerCallbacks.EvtDeviceD0Entry = CDevice::OnD0Entry;
+ powerCallbacks.EvtDeviceD0Exit = CDevice::OnD0Exit;
+
+ WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &powerCallbacks);
+
+ WDF_OBJECT_ATTRIBUTES deviceAttributes;
+ WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&deviceAttributes,
+ CDevice);
+
+ deviceAttributes.EvtCleanupCallback = CDevice::OnCleanup;
+ deviceAttributes.SynchronizationScope = WdfSynchronizationScopeNone;
+ deviceAttributes.ExecutionLevel = WdfExecutionLevelPassive;
+
+ WDFDEVICE device;
+ status = WdfDeviceCreate(&DeviceInit, &deviceAttributes, &device);
+
+ if (!NT_SUCCESS(status))
+ {
+ TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DEVICE, "WdfDeviceCreate failed with Status %!STATUS!", status);
+ goto Exit;
+ }
+
+ // Construct device object on the preallocated buffer using placement 'new'
+ CDevice* pDevice = new (GetDeviceObject(device)) CDevice(device);
+
+ status = pDevice->Initialize();
+
+Exit:
+ return status;
+}
+
+NTSTATUS
+CDevice::Initialize()
+{
+ NTSTATUS status = STATUS_SUCCESS;
+
+ status = CQueue::AddQueueToDevice(_Device, &_Queue);
+
+ // Register GNSS Device interface. Note that this sample is not publishing a symbolic link.
+ status = WdfDeviceCreateDeviceInterface(_Device,
+ (LPGUID)&GUID_DEVINTERFACE_GNSS,
+ nullptr);
+
+ if (!NT_SUCCESS(status))
+ {
+ TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DEVICE, "WdfDeviceCreateDeviceInterface failed with %!STATUS!", status);
+ goto Exit;
+ }
+
+Exit:
+ return status;
+}
+
+void
+CDevice::OnCleanup(
+ _In_ WDFOBJECT Object
+)
+{
+ CDevice *pDevice = GetDeviceObject(Object);
+
+ // Device object constructed using placement 'new' so explicitly invoke destructor
+ pDevice->~CDevice();
+}
+
+NTSTATUS
+CDevice::OnD0Entry(
+ _In_ WDFDEVICE /*Device*/,
+ _In_ WDF_POWER_DEVICE_STATE /*PreviousState*/
+)
+{
+ NTSTATUS status;
+
+ //
+ // FIX ME:
+ // Add further functionality.
+ // Refer to power consideration from MSDN document: https://docs.microsoft.com/en-us/windows-hardware/drivers/gnss/gnss-driver-requirements
+ //
+
+ status = STATUS_SUCCESS;
+
+ return status;
+}
+
+NTSTATUS
+CDevice::OnD0Exit(
+ _In_ WDFDEVICE /*Device*/,
+ _In_ WDF_POWER_DEVICE_STATE /*TargetState*/
+)
+{
+ NTSTATUS status;
+
+ //
+ // FIX ME:
+ // Add further functionality.
+ // Refer to power consideration from MSDN document: https://docs.microsoft.com/en-us/windows-hardware/drivers/gnss/gnss-driver-requirements
+ //
+
+ status = STATUS_SUCCESS;
+
+ return status;
+}
diff --git a/gnss/gnssUmdf/Device.h b/gnss/gnssUmdf/Device.h
new file mode 100644
index 00000000..35072bfc
--- /dev/null
+++ b/gnss/gnssUmdf/Device.h
@@ -0,0 +1,44 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+Module Name:
+
+ device.h
+
+Abstract:
+
+ This file contains the device definitions.
+
+Environment:
+
+ Windows User-Mode Driver Framework
+
+--*/
+
+#pragma once
+
+class CQueue;
+
+class CDevice
+{
+public:
+ // This is called from PnP manager in response to AddDevice call
+ static EVT_WDF_DRIVER_DEVICE_ADD OnDeviceAdd;
+
+private:
+ CDevice(_In_ WDFDEVICE Device);
+ ~CDevice();
+
+ static EVT_WDF_OBJECT_CONTEXT_CLEANUP OnCleanup;
+ static EVT_WDF_DEVICE_D0_ENTRY OnD0Entry;
+ static EVT_WDF_DEVICE_D0_EXIT OnD0Exit;
+
+ NTSTATUS Initialize();
+ CQueue* GetQueue();
+
+ WDFDEVICE _Device = nullptr;
+ CQueue* _Queue = nullptr;
+};
+
+WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(CDevice, GetDeviceObject);
diff --git a/gnss/gnssUmdf/Driver.cpp b/gnss/gnssUmdf/Driver.cpp
new file mode 100644
index 00000000..af443b12
--- /dev/null
+++ b/gnss/gnssUmdf/Driver.cpp
@@ -0,0 +1,107 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+Module Name:
+
+ driver.cpp
+
+Abstract:
+
+ This file contains the driver entry points and callbacks.
+
+Environment:
+
+ Windows User-Mode Driver Framework
+
+--*/
+
+#include "precomp.h"
+#include "Trace.h"
+#include "Defaults.h"
+#include "Driver.h"
+#include "Device.h"
+
+#include "Driver.tmh"
+
+
+extern "C"
+NTSTATUS
+DriverEntry(
+ _In_ PDRIVER_OBJECT DriverObject,
+ _In_ PUNICODE_STRING RegistryPath
+)
+{
+ NTSTATUS status = STATUS_SUCCESS;
+
+ // Initialize WPP Tracing
+ WPP_INIT_TRACING(DriverObject, RegistryPath);
+
+ TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Entry");
+
+ // Register a cleanup callback so that we can call WPP_CLEANUP when
+ // the framework driver object is deleted during driver unload.
+ WDF_OBJECT_ATTRIBUTES attributes;
+ WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
+ attributes.EvtCleanupCallback = GnssUmdfEvtDriverContextCleanup;
+
+ WDF_DRIVER_CONFIG config;
+ WDF_DRIVER_CONFIG_INIT(&config,
+ CDevice::OnDeviceAdd);
+
+ config.EvtDriverUnload = OnDriverUnload;
+
+ status = WdfDriverCreate(DriverObject,
+ RegistryPath,
+ &attributes,
+ &config,
+ WDF_NO_HANDLE);
+
+ if (!NT_SUCCESS(status))
+ {
+ TraceEvents(TRACE_LEVEL_ERROR, TRACE_DRIVER, "WdfDriverCreate failed %!STATUS!", status);
+
+ WPP_CLEANUP(DriverObject);
+
+ return status;
+ }
+
+ TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Exit");
+
+ return status;
+}
+
+void
+GnssUmdfEvtDriverContextCleanup(
+ _In_ WDFOBJECT DriverObject
+)
+/*++
+Routine Description:
+
+ Free all the resources allocated in DriverEntry.
+
+Arguments:
+
+ DriverObject - handle to a WDF Driver object.
+
+Return Value:
+
+ void.
+
+--*/
+{
+ UNREFERENCED_PARAMETER(DriverObject);
+
+ TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Entry");
+
+ // Stop WPP Tracing
+ WPP_CLEANUP(WdfDriverWdmGetDriverObject((WDFDRIVER)DriverObject));
+}
+
+void
+OnDriverUnload(
+ _In_ WDFDRIVER /* Driver */
+)
+{
+ WPP_CLEANUP(Driver);
+}
diff --git a/gnss/gnssUmdf/Driver.h b/gnss/gnssUmdf/Driver.h
new file mode 100644
index 00000000..5de6d35e
--- /dev/null
+++ b/gnss/gnssUmdf/Driver.h
@@ -0,0 +1,22 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+Module Name:
+
+ driver.h
+
+Abstract:
+
+ This file contains the driver definitions.
+
+Environment:
+
+ Windows User-Mode Driver Framework
+
+--*/
+
+#pragma once
+
+EVT_WDF_DRIVER_UNLOAD OnDriverUnload;
+EVT_WDF_OBJECT_CONTEXT_CLEANUP GnssUmdfEvtDriverContextCleanup;
diff --git a/gnss/gnssUmdf/FixHandler.cpp b/gnss/gnssUmdf/FixHandler.cpp
new file mode 100644
index 00000000..52b09a82
--- /dev/null
+++ b/gnss/gnssUmdf/FixHandler.cpp
@@ -0,0 +1,228 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+Module Name:
+
+ fixhandler.cpp
+
+Abstract:
+
+ This file contains the Fix handler and contains logic to provide position.
+
+Environment:
+
+ Windows User-Mode Driver Framework
+
+--*/
+
+#include "precomp.h"
+#include "Trace.h"
+#include "Defaults.h"
+#include "FixSession.h"
+#include "FixHandler.h"
+
+#include "FixHandler.tmh"
+
+
+NTSTATUS
+CFixHandler::Initialize(
+ _In_ WDFQUEUE Queue
+)
+{
+ NTSTATUS status = STATUS_SUCCESS;
+
+ status = _SingleShotSession.Initialize(Queue);
+
+ return status;
+}
+
+NTSTATUS
+CFixHandler::StartFix(
+ _In_ WDFREQUEST Request,
+ _In_ BOOL LocationServiceEnabled
+)
+{
+ NTSTATUS status = STATUS_SUCCESS;
+ PGNSS_FIXSESSION_PARAM fixSessionParameters = nullptr;
+
+ // For privacy reasons, the location stack notifies the driver when user toggles the location device controls.
+ // When set to off, the driver must not entertain any new location sessions.
+ if (!LocationServiceEnabled)
+ {
+ status = STATUS_UNSUCCESSFUL;
+ TraceEvents(TRACE_LEVEL_ERROR, TRACE_FIX, "Location master switch is off, we do not start a fix session");
+ goto Exit;
+ }
+
+ status = WdfRequestRetrieveInputBuffer(Request, sizeof(GNSS_FIXSESSION_PARAM), (void**)&fixSessionParameters, nullptr);
+ if (!NT_SUCCESS(status))
+ {
+ TraceEvents(TRACE_LEVEL_ERROR, TRACE_FIX, "WdfRequestRetrieveInputBuffer failed with %!STATUS!", status);
+ goto Exit;
+ }
+
+ //
+ // FIX ME:
+ // This sample currently supports only single shot session fix.
+ // If you support another session type, e.g., distance tracking, update the logic below accordingly.
+ //
+ if (fixSessionParameters->SessionType != GNSS_FixSession_SingleShot)
+ {
+ status = STATUS_UNSUCCESSFUL;
+ TraceEvents(TRACE_LEVEL_ERROR, TRACE_FIX, "Session type is not GNSS_FixSession_SingleShot");
+ goto Exit;
+ }
+
+ _CurrentSinglsShotSessionId = fixSessionParameters->FixSessionID;
+
+ status = _SingleShotSession.StartAcquiringFix(fixSessionParameters);
+ if (!NT_SUCCESS(status))
+ {
+ TraceEvents(TRACE_LEVEL_ERROR, TRACE_FIX, "StartFix failed with %!STATUS!", status);
+ goto Exit;
+ }
+
+Exit:
+ return status;
+}
+
+NTSTATUS
+CFixHandler::StopFix(
+ _In_ WDFREQUEST Request
+)
+{
+ NTSTATUS status = STATUS_SUCCESS;
+ PGNSS_STOPFIXSESSION_PARAM stopFixSessionParam = nullptr;
+
+ status = WdfRequestRetrieveInputBuffer(Request, sizeof(GNSS_STOPFIXSESSION_PARAM), (void**)&stopFixSessionParam, nullptr);
+ if (!NT_SUCCESS(status))
+ {
+ TraceEvents(TRACE_LEVEL_ERROR, TRACE_FIX, "WdfRequestRetrieveInputBuffer failed with %!STATUS!", status);
+ goto Exit;
+ }
+
+ // Send the session parameters to the right session based on the ID
+ if (stopFixSessionParam->FixSessionID != _CurrentSinglsShotSessionId)
+ {
+ status = STATUS_UNSUCCESSFUL;
+ TraceEvents(TRACE_LEVEL_ERROR, TRACE_FIX, "Session type is not GNSS_FixSession_SingleShot");
+ goto Exit;
+ }
+
+ _CurrentSinglsShotSessionId = INVALID_SESSION_ID;
+
+ status = _SingleShotSession.StopAcquiringFix(stopFixSessionParam);
+ if (!NT_SUCCESS(status))
+ {
+ TraceEvents(TRACE_LEVEL_ERROR, TRACE_FIX, "StopFix failed with %!STATUS!", status);
+ goto Exit;
+ }
+
+Exit:
+ return status;
+}
+
+NTSTATUS
+CFixHandler::StopExistingSinglsShotFix()
+{
+ NTSTATUS status = STATUS_SUCCESS;
+ PGNSS_STOPFIXSESSION_PARAM stopFixSessionParam = nullptr;
+
+ if (_CurrentSinglsShotSessionId == INVALID_SESSION_ID)
+ {
+ TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_FIX, "There is no single shot session to stop");
+ goto Exit;
+ }
+
+ _CurrentSinglsShotSessionId = INVALID_SESSION_ID;
+
+ INIT_POD_GNSS_STRUCT(stopFixSessionParam);
+ status = _SingleShotSession.StopAcquiringFix(stopFixSessionParam);
+ if (!NT_SUCCESS(status))
+ {
+ TraceEvents(TRACE_LEVEL_ERROR, TRACE_FIX, "StopFix failed with %!STATUS!", status);
+ goto Exit;
+ }
+
+Exit:
+ return status;
+}
+
+NTSTATUS
+CFixHandler::ModifyFix(
+ _In_ WDFREQUEST Request
+)
+{
+ NTSTATUS status = STATUS_SUCCESS;
+ PGNSS_FIXSESSION_PARAM fixSessionParameters = nullptr;
+
+ status = WdfRequestRetrieveInputBuffer(Request, sizeof(GNSS_FIXSESSION_PARAM), (void**)&fixSessionParameters, nullptr);
+ if (!NT_SUCCESS(status))
+ {
+ TraceEvents(TRACE_LEVEL_ERROR, TRACE_FIX, "WdfRequestRetrieveInputBuffer failed with %!STATUS!", status);
+ goto Exit;
+ }
+
+ //
+ // FIX ME:
+ // We currently support only single shot session fix.
+ // If you support another session type, e.g., distance tracking, update the logic below accordingly.
+ //
+ if (fixSessionParameters->SessionType != GNSS_FixSession_SingleShot)
+ {
+ status = STATUS_UNSUCCESSFUL;
+ TraceEvents(TRACE_LEVEL_ERROR, TRACE_FIX, "Session type is not GNSS_FixSession_SingleShot");
+ goto Exit;
+ }
+
+ //
+ // FIX ME:
+ // Since only single session is supported, use _SingleShotSession instance.
+ // If multiple sessions, get the right session pointer searched by the session ID.
+ //
+ _SingleShotSession.ModifyAcquiringFix(fixSessionParameters);
+
+ if (!NT_SUCCESS(status))
+ {
+ TraceEvents(TRACE_LEVEL_ERROR, TRACE_FIX, "ModifyFix failed with %!STATUS!", status);
+ goto Exit;
+ }
+
+Exit:
+ return status;
+}
+
+NTSTATUS
+CFixHandler::GetFixRequest(
+ _In_ WDFREQUEST Request
+)
+{
+ NTSTATUS status = STATUS_SUCCESS;
+ ULONG sessionId = INVALID_SESSION_ID;
+ ULONG *pSessionId = nullptr;
+
+ // Get the session ID this get fix is for
+ status = WdfRequestRetrieveInputBuffer(Request, sizeof(sessionId), (void**)&pSessionId, nullptr);
+ if (!NT_SUCCESS(status))
+ {
+ TraceEvents(TRACE_LEVEL_ERROR, TRACE_FIX, "Could not retrieve input sessionID for request");
+ goto Exit;
+ }
+
+ //
+ // FIX ME:
+ // Single session is only option now, but if multiple sessions, this sample should do this check at the FixHandler Level.
+ //
+ sessionId = *pSessionId;
+
+ status = _SingleShotSession.GetFix(Request);
+ if (!NT_SUCCESS(status))
+ {
+ TraceEvents(TRACE_LEVEL_ERROR, TRACE_FIX, "SinglShotSession.GetFix failed with %!STATUS!", status);
+ goto Exit;
+ }
+
+Exit:
+ return status;
+}
diff --git a/gnss/gnssUmdf/FixHandler.h b/gnss/gnssUmdf/FixHandler.h
new file mode 100644
index 00000000..6ade10a7
--- /dev/null
+++ b/gnss/gnssUmdf/FixHandler.h
@@ -0,0 +1,39 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+Module Name:
+
+ Fixhandler.h
+
+Abstract:
+
+ This module contains the type definitions of the fix logic of the Umdf Gnss Driver.
+
+Environment:
+
+ Windows User-Mode Driver Framework
+
+--*/
+
+#pragma once
+
+class CFixSession;
+
+class CFixHandler
+{
+public:
+ NTSTATUS Initialize(_In_ WDFQUEUE Queue);
+
+ NTSTATUS StartFix(_In_ WDFREQUEST Request, _In_ BOOL LocationServiceEnabled);
+ NTSTATUS StopFix(_In_ WDFREQUEST Request);
+ NTSTATUS GetFixRequest(_In_ WDFREQUEST Request);
+ NTSTATUS ModifyFix(_In_ WDFREQUEST Request);
+ NTSTATUS StopExistingSinglsShotFix();
+
+private:
+ // Session objects (single shot, distance tracking etc.)
+ CFixSession _SingleShotSession;
+
+ ULONG _CurrentSinglsShotSessionId = INVALID_SESSION_ID;
+};
diff --git a/gnss/gnssUmdf/FixSession.cpp b/gnss/gnssUmdf/FixSession.cpp
new file mode 100644
index 00000000..14418a8f
--- /dev/null
+++ b/gnss/gnssUmdf/FixSession.cpp
@@ -0,0 +1,512 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+Module Name:
+
+ fixsession.cpp
+
+Abstract:
+
+ This file contains the Fix sessions and contains logic to provide position.
+
+Environment:
+
+ Windows User-Mode Driver Framework
+
+--*/
+
+#include "precomp.h"
+#include "Trace.h"
+#include "Defaults.h"
+#include "FixSession.h"
+#include "FixHandler.h"
+
+#include "FixSession.tmh"
+
+
+static void CALLBACK
+s_FixThreadStub(
+ _Inout_ PTP_CALLBACK_INSTANCE Instance,
+ _Inout_opt_ PVOID Context,
+ _Inout_ PTP_WORK Work
+);
+
+CFixSession::CFixSession() :
+ _Id(INVALID_SESSION_ID),
+ _State(STOPPED),
+ _HasCachedFix(false),
+ _StopFixEvent(nullptr),
+ _ThreadpoolWork(nullptr)
+{
+ InitializeCriticalSection(&_Lock);
+ _GnssPosition = g_DefaultGnssFixData;
+}
+
+CFixSession::~CFixSession()
+{
+ if (_StopFixEvent != nullptr && _ThreadpoolWork != nullptr)
+ {
+ SetEvent(_StopFixEvent);
+ WaitForThreadpoolWorkCallbacks(_ThreadpoolWork, TRUE);
+ }
+
+ if (_StopFixEvent != nullptr)
+ {
+ CloseHandle(_StopFixEvent);
+ _StopFixEvent = nullptr;
+ }
+
+ if (_ThreadpoolWork != nullptr)
+ {
+ CloseThreadpoolWork(_ThreadpoolWork);
+ _ThreadpoolWork = nullptr;
+ }
+
+ DeleteCriticalSection(&_Lock);
+}
+
+NTSTATUS
+CFixSession::Initialize(
+ _In_ WDFQUEUE Queue
+)
+{
+ EnterCriticalSection(&_Lock);
+
+ NTSTATUS status = STATUS_SUCCESS;
+
+ // set the state
+ _State = STOPPED;
+
+ // Create the TP work
+ _ThreadpoolWork = CreateThreadpoolWork(
+ (PTP_WORK_CALLBACK)s_FixThreadStub,
+ (PVOID)this,
+ nullptr
+ );
+
+ if (_ThreadpoolWork == nullptr)
+ {
+ status = STATUS_UNSUCCESSFUL;
+ goto Exit;
+ }
+
+ // Create the stop fix Event
+ _StopFixEvent = CreateEvent(/* lpEventAttributes */ nullptr, /* bManualReset */ FALSE, /* bInitialState */ FALSE, /* lpName */ nullptr);
+ if (_StopFixEvent == nullptr)
+ {
+ status = STATUS_UNSUCCESSFUL;
+ goto Exit;
+ }
+
+ // Create the manual dispatch queue
+ WDF_IO_QUEUE_CONFIG queueConfiguration;
+ WDF_IO_QUEUE_CONFIG_INIT(&queueConfiguration, WdfIoQueueDispatchManual);
+
+ // Initialize the attributes of the queue. Set the execution level to
+ // passive to force all IRPs to be sent to the driver at passive IRQL.
+ WDF_OBJECT_ATTRIBUTES ioQueueAttributes;
+ WDF_OBJECT_ATTRIBUTES_INIT(&ioQueueAttributes);
+ ioQueueAttributes.SynchronizationScope = WdfSynchronizationScopeQueue;
+ ioQueueAttributes.ExecutionLevel = WdfExecutionLevelPassive;
+ status = WdfIoQueueCreate(WdfIoQueueGetDevice(Queue),
+ &queueConfiguration,
+ &ioQueueAttributes,
+ &_FixAcquisitionRequestQueue);
+
+Exit:
+ LeaveCriticalSection(&_Lock);
+ return status;
+}
+
+NTSTATUS
+CFixSession::StartAcquiringFix(
+ _In_ PGNSS_FIXSESSION_PARAM FixSessionParameters
+)
+{
+ NTSTATUS status = STATUS_SUCCESS;
+
+ EnterCriticalSection(&_Lock);
+
+ // Check the state of the thread.
+ // If already running we should not get this request
+ // as multiplexing is not supported for Singleshot
+ if (_State == ACQUIRING)
+ {
+ status = STATUS_UNSUCCESSFUL;
+ goto Exit;
+ }
+
+ // Create PTP_WORK only when first start fix is called.
+ if (_ThreadpoolWork == nullptr)
+ {
+ // Not initialized. Error out
+ status = STATUS_UNSUCCESSFUL;
+ goto Exit;
+ }
+
+ _Id = FixSessionParameters->FixSessionID;
+ _State = ACQUIRING;
+ _FixParameter = *FixSessionParameters;
+
+ ResetEvent(_StopFixEvent);
+
+ // Post a work object to the thread
+ SubmitThreadpoolWork(_ThreadpoolWork);
+
+ // Initialize the GetFix Queue
+ WdfIoQueueStart(_FixAcquisitionRequestQueue);
+
+Exit:
+ LeaveCriticalSection(&_Lock);
+
+ return status;
+}
+
+NTSTATUS
+CFixSession::StopAcquiringFix(
+ _In_ PGNSS_STOPFIXSESSION_PARAM StopFixSessionParam
+)
+{
+ NTSTATUS status = STATUS_SUCCESS;
+
+ {
+ EnterCriticalSection(&_Lock);
+
+ // If Ids don't Match return Error
+ if (StopFixSessionParam->FixSessionID != _Id)
+ {
+ status = STATUS_UNSUCCESSFUL;
+ TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_FIX, "Id mismatch in Stop Fix Session call");
+ goto Exit;
+ }
+
+ // Check the state of the session
+ if (_State != ACQUIRING)
+ {
+ TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_FIX, "Can't stop an inactive session.");
+ goto Exit;
+ }
+
+ // Stop the current processing of the fix session
+ if (_StopFixEvent != nullptr)
+ {
+ SetEvent(_StopFixEvent);
+ }
+
+ LeaveCriticalSection(&_Lock);
+ }
+
+ // Wait for any threadpool work to finish.
+ if (_ThreadpoolWork != nullptr)
+ {
+ WaitForThreadpoolWorkCallbacks(_ThreadpoolWork, TRUE);
+ }
+
+ EnterCriticalSection(&_Lock);
+ _State = STOPPED;
+
+ // Drain the GetFix Queue
+ WdfIoQueuePurgeSynchronously(_FixAcquisitionRequestQueue);
+
+Exit:
+ LeaveCriticalSection(&_Lock);
+
+ return status;
+}
+
+NTSTATUS
+CFixSession::ModifyAcquiringFix(
+ _In_ PGNSS_FIXSESSION_PARAM ModifyFixSessionParam
+)
+{
+ NTSTATUS status = STATUS_SUCCESS;
+
+ EnterCriticalSection(&_Lock);
+
+ memcpy_s(&_FixParameter, sizeof(GNSS_FIXSESSION_PARAM), ModifyFixSessionParam, sizeof(*ModifyFixSessionParam));
+
+ LeaveCriticalSection(&_Lock);
+
+ return status;
+}
+
+NTSTATUS
+CFixSession::ReportGnssFix(
+ _In_ PGNSS_FIXDATA GnssFix
+)
+{
+ EnterCriticalSection(&_Lock);
+
+ NTSTATUS status = STATUS_SUCCESS;
+ WDFREQUEST Request;
+ WDF_IO_QUEUE_STATE QueueStatus;
+ ULONG uRequest;
+
+ QueueStatus = WdfIoQueueGetState(_FixAcquisitionRequestQueue, &uRequest, nullptr);
+ if (!WDF_IO_QUEUE_READY(QueueStatus) || (uRequest == 0))
+ {
+ status = STATUS_UNSUCCESSFUL;
+ goto Exit;
+ }
+
+ if (STATUS_SUCCESS == WdfIoQueueRetrieveNextRequest(_FixAcquisitionRequestQueue, &Request))
+ {
+ status = CompleteRequestWithGnssFix(Request, GnssFix);
+ if (!NT_SUCCESS(status))
+ {
+ TraceEvents(TRACE_LEVEL_ERROR, TRACE_FIX, "Could not respond with fix data with %!STATUS!", status);
+ goto Exit;
+ }
+ }
+ else
+ {
+ TraceEvents(TRACE_LEVEL_ERROR, TRACE_FIX, "Couldn't retrieve the next request with %!STATUS!", status);
+ goto Exit;
+ }
+
+Exit:
+ LeaveCriticalSection(&_Lock);
+
+ return status;
+}
+
+NTSTATUS
+CFixSession::CompleteRequestWithGnssFix(
+ _In_ WDFREQUEST Request,
+ PGNSS_FIXDATA GnssFix
+)
+{
+ NTSTATUS status = STATUS_SUCCESS;
+ PVOID outputBuffer;
+ size_t outputBufferLength;
+ PGNSS_EVENT gnssEvent;
+ size_t size = FIELD_OFFSET(GNSS_EVENT, FixData) + sizeof(GNSS_FIXDATA);
+
+ status = WdfRequestRetrieveOutputBuffer(Request,
+ size,
+ &outputBuffer,
+ &outputBufferLength);
+
+ if (!NT_SUCCESS(status))
+ {
+ TraceEvents(TRACE_LEVEL_ERROR, TRACE_FIX, "WdfRequestRetrieveOutputBuffer() failed with %!STATUS!", status);
+ goto Exit;
+ }
+
+ gnssEvent = ((GNSS_EVENT *)outputBuffer);
+ memset(outputBuffer, 0, size);
+ gnssEvent->Version = GNSS_DRIVER_VERSION_2;
+ gnssEvent->EventType = GNSS_Event_FixAvailable;
+ gnssEvent->EventDataSize = sizeof(GNSS_FIXDATA);
+ gnssEvent->Size = (ULONG)size;
+ memcpy_s(&gnssEvent->FixData, sizeof(GNSS_FIXDATA), GnssFix, sizeof(GNSS_FIXDATA));
+ gnssEvent->FixData.FixSessionID = _Id;
+
+ WdfRequestCompleteWithInformation(Request, STATUS_SUCCESS, outputBufferLength);
+ status = STATUS_PENDING;
+Exit:
+ return status;
+}
+
+NTSTATUS
+CFixSession::UpdateCurrentPosition(
+ _In_ PGNSS_FIXDATA GnssFix
+)
+{
+ NTSTATUS status = STATUS_SUCCESS;
+
+ EnterCriticalSection(&_Lock);
+
+ memcpy_s(&_GnssPosition, sizeof(GNSS_FIXDATA), GnssFix, sizeof(*GnssFix));
+
+ LeaveCriticalSection(&_Lock);
+
+ return status;
+}
+
+NTSTATUS
+CFixSession::GetFix(
+ _In_ WDFREQUEST Request
+)
+{
+ NTSTATUS status = STATUS_SUCCESS;
+ ULONG sessionId = INVALID_SESSION_ID;
+ PGNSS_EVENT outputEvent = nullptr;
+ ULONG *pSessionId = nullptr;
+
+ EnterCriticalSection(&_Lock);
+
+ // Verify the size of where output goes eventually, when this IRP is serviced
+ status = WdfRequestRetrieveOutputBuffer(Request, sizeof(GNSS_EVENT), (void**)&outputEvent, nullptr);
+ if (!NT_SUCCESS(status))
+ {
+ TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_FIX, "Could not retrieve output buffer for request with %!STATUS!", status);
+ goto Exit;
+ }
+
+ // Get the session ID this get fix is for
+ status = WdfRequestRetrieveInputBuffer(Request, sizeof(sessionId), (void**)&pSessionId, nullptr);
+ if (!NT_SUCCESS(status))
+ {
+ TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_FIX, "Could not retrieve input sessionID for request");
+ goto Exit;
+ }
+
+ sessionId = *pSessionId;
+
+ // Check if the Ids match
+ if (_Id != sessionId)
+ {
+ status = STATUS_UNSUCCESSFUL;
+ goto Exit;
+ }
+ // If we have a cached fix around because we tried to respond while there
+ // weren't any getfixes around, answer immediately with it
+ if (_HasCachedFix)
+ {
+ status = CompleteRequestWithGnssFix(Request, &_GnssPosition);
+
+ _HasCachedFix = !(NT_SUCCESS(status));
+ }
+ // Otherwise, we push the request into a queue
+ else
+ {
+ status = WdfRequestForwardToIoQueue(Request, _FixAcquisitionRequestQueue);
+ if (!NT_SUCCESS(status))
+ {
+ TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_FIX, "WdfRequestForwardToIoQueue failed with %!STATUS!", status);
+ goto Exit;
+ }
+
+ status = STATUS_PENDING;
+ }
+
+Exit:
+ LeaveCriticalSection(&_Lock);
+
+ return status;
+}
+
+static void CALLBACK
+s_FixThreadStub(
+ _Inout_ PTP_CALLBACK_INSTANCE /*Instance*/,
+ _Inout_opt_ PVOID Context,
+ _Inout_ PTP_WORK /*Work*/
+)
+{
+ CFixSession *pFixSession = static_cast<CFixSession *>(Context);
+
+ pFixSession->AcquireSingleFix();
+}
+
+void
+CFixSession::AcquireSingleFix()
+{
+ NTSTATUS status = STATUS_SUCCESS;
+
+ while (true)
+ {
+ // Wait stop fix event for 1 second and then retrieve position
+ DWORD WaitCode = WaitForSingleObject(_StopFixEvent, DEFAULT_FIX_INTERVAL_SECONDS * 1000);
+ if (WaitCode == WAIT_TIMEOUT)
+ {
+ status = RetrievePosition(&_GnssPosition);
+ if (!NT_SUCCESS(status))
+ {
+ TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_FIX, "Fail to retrieve fix data from position source");
+ }
+
+ // Send the default fix to the session
+ status = ReportGnssFix(&_GnssPosition);
+ if (!NT_SUCCESS(status))
+ {
+ // We were not able to send the fix so cache it
+ _HasCachedFix = true;
+ }
+ else
+ {
+ if (_GnssPosition.IsFinalFix != FALSE)
+ {
+ break;
+ }
+ }
+ }
+ else if (WaitCode == WAIT_OBJECT_0)
+ {
+ // Stop session signalled
+ break;
+ }
+ }
+
+ EnterCriticalSection(&_Lock);
+
+ // Reset the StopFix Event if it is set
+ ResetEvent(_StopFixEvent);
+
+ // Update the state of the session
+ _State = STOPPED;
+
+ LeaveCriticalSection(&_Lock);
+}
+
+
+NTSTATUS
+CFixSession::RetrievePosition(
+ _Inout_ PGNSS_FIXDATA GnssFixData
+)
+{
+ NTSTATUS status = STATUS_SUCCESS;
+
+ //
+ // FIX ME:
+ // You can retrieve a position from a predefined position or GPS HW.
+ // This sample code calls RetrievePositionFromPredefinedValue to give fake location.
+ // To give a real location from GPS HW, replace this function with new function that defines
+ // (1) establishing and enumerating HW interface such as Serial or Bluetooth, and
+ // (2) reading and parsing NMEA messages from the interface.
+ // You can also define a custom IOCTL instead, updating _GnssPosition directly in CQueue and skip the call below as no-op.
+ //
+ status = RetrievePositionFromPredefinedValue(GnssFixData);
+
+ return status;
+}
+
+NTSTATUS
+CFixSession::RetrievePositionFromPredefinedValue(
+ _Out_ PGNSS_FIXDATA GnssFixData
+)
+{
+ NTSTATUS status = STATUS_SUCCESS;
+
+ //
+ // FIX ME:
+ // Specify user-defined GNSS_FIXDATA output based off the DDI format. The following is just an example.
+ //
+ *GnssFixData =
+ {
+ sizeof(GNSS_FIXDATA),
+ GNSS_DRIVER_DDK_VERSION,
+ INVALID_SESSION_ID,
+ { 0xCD700000, 0x1D48908 }, // an example date/time, Dec/01/2018
+ TRUE,
+ STATUS_SUCCESS,
+ GNSS_FIXDETAIL_BASIC | GNSS_FIXDETAIL_ACCURACY,
+ {
+ sizeof(GNSS_FIXDATA_BASIC),
+ GNSS_DRIVER_DDK_VERSION,
+ // Location: Mount Rainier National Park
+ 46.852273,
+ -121.757468,
+ 0.0,
+ 0.0,
+ 0.0
+ },
+ {
+ sizeof(GNSS_FIXDATA_ACCURACY),
+ GNSS_DRIVER_DDK_VERSION,
+ 10 // Meters accuracy
+ }
+ };
+ return status;
+}
diff --git a/gnss/gnssUmdf/FixSession.h b/gnss/gnssUmdf/FixSession.h
new file mode 100644
index 00000000..f8298306
--- /dev/null
+++ b/gnss/gnssUmdf/FixSession.h
@@ -0,0 +1,60 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+Module Name:
+
+ Fixsession.h
+
+Abstract:
+
+ This module contains the type definitions of the fix logic of the Umdf Gnss Driver.
+
+Environment:
+
+ Windows User-Mode Driver Framework
+
+--*/
+
+#pragma once
+
+//
+// This class implements the Fix sessions and contains logic to provide position within GNSS driver.
+//
+class CFixSession
+{
+public:
+ CFixSession();
+ ~CFixSession();
+
+ void AcquireSingleFix();
+ NTSTATUS Initialize(_In_ WDFQUEUE Queue);
+ NTSTATUS StartAcquiringFix(_In_ PGNSS_FIXSESSION_PARAM FixSessionParameters);
+ NTSTATUS StopAcquiringFix(_In_ PGNSS_STOPFIXSESSION_PARAM StopFixSessionParam);
+ NTSTATUS ModifyAcquiringFix(_In_ PGNSS_FIXSESSION_PARAM ModifyFixSessionParam);
+ NTSTATUS GetFix(_In_ WDFREQUEST Request);
+ NTSTATUS UpdateCurrentPosition(_In_ PGNSS_FIXDATA GnssFix);
+
+ NTSTATUS RetrievePosition(_Inout_ PGNSS_FIXDATA GnssFixData);
+ NTSTATUS RetrievePositionFromPredefinedValue(_Out_ PGNSS_FIXDATA GnssFixData);
+
+private:
+ enum STATE
+ {
+ ACQUIRING = 0,
+ STOPPED
+ };
+
+ ULONG _Id = INVALID_SESSION_ID;
+ STATE _State = STOPPED;
+ GNSS_FIXSESSION_PARAM _FixParameter = {};
+ WDFQUEUE _FixAcquisitionRequestQueue = nullptr;
+ bool _HasCachedFix = false;
+ GNSS_FIXDATA _GnssPosition = {};
+ HANDLE _StopFixEvent = nullptr;
+ PTP_WORK _ThreadpoolWork = nullptr;
+ CRITICAL_SECTION _Lock;
+
+ NTSTATUS CompleteRequestWithGnssFix(_In_ WDFREQUEST Request, PGNSS_FIXDATA GnssFix);
+ NTSTATUS ReportGnssFix(_In_ PGNSS_FIXDATA GnssFix);
+};
diff --git a/gnss/gnssUmdf/Queue.cpp b/gnss/gnssUmdf/Queue.cpp
new file mode 100644
index 00000000..fdf23ab2
--- /dev/null
+++ b/gnss/gnssUmdf/Queue.cpp
@@ -0,0 +1,482 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+Module Name:
+
+ queue.cpp
+
+Abstract:
+
+ This file contains the queue entry points and callbacks.
+
+Environment:
+
+ Windows User-Mode Driver Framework
+
+--*/
+
+#include "precomp.h"
+#include "Trace.h"
+#include "Defaults.h"
+#include "Device.h"
+#include "FixSession.h"
+#include "FixHandler.h"
+#include "Queue.h"
+
+#include "Queue.tmh"
+
+
+CQueue::CQueue(
+ WDFQUEUE Queue
+) :
+ _Queue(Queue),
+ _ForcedDriverVersion(GNSS_DRIVER_DDK_VERSION)
+{
+ InitializeCriticalSection(&_Lock);
+}
+
+CQueue::~CQueue()
+{
+ DeleteCriticalSection(&_Lock);
+ _Queue = nullptr;
+}
+
+
+void
+CQueue::OnCleanup(
+ _In_ WDFOBJECT Object
+)
+{
+ CQueue *pQueue = GetQueueObject(Object);
+
+ // Queue object constructed using placement 'new' so explicitly invoke destructor
+ pQueue->~CQueue();
+}
+
+NTSTATUS
+CQueue::Initialize()
+{
+ NTSTATUS status = STATUS_SUCCESS;
+
+ // Initialize the Fix Handler
+ status = _FixHandler.Initialize(_Queue);
+ if (!NT_SUCCESS(status))
+ {
+ TraceEvents(TRACE_LEVEL_ERROR, TRACE_QUEUE, "_FixHandler->Initialize failed with %!STATUS!", status);
+ goto Exit;
+ }
+
+Exit:
+ return status;
+}
+
+void
+CQueue::OnIoDeviceControl(
+ _In_ WDFQUEUE Queue,
+ _In_ WDFREQUEST Request,
+ _In_ size_t OutputBufferLength,
+ _In_ size_t InputBufferLength,
+ _In_ ULONG IoControlCode
+)
+{
+ CQueue *pQueue = GetQueueObject(Queue);
+
+ pQueue->OnIoDeviceControl(Request, IoControlCode, InputBufferLength, OutputBufferLength);
+}
+
+NTSTATUS
+CQueue::AddQueueToDevice(
+ _In_ WDFDEVICE Device,
+ _Outptr_ CQueue** Queue
+)
+{
+ NTSTATUS status = STATUS_SUCCESS;
+
+ // Create a sequential IO Queue for serial operation and supply all the callbacks.
+ // A sequential queue will cause all IO requests to be serialized to the device (i.e., only one request will sent at a time).
+ WDF_IO_QUEUE_CONFIG queueConfig;
+ WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&queueConfig,
+ WdfIoQueueDispatchSequential);
+
+ queueConfig.PowerManaged = WdfFalse;
+ queueConfig.EvtIoDeviceControl = CQueue::OnIoDeviceControl;
+
+ WDF_OBJECT_ATTRIBUTES queueAttributes;
+ WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&queueAttributes,
+ CQueue);
+
+ queueAttributes.EvtCleanupCallback = CQueue::OnCleanup;
+
+ WDFQUEUE queue = nullptr;
+ status = WdfIoQueueCreate(Device,
+ &queueConfig,
+ &queueAttributes,
+ &queue);
+
+ if (!NT_SUCCESS(status))
+ {
+ TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DEVICE, "WdfIoQueueCreate failed with Status %!STATUS!", status);
+ goto Exit;
+ }
+
+ // Construct a queue object on the preallocated buffer using placement new operation
+ *Queue = new (GetQueueObject(queue)) CQueue(queue);
+
+ status = (*Queue)->Initialize();
+ if (!NT_SUCCESS(status))
+ {
+ TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DEVICE, "CQueue::Initialize failed with %!STATUS!", status);
+ goto Exit;
+ }
+
+Exit:
+ return status;
+}
+
+void
+CQueue::OnIoDeviceControl(
+ _In_ WDFREQUEST Request,
+ _In_ ULONG IoControlCode,
+ _In_ size_t InputBufferLength,
+ _In_ size_t OutputBufferLength)
+{
+ TraceEvents(TRACE_LEVEL_INFORMATION,
+ TRACE_QUEUE,
+ "Request = %p, IoControlCode = 0x%x InputBufferLength=%d OutputBufferLength=%d",
+ Request, IoControlCode, (int)InputBufferLength, (int)OutputBufferLength);
+
+ NTSTATUS status = STATUS_SUCCESS;
+
+ switch (IoControlCode)
+ {
+ // Capability Exchange
+ case IOCTL_GNSS_SEND_PLATFORM_CAPABILITY:
+ break;
+ case IOCTL_GNSS_GET_DEVICE_CAPABILITY:
+ status = GetDeviceCapability(Request);
+ break;
+
+ case IOCTL_GNSS_GET_CHIPSETINFO:
+ status = GetChipsetInfo(Request);
+ break;
+
+ // Fix
+ case IOCTL_GNSS_START_FIXSESSION:
+ status = _FixHandler.StartFix(Request, _InternalState.SetLocationServiceEnabled);
+ break;
+ case IOCTL_GNSS_STOP_FIXSESSION:
+ status = _FixHandler.StopFix(Request);
+ break;
+ case IOCTL_GNSS_MODIFY_FIXSESSION:
+ status = _FixHandler.ModifyFix(Request);
+ break;
+ case IOCTL_GNSS_GET_FIXDATA:
+ status = _FixHandler.GetFixRequest(Request);
+ break;
+
+ // Driver Command
+ case IOCTL_GNSS_SEND_DRIVERCOMMAND:
+ status = HandleDriverCommand(Request);
+ break;
+
+ //
+ // FIX ME:
+ // The below is optional IOCTLs. Driver developer may choose to implement for advanced functionality.
+ //
+
+ // Agnss
+ case IOCTL_GNSS_INJECT_AGNSS:
+ case IOCTL_GNSS_LISTEN_AGNSS:
+ // Supl
+ case IOCTL_GNSS_SET_SUPL_HSLP:
+ case IOCTL_GNSS_CONFIG_SUPL_CERT:
+ case IOCTL_GNSS_SET_V2UPL_CONFIG:
+ //Ni
+ case IOCTL_GNSS_LISTEN_DRIVER_REQUEST:
+ case IOCTL_GNSS_RESPOND_NI:
+ case IOCTL_GNSS_LISTEN_NI:
+ //Geofence
+ case IOCTL_GNSS_LISTEN_GEOFENCE_ALERT:
+ case IOCTL_GNSS_LISTEN_GEOFENCES_TRACKINGSTATUS:
+ case IOCTL_GNSS_CREATE_GEOFENCE:
+ case IOCTL_GNSS_DELETE_GEOFENCE:
+ // Breadcrumbing
+ case IOCTL_GNSS_START_BREADCRUMBING:
+ case IOCTL_GNSS_STOP_BREADCRUMBING:
+ case IOCTL_GNSS_LISTEN_BREADCRUMBING_ALERT:
+ case IOCTL_GNSS_POP_BREADCRUMBS:
+ // Ioctls that are not implemented
+ case IOCTL_GNSS_LISTEN_ERROR:
+ case IOCTL_GNSS_EXECUTE_CWTEST:
+ case IOCTL_GNSS_EXECUTE_SELFTEST:
+ case IOCTL_GNSS_LISTEN_NMEA:
+ status = STATUS_NOT_IMPLEMENTED;
+ break;
+
+ default:
+ status = STATUS_INVALID_DEVICE_REQUEST;
+ break;
+ }
+
+ if (status != STATUS_PENDING)
+ {
+ TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_QUEUE, "%!FUNC! Completing Request with status %!STATUS!", status);
+ WdfRequestComplete(Request, status);
+ }
+}
+
+NTSTATUS
+CQueue::GetDeviceCapability(
+ _In_ WDFREQUEST Request
+)
+{
+ NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST;
+ PGNSS_DEVICE_CAPABILITY outputParam;
+
+ status = WdfRequestRetrieveOutputBuffer(Request, sizeof(*outputParam), (void**)&outputParam, nullptr);
+ if (!NT_SUCCESS(status))
+ {
+ TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_QUEUE, "%!FUNC! Could not retrieve output buffer for request with status = %!STATUS!", status);
+ goto Exit;
+ }
+
+ INIT_POD_GNSS_STRUCT(outputParam);
+
+ //
+ // FIX ME:
+ // The functionality below is optional. Driver developer may choose to implement for advanced functionality/better performance.
+ //
+ {
+ outputParam->SupportContinuousTracking = FALSE;
+
+ outputParam->SupportDistanceTracking = FALSE;
+
+ outputParam->GeofencingSupport = FALSE;
+ outputParam->MaxGeofencesSupported = 0;
+
+ outputParam->RequireAGnssInjection = FALSE;
+ outputParam->AgnssFormatSupported = FALSE;
+ outputParam->AgnssFormatPreferred = FALSE;
+
+ outputParam->SupportCpLocation = FALSE;
+ outputParam->SupportSuplV2 = FALSE;
+ outputParam->SupportSuplV1 = FALSE;
+ outputParam->SupportUplV2 = FALSE;
+ outputParam->SupportedSuplVersion.MajorVersion = 0;
+ outputParam->SupportedSuplVersion.MinorVersion = 0;
+
+ outputParam->MaxGnssBreadCrumbFixes = 0;
+ outputParam->GnssBreadCrumbPayloadVersion = BREADCRUMBING_UNSUPPORTED;
+
+ // Update the Driver version if forced through IOCTL
+ outputParam->Version = _ForcedDriverVersion;
+ }
+
+ WdfRequestCompleteWithInformation(Request, STATUS_SUCCESS, sizeof(*outputParam));
+ status = STATUS_PENDING;
+
+Exit:
+ return status;
+}
+
+NTSTATUS
+CQueue::GetChipsetInfo(
+ _In_ WDFREQUEST Request
+)
+{
+ //
+ // FIX ME:
+ // The following is an example. Replace the values accordingly
+ //
+ static const wchar_t s_ManufacturerID[] = L"Microsoft Test";
+ static const wchar_t s_HardwareID[] = L"UMDF Gnss";
+ static const wchar_t s_FirmwareVersion[] = L"1.0.0.0";
+
+ NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST;
+ PGNSS_CHIPSETINFO outputParam;
+
+ status = WdfRequestRetrieveOutputBuffer(Request, sizeof(*outputParam), (void**)&outputParam, nullptr);
+ if (!NT_SUCCESS(status))
+ {
+ TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_QUEUE, "%!FUNC! Could not retrieve output buffer for request with status = %!STATUS!", status);
+ goto Exit;
+ }
+
+ INIT_POD_GNSS_STRUCT(outputParam);
+
+ memset(&(outputParam->ManufacturerID), 0, sizeof(outputParam->ManufacturerID));
+ memset(&(outputParam->HardwareID), 0, sizeof(outputParam->HardwareID));
+ memset(&(outputParam->FirmwareVersion), 0, sizeof(outputParam->FirmwareVersion));
+
+ memcpy_s(&(outputParam->ManufacturerID), sizeof(outputParam->ManufacturerID), &s_ManufacturerID, sizeof(s_ManufacturerID));
+ memcpy_s(&(outputParam->HardwareID), sizeof(outputParam->HardwareID), &s_HardwareID, sizeof(s_HardwareID));
+ memcpy_s(&(outputParam->FirmwareVersion), sizeof(outputParam->FirmwareVersion), &s_FirmwareVersion, sizeof(s_FirmwareVersion));
+
+ WdfRequestCompleteWithInformation(Request, STATUS_SUCCESS, sizeof(*outputParam));
+ status = STATUS_PENDING;
+
+Exit:
+ return status;
+}
+
+NTSTATUS
+CQueue::HandleDriverCommand(
+ _In_ WDFREQUEST Request
+)
+{
+ NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST;
+ PGNSS_DRIVERCOMMAND_PARAM command = nullptr;
+
+ // Check that there is enough room to output the returned GNSS_DEVICE_CAPABILITY
+ status = WdfRequestRetrieveInputBuffer(Request, sizeof(*command), (void**)&command, nullptr);
+
+ if (!NT_SUCCESS(status))
+ {
+ TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_QUEUE, "%!FUNC! Could not retrieve input buffer for DriverCommand request with status = %!STATUS!", status);
+ goto Exit;
+ }
+
+ // Check that the sizes are well-formed
+ if ((command->Size < (ULONG)FIELD_OFFSET(GNSS_DRIVERCOMMAND_PARAM, CommandData[command->CommandDataSize])))
+ {
+ TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_QUEUE, "Command is not formatted correctly : unexpected sizes specified");
+ goto Exit;
+ }
+
+ switch (command->CommandType)
+ {
+ case GNSS_ClearAgnssData:
+ status = ClearAgnssData(command);
+ break;
+ case GNSS_ResetEngine:
+ status = ResetEngine(command);
+ break;
+ case GNSS_SetLocationServiceEnabled:
+ status = SetLocationServiceStatus(command);
+ break;
+ case GNSS_ForceOperationMode:
+ status = SetOperationMode(command);
+ break;
+
+ //
+ // FIX ME:
+ // Below are optional driver commands. Driver developer may choose to implement for advanced functionality.
+ //
+ case GNSS_SetLocationNIRequestAllowed:
+ case GNSS_ResetGeofencesTracking:
+ case GNSS_SetNiTimeoutInterval:
+ case GNSS_SetSuplVersion:
+ case GNSS_SetUplServerAccessInterval:
+ status = STATUS_NOT_IMPLEMENTED;
+ break;
+ default:
+ status = STATUS_INVALID_DEVICE_REQUEST;
+ break;
+ }
+
+Exit:
+ return status;
+}
+
+NTSTATUS
+CQueue::SetLocationServiceStatus(
+ _In_ PGNSS_DRIVERCOMMAND_PARAM CommandParam
+)
+{
+ NTSTATUS status = STATUS_SUCCESS;
+
+ status = GetDataFromCommand(CommandParam, &_InternalState.SetLocationServiceEnabled) ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
+
+ if (!_InternalState.SetLocationServiceEnabled)
+ {
+ //
+ // FIX ME:
+ // We must stop any ongoing location sessions of any kind (geofence tracking, assistance data refresh, etc. if any).
+ // For example, if you have distance tracking fix session, stop the session as well.
+ //
+ status = _FixHandler.StopExistingSinglsShotFix();
+ }
+
+ return status;
+}
+
+NTSTATUS
+CQueue::ResetEngine(
+ _In_ PGNSS_DRIVERCOMMAND_PARAM /*CommandParam*/
+)
+{
+ NTSTATUS status = STATUS_SUCCESS;
+
+ //
+ // FIX ME:
+ // This is mandatory command, but sample driver cannot support Reset engine command because this is vendor/HW-specific feature.
+ // You must customize this accordingly. The sample below demonstrates how it might work by resetting internal structure.
+ //
+ _AgnssNeeded[AGNSS_TIME_IDX] = TRUE;
+ _AgnssNeeded[AGNSS_POS_IDX] = TRUE;
+ _AgnssNeeded[AGNSS_BLOB_IDX] = TRUE;
+
+ return status;
+}
+
+NTSTATUS
+CQueue::ClearAgnssData(
+ _In_ PGNSS_DRIVERCOMMAND_PARAM CommandParam
+)
+{
+ NTSTATUS status = STATUS_SUCCESS;
+ DWORD data = 0;
+
+ //
+ // FIX ME:
+ // This is mandatory command, but sample driver cannot support Clear AGNSS data because this is vendor/HW-specific feature.
+ // You must customize this accordingly. The sample below demonstrates how it might work by resetting internal structure.
+ //
+ if (GetDataFromCommand(CommandParam, &data))
+ {
+ GNSS_AGNSS_REQUEST_TYPE reqType = (GNSS_AGNSS_REQUEST_TYPE)data;
+ _AgnssNeeded[reqType] = TRUE;
+ }
+ else
+ {
+ status = STATUS_UNSUCCESSFUL;
+ }
+
+ return status;
+}
+
+NTSTATUS
+CQueue::SetOperationMode(
+ _In_ PGNSS_DRIVERCOMMAND_PARAM CommandParam
+)
+{
+ NTSTATUS status = STATUS_SUCCESS;
+
+ //
+ // FIX ME:
+ // This is mandatory only if SUPL is supported. SUPL is not mandatory unless it is required by mobile operator.
+ // You must customize this code accordingly, depending on the requirement.
+ //
+ status = GetDataFromCommand(CommandParam, &_InternalState.OperationMode) ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
+
+ return status;
+}
+
+template <class DataT>
+BOOL CQueue::GetDataFromCommand(
+ _In_ PGNSS_DRIVERCOMMAND_PARAM Command,
+ _Out_ DataT* Data)
+{
+ size_t dataLen = sizeof(*Data);
+
+ memset(Data, 0, dataLen);
+
+ if (!Command || (Command->CommandDataSize != dataLen))
+ {
+ return FALSE;
+ }
+
+ memcpy_s(Data, dataLen, Command->CommandData, dataLen);
+ return TRUE;
+}
diff --git a/gnss/gnssUmdf/Queue.h b/gnss/gnssUmdf/Queue.h
new file mode 100644
index 00000000..89a105ac
--- /dev/null
+++ b/gnss/gnssUmdf/Queue.h
@@ -0,0 +1,78 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+Module Name:
+
+ queue.h
+
+Abstract:
+
+ This file contains the queue definitions for the Umdf Gnss Driver.
+
+Environment:
+
+ Windows User-Mode Driver Framework
+
+--*/
+
+#pragma once
+
+class CFixHandler;
+
+//
+//This class sets up IO queue, performs the IOCTL operations, and implements the type definitions for the driver's device callback.
+//
+class CQueue
+{
+public:
+ static NTSTATUS AddQueueToDevice(_In_ WDFDEVICE device, _Outptr_ CQueue** queue);
+
+private:
+ enum
+ {
+ AGNSS_TIME_IDX = GNSS_AGNSS_TimeInjection,
+ AGNSS_POS_IDX = GNSS_AGNSS_PositionInjection,
+ AGNSS_BLOB_IDX = GNSS_AGNSS_BlobInjection,
+ AGNSS_MAX_IDX
+ };
+
+ typedef struct {
+ DWORD OperationMode;
+ BOOL SetLocationNiRequestAllowed;
+ BOOL SetLocationServiceEnabled;
+ } GnssInternalState;
+
+ WDFQUEUE _Queue;
+ CRITICAL_SECTION _Lock;
+ CFixHandler _FixHandler;
+ ULONG _ForcedDriverVersion = GNSS_DRIVER_DDK_VERSION;
+ GnssInternalState _InternalState = {};
+ BOOL _AgnssNeeded[AGNSS_MAX_IDX];
+
+ CQueue(WDFQUEUE Queue);
+ ~CQueue();
+
+ static EVT_WDF_OBJECT_CONTEXT_CLEANUP OnCleanup;
+ static EVT_WDF_IO_QUEUE_IO_DEVICE_CONTROL OnIoDeviceControl;
+
+ template <class DataT>
+ BOOL GetDataFromCommand(_In_ PGNSS_DRIVERCOMMAND_PARAM Command,
+ _Out_ DataT* Data);
+
+ NTSTATUS Initialize();
+ void OnIoDeviceControl(_In_ WDFREQUEST Request,
+ _In_ ULONG IoControlCode,
+ _In_ size_t InputBufferLength,
+ _In_ size_t OutputBufferLength);
+ NTSTATUS GetDeviceCapability(_In_ WDFREQUEST Request);
+ NTSTATUS GetChipsetInfo(_In_ WDFREQUEST Request);
+ NTSTATUS HandleDriverCommand(_In_ WDFREQUEST Request);
+
+ NTSTATUS ResetEngine(_In_ PGNSS_DRIVERCOMMAND_PARAM CommandParam);
+ NTSTATUS ClearAgnssData(_In_ PGNSS_DRIVERCOMMAND_PARAM CommandParam);
+ NTSTATUS SetLocationServiceStatus(_In_ PGNSS_DRIVERCOMMAND_PARAM CommandParam);
+ NTSTATUS SetOperationMode(_In_ PGNSS_DRIVERCOMMAND_PARAM CommandParam);
+};
+
+WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(CQueue, GetQueueObject);
diff --git a/gnss/gnssUmdf/Trace.h b/gnss/gnssUmdf/Trace.h
new file mode 100644
index 00000000..6b6af60b
--- /dev/null
+++ b/gnss/gnssUmdf/Trace.h
@@ -0,0 +1,64 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+Module Name:
+
+ Trace.h
+
+Abstract:
+
+ This module contains the local type definitions for the Umdf Gnss Driver.
+
+Environment:
+
+ Windows User-Mode Driver Framework
+
+--*/
+
+#pragma once
+
+//
+// Define the tracing flags.
+//
+
+#define WPP_CONTROL_GUIDS \
+ WPP_DEFINE_CONTROL_GUID( \
+ GnssUmdfTraceGuid, (ceb3bf01,80e4,4dc7,b3bf,f6b5279eb8c4), \
+ \
+ WPP_DEFINE_BIT(MYDRIVER_ALL_INFO) \
+ WPP_DEFINE_BIT(TRACE_DRIVER) \
+ WPP_DEFINE_BIT(TRACE_DEVICE) \
+ WPP_DEFINE_BIT(TRACE_QUEUE) \
+ WPP_DEFINE_BIT(TRACE_FIX) \
+ )
+
+#define WPP_FLAG_LEVEL_LOGGER(flag, level) \
+ WPP_LEVEL_LOGGER(flag)
+
+#define WPP_FLAG_LEVEL_ENABLED(flag, level) \
+ (WPP_LEVEL_ENABLED(flag) && \
+ WPP_CONTROL(WPP_BIT_ ## flag).Level >= level)
+
+#define WPP_LEVEL_FLAGS_LOGGER(lvl,flags) \
+ WPP_LEVEL_LOGGER(flags)
+
+#define WPP_LEVEL_FLAGS_ENABLED(lvl, flags) \
+ (WPP_LEVEL_ENABLED(flags) && WPP_CONTROL(WPP_BIT_ ## flags).Level >= lvl)
+
+//
+// This comment block is scanned by the trace preprocessor to define our
+// Trace function.
+//
+// begin_wpp config
+// FUNC Trace{FLAG=MYDRIVER_ALL_INFO}(LEVEL, MSG, ...);
+// FUNC TraceEvents(LEVEL, FLAGS, MSG, ...);
+// end_wpp
+
+//
+//
+// Driver specific #defines
+//
+#if UMDF_VERSION_MAJOR == 2 && UMDF_VERSION_MINOR == 0
+ #define MYDRIVER_TRACING_ID L"Microsoft\\UMDF2.0\\gnssUmdf V1.0"
+#endif
diff --git a/gnss/gnssUmdf/gnssUmdf.inf b/gnss/gnssUmdf/gnssUmdf.inf
new file mode 100644
index 00000000..65dd5e59
--- /dev/null
+++ b/gnss/gnssUmdf/gnssUmdf.inf
Binary files differ
diff --git a/gnss/gnssUmdf/gnssUmdf.vcxproj b/gnss/gnssUmdf/gnssUmdf.vcxproj
new file mode 100644
index 00000000..bcfd27ae
--- /dev/null
+++ b/gnss/gnssUmdf/gnssUmdf.vcxproj
@@ -0,0 +1,301 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|ARM">
+ <Configuration>Debug</Configuration>
+ <Platform>ARM</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|ARM">
+ <Configuration>Release</Configuration>
+ <Platform>ARM</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|ARM64">
+ <Configuration>Debug</Configuration>
+ <Platform>ARM64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|ARM64">
+ <Configuration>Release</Configuration>
+ <Platform>ARM64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="Device.cpp" />
+ <ClCompile Include="Driver.cpp" />
+ <ClCompile Include="FixHandler.cpp" />
+ <ClCompile Include="FixSession.cpp" />
+ <ClCompile Include="Queue.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="precomp.h" />
+ <ClInclude Include="Device.h" />
+ <ClInclude Include="Driver.h" />
+ <ClInclude Include="FixHandler.h" />
+ <ClInclude Include="FixSession.h" />
+ <ClInclude Include="Defaults.h" />
+ <ClInclude Include="Queue.h" />
+ <ClInclude Include="Trace.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <Inf Include="gnssUmdf.inf" />
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{AC97DD9E-781F-4FCE-8AC7-ADE57C633A13}</ProjectGuid>
+ <TemplateGuid>{32909489-7be5-497b-aafa-db6669d9b44b}</TemplateGuid>
+ <MinimumVisualStudioVersion>12.0</MinimumVisualStudioVersion>
+ <Configuration>Debug</Configuration>
+ <Platform Condition="'$(Platform)' == ''">Win32</Platform>
+ <RootNamespace>gnssUmdf</RootNamespace>
+ <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
+ </PropertyGroup>
+ <PropertyGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset>
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ </PropertyGroup>
+ <PropertyGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset>
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ </PropertyGroup>
+ <PropertyGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset>
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ </PropertyGroup>
+ <PropertyGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset>
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ </PropertyGroup>
+ <PropertyGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
+ <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset>
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ </PropertyGroup>
+ <PropertyGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
+ <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset>
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ </PropertyGroup>
+ <PropertyGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
+ <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset>
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ </PropertyGroup>
+ <PropertyGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
+ <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset>
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <UMDF_VERSION_MAJOR>2</UMDF_VERSION_MAJOR>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <UMDF_VERSION_MAJOR>2</UMDF_VERSION_MAJOR>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <UMDF_VERSION_MAJOR>2</UMDF_VERSION_MAJOR>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <UMDF_VERSION_MAJOR>2</UMDF_VERSION_MAJOR>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <UMDF_VERSION_MAJOR>2</UMDF_VERSION_MAJOR>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <UMDF_VERSION_MAJOR>2</UMDF_VERSION_MAJOR>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <UMDF_VERSION_MAJOR>2</UMDF_VERSION_MAJOR>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <UMDF_VERSION_MAJOR>2</UMDF_VERSION_MAJOR>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <DebuggerFlavor>DbgengRemoteDebugger</DebuggerFlavor>
+ <OutDir>$(ProjectDir)bin\$(Platform)\$(ConfigurationName)\</OutDir>
+ <IntDir>$(ProjectDir)obj\$(Platform)\$(ConfigurationName)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <DebuggerFlavor>DbgengRemoteDebugger</DebuggerFlavor>
+ <OutDir>$(ProjectDir)bin\$(Platform)\$(ConfigurationName)\</OutDir>
+ <IntDir>$(ProjectDir)obj\$(Platform)\$(ConfigurationName)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <DebuggerFlavor>DbgengRemoteDebugger</DebuggerFlavor>
+ <OutDir>$(ProjectDir)bin\$(Platform)\$(ConfigurationName)\</OutDir>
+ <IntDir>$(ProjectDir)obj\$(Platform)\$(ConfigurationName)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <DebuggerFlavor>DbgengRemoteDebugger</DebuggerFlavor>
+ <OutDir>$(ProjectDir)bin\$(Platform)\$(ConfigurationName)\</OutDir>
+ <IntDir>$(ProjectDir)obj\$(Platform)\$(ConfigurationName)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
+ <DebuggerFlavor>DbgengRemoteDebugger</DebuggerFlavor>
+ <OutDir>$(ProjectDir)bin\$(Platform)\$(ConfigurationName)\</OutDir>
+ <IntDir>$(ProjectDir)obj\$(Platform)\$(ConfigurationName)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
+ <DebuggerFlavor>DbgengRemoteDebugger</DebuggerFlavor>
+ <OutDir>$(ProjectDir)bin\$(Platform)\$(ConfigurationName)\</OutDir>
+ <IntDir>$(ProjectDir)obj\$(Platform)\$(ConfigurationName)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
+ <DebuggerFlavor>DbgengRemoteDebugger</DebuggerFlavor>
+ <OutDir>$(ProjectDir)bin\$(Platform)\$(ConfigurationName)\</OutDir>
+ <IntDir>$(ProjectDir)obj\$(Platform)\$(ConfigurationName)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
+ <DebuggerFlavor>DbgengRemoteDebugger</DebuggerFlavor>
+ <OutDir>$(ProjectDir)bin\$(Platform)\$(ConfigurationName)\</OutDir>
+ <IntDir>$(ProjectDir)obj\$(Platform)\$(ConfigurationName)\</IntDir>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <WppEnabled>true</WppEnabled>
+ <WppRecorderEnabled>true</WppRecorderEnabled>
+ <WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">trace.h</WppScanConfigurationData>
+ <WarningLevel>Level4</WarningLevel>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <PrecompiledHeader>Create</PrecompiledHeader>
+ <PrecompiledHeaderFile>precomp.h</PrecompiledHeaderFile>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <WppEnabled>true</WppEnabled>
+ <WppRecorderEnabled>true</WppRecorderEnabled>
+ <WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">trace.h</WppScanConfigurationData>
+ <WarningLevel>Level4</WarningLevel>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <PrecompiledHeader>Create</PrecompiledHeader>
+ <PrecompiledHeaderFile>precomp.h</PrecompiledHeaderFile>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <WppEnabled>true</WppEnabled>
+ <WppRecorderEnabled>true</WppRecorderEnabled>
+ <WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">trace.h</WppScanConfigurationData>
+ <WarningLevel>Level4</WarningLevel>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <PrecompiledHeader>Create</PrecompiledHeader>
+ <PrecompiledHeaderFile>precomp.h</PrecompiledHeaderFile>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <WppEnabled>true</WppEnabled>
+ <WppRecorderEnabled>true</WppRecorderEnabled>
+ <WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">trace.h</WppScanConfigurationData>
+ <WarningLevel>Level4</WarningLevel>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <PrecompiledHeader>Create</PrecompiledHeader>
+ <PrecompiledHeaderFile>precomp.h</PrecompiledHeaderFile>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
+ <ClCompile>
+ <WppEnabled>true</WppEnabled>
+ <WppRecorderEnabled>true</WppRecorderEnabled>
+ <WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">trace.h</WppScanConfigurationData>
+ <WarningLevel>Level4</WarningLevel>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <PrecompiledHeader>Create</PrecompiledHeader>
+ <PrecompiledHeaderFile>precomp.h</PrecompiledHeaderFile>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
+ <ClCompile>
+ <WppEnabled>true</WppEnabled>
+ <WppRecorderEnabled>true</WppRecorderEnabled>
+ <WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">trace.h</WppScanConfigurationData>
+ <WarningLevel>Level4</WarningLevel>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <PrecompiledHeader>Create</PrecompiledHeader>
+ <PrecompiledHeaderFile>precomp.h</PrecompiledHeaderFile>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
+ <ClCompile>
+ <WppEnabled>true</WppEnabled>
+ <WppRecorderEnabled>true</WppRecorderEnabled>
+ <WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">trace.h</WppScanConfigurationData>
+ <WarningLevel>Level4</WarningLevel>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <PrecompiledHeader>Create</PrecompiledHeader>
+ <PrecompiledHeaderFile>precomp.h</PrecompiledHeaderFile>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
+ <ClCompile>
+ <WppEnabled>true</WppEnabled>
+ <WppRecorderEnabled>true</WppRecorderEnabled>
+ <WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">trace.h</WppScanConfigurationData>
+ <WarningLevel>Level4</WarningLevel>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <PrecompiledHeader>Create</PrecompiledHeader>
+ <PrecompiledHeaderFile>precomp.h</PrecompiledHeaderFile>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <FilesToPackage Include="$(TargetPath)" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/gnss/gnssUmdf/gnssUmdf.vcxproj.filters b/gnss/gnssUmdf/gnssUmdf.vcxproj.filters
new file mode 100644
index 00000000..15af8928
--- /dev/null
+++ b/gnss/gnssUmdf/gnssUmdf.vcxproj.filters
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
+ </Filter>
+ <Filter Include="Driver Files">
+ <UniqueIdentifier>{8E41214B-6785-4CFE-B992-037D68949A14}</UniqueIdentifier>
+ <Extensions>inf;inv;inx;mof;mc;</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <Inf Include="gnssUmdf.inf">
+ <Filter>Driver Files</Filter>
+ </Inf>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="Device.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="Driver.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="Queue.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="Trace.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="Defaults.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="FixHandler.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="FixSession.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="precomp.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="Device.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="Driver.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="Queue.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="FixHandler.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="FixSession.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/gnss/gnssUmdf/precomp.h b/gnss/gnssUmdf/precomp.h
new file mode 100644
index 00000000..e07f2171
--- /dev/null
+++ b/gnss/gnssUmdf/precomp.h
@@ -0,0 +1,29 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+Module Name:
+
+ precomp.h
+
+Abstract:
+
+ This module contains the common type definitions and includes.
+
+Environment:
+
+ Windows User-Mode Driver Framework
+
+--*/
+
+#pragma once
+
+//
+// Include the type specific headers.
+//
+#include <windows.h>
+#include <wdf.h>
+#include <initguid.h>
+#include <sstream>
+#include <vector>
+#include <gnssdriver.h>
diff --git a/nfc/NfcCxSample/README.md b/nfc/NfcCxSample/README.md
new file mode 100644
index 00000000..fe2abbc8
--- /dev/null
+++ b/nfc/NfcCxSample/README.md
@@ -0,0 +1,49 @@
+---
+topic: sample
+name: NFC CX client driver sample
+description: Sample code for creating a NFC driver using the NFC Class Extension.
+generateZip: true
+author: windows-driver-content
+languages:
+- cpp
+products:
+- windows
+technologies:
+- WDF
+- UMDF2
+---
+
+# NFC CX client driver sample
+
+A template for creating an NFC functional driver using the NFC Class Extension (CX) driver.
+
+This is a complete version of the code created in the [NFC CX quick start guide](https://docs.microsoft.com/windows-hardware/drivers/nfc/nfc-class-extension-quickstart).
+
+## Prerequisites
+
+To use the NFC CX, your NFC Controller must implement NFC Forum's [NFC Controller Interface (NCI)](https://nfc-forum.org/our-work/specifications-and-application-documents/specifications/nfc-controller-interface-nci-specification/) protocol.
+
+In addition, the NFC CX requires the driver to use the [UMDF 2](https://docs.microsoft.com/windows-hardware/drivers/wdf/overview-of-the-umdf) framework.
+
+## Universal windows driver compliant
+
+This sample builds a Universal Windows Driver. It uses only APIs and DDIs that are included in OneCoreUAP.
+
+## File manifest
+
+### WDK
+
+- [NfcCx.h](https://docs.microsoft.com/windows-hardware/drivers/ddi/content/nfccx/) - The NFC CX's client driver API. (This file is included in the WDK.)
+
+### Project
+
+- [Driver.cpp](windows-drivertemplate-nfc/Driver.cpp)
+ - `DriverEntry` - Driver initialization.
+
+- [Device.cpp](windows-drivertemplate-nfc/Device.cpp)
+ - `DeviceContext::AddDevice` - Device initialization, including initializing the NFC CX driver.
+ - `DeviceContext::WriteNciPacket` - The implementation of the [`EvtNfcCxWriteNciPacket`](https://docs.microsoft.com/windows-hardware/drivers/ddi/content/nfccx/nc-nfccx-evt_nfc_cx_write_nci_packet) callback function.
+ - `DeviceContext::ReadNciPacket` - Demonstrates calling [`NfcCxNciReadNotification`](https://docs.microsoft.com/windows-hardware/drivers/ddi/content/nfccx/nf-nfccx-nfccxncireadnotification).
+
+- [Device.h](windows-drivertemplate-nfc/Device.h)
+ - `DeviceContext` - The class that stores the device instance's state.
diff --git a/nfc/NfcCxSample/windows-drivertemplate-nfc.sln b/nfc/NfcCxSample/windows-drivertemplate-nfc.sln
new file mode 100644
index 00000000..c2a7a8bf
--- /dev/null
+++ b/nfc/NfcCxSample/windows-drivertemplate-nfc.sln
@@ -0,0 +1,51 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.28010.2048
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "windows-drivertemplate-nfc", "windows-drivertemplate-nfc\windows-drivertemplate-nfc.vcxproj", "{E84EF126-888E-4B14-93A3-3B7776036D01}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|ARM = Debug|ARM
+ Debug|ARM64 = Debug|ARM64
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|ARM = Release|ARM
+ Release|ARM64 = Release|ARM64
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {E84EF126-888E-4B14-93A3-3B7776036D01}.Debug|ARM.ActiveCfg = Debug|ARM
+ {E84EF126-888E-4B14-93A3-3B7776036D01}.Debug|ARM.Build.0 = Debug|ARM
+ {E84EF126-888E-4B14-93A3-3B7776036D01}.Debug|ARM.Deploy.0 = Debug|ARM
+ {E84EF126-888E-4B14-93A3-3B7776036D01}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {E84EF126-888E-4B14-93A3-3B7776036D01}.Debug|ARM64.Build.0 = Debug|ARM64
+ {E84EF126-888E-4B14-93A3-3B7776036D01}.Debug|ARM64.Deploy.0 = Debug|ARM64
+ {E84EF126-888E-4B14-93A3-3B7776036D01}.Debug|x64.ActiveCfg = Debug|x64
+ {E84EF126-888E-4B14-93A3-3B7776036D01}.Debug|x64.Build.0 = Debug|x64
+ {E84EF126-888E-4B14-93A3-3B7776036D01}.Debug|x64.Deploy.0 = Debug|x64
+ {E84EF126-888E-4B14-93A3-3B7776036D01}.Debug|x86.ActiveCfg = Debug|Win32
+ {E84EF126-888E-4B14-93A3-3B7776036D01}.Debug|x86.Build.0 = Debug|Win32
+ {E84EF126-888E-4B14-93A3-3B7776036D01}.Debug|x86.Deploy.0 = Debug|Win32
+ {E84EF126-888E-4B14-93A3-3B7776036D01}.Release|ARM.ActiveCfg = Release|ARM
+ {E84EF126-888E-4B14-93A3-3B7776036D01}.Release|ARM.Build.0 = Release|ARM
+ {E84EF126-888E-4B14-93A3-3B7776036D01}.Release|ARM.Deploy.0 = Release|ARM
+ {E84EF126-888E-4B14-93A3-3B7776036D01}.Release|ARM64.ActiveCfg = Release|ARM64
+ {E84EF126-888E-4B14-93A3-3B7776036D01}.Release|ARM64.Build.0 = Release|ARM64
+ {E84EF126-888E-4B14-93A3-3B7776036D01}.Release|ARM64.Deploy.0 = Release|ARM64
+ {E84EF126-888E-4B14-93A3-3B7776036D01}.Release|x64.ActiveCfg = Release|x64
+ {E84EF126-888E-4B14-93A3-3B7776036D01}.Release|x64.Build.0 = Release|x64
+ {E84EF126-888E-4B14-93A3-3B7776036D01}.Release|x64.Deploy.0 = Release|x64
+ {E84EF126-888E-4B14-93A3-3B7776036D01}.Release|x86.ActiveCfg = Release|Win32
+ {E84EF126-888E-4B14-93A3-3B7776036D01}.Release|x86.Build.0 = Release|Win32
+ {E84EF126-888E-4B14-93A3-3B7776036D01}.Release|x86.Deploy.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {E67B0F62-B28A-4B28-845C-B31B2614CF22}
+ EndGlobalSection
+EndGlobal
diff --git a/nfc/NfcCxSample/windows-drivertemplate-nfc/Device.cpp b/nfc/NfcCxSample/windows-drivertemplate-nfc/Device.cpp
new file mode 100644
index 00000000..5429d2a8
--- /dev/null
+++ b/nfc/NfcCxSample/windows-drivertemplate-nfc/Device.cpp
@@ -0,0 +1,343 @@
+#include <new>
+
+#include "Device.h"
+
+// [Required]
+// Called when the device is provisioned during system boot or when a new device is plugged-in while the
+// system is running.
+//
+// https://docs.microsoft.com/windows-hardware/drivers/ddi/content/wdfdriver/nc-wdfdriver-evt_wdf_driver_device_add
+NTSTATUS DeviceContext::AddDevice(
+ _In_ WDFDRIVER Driver,
+ _Inout_ PWDFDEVICE_INIT DeviceInit)
+{
+ (void)Driver;
+
+ NTSTATUS status;
+
+ // Configure the NFC Class Extension.
+ // Note: The NFC_CX_TRANSPORT_TYPE is only used for telemetry purposes. It does not affect the behavior of
+ // the driver.
+ NFC_CX_CLIENT_CONFIG nfcCxConfig;
+ NFC_CX_CLIENT_CONFIG_INIT(&nfcCxConfig, NFC_CX_TRANSPORT_CUSTOM);
+
+#ifdef ENABLE_IF_IMPLEMENTING_CUSTOM_IOCTLS
+ nfcCxConfig.EvtNfcCxDeviceIoControl = IoControl;
+#endif
+
+ // Provide the NCI Write callback, which is called by the NFC CX when it has an NCI packet that needs to
+ // be sent to the NFC Controller.
+ nfcCxConfig.EvtNfcCxWriteNciPacket = WriteNciPacket;
+
+ // Instruct the NFC CX to read the existing NCI configuration values and only update them if necessary.
+ nfcCxConfig.DriverFlags = NFC_CX_DRIVER_ENABLE_EEPROM_WRITE_PROTECTION;
+
+ status = NfcCxDeviceInitConfig(DeviceInit, &nfcCxConfig);
+ if (!NT_SUCCESS(status))
+ {
+ return status;
+ }
+
+ // Create the PnP power callbacks configuration.
+ WDF_PNPPOWER_EVENT_CALLBACKS pnpCallbacks;
+ WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpCallbacks);
+ pnpCallbacks.EvtDevicePrepareHardware = PrepareHardware;
+ pnpCallbacks.EvtDeviceReleaseHardware = ReleaseHardware;
+ pnpCallbacks.EvtDeviceD0Entry = D0Entry;
+ pnpCallbacks.EvtDeviceD0Exit = D0Exit;
+
+ // Set the PnP power callbacks.
+ WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpCallbacks);
+
+ // Create WDF object attributes for the device.
+ WDF_OBJECT_ATTRIBUTES deviceAttributes;
+ WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&deviceAttributes, DeviceContext);
+ deviceAttributes.EvtDestroyCallback = Destroy;
+
+ // Create the device.
+ WDFDEVICE device;
+ status = WdfDeviceCreate(&DeviceInit, &deviceAttributes, &device);
+ if (!NT_SUCCESS(status))
+ {
+ return status;
+ }
+
+ // Get a pointer to the raw memory that WDF allocated for the Device class.
+ DeviceContext* context = DeviceGetContext(device);
+
+ // Initialize the raw memory using C++'s placement new operator.
+ // https://en.cppreference.com/w/cpp/language/new
+ new (context) DeviceContext(device);
+
+ // Let the NFC Class Extension initialize the device.
+ status = NfcCxDeviceInitialize(device);
+ if (!NT_SUCCESS(status))
+ {
+ return status;
+ }
+
+ // Create the RF config. (Enable everything.)
+ NFC_CX_RF_DISCOVERY_CONFIG discoveryConfig;
+ NFC_CX_RF_DISCOVERY_CONFIG_INIT(&discoveryConfig);
+ discoveryConfig.PollConfig = NFC_CX_POLL_NFC_A | NFC_CX_POLL_NFC_B | NFC_CX_POLL_NFC_F_212 | NFC_CX_POLL_NFC_F_424 | NFC_CX_POLL_NFC_15693 | NFC_CX_POLL_NFC_ACTIVE | NFC_CX_POLL_NFC_A_KOVIO;
+ discoveryConfig.NfcIPMode = NFC_CX_NFCIP_NFC_A | NFC_CX_NFCIP_NFC_F_212 | NFC_CX_NFCIP_NFC_F_424 | NFC_CX_NFCIP_NFC_ACTIVE | NFC_CX_NFCIP_NFC_ACTIVE_A | NFC_CX_NFCIP_NFC_ACTIVE_F_212 | NFC_CX_NFCIP_NFC_ACTIVE_F_424;
+ discoveryConfig.NfcIPTgtMode = NFC_CX_NFCIP_TGT_NFC_A | NFC_CX_NFCIP_TGT_NFC_F | NFC_CX_NFCIP_TGT_NFC_ACTIVE_A | NFC_CX_NFCIP_TGT_NFC_ACTIVE_F;
+ discoveryConfig.NfcCEMode = NFC_CX_CE_NFC_A | NFC_CX_CE_NFC_B | NFC_CX_CE_NFC_F;
+
+ // Set the RF config.
+ status = NfcCxSetRfDiscoveryConfig(device, &discoveryConfig);
+ if (!NT_SUCCESS(status))
+ {
+ return status;
+ }
+
+#ifdef ENABLE_IF_USING_SEQUENCE_HANDLER_CALLBACKS
+ // Set the NFC Class Extension sequence handlers.
+ for (int sequenceType = 0; sequenceType != SequenceMaximum; ++sequenceType)
+ {
+ status = NfcCxRegisterSequenceHandler(device, NFC_CX_SEQUENCE(sequenceType), SequenceHandler);
+ if (!NT_SUCCESS(status))
+ {
+ return status;
+ }
+ }
+#endif
+
+ return STATUS_SUCCESS;
+}
+
+DeviceContext::DeviceContext(_In_ WDFDEVICE Device) :
+ _Device(Device)
+{
+}
+
+// [Required]
+// Called when the memory for the class is about to be freed by WDF.
+//
+// https://docs.microsoft.com/windows-hardware/drivers/ddi/content/wdfobject/nc-wdfobject-evt_wdf_object_context_destroy
+void DeviceContext::Destroy(
+ _In_ WDFOBJECT Object)
+{
+ // Manually call the destructor for the class.
+ // This mirrors the use of the placement new operator in `DeviceContext::AddDevice`.
+ DeviceContext* context = DeviceGetContext(Object);
+ context->~DeviceContext();
+}
+
+// [Likely required]
+// Called when the device's hardware resources are ready to be initialized.
+//
+// https://docs.microsoft.com/windows-hardware/drivers/ddi/content/wdfdevice/nc-wdfdevice-evt_wdf_device_prepare_hardware
+NTSTATUS DeviceContext::PrepareHardware(
+ _In_ WDFDEVICE Device,
+ _In_ WDFCMRESLIST ResourcesRaw,
+ _In_ WDFCMRESLIST ResourcesTranslated)
+{
+ (void)Device;
+ (void)ResourcesRaw;
+ (void)ResourcesTranslated;
+
+ // FIX ME:
+ // Initialize the hardware so that it is ready to accept NCI packets.
+
+ return STATUS_SUCCESS;
+}
+
+// [Likely required]
+// Called when the device's hardware resources are no longer accessible.
+//
+// https://docs.microsoft.com/windows-hardware/drivers/ddi/content/wdfdevice/nc-wdfdevice-evt_wdf_device_release_hardware
+NTSTATUS DeviceContext::ReleaseHardware(
+ _In_ WDFDEVICE Device,
+ _In_ WDFCMRESLIST ResourcesTranslated)
+{
+ (void)Device;
+ (void)ResourcesTranslated;
+
+ // FIX ME:
+ // If neccessary, free any resources created by PrepareHardware.
+
+ return STATUS_SUCCESS;
+}
+
+// [Likely required]
+// Called when the NFC Controller is entering the fully powered-on state.
+//
+// https://docs.microsoft.com/windows-hardware/drivers/ddi/content/wdfdevice/nc-wdfdevice-evt_wdf_device_d0_entry
+NTSTATUS DeviceContext::D0Entry(
+ _In_ WDFDEVICE Device,
+ _In_ WDF_POWER_DEVICE_STATE PreviousState)
+{
+ (void)PreviousState;
+
+ NTSTATUS status;
+
+ // Invoke the HostActionStart event, so that the NFC Class Extension initializes the NFC Controller (by
+ // sending the relevant NCI packets).
+ NFC_CX_HARDWARE_EVENT eventArgs = {};
+ eventArgs.HostAction = HostActionStart;
+
+ status = NfcCxHardwareEvent(Device, &eventArgs);
+ if (!NT_SUCCESS(status))
+ {
+ return status;
+ }
+
+ return STATUS_SUCCESS;
+}
+
+// [Likely required]
+// Called when the NFC Controller is entering a low power state.
+//
+// By default, the NFC Class Extension will prevent this callback from being invoked if there is an client
+// process that may be using the NFC Controller. So it is okay for the NFC Controller to be fully
+// uninitialized here.
+//
+// https://docs.microsoft.com/windows-hardware/drivers/ddi/content/wdfdevice/nc-wdfdevice-evt_wdf_device_d0_exit
+NTSTATUS DeviceContext::D0Exit(
+ _In_ WDFDEVICE Device,
+ _In_ WDF_POWER_DEVICE_STATE TargetState)
+{
+ (void)TargetState;
+
+ NTSTATUS status;
+
+ // Invoke the HostActionStop event, so that the NFC Class Extension uninitializes the NFC Controller (by sending
+ // the relevant NCI packets).
+ NFC_CX_HARDWARE_EVENT eventArgs = {};
+ eventArgs.HostAction = HostActionStop;
+
+ status = NfcCxHardwareEvent(Device, &eventArgs);
+ if (!NT_SUCCESS(status))
+ {
+ return status;
+ }
+
+ return STATUS_SUCCESS;
+}
+
+// [Optional]
+// Called when certain state transitions occur within the NFC Class Extension state machine. This can be used to send
+// custom commands to the NFC Controller if neccessary.
+//
+// https://docs.microsoft.com/windows-hardware/drivers/nfc/sequence-handling
+void DeviceContext::SequenceHandler(
+ _In_ WDFDEVICE Device,
+ _In_ NFC_CX_SEQUENCE Sequence,
+ _In_ PFN_NFC_CX_SEQUENCE_COMPLETION_ROUTINE CompletionRoutine,
+ _In_opt_ WDFCONTEXT CompletionContext)
+{
+ (void)Sequence;
+
+ // Nothing to do. So complete the sequence handler immediately.
+ // Note: CompletionRoutine may be called asynchronously.
+ CompletionRoutine(Device, STATUS_SUCCESS, 0, CompletionContext);
+}
+
+// [Optional]
+// Can be used to implement custom IOCTLs.
+//
+// The NFC Class Extension registers for the default I/O queue and so it gets the first crack at handling all I/O requests.
+// If this callback is enabled, any IOCTL the NFC Class Extension doesn't recognize will be forwarded here.
+//
+// https://docs.microsoft.com/windows-hardware/drivers/ddi/content/nfccx/nc-nfccx-evt_nfc_cx_device_io_control
+void DeviceContext::IoControl(
+ _In_ WDFDEVICE Device,
+ _In_ WDFREQUEST Request,
+ _In_ size_t OutputBufferLength,
+ _In_ size_t InputBufferLength,
+ _In_ ULONG IoControlCode)
+{
+ (void)Device;
+ (void)OutputBufferLength;
+ (void)InputBufferLength;
+ (void)IoControlCode;
+
+ // No custom IOCTLs are currently supported. So complete all I/O requests with a standard error.
+ WdfRequestComplete(Request, STATUS_INVALID_DEVICE_STATE);
+}
+
+// [Required]
+// Called by the NFC Class Extension when an NCI packet must be sent to the NFC Controller.
+//
+// https://docs.microsoft.com/windows-hardware/drivers/ddi/content/nfccx/nc-nfccx-evt_nfc_cx_write_nci_packet
+void DeviceContext::WriteNciPacket(
+ _In_ WDFDEVICE Device,
+ _In_ WDFREQUEST Request)
+{
+ (void)Device;
+
+ NTSTATUS status;
+
+ // Get the NCI packet.
+ void* nciPacket;
+ size_t nciPacketLength;
+ status = WdfRequestRetrieveInputBuffer(Request, 0, &nciPacket, &nciPacketLength);
+ if (!NT_SUCCESS(status))
+ {
+ WdfRequestComplete(Request, status);
+ return;
+ }
+
+ // FIX ME:
+ // Send NCI packet to NFC Controller hardware using the relevant bus API.
+ // For example,
+ // - I2C or SPI: https://docs.microsoft.com/windows-hardware/drivers/spb/spb-peripheral-device-drivers
+ // - USB: https://docs.microsoft.com/windows-hardware/drivers/usbcon/usb-driver-development-guide
+
+ // FIX ME:
+ // Complete I/O request with STATUS_SUCCESS if NCI packet is succesfully sent to the NFC Controller.
+ WdfRequestComplete(Request, STATUS_NOT_IMPLEMENTED);
+}
+
+// FIX ME:
+// Ensure NfcCxNciReadNotification is called when the NFC Controller needs to send an NCI packet to the driver.
+// This is usually done in response to a hardware notification. For example,
+// - GPIO interrupt (I2C or SPI): https://docs.microsoft.com/windows-hardware/drivers/gpio/gpio-interrupts
+// - USB continuous reader: https://docs.microsoft.com/windows-hardware/drivers/usbcon/how-to-use-the-continous-reader-for-getting-data-from-a-usb-endpoint--umdf-/
+//
+// https://docs.microsoft.com/windows-hardware/drivers/ddi/content/nfccx/nf-nfccx-nfccxncireadnotification
+
+// A helper function that forwards NCI packets from the NFC Controller to the NFC Class Extension driver.
+//
+// NOTE: If the NCI packet is already packaged within an existing WDFMEMORY, then the NfcCxNciReadNotification
+// function can be called directly.
+NTSTATUS DeviceContext::ReadNciPacket(
+ _In_reads_bytes_(nciPacketLength) void* nciPacket,
+ _In_ size_t nciPacketLength)
+{
+ NTSTATUS status;
+
+ if (!_NciReadMemory)
+ {
+ // Create the WDFMEMORY object that will be used for all NCI reads.
+ WDF_OBJECT_ATTRIBUTES memoryAttributes;
+ WDF_OBJECT_ATTRIBUTES_INIT(&memoryAttributes);
+ memoryAttributes.ParentObject = _Device;
+
+ status = WdfMemoryCreatePreallocated(&memoryAttributes, nciPacket, nciPacketLength, &_NciReadMemory);
+ if (!NT_SUCCESS(status))
+ {
+ return status;
+ }
+ }
+ else
+ {
+ // Re-assign the WDFMEMORY to point to the new NCI packet.
+ status = WdfMemoryAssignBuffer(_NciReadMemory, nciPacket, nciPacketLength);
+ if (!NT_SUCCESS(status))
+ {
+ return status;
+ }
+ }
+
+ // Note: NfcCxNciReadNotification does not store a reference to the WDFMEMORY object passed to it. So it
+ // is safe to free the NCI packet's memory after the call has completed.
+ status = NfcCxNciReadNotification(_Device, _NciReadMemory);
+ if (!NT_SUCCESS(status))
+ {
+ return status;
+ }
+
+ return STATUS_SUCCESS;
+}
diff --git a/nfc/NfcCxSample/windows-drivertemplate-nfc/Device.h b/nfc/NfcCxSample/windows-drivertemplate-nfc/Device.h
new file mode 100644
index 00000000..5d373d11
--- /dev/null
+++ b/nfc/NfcCxSample/windows-drivertemplate-nfc/Device.h
@@ -0,0 +1,74 @@
+#pragma once
+
+#include <windows.h>
+#include <wdf.h>
+#include <NfcCx.h>
+
+class DeviceContext
+{
+public:
+ // Implementation of `EvtDriverDeviceAdd`.
+ static NTSTATUS AddDevice(
+ _In_ WDFDRIVER Driver,
+ _Inout_ PWDFDEVICE_INIT DeviceInit);
+
+private:
+ DeviceContext(_In_ WDFDEVICE Device);
+ ~DeviceContext() = default;
+
+ // Implementation of `EvtDestroyCallback`.
+ static void Destroy(
+ _In_ WDFOBJECT Object);
+
+ // Implementation of `EvtDevicePrepareHardware`.
+ static NTSTATUS PrepareHardware(
+ _In_ WDFDEVICE Device,
+ _In_ WDFCMRESLIST ResourcesRaw,
+ _In_ WDFCMRESLIST ResourcesTranslated);
+
+ // Implementation of `EvtDeviceReleaseHardware`.
+ static NTSTATUS ReleaseHardware(
+ _In_ WDFDEVICE Device,
+ _In_ WDFCMRESLIST ResourcesTranslated);
+
+ // Implementation of `EvtDeviceD0Entry`.
+ static NTSTATUS D0Entry(
+ _In_ WDFDEVICE Device,
+ _In_ WDF_POWER_DEVICE_STATE PreviousState);
+
+ // Implementation of `EvtDeviceD0Exit`.
+ static NTSTATUS D0Exit(
+ _In_ WDFDEVICE Device,
+ _In_ WDF_POWER_DEVICE_STATE TargetState);
+
+ // Implementation of `EvtNfcCxSequenceHandler`.
+ static void SequenceHandler(
+ _In_ WDFDEVICE Device,
+ _In_ NFC_CX_SEQUENCE Sequence,
+ _In_ PFN_NFC_CX_SEQUENCE_COMPLETION_ROUTINE CompletionRoutine,
+ _In_opt_ WDFCONTEXT CompletionContext);
+
+ static void IoControl(
+ _In_ WDFDEVICE Device,
+ _In_ WDFREQUEST Request,
+ _In_ size_t OutputBufferLength,
+ _In_ size_t InputBufferLength,
+ _In_ ULONG IoControlCode);
+
+ // Implementation of `EvtNfcCxWriteNciPacket`.
+ static void WriteNciPacket(
+ _In_ WDFDEVICE Device,
+ _In_ WDFREQUEST Request);
+
+ NTSTATUS ReadNciPacket(
+ _In_reads_bytes_(nciPacketLength) void* nciPacket,
+ _In_ size_t nciPacketLength);
+
+ const WDFDEVICE _Device = nullptr;
+ WDFMEMORY _NciReadMemory = nullptr;
+};
+
+// Define the DeviceGetContext() function which can be used to get a pointer the DeviceContext from a WDFDEVICE object.
+// Equivalent to:
+// DeviceContext* DeviceGetContext(WDFOBJECT Handle) { ... }
+WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(DeviceContext, DeviceGetContext);
diff --git a/nfc/NfcCxSample/windows-drivertemplate-nfc/Driver.cpp b/nfc/NfcCxSample/windows-drivertemplate-nfc/Driver.cpp
new file mode 100644
index 00000000..c07eabe8
--- /dev/null
+++ b/nfc/NfcCxSample/windows-drivertemplate-nfc/Driver.cpp
@@ -0,0 +1,41 @@
+#include <windows.h>
+#include <wdf.h>
+
+#include "Device.h"
+
+extern "C" DRIVER_INITIALIZE DriverEntry;
+
+// [Required]
+// The entry point for the driver.
+//
+// In general, almost nothing should be done during driver initialization. Instead, almost all resources should
+// be associated with a specific device.
+//
+// https://docs.microsoft.com/windows-hardware/drivers/wdf/driverentry-for-kmdf-drivers
+extern "C" NTSTATUS DriverEntry(
+ _In_ PDRIVER_OBJECT DriverObject,
+ _In_ PUNICODE_STRING RegistryPath
+ )
+{
+ NTSTATUS status;
+
+ // Specify `DeviceContext::AddDevice` as the `EvtDriverDeviceAdd` callback function
+ // for the driver.
+ WDF_DRIVER_CONFIG driverConfig;
+ WDF_DRIVER_CONFIG_INIT(&driverConfig, DeviceContext::AddDevice);
+
+ // Initialize WDF.
+ status = WdfDriverCreate(
+ DriverObject,
+ RegistryPath,
+ WDF_NO_OBJECT_ATTRIBUTES,
+ &driverConfig,
+ WDF_NO_HANDLE
+ );
+ if (!NT_SUCCESS(status))
+ {
+ return status;
+ }
+
+ return STATUS_SUCCESS;
+}
diff --git a/nfc/NfcCxSample/windows-drivertemplate-nfc/windows-drivertemplate-nfc.inf b/nfc/NfcCxSample/windows-drivertemplate-nfc/windows-drivertemplate-nfc.inf
new file mode 100644
index 00000000..d6070a8c
--- /dev/null
+++ b/nfc/NfcCxSample/windows-drivertemplate-nfc/windows-drivertemplate-nfc.inf
Binary files differ
diff --git a/nfc/NfcCxSample/windows-drivertemplate-nfc/windows-drivertemplate-nfc.vcxproj b/nfc/NfcCxSample/windows-drivertemplate-nfc/windows-drivertemplate-nfc.vcxproj
new file mode 100644
index 00000000..ce9fe362
--- /dev/null
+++ b/nfc/NfcCxSample/windows-drivertemplate-nfc/windows-drivertemplate-nfc.vcxproj
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|ARM">
+ <Configuration>Debug</Configuration>
+ <Platform>ARM</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|ARM">
+ <Configuration>Release</Configuration>
+ <Platform>ARM</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|ARM64">
+ <Configuration>Debug</Configuration>
+ <Platform>ARM64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|ARM64">
+ <Configuration>Release</Configuration>
+ <Platform>ARM64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <ItemGroup>
+ <Inf Include="windows-drivertemplate-nfc.inf" />
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{E84EF126-888E-4B14-93A3-3B7776036D01}</ProjectGuid>
+ <TemplateGuid>{2177f19c-eb4c-4687-9e7f-f9eec1f12cf1}</TemplateGuid>
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+ <MinimumVisualStudioVersion>12.0</MinimumVisualStudioVersion>
+ <Configuration>Debug</Configuration>
+ <Platform Condition="'$(Platform)' == ''">Win32</Platform>
+ <RootNamespace>windows_drivertemplate_nfc</RootNamespace>
+ <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
+ </PropertyGroup>
+ <PropertyGroup Label="PropertySheets">
+ <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset>
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Label="Configuration">
+ <TargetVersion>Windows10</TargetVersion>
+ <UMDF_VERSION_MAJOR>2</UMDF_VERSION_MAJOR>
+ <NfcDriver>true</NfcDriver>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
+ <UseDebugLibraries>true</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
+ <UseDebugLibraries>false</UseDebugLibraries>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <DebuggerFlavor>DbgengRemoteDebugger</DebuggerFlavor>
+ </PropertyGroup>
+ <PropertyGroup>
+ <RunCodeAnalysis>true</RunCodeAnalysis>
+ </PropertyGroup>
+ <ItemDefinitionGroup>
+ <ClCompile>
+ <EnablePREfast>true</EnablePREfast>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <FilesToPackage Include="$(TargetPath)" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="Device.cpp" />
+ <ClCompile Include="Driver.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="Device.h" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/nfc/NfcCxSample/windows-drivertemplate-nfc/windows-drivertemplate-nfc.vcxproj.filters b/nfc/NfcCxSample/windows-drivertemplate-nfc/windows-drivertemplate-nfc.vcxproj.filters
new file mode 100644
index 00000000..c02665df
--- /dev/null
+++ b/nfc/NfcCxSample/windows-drivertemplate-nfc/windows-drivertemplate-nfc.vcxproj.filters
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <ClCompile Include="Driver.cpp" />
+ <ClCompile Include="Device.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <Inf Include="windows-drivertemplate-nfc.inf" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="Device.h" />
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/print/XPSDrvSmpl/README.md b/print/XPSDrvSmpl/README.md
index 79618500..1d1eb790 100644
--- a/print/XPSDrvSmpl/README.md
+++ b/print/XPSDrvSmpl/README.md
@@ -17,7 +17,7 @@ Windows includes a print architecture and a document format known as XPS (XML Pa
This sample is intended to provide a starting point for developing XPSDrv printer drivers and to illustrate the facility and potential of an XPSDrv print driver. This goal is accomplished by implementing a number of real-world features within a set of XPS print pipeline filters that are configured through a configuration plug-in that supports custom UI content and PrintTicket handling.
-The sample broadly consists of three components: a set of filters, a configuration plug-in for handling custom UI content, and a configuration plug-in for handling more advanced PrintTicket features. For more information, see [XPS Printing Features](http://msdn.microsoft.com/en-us/library/windows/hardware/ff564299(v=vs.85).aspx).
+The sample broadly consists of three components: a set of filters, a configuration plug-in for handling custom UI content, and a configuration plug-in for handling more advanced PrintTicket features. For more information, see [XPS Printing Features](https://docs.microsoft.com/en-us/windows-hardware/drivers/print/xps-printing-features).
Build the sample
@@ -46,7 +46,7 @@ To build a driver solution using Windows Driver Kit (WDK) 10 and Visual Studio 2
2. In the Version section, add a reference to a catalog file like this: CatalogFile=XpsDrvSmpl.cat.
3. In the SourceDisksFiles section, change the location of the DLL files you are building to =1. This indicates that there is no architecture specific directory in this driver. If you ship multiple architectures simultaneously, you will need to collate the driver INF manually.
-At this point, Visual Studio 2017 will be able to build a driver package and output the files to disk. In order to configure driver signing and deployment, see [Developing, Testing, and Deploying Drivers](http://msdn.microsoft.com/en-us/library/windows/hardware/ff554651(v=vs.85).aspx).
+At this point, Visual Studio 2017 will be able to build a driver package and output the files to disk. In order to configure driver signing and deployment, see [Developing, Testing, and Deploying Drivers](https://docs.microsoft.com/en-us/windows-hardware/drivers/develop/).
**Note** If you compile your sample driver with Microsoft Visual Studio version 10, or 11 with the \_DEBUG flag set, then you should not use CComVariant on the following two XPS Print Filter Pipeline properties:
@@ -90,7 +90,7 @@ Two interfaces are defined in *ipkarch.h* and *ipkfile.h* that need support from
- Simplify the scaling filter to use the XPS interfaces (like the other four filters)
- License the third-party zip library that is used in the sample
-- Modify the sample to use another ZIP library. For example, you can modify the sample to use the [Packaging API Reference](http://msdn.microsoft.com/en-us/library/windows/desktop/dd371643(v=vs.85).aspx)
+- Modify the sample to use another ZIP library. For example, you can modify the sample to use the [Packaging API Reference](https://docs.microsoft.com/en-us/previous-versions/windows/desktop/opc/packaging-programming-reference)
IPKArch defines an interface for initializing, controlling, and accessing the PK archive. IPKFile defines an interface that abstracts the details of a PK archive file header record from the XPS container handling. Access to the files within the archive is provided through a map between the file name and file objects that support the IPKFile interface. This allows the XPS processing code to retrieve file data by name (a convenience as the interaction between parts and relationships between parts is defined using the part name).
diff --git a/serial/serial/trace.h b/serial/serial/trace.h
index f06efa9f..cb7f5f34 100644
--- a/serial/serial/trace.h
+++ b/serial/serial/trace.h
@@ -90,7 +90,7 @@ TraceEvents (
#define WPP_CHECK_FOR_NULL_STRING //to prevent exceptions due to NULL strings
#define WPP_CONTROL_GUIDS \
- WPP_DEFINE_CONTROL_GUID(SerialTraceGuid,(bc6c9364,fc67,42c5,acf7,abed3b12ecc6), \
+ WPP_DEFINE_CONTROL_GUID(SerialTraceGuid,(f3a79ab6,9827,4419,9465,45cf949ef659), \
WPP_DEFINE_BIT(DBG_INIT) /* bit 0 = 0x00000001 */ \
WPP_DEFINE_BIT(DBG_PNP) /* bit 1 = 0x00000002 */ \
WPP_DEFINE_BIT(DBG_POWER) /* bit 2 = 0x00000004 */ \