summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGirish Pattabiraman <[email protected]>2018-08-13 10:54:19 -0700
committerAdonais Romero González <[email protected]>2018-08-13 10:54:19 -0700
commit2af3e666d01a60568c2875b4ccbd56b122ad714f (patch)
tree29825a7b7cb0f6a9f77f1ab6e5813665d45ca4cc
parent181c180357cdf9a04d5e3bb21a8e86dc2155ca69 (diff)
Update sample to get ready for RS4 changes - merge pre-RS4 fixes. (#256)
* Format Changes ============== * Add KSEVENT_PINCAPS_FORMATCHANGE to Bluetooth HFP Endpoints * Remove 8 bit formats from Bluetooth HFP Endpoints Name Template ============== * Bluetooth Endpoints are now based on templates in INF and then customized with endpoints specific data Sideband Common Interface for future Sideband buses =================================================== * Add ISidebandDevice * Add current directory to TabletAudioSample include path. Remove unused compiler flags. * RS4 bug fixes
-rw-r--r--audio/sysvad/APO/DelayAPO/Delay.cpp (renamed from audio/sysvad/SwapAPO/DelayAPO/Delay.cpp)0
-rw-r--r--audio/sysvad/APO/DelayAPO/DelayAPO.h (renamed from audio/sysvad/SwapAPO/DelayAPO/DelayAPO.h)0
-rw-r--r--audio/sysvad/APO/DelayAPO/DelayAPO.vcxproj (renamed from audio/sysvad/SwapAPO/DelayAPO/DelayAPO.vcxproj)16
-rw-r--r--audio/sysvad/APO/DelayAPO/DelayAPO.vcxproj.Filters (renamed from audio/sysvad/SwapAPO/DelayAPO/DelayAPO.vcxproj.Filters)36
-rw-r--r--audio/sysvad/APO/DelayAPO/DelayAPODll.cpp70
-rw-r--r--audio/sysvad/APO/DelayAPO/DelayAPODll.def (renamed from audio/sysvad/SwapAPO/DelayAPO/DelayAPODll.def)2
-rw-r--r--audio/sysvad/APO/DelayAPO/DelayAPODll.idl (renamed from audio/sysvad/SwapAPO/DelayAPO/DelayAPODll.idl)0
-rw-r--r--audio/sysvad/APO/DelayAPO/DelayAPODll.rc (renamed from audio/sysvad/SwapAPO/DelayAPO/DelayAPODll.rc)6
-rw-r--r--audio/sysvad/APO/DelayAPO/DelayAPODll.rgs (renamed from audio/sysvad/SwapAPO/DelayAPO/DelayAPODll.rgs)0
-rw-r--r--audio/sysvad/APO/DelayAPO/DelayAPOInterface.idl (renamed from audio/sysvad/SwapAPO/DelayAPO/DelayAPOInterface.idl)0
-rw-r--r--audio/sysvad/APO/DelayAPO/DelayAPOMFX.cpp (renamed from audio/sysvad/SwapAPO/DelayAPO/DelayAPOMFX.cpp)0
-rw-r--r--audio/sysvad/APO/DelayAPO/DelayAPOMFX.rgs (renamed from audio/sysvad/SwapAPO/DelayAPO/DelayAPOMFX.rgs)0
-rw-r--r--audio/sysvad/APO/DelayAPO/DelayAPOSFX.cpp (renamed from audio/sysvad/SwapAPO/DelayAPO/DelayAPOSFX.cpp)0
-rw-r--r--audio/sysvad/APO/DelayAPO/DelayAPOSFX.rgs (renamed from audio/sysvad/SwapAPO/DelayAPO/DelayAPOSFX.rgs)0
-rw-r--r--audio/sysvad/APO/DelayAPO/Resource.h (renamed from audio/sysvad/SwapAPO/DelayAPO/Resource.h)0
-rw-r--r--audio/sysvad/APO/DelayAPO/delayapo.png (renamed from audio/sysvad/SwapAPO/DelayAPO/delayapo.png)bin1180 -> 1180 bytes
-rw-r--r--audio/sysvad/APO/DelayAPO/makefile (renamed from audio/sysvad/SwapAPO/DelayAPO/makefile)0
-rw-r--r--audio/sysvad/APO/DelayAPO/sources (renamed from audio/sysvad/SwapAPO/DelayAPO/sources)0
-rw-r--r--audio/sysvad/APO/Inc/CommonMacros.h (renamed from audio/sysvad/SwapAPO/Inc/CommonMacros.h)0
-rw-r--r--audio/sysvad/APO/Inc/CustomPropKeys.h (renamed from audio/sysvad/SwapAPO/Inc/CustomPropKeys.h)0
-rw-r--r--audio/sysvad/APO/Inc/tlist.h (renamed from audio/sysvad/SwapAPO/Inc/tlist.h)0
-rw-r--r--audio/sysvad/APO/SwapAPO/Resource.h (renamed from audio/sysvad/SwapAPO/APO/Resource.h)0
-rw-r--r--audio/sysvad/APO/SwapAPO/SwapAPO.h (renamed from audio/sysvad/SwapAPO/APO/SwapAPO.h)0
-rw-r--r--audio/sysvad/APO/SwapAPO/SwapAPO.vcxproj (renamed from audio/sysvad/SwapAPO/APO/SwapAPO.vcxproj)16
-rw-r--r--audio/sysvad/APO/SwapAPO/SwapAPO.vcxproj.Filters (renamed from audio/sysvad/SwapAPO/APO/SwapAPO.vcxproj.Filters)36
-rw-r--r--audio/sysvad/APO/SwapAPO/SwapAPODll.cpp72
-rw-r--r--audio/sysvad/APO/SwapAPO/SwapAPODll.def (renamed from audio/sysvad/SwapAPO/APO/SwapAPODll.def)2
-rw-r--r--audio/sysvad/APO/SwapAPO/SwapAPODll.idl (renamed from audio/sysvad/SwapAPO/APO/SwapAPODll.idl)0
-rw-r--r--audio/sysvad/APO/SwapAPO/SwapAPODll.rc (renamed from audio/sysvad/SwapAPO/APO/SwapAPODll.rc)6
-rw-r--r--audio/sysvad/APO/SwapAPO/SwapAPODll.rgs (renamed from audio/sysvad/SwapAPO/APO/SwapAPODll.rgs)0
-rw-r--r--audio/sysvad/APO/SwapAPO/SwapAPOInterface.idl (renamed from audio/sysvad/SwapAPO/APO/SwapAPOInterface.idl)0
-rw-r--r--audio/sysvad/APO/SwapAPO/SwapAPOMFX.rgs (renamed from audio/sysvad/SwapAPO/APO/SwapAPOMFX.rgs)0
-rw-r--r--audio/sysvad/APO/SwapAPO/SwapAPOSFX.rgs (renamed from audio/sysvad/SwapAPO/APO/SwapAPOSFX.rgs)0
-rw-r--r--audio/sysvad/APO/SwapAPO/makefile (renamed from audio/sysvad/SwapAPO/APO/makefile)0
-rw-r--r--audio/sysvad/APO/SwapAPO/sources (renamed from audio/sysvad/SwapAPO/APO/sources)0
-rw-r--r--audio/sysvad/APO/SwapAPO/swap.cpp (renamed from audio/sysvad/SwapAPO/APO/swap.cpp)0
-rw-r--r--audio/sysvad/APO/SwapAPO/swapapo.png (renamed from audio/sysvad/SwapAPO/APO/swapapo.png)bin1251 -> 1251 bytes
-rw-r--r--audio/sysvad/APO/SwapAPO/swapapomfx.cpp (renamed from audio/sysvad/SwapAPO/APO/swapapomfx.cpp)0
-rw-r--r--audio/sysvad/APO/SwapAPO/swapaposfx.cpp (renamed from audio/sysvad/SwapAPO/APO/swapaposfx.cpp)0
-rw-r--r--audio/sysvad/BthhfpDevice.cpp3319
-rw-r--r--audio/sysvad/BthhfpDevice.h476
-rw-r--r--audio/sysvad/ContosoKeywordDetector.h2
-rw-r--r--audio/sysvad/EndpointsCommon/EndpointsCommon.vcxproj17
-rw-r--r--audio/sysvad/EndpointsCommon/EndpointsCommon.vcxproj.Filters43
-rw-r--r--audio/sysvad/EndpointsCommon/MiniportAudioEngineNode.cpp264
-rw-r--r--audio/sysvad/EndpointsCommon/MiniportStreamAudioEngineNode.cpp102
-rw-r--r--audio/sysvad/EndpointsCommon/NewDelete.cpp157
-rw-r--r--audio/sysvad/EndpointsCommon/NewDelete.h116
-rw-r--r--audio/sysvad/EndpointsCommon/bthhfpmictopo.cpp14
-rw-r--r--audio/sysvad/EndpointsCommon/bthhfpmicwavtable.h50
-rw-r--r--audio/sysvad/EndpointsCommon/bthhfpmicwbwavtable.h109
-rw-r--r--audio/sysvad/EndpointsCommon/bthhfpminipairs.h72
-rw-r--r--audio/sysvad/EndpointsCommon/bthhfpminwavert.cpp19
-rw-r--r--audio/sysvad/EndpointsCommon/bthhfpspeakertopo.cpp14
-rw-r--r--audio/sysvad/EndpointsCommon/bthhfpspeakertoptable.h4
-rw-r--r--audio/sysvad/EndpointsCommon/bthhfpspeakerwavtable.h346
-rw-r--r--audio/sysvad/EndpointsCommon/bthhfpspeakerwbwavtable.h522
-rw-r--r--audio/sysvad/EndpointsCommon/bthhfptopo.cpp99
-rw-r--r--audio/sysvad/EndpointsCommon/micarray1toptable.h4
-rw-r--r--audio/sysvad/EndpointsCommon/micarraytopo.cpp21
-rw-r--r--audio/sysvad/EndpointsCommon/micarraywavtable.h23
-rw-r--r--audio/sysvad/EndpointsCommon/mintopo.cpp52
-rw-r--r--audio/sysvad/EndpointsCommon/mintopo.h46
-rw-r--r--audio/sysvad/EndpointsCommon/minwavert.cpp641
-rw-r--r--audio/sysvad/EndpointsCommon/minwavert.h232
-rw-r--r--audio/sysvad/EndpointsCommon/minwavertstream.cpp496
-rw-r--r--audio/sysvad/EndpointsCommon/minwavertstream.h37
-rw-r--r--audio/sysvad/EndpointsCommon/simple.h13
-rw-r--r--audio/sysvad/EndpointsCommon/sources30
-rw-r--r--audio/sysvad/EndpointsCommon/speakerhptopo.cpp1
-rw-r--r--audio/sysvad/EndpointsCommon/speakerhptoptable.h14
-rw-r--r--audio/sysvad/EndpointsCommon/speakerhpwavtable.h6
-rw-r--r--audio/sysvad/EndpointsCommon/speakerwavtable.h6
-rw-r--r--audio/sysvad/KeywordDetectorAdapter/KeywordDetectorContosoAdapter.cpp2
-rw-r--r--audio/sysvad/Package/package.VcxProj4
-rw-r--r--audio/sysvad/PhoneAudioSample/Cellulartopo.cpp190
-rw-r--r--audio/sysvad/PhoneAudioSample/Cellulartopo.h25
-rw-r--r--audio/sysvad/PhoneAudioSample/Cellulartoptable.h16
-rw-r--r--audio/sysvad/PhoneAudioSample/Cellularwavtable.h12
-rw-r--r--audio/sysvad/PhoneAudioSample/FMWavTable.h7
-rw-r--r--audio/sysvad/PhoneAudioSample/PhoneAudioSample.rc (renamed from audio/sysvad/sysvad.rc)8
-rw-r--r--audio/sysvad/PhoneAudioSample/PhoneAudioSample.vcxproj13
-rw-r--r--audio/sysvad/PhoneAudioSample/PhoneAudioSample.vcxproj.Filters55
-rw-r--r--audio/sysvad/PhoneAudioSample/handsetmictopo.cpp2
-rw-r--r--audio/sysvad/PhoneAudioSample/handsetmicwavtable.h6
-rw-r--r--audio/sysvad/PhoneAudioSample/handsetspeakertopo.cpp2
-rw-r--r--audio/sysvad/PhoneAudioSample/handsetspeakerwavtable.h6
-rw-r--r--audio/sysvad/PhoneAudioSample/michswavtable.h6
-rw-r--r--audio/sysvad/PhoneAudioSample/minipairs.h44
-rw-r--r--audio/sysvad/PhoneAudioSample/phoneaudiosample.inx (renamed from audio/sysvad/PhoneAudioSample/phoneaudiosample.inf)bin45134 -> 45318 bytes
-rw-r--r--audio/sysvad/PhoneAudioSample/sources23
-rw-r--r--audio/sysvad/PhoneAudioSample/speakerhswavtable.h6
-rw-r--r--audio/sysvad/README.md35
-rw-r--r--audio/sysvad/SwapAPO/APO/SwapAPODll.cpp152
-rw-r--r--audio/sysvad/SwapAPO/DelayAPO/DelayAPODll.cpp148
-rw-r--r--audio/sysvad/TabletAudioSample/ComponentizedApoSample.inx (renamed from audio/sysvad/TabletAudioSample/ComponentizedApoSample.inf)bin15522 -> 15426 bytes
-rw-r--r--audio/sysvad/TabletAudioSample/ComponentizedAudioSample.inx (renamed from audio/sysvad/TabletAudioSample/ComponentizedAudioSample.inf)bin43560 -> 49782 bytes
-rw-r--r--audio/sysvad/TabletAudioSample/ComponentizedAudioSampleExtension.inx (renamed from audio/sysvad/TabletAudioSample/ComponentizedAudioSampleExtension.inf)bin9534 -> 7688 bytes
-rw-r--r--audio/sysvad/TabletAudioSample/TabletAudioSample.rc30
-rw-r--r--audio/sysvad/TabletAudioSample/TabletAudioSample.vcxproj61
-rw-r--r--audio/sysvad/TabletAudioSample/TabletAudioSample.vcxproj.Filters40
-rw-r--r--audio/sysvad/TabletAudioSample/hdmitoptable.h52
-rw-r--r--audio/sysvad/TabletAudioSample/hdmiwavtable.h326
-rw-r--r--audio/sysvad/TabletAudioSample/micintopo.cpp2
-rw-r--r--audio/sysvad/TabletAudioSample/micinwavtable.h6
-rw-r--r--audio/sysvad/TabletAudioSample/minipairs.h50
-rw-r--r--audio/sysvad/TabletAudioSample/sources18
-rw-r--r--audio/sysvad/TabletAudioSample/spdifwavtable.h6
-rw-r--r--audio/sysvad/TabletAudioSample/tabletaudiosample.inx (renamed from audio/sysvad/TabletAudioSample/tabletaudiosample.inf)bin61298 -> 67372 bytes
-rw-r--r--audio/sysvad/ToneGenerator.cpp11
-rw-r--r--audio/sysvad/ToneGenerator.h5
-rw-r--r--audio/sysvad/adapter.cpp80
-rw-r--r--audio/sysvad/common.cpp4072
-rw-r--r--audio/sysvad/common.h162
-rw-r--r--audio/sysvad/hw.cpp3
-rw-r--r--audio/sysvad/savedata.cpp40
-rw-r--r--audio/sysvad/sources.inc3
-rw-r--r--audio/sysvad/sysvad.h121
-rw-r--r--audio/sysvad/sysvad.sln80
119 files changed, 7604 insertions, 5955 deletions
diff --git a/audio/sysvad/SwapAPO/DelayAPO/Delay.cpp b/audio/sysvad/APO/DelayAPO/Delay.cpp
index 721de3ef..721de3ef 100644
--- a/audio/sysvad/SwapAPO/DelayAPO/Delay.cpp
+++ b/audio/sysvad/APO/DelayAPO/Delay.cpp
diff --git a/audio/sysvad/SwapAPO/DelayAPO/DelayAPO.h b/audio/sysvad/APO/DelayAPO/DelayAPO.h
index e59fccf7..e59fccf7 100644
--- a/audio/sysvad/SwapAPO/DelayAPO/DelayAPO.h
+++ b/audio/sysvad/APO/DelayAPO/DelayAPO.h
diff --git a/audio/sysvad/SwapAPO/DelayAPO/DelayAPO.vcxproj b/audio/sysvad/APO/DelayAPO/DelayAPO.vcxproj
index ee3db3f6..8e6ce26d 100644
--- a/audio/sysvad/SwapAPO/DelayAPO/DelayAPO.vcxproj
+++ b/audio/sysvad/APO/DelayAPO/DelayAPO.vcxproj
@@ -141,11 +141,11 @@
</ClCompile>
<Midl>
<PreprocessorDefinitions>%(PreprocessorDefinitions);_WINDLL;_USRDLL;UNICODE;_UNICODE</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\;.</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\</AdditionalIncludeDirectories>
</Midl>
<ResourceCompile>
<PreprocessorDefinitions>%(PreprocessorDefinitions);_WINDLL;_USRDLL;UNICODE;_UNICODE</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\;.</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\</AdditionalIncludeDirectories>
</ResourceCompile>
<Link>
<AdditionalDependencies>%(AdditionalDependencies);Kernel32.lib;ole32.lib;oleaut32.lib;advapi32.lib;user32.lib;uuid.lib;AudioBaseProcessingObjectV140.lib;audiomediatypecrt.lib;AudioEng.lib</AdditionalDependencies>
@@ -165,11 +165,11 @@
</ClCompile>
<Midl>
<PreprocessorDefinitions>%(PreprocessorDefinitions);_WINDLL;_USRDLL;UNICODE;_UNICODE</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\;.</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\</AdditionalIncludeDirectories>
</Midl>
<ResourceCompile>
<PreprocessorDefinitions>%(PreprocessorDefinitions);_WINDLL;_USRDLL;UNICODE;_UNICODE</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\;.</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\</AdditionalIncludeDirectories>
</ResourceCompile>
<Link>
<AdditionalDependencies>%(AdditionalDependencies);Kernel32.lib;ole32.lib;oleaut32.lib;advapi32.lib;user32.lib;uuid.lib;AudioBaseProcessingObjectV140.lib;audiomediatypecrt.lib;AudioEng.lib</AdditionalDependencies>
@@ -189,11 +189,11 @@
</ClCompile>
<Midl>
<PreprocessorDefinitions>%(PreprocessorDefinitions);_WINDLL;_USRDLL;UNICODE;_UNICODE</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\;.</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\</AdditionalIncludeDirectories>
</Midl>
<ResourceCompile>
<PreprocessorDefinitions>%(PreprocessorDefinitions);_WINDLL;_USRDLL;UNICODE;_UNICODE</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\;.</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\</AdditionalIncludeDirectories>
</ResourceCompile>
<Link>
<AdditionalDependencies>%(AdditionalDependencies);Kernel32.lib;ole32.lib;oleaut32.lib;advapi32.lib;user32.lib;uuid.lib;AudioBaseProcessingObjectV140.lib;audiomediatypecrt.lib;AudioEng.lib</AdditionalDependencies>
@@ -213,11 +213,11 @@
</ClCompile>
<Midl>
<PreprocessorDefinitions>%(PreprocessorDefinitions);_WINDLL;_USRDLL;UNICODE;_UNICODE</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\;.</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\</AdditionalIncludeDirectories>
</Midl>
<ResourceCompile>
<PreprocessorDefinitions>%(PreprocessorDefinitions);_WINDLL;_USRDLL;UNICODE;_UNICODE</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\;.</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\</AdditionalIncludeDirectories>
</ResourceCompile>
<Link>
<AdditionalDependencies>%(AdditionalDependencies);Kernel32.lib;ole32.lib;oleaut32.lib;advapi32.lib;user32.lib;uuid.lib;AudioBaseProcessingObjectV140.lib;audiomediatypecrt.lib;AudioEng.lib</AdditionalDependencies>
diff --git a/audio/sysvad/SwapAPO/DelayAPO/DelayAPO.vcxproj.Filters b/audio/sysvad/APO/DelayAPO/DelayAPO.vcxproj.Filters
index a1e7102a..1858f392 100644
--- a/audio/sysvad/SwapAPO/DelayAPO/DelayAPO.vcxproj.Filters
+++ b/audio/sysvad/APO/DelayAPO/DelayAPO.vcxproj.Filters
@@ -13,47 +13,29 @@
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml</Extensions>
<UniqueIdentifier>{a57b6b78-38ae-4348-ade3-0200e81a3dd7}</UniqueIdentifier>
</Filter>
+ <Filter Include="IDL Files">
+ <Extensions>idl</Extensions>
+ <UniqueIdentifier>{c6318700-1bce-4812-92f1-160881e4c976}</UniqueIdentifier>
+ </Filter>
</ItemGroup>
<ItemGroup>
- <ClCompile Include="Delay.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="DelayAPODll.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="DelayAPOMFX.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="DelayAPOSFX.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
<Midl Include="DelayAPODll.idl">
- <Filter>Source Files</Filter>
+ <Filter>IDL Files</Filter>
</Midl>
<Midl Include="DelayAPOInterface.idl">
- <Filter>Source Files</Filter>
+ <Filter>IDL Files</Filter>
</Midl>
</ItemGroup>
<ItemGroup>
- <ResourceCompile Include="DelayAPODll.rc">
- <Filter>Resource Files</Filter>
- </ResourceCompile>
- </ItemGroup>
- <ItemGroup>
- <ClInclude Include="Resource.h">
- <Filter>Header Files</Filter>
- </ClInclude>
- <ClInclude Include="DelayAPO.h" />
- <ClInclude Include="Resource.h">
+ <ClInclude Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd">
<Filter>Header Files</Filter>
</ClInclude>
- <ClInclude Include="DelayAPO.h" />
</ItemGroup>
<ItemGroup>
- <None Include="*.ico;*.cur;*.bmp;*.dlg;*.rct;*.gif;*.jpg;*.jpeg;*.wav;*.jpe;*.tiff;*.tif;*.png;*.rc2">
+ <None Include="*.rc;*.ico;*.cur;*.bmp;*.dlg;*.rct;*.gif;*.jpg;*.jpeg;*.wav;*.jpe;*.tiff;*.tif;*.png;*.rc2">
<Filter>Resource Files</Filter>
</None>
- <None Include="*.def;*.bat;*.hpj;*.asmx">
+ <None Include="*.cpp;*.def;*.bat;*.hpj;*.asmx">
<Filter>Source Files</Filter>
</None>
</ItemGroup>
diff --git a/audio/sysvad/APO/DelayAPO/DelayAPODll.cpp b/audio/sysvad/APO/DelayAPO/DelayAPODll.cpp
new file mode 100644
index 00000000..fe49a000
--- /dev/null
+++ b/audio/sysvad/APO/DelayAPO/DelayAPODll.cpp
@@ -0,0 +1,70 @@
+//
+// DelayAPODll.cpp -- Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// Author:
+//
+// Description:
+//
+// DelayAPODll.cpp : Implementation of DLL Exports.
+
+#include <atlbase.h>
+#include <atlcom.h>
+#include <atlcoll.h>
+#include <atlsync.h>
+#include <mmreg.h>
+
+#include "resource.h"
+#include "DelayAPODll.h"
+#include <DelayAPO.h>
+
+#include <DelayAPODll_i.c>
+
+//-------------------------------------------------------------------------
+// Array of APO_REG_PROPERTIES structures implemented in this module.
+// Each new APO implementation will be added to this array.
+//
+APO_REG_PROPERTIES const *gCoreAPOs[] =
+{
+ &CDelayAPOMFX::sm_RegProperties.m_Properties,
+ &CDelayAPOSFX::sm_RegProperties.m_Properties
+};
+
+// {secret}
+class CDelayAPODllModule : public CAtlDllModuleT< CDelayAPODllModule >
+{
+public :
+ DECLARE_LIBID(LIBID_DelayAPODlllib)
+ DECLARE_REGISTRY_APPID_RESOURCEID(IDR_DELAYAPODLL, "{0A21D954-674A-4C09-806E-DB4FBE8F199C}")
+};
+
+// {secret}
+CDelayAPODllModule _AtlModule;
+
+
+// {secret}
+extern "C" BOOL WINAPI DllMain(HINSTANCE /* hInstance */, DWORD dwReason, LPVOID lpReserved)
+{
+ if (DLL_PROCESS_ATTACH == dwReason)
+ {
+ }
+ // do necessary cleanup only if the DLL is being unloaded dynamically
+ else if ((DLL_PROCESS_DETACH == dwReason) && (NULL == lpReserved))
+ {
+ }
+
+ return _AtlModule.DllMain(dwReason, lpReserved);
+}
+
+
+// {secret}
+STDAPI DllCanUnloadNow(void)
+{
+ return _AtlModule.DllCanUnloadNow();
+}
+
+
+// {secret}
+STDAPI DllGetClassObject(_In_ REFCLSID rclsid,_In_ REFIID riid, _Outptr_ LPVOID* ppv)
+{
+ return _AtlModule.DllGetClassObject(rclsid, riid, ppv);
+}
diff --git a/audio/sysvad/SwapAPO/DelayAPO/DelayAPODll.def b/audio/sysvad/APO/DelayAPO/DelayAPODll.def
index 722ab4c4..f4b6fcd9 100644
--- a/audio/sysvad/SwapAPO/DelayAPO/DelayAPODll.def
+++ b/audio/sysvad/APO/DelayAPO/DelayAPODll.def
@@ -2,5 +2,3 @@
EXPORTS
DllCanUnloadNow PRIVATE
DllGetClassObject PRIVATE
- DllRegisterServer PRIVATE
- DllUnregisterServer PRIVATE
diff --git a/audio/sysvad/SwapAPO/DelayAPO/DelayAPODll.idl b/audio/sysvad/APO/DelayAPO/DelayAPODll.idl
index 46b4fe5b..46b4fe5b 100644
--- a/audio/sysvad/SwapAPO/DelayAPO/DelayAPODll.idl
+++ b/audio/sysvad/APO/DelayAPO/DelayAPODll.idl
diff --git a/audio/sysvad/SwapAPO/DelayAPO/DelayAPODll.rc b/audio/sysvad/APO/DelayAPO/DelayAPODll.rc
index 8cdc8249..dc6e9532 100644
--- a/audio/sysvad/SwapAPO/DelayAPO/DelayAPODll.rc
+++ b/audio/sysvad/APO/DelayAPO/DelayAPODll.rc
@@ -8,8 +8,8 @@ Copyright (c) Microsoft Corporation. All Rights Reserved
#define VER_FILETYPE VFT_DLL
#define VER_FILESUBTYPE VFT_UNKNOWN
#define VER_FILEDESCRIPTION_STR "Delay APO"
-#define VER_INTERNALNAME_STR "DELAYAPODll"
-#define VER_ORIGINALFILENAME_STR "DelayAPODll.Dll"
+#define VER_INTERNALNAME_STR "DelayAPO"
+#define VER_ORIGINALFILENAME_STR "DelayAPO.Dll"
#include <Common.ver>
IDR_DELAYAPODLL REGISTRY "DelayAPODll.rgs"
@@ -17,7 +17,7 @@ IDR_DELAYAPOMFX REGISTRY "DelayAPOMFX.rgs"
IDR_DELAYAPOSFX REGISTRY "DelayAPOSFX.rgs"
// ICON
-IDI_EFFECT_ICON RCDATA "DelayApo.png"
+IDI_EFFECT_ICON RCDATA "DelayAPO.png"
#if 0
1 TYPELIB "DelayAPODll.tlb"
diff --git a/audio/sysvad/SwapAPO/DelayAPO/DelayAPODll.rgs b/audio/sysvad/APO/DelayAPO/DelayAPODll.rgs
index 5ccba570..5ccba570 100644
--- a/audio/sysvad/SwapAPO/DelayAPO/DelayAPODll.rgs
+++ b/audio/sysvad/APO/DelayAPO/DelayAPODll.rgs
diff --git a/audio/sysvad/SwapAPO/DelayAPO/DelayAPOInterface.idl b/audio/sysvad/APO/DelayAPO/DelayAPOInterface.idl
index f74cd5fb..f74cd5fb 100644
--- a/audio/sysvad/SwapAPO/DelayAPO/DelayAPOInterface.idl
+++ b/audio/sysvad/APO/DelayAPO/DelayAPOInterface.idl
diff --git a/audio/sysvad/SwapAPO/DelayAPO/DelayAPOMFX.cpp b/audio/sysvad/APO/DelayAPO/DelayAPOMFX.cpp
index 5f5ad2c6..5f5ad2c6 100644
--- a/audio/sysvad/SwapAPO/DelayAPO/DelayAPOMFX.cpp
+++ b/audio/sysvad/APO/DelayAPO/DelayAPOMFX.cpp
diff --git a/audio/sysvad/SwapAPO/DelayAPO/DelayAPOMFX.rgs b/audio/sysvad/APO/DelayAPO/DelayAPOMFX.rgs
index 0d1f19e2..0d1f19e2 100644
--- a/audio/sysvad/SwapAPO/DelayAPO/DelayAPOMFX.rgs
+++ b/audio/sysvad/APO/DelayAPO/DelayAPOMFX.rgs
diff --git a/audio/sysvad/SwapAPO/DelayAPO/DelayAPOSFX.cpp b/audio/sysvad/APO/DelayAPO/DelayAPOSFX.cpp
index 81594bb7..81594bb7 100644
--- a/audio/sysvad/SwapAPO/DelayAPO/DelayAPOSFX.cpp
+++ b/audio/sysvad/APO/DelayAPO/DelayAPOSFX.cpp
diff --git a/audio/sysvad/SwapAPO/DelayAPO/DelayAPOSFX.rgs b/audio/sysvad/APO/DelayAPO/DelayAPOSFX.rgs
index 1a100539..1a100539 100644
--- a/audio/sysvad/SwapAPO/DelayAPO/DelayAPOSFX.rgs
+++ b/audio/sysvad/APO/DelayAPO/DelayAPOSFX.rgs
diff --git a/audio/sysvad/SwapAPO/DelayAPO/Resource.h b/audio/sysvad/APO/DelayAPO/Resource.h
index eda62a7a..eda62a7a 100644
--- a/audio/sysvad/SwapAPO/DelayAPO/Resource.h
+++ b/audio/sysvad/APO/DelayAPO/Resource.h
diff --git a/audio/sysvad/SwapAPO/DelayAPO/delayapo.png b/audio/sysvad/APO/DelayAPO/delayapo.png
index 055bdc2c..055bdc2c 100644
--- a/audio/sysvad/SwapAPO/DelayAPO/delayapo.png
+++ b/audio/sysvad/APO/DelayAPO/delayapo.png
Binary files differ
diff --git a/audio/sysvad/SwapAPO/DelayAPO/makefile b/audio/sysvad/APO/DelayAPO/makefile
index 593ab379..593ab379 100644
--- a/audio/sysvad/SwapAPO/DelayAPO/makefile
+++ b/audio/sysvad/APO/DelayAPO/makefile
diff --git a/audio/sysvad/SwapAPO/DelayAPO/sources b/audio/sysvad/APO/DelayAPO/sources
index 355dc80f..355dc80f 100644
--- a/audio/sysvad/SwapAPO/DelayAPO/sources
+++ b/audio/sysvad/APO/DelayAPO/sources
diff --git a/audio/sysvad/SwapAPO/Inc/CommonMacros.h b/audio/sysvad/APO/Inc/CommonMacros.h
index 097c6d47..097c6d47 100644
--- a/audio/sysvad/SwapAPO/Inc/CommonMacros.h
+++ b/audio/sysvad/APO/Inc/CommonMacros.h
diff --git a/audio/sysvad/SwapAPO/Inc/CustomPropKeys.h b/audio/sysvad/APO/Inc/CustomPropKeys.h
index dab286a5..dab286a5 100644
--- a/audio/sysvad/SwapAPO/Inc/CustomPropKeys.h
+++ b/audio/sysvad/APO/Inc/CustomPropKeys.h
diff --git a/audio/sysvad/SwapAPO/Inc/tlist.h b/audio/sysvad/APO/Inc/tlist.h
index 6c0479aa..6c0479aa 100644
--- a/audio/sysvad/SwapAPO/Inc/tlist.h
+++ b/audio/sysvad/APO/Inc/tlist.h
diff --git a/audio/sysvad/SwapAPO/APO/Resource.h b/audio/sysvad/APO/SwapAPO/Resource.h
index 0e7dff6d..0e7dff6d 100644
--- a/audio/sysvad/SwapAPO/APO/Resource.h
+++ b/audio/sysvad/APO/SwapAPO/Resource.h
diff --git a/audio/sysvad/SwapAPO/APO/SwapAPO.h b/audio/sysvad/APO/SwapAPO/SwapAPO.h
index fc279460..fc279460 100644
--- a/audio/sysvad/SwapAPO/APO/SwapAPO.h
+++ b/audio/sysvad/APO/SwapAPO/SwapAPO.h
diff --git a/audio/sysvad/SwapAPO/APO/SwapAPO.vcxproj b/audio/sysvad/APO/SwapAPO/SwapAPO.vcxproj
index 9737729a..295833ea 100644
--- a/audio/sysvad/SwapAPO/APO/SwapAPO.vcxproj
+++ b/audio/sysvad/APO/SwapAPO/SwapAPO.vcxproj
@@ -141,11 +141,11 @@
</ClCompile>
<Midl>
<PreprocessorDefinitions>%(PreprocessorDefinitions);_WINDLL;_USRDLL;UNICODE;_UNICODE</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\;.</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\</AdditionalIncludeDirectories>
</Midl>
<ResourceCompile>
<PreprocessorDefinitions>%(PreprocessorDefinitions);_WINDLL;_USRDLL;UNICODE;_UNICODE</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\;.</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\</AdditionalIncludeDirectories>
</ResourceCompile>
<Link>
<AdditionalDependencies>%(AdditionalDependencies);Kernel32.lib;ole32.lib;oleaut32.lib;advapi32.lib;user32.lib;uuid.lib;AudioBaseProcessingObjectV140.lib;audiomediatypecrt.lib;AudioEng.lib</AdditionalDependencies>
@@ -165,11 +165,11 @@
</ClCompile>
<Midl>
<PreprocessorDefinitions>%(PreprocessorDefinitions);_WINDLL;_USRDLL;UNICODE;_UNICODE</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\;.</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\</AdditionalIncludeDirectories>
</Midl>
<ResourceCompile>
<PreprocessorDefinitions>%(PreprocessorDefinitions);_WINDLL;_USRDLL;UNICODE;_UNICODE</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\;.</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\</AdditionalIncludeDirectories>
</ResourceCompile>
<Link>
<AdditionalDependencies>%(AdditionalDependencies);Kernel32.lib;ole32.lib;oleaut32.lib;advapi32.lib;user32.lib;uuid.lib;AudioBaseProcessingObjectV140.lib;audiomediatypecrt.lib;AudioEng.lib</AdditionalDependencies>
@@ -189,11 +189,11 @@
</ClCompile>
<Midl>
<PreprocessorDefinitions>%(PreprocessorDefinitions);_WINDLL;_USRDLL;UNICODE;_UNICODE</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\;.</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\</AdditionalIncludeDirectories>
</Midl>
<ResourceCompile>
<PreprocessorDefinitions>%(PreprocessorDefinitions);_WINDLL;_USRDLL;UNICODE;_UNICODE</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\;.</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\</AdditionalIncludeDirectories>
</ResourceCompile>
<Link>
<AdditionalDependencies>%(AdditionalDependencies);Kernel32.lib;ole32.lib;oleaut32.lib;advapi32.lib;user32.lib;uuid.lib;AudioBaseProcessingObjectV140.lib;audiomediatypecrt.lib;AudioEng.lib</AdditionalDependencies>
@@ -213,11 +213,11 @@
</ClCompile>
<Midl>
<PreprocessorDefinitions>%(PreprocessorDefinitions);_WINDLL;_USRDLL;UNICODE;_UNICODE</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\;.</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\</AdditionalIncludeDirectories>
</Midl>
<ResourceCompile>
<PreprocessorDefinitions>%(PreprocessorDefinitions);_WINDLL;_USRDLL;UNICODE;_UNICODE</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\;.</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\</AdditionalIncludeDirectories>
</ResourceCompile>
<Link>
<AdditionalDependencies>%(AdditionalDependencies);Kernel32.lib;ole32.lib;oleaut32.lib;advapi32.lib;user32.lib;uuid.lib;AudioBaseProcessingObjectV140.lib;audiomediatypecrt.lib;AudioEng.lib</AdditionalDependencies>
diff --git a/audio/sysvad/SwapAPO/APO/SwapAPO.vcxproj.Filters b/audio/sysvad/APO/SwapAPO/SwapAPO.vcxproj.Filters
index 631acbca..9b3493d4 100644
--- a/audio/sysvad/SwapAPO/APO/SwapAPO.vcxproj.Filters
+++ b/audio/sysvad/APO/SwapAPO/SwapAPO.vcxproj.Filters
@@ -13,47 +13,29 @@
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml</Extensions>
<UniqueIdentifier>{A9DFA5D3-3035-416E-BBD8-8D0745973136}</UniqueIdentifier>
</Filter>
+ <Filter Include="IDL Files">
+ <Extensions>idl</Extensions>
+ <UniqueIdentifier>{6d66b527-51f6-480e-a9d1-813fa5081a43}</UniqueIdentifier>
+ </Filter>
</ItemGroup>
<ItemGroup>
- <ClCompile Include="Swap.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="SwapAPODll.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="SwapAPOMFX.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="SwapAPOSFX.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
<Midl Include="SwapAPODll.idl">
- <Filter>Source Files</Filter>
+ <Filter>IDL Files</Filter>
</Midl>
<Midl Include="SwapAPOInterface.idl">
- <Filter>Source Files</Filter>
+ <Filter>IDL Files</Filter>
</Midl>
</ItemGroup>
<ItemGroup>
- <ResourceCompile Include="SwapAPODll.rc">
- <Filter>Resource Files</Filter>
- </ResourceCompile>
- </ItemGroup>
- <ItemGroup>
- <ClInclude Include="Resource.h">
- <Filter>Header Files</Filter>
- </ClInclude>
- <ClInclude Include="SwapAPO.h" />
- <ClInclude Include="Resource.h">
+ <ClInclude Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd">
<Filter>Header Files</Filter>
</ClInclude>
- <ClInclude Include="SwapAPO.h" />
</ItemGroup>
<ItemGroup>
- <None Include="*.ico;*.cur;*.bmp;*.dlg;*.rct;*.gif;*.jpg;*.jpeg;*.wav;*.jpe;*.tiff;*.tif;*.png;*.rc2">
+ <None Include="*.rc;*.ico;*.cur;*.bmp;*.dlg;*.rct;*.gif;*.jpg;*.jpeg;*.wav;*.jpe;*.tiff;*.tif;*.png;*.rc2">
<Filter>Resource Files</Filter>
</None>
- <None Include="*.def;*.bat;*.hpj;*.asmx">
+ <None Include="*.cpp;*.def;*.bat;*.hpj;*.asmx">
<Filter>Source Files</Filter>
</None>
</ItemGroup>
diff --git a/audio/sysvad/APO/SwapAPO/SwapAPODll.cpp b/audio/sysvad/APO/SwapAPO/SwapAPODll.cpp
new file mode 100644
index 00000000..22e810bf
--- /dev/null
+++ b/audio/sysvad/APO/SwapAPO/SwapAPODll.cpp
@@ -0,0 +1,72 @@
+//
+// SwapAPODll.cpp -- Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// Author:
+//
+// Description:
+//
+// SwapAPODll.cpp : Implementation of DLL Exports.
+
+#include <atlbase.h>
+#include <atlcom.h>
+#include <atlcoll.h>
+#include <atlsync.h>
+#include <mmreg.h>
+
+#include "resource.h"
+#include "SwapAPODll.h"
+#include <SwapAPO.h>
+
+#include <SwapAPODll_i.c>
+
+//-------------------------------------------------------------------------
+// Array of APO_REG_PROPERTIES structures implemented in this module.
+// Each new APO implementation will be added to this array.
+//
+APO_REG_PROPERTIES const *gCoreAPOs[] =
+{
+ &CSwapAPOMFX::sm_RegProperties.m_Properties,
+ &CSwapAPOSFX::sm_RegProperties.m_Properties
+};
+
+// {secret}
+class CSwapAPODllModule : public CAtlDllModuleT< CSwapAPODllModule >
+{
+public :
+ DECLARE_LIBID(LIBID_SwapAPODlllib)
+ DECLARE_REGISTRY_APPID_RESOURCEID(IDR_SWAPAPODLL, "{0A21D954-674A-4C09-806E-DB4FBE8F199C}")
+};
+
+// {secret}
+CSwapAPODllModule _AtlModule;
+
+
+// {secret}
+extern "C" BOOL WINAPI DllMain(HINSTANCE /* hInstance */, DWORD dwReason, LPVOID lpReserved)
+{
+ if (DLL_PROCESS_ATTACH == dwReason)
+ {
+ }
+ // do necessary cleanup only if the DLL is being unloaded dynamically
+ else if ((DLL_PROCESS_DETACH == dwReason) && (NULL == lpReserved))
+ {
+ }
+
+ return _AtlModule.DllMain(dwReason, lpReserved);
+}
+
+
+// {secret}
+__control_entrypoint(DllExport)
+STDAPI DllCanUnloadNow(void)
+{
+ return _AtlModule.DllCanUnloadNow();
+}
+
+
+// {secret}
+_Check_return_
+STDAPI DllGetClassObject(_In_ REFCLSID rclsid, _In_ REFIID riid, _Outptr_ LPVOID FAR* ppv)
+{
+ return _AtlModule.DllGetClassObject(rclsid, riid, ppv);
+}
diff --git a/audio/sysvad/SwapAPO/APO/SwapAPODll.def b/audio/sysvad/APO/SwapAPO/SwapAPODll.def
index 722ab4c4..f4b6fcd9 100644
--- a/audio/sysvad/SwapAPO/APO/SwapAPODll.def
+++ b/audio/sysvad/APO/SwapAPO/SwapAPODll.def
@@ -2,5 +2,3 @@
EXPORTS
DllCanUnloadNow PRIVATE
DllGetClassObject PRIVATE
- DllRegisterServer PRIVATE
- DllUnregisterServer PRIVATE
diff --git a/audio/sysvad/SwapAPO/APO/SwapAPODll.idl b/audio/sysvad/APO/SwapAPO/SwapAPODll.idl
index e9000c7c..e9000c7c 100644
--- a/audio/sysvad/SwapAPO/APO/SwapAPODll.idl
+++ b/audio/sysvad/APO/SwapAPO/SwapAPODll.idl
diff --git a/audio/sysvad/SwapAPO/APO/SwapAPODll.rc b/audio/sysvad/APO/SwapAPO/SwapAPODll.rc
index 119a3ebc..b73f4734 100644
--- a/audio/sysvad/SwapAPO/APO/SwapAPODll.rc
+++ b/audio/sysvad/APO/SwapAPO/SwapAPODll.rc
@@ -8,8 +8,8 @@ Copyright (c) Microsoft Corporation. All Rights Reserved
#define VER_FILETYPE VFT_DLL
#define VER_FILESUBTYPE VFT_UNKNOWN
#define VER_FILEDESCRIPTION_STR "Swap APO"
-#define VER_INTERNALNAME_STR "SWAPAPODll"
-#define VER_ORIGINALFILENAME_STR "SwapAPODll.Dll"
+#define VER_INTERNALNAME_STR "SwapAPO"
+#define VER_ORIGINALFILENAME_STR "SwapAPO.Dll"
#include <Common.ver>
IDR_SWAPAPODLL REGISTRY "SwapAPODll.rgs"
@@ -17,7 +17,7 @@ IDR_SWAPAPOMFX REGISTRY "SwapAPOMFX.rgs"
IDR_SWAPAPOSFX REGISTRY "SwapAPOSFX.rgs"
// ICON
-IDI_EFFECT_ICON RCDATA "SwapApo.png"
+IDI_EFFECT_ICON RCDATA "SwapAPO.png"
#if 0
1 TYPELIB "SwapAPODll.tlb"
diff --git a/audio/sysvad/SwapAPO/APO/SwapAPODll.rgs b/audio/sysvad/APO/SwapAPO/SwapAPODll.rgs
index ab3277b3..ab3277b3 100644
--- a/audio/sysvad/SwapAPO/APO/SwapAPODll.rgs
+++ b/audio/sysvad/APO/SwapAPO/SwapAPODll.rgs
diff --git a/audio/sysvad/SwapAPO/APO/SwapAPOInterface.idl b/audio/sysvad/APO/SwapAPO/SwapAPOInterface.idl
index e83f16fb..e83f16fb 100644
--- a/audio/sysvad/SwapAPO/APO/SwapAPOInterface.idl
+++ b/audio/sysvad/APO/SwapAPO/SwapAPOInterface.idl
diff --git a/audio/sysvad/SwapAPO/APO/SwapAPOMFX.rgs b/audio/sysvad/APO/SwapAPO/SwapAPOMFX.rgs
index 3bebda2e..3bebda2e 100644
--- a/audio/sysvad/SwapAPO/APO/SwapAPOMFX.rgs
+++ b/audio/sysvad/APO/SwapAPO/SwapAPOMFX.rgs
diff --git a/audio/sysvad/SwapAPO/APO/SwapAPOSFX.rgs b/audio/sysvad/APO/SwapAPO/SwapAPOSFX.rgs
index c553edd5..c553edd5 100644
--- a/audio/sysvad/SwapAPO/APO/SwapAPOSFX.rgs
+++ b/audio/sysvad/APO/SwapAPO/SwapAPOSFX.rgs
diff --git a/audio/sysvad/SwapAPO/APO/makefile b/audio/sysvad/APO/SwapAPO/makefile
index c7837f4f..c7837f4f 100644
--- a/audio/sysvad/SwapAPO/APO/makefile
+++ b/audio/sysvad/APO/SwapAPO/makefile
diff --git a/audio/sysvad/SwapAPO/APO/sources b/audio/sysvad/APO/SwapAPO/sources
index 7baf3745..7baf3745 100644
--- a/audio/sysvad/SwapAPO/APO/sources
+++ b/audio/sysvad/APO/SwapAPO/sources
diff --git a/audio/sysvad/SwapAPO/APO/swap.cpp b/audio/sysvad/APO/SwapAPO/swap.cpp
index 6fa39fa3..6fa39fa3 100644
--- a/audio/sysvad/SwapAPO/APO/swap.cpp
+++ b/audio/sysvad/APO/SwapAPO/swap.cpp
diff --git a/audio/sysvad/SwapAPO/APO/swapapo.png b/audio/sysvad/APO/SwapAPO/swapapo.png
index 861d5bcb..861d5bcb 100644
--- a/audio/sysvad/SwapAPO/APO/swapapo.png
+++ b/audio/sysvad/APO/SwapAPO/swapapo.png
Binary files differ
diff --git a/audio/sysvad/SwapAPO/APO/swapapomfx.cpp b/audio/sysvad/APO/SwapAPO/swapapomfx.cpp
index b4e6e95a..b4e6e95a 100644
--- a/audio/sysvad/SwapAPO/APO/swapapomfx.cpp
+++ b/audio/sysvad/APO/SwapAPO/swapapomfx.cpp
diff --git a/audio/sysvad/SwapAPO/APO/swapaposfx.cpp b/audio/sysvad/APO/SwapAPO/swapaposfx.cpp
index c7bba1e1..c7bba1e1 100644
--- a/audio/sysvad/SwapAPO/APO/swapaposfx.cpp
+++ b/audio/sysvad/APO/SwapAPO/swapaposfx.cpp
diff --git a/audio/sysvad/BthhfpDevice.cpp b/audio/sysvad/BthhfpDevice.cpp
new file mode 100644
index 00000000..3d0a388f
--- /dev/null
+++ b/audio/sysvad/BthhfpDevice.cpp
@@ -0,0 +1,3319 @@
+/*++
+
+Copyright (c) Microsoft Corporation All Rights Reserved
+
+Module Name:
+
+ common.cpp
+
+Abstract:
+
+ Implementation of the BthHfpDevice class.
+
+--*/
+
+#pragma warning (disable : 4127)
+
+#include <initguid.h>
+#include <sysvad.h>
+#include "hw.h"
+#include "savedata.h"
+#include "IHVPrivatePropertySet.h"
+#include "simple.h"
+
+#ifdef SYSVAD_BTH_BYPASS
+#include <limits.h>
+#include <bthhfpddi.h>
+#include <wdmguid.h> // guild-arrival/removal
+#include <devpkey.h>
+#include "bthhfpminipairs.h"
+#include "BthhfpDevice.h"
+
+//
+// BthHfpDevice implementation.
+//
+
+// # of sec before sync request is cancelled.
+#define BTH_HFP_SYNC_REQ_TIMEOUT_IN_SEC 60
+#define BTH_HFP_NOTIFICATION_MAX_ERROR_COUNT 5
+
+//=============================================================================
+#pragma code_seg("PAGE")
+STDMETHODIMP
+BthHfpDevice::NonDelegatingQueryInterface
+(
+ _In_ REFIID Interface,
+ _COM_Outptr_ PVOID * Object
+)
+/*++
+
+Routine Description:
+
+QueryInterface routine for BthHfpDevice
+
+Arguments:
+
+Interface -
+
+Object -
+
+Return Value:
+
+NT status code.
+
+--*/
+{
+ PAGED_CODE();
+
+ ASSERT(Object);
+
+ if (IsEqualGUIDAligned(Interface, IID_IUnknown))
+ {
+ *Object = PVOID(PUNKNOWN(PSIDEBANDDEVICECOMMON(this)));
+ }
+ else if (IsEqualGUIDAligned(Interface, IID_IBthHfpDeviceCommon))
+ {
+ *Object = PVOID(PSIDEBANDDEVICECOMMON(this));
+ }
+ else
+ {
+ *Object = NULL;
+ }
+
+ if (*Object)
+ {
+ PUNKNOWN(*Object)->AddRef();
+ return STATUS_SUCCESS;
+ }
+
+ return STATUS_INVALID_PARAMETER;
+} // NonDelegatingQueryInterface
+
+ //=============================================================================
+ // Dummy stubs to override the default WDF behavior of closing the target
+ // on query remove. This driver closes and deletes the supporting objects
+ // when the target removes the BTH HFP SCO Bypass interface.
+ //
+
+#pragma code_seg("PAGE")
+NTSTATUS
+BthHfpDevice::EvtBthHfpTargetQueryRemove
+(
+ _In_ WDFIOTARGET IoTarget
+)
+{
+ PAGED_CODE();
+ DPF_ENTER(("[BthHfpDevice::EvtBthHfpTargetQueryRemove]"));
+
+ UNREFERENCED_PARAMETER(IoTarget);
+ return STATUS_SUCCESS;
+}
+
+#pragma code_seg("PAGE")
+VOID
+BthHfpDevice::EvtBthHfpTargetRemoveCanceled
+(
+ _In_ WDFIOTARGET IoTarget
+)
+{
+ PAGED_CODE();
+ DPF_ENTER(("[BthHfpDevice::EvtBthHfpTargetRemoveCanceled]"));
+
+ UNREFERENCED_PARAMETER(IoTarget);
+}
+#pragma code_seg("PAGE")
+VOID
+BthHfpDevice::EvtBthHfpTargetRemoveComplete
+(
+ _In_ WDFIOTARGET IoTarget
+)
+{
+ PAGED_CODE();
+ DPF_ENTER(("[BthHfpDevice::EvtBthHfpTargetRemoveComplete]"));
+
+ UNREFERENCED_PARAMETER(IoTarget);
+}
+
+//=============================================================================
+#pragma code_seg("PAGE")
+NTSTATUS
+BthHfpDevice::Init
+(
+ _In_ IAdapterCommon * Adapter,
+ _In_ PUNICODE_STRING SymbolicLinkName
+)
+{
+ PAGED_CODE();
+ DPF_ENTER(("[BthHfpDevice::Init]"));
+
+ NTSTATUS ntStatus = STATUS_SUCCESS;
+ BthHfpDeviceNotificationWorkItemContext *wiCtx = NULL;
+ BthHfpDeviceNotificationReqContext *reqCtx = NULL;
+ WDF_OBJECT_ATTRIBUTES attributes;
+ WDF_IO_TARGET_OPEN_PARAMS openParams;
+ WDF_WORKITEM_CONFIG wiConfig;
+
+ AddRef(); // first ref.
+
+ //
+ // Basic init of all the class' members.
+ //
+ m_State = eBthHfpStateInitializing;
+ m_Adapter = Adapter;
+
+ // Static config.
+ m_WdfIoTarget = NULL;
+ m_SpeakerMiniports = NULL;
+ m_MicMiniports = NULL;
+ m_UnknownSpeakerTopology = NULL;
+ m_UnknownSpeakerWave = NULL;
+ m_UnknownMicTopology = NULL;
+ m_UnknownMicWave = NULL;
+ m_Descriptor = NULL;
+ m_VolumePropValues = NULL;
+
+ // Notification updates.
+ m_SpeakerVolumeLevel = 0;
+ m_MicVolumeLevel = 0;
+ m_ConnectionStatusLong = FALSE;
+ m_StreamStatusLong = STATUS_INVALID_DEVICE_STATE; // Sco stream is not open.
+ m_NRECDisableStatusLong = FALSE;
+
+ m_StreamReq = NULL;
+ m_SpeakerVolumeReq = NULL;
+ m_MicVolumeReq = NULL;
+ m_ConnectionReq = NULL;
+ m_NRECDisableStatusReq = NULL;
+
+ m_WorkItem = NULL;
+ m_ReqCollection = NULL;
+ m_CodecId = 0;
+
+ m_nStreams = 0;
+
+ KeInitializeEvent(&m_StreamStatusEvent, NotificationEvent, TRUE);
+
+ InitializeListHead(&m_ListEntry);
+ KeInitializeSpinLock(&m_Lock);
+
+ RtlZeroMemory(&m_SymbolicLinkName, sizeof(m_SymbolicLinkName));
+
+ RtlZeroMemory(&m_SpeakerVolumeCallback, sizeof(m_SpeakerVolumeCallback));
+ RtlZeroMemory(&m_SpeakerConnectionStatusCallback, sizeof(m_SpeakerConnectionStatusCallback));
+ RtlZeroMemory(&m_MicVolumeCallback, sizeof(m_MicVolumeCallback));
+ RtlZeroMemory(&m_MicConnectionStatusCallback, sizeof(m_MicConnectionStatusCallback));
+ RtlZeroMemory(&m_SpeakerFormatChangeCallback, sizeof(m_SpeakerFormatChangeCallback));
+ RtlZeroMemory(&m_MicFormatChangeCallback, sizeof(m_MicFormatChangeCallback));
+
+ //
+ // Allocate a notification WDF work-item.
+ //
+ WDF_WORKITEM_CONFIG_INIT(&wiConfig, EvtBthHfpDeviceNotificationStatusWorkItem);
+ wiConfig.AutomaticSerialization = FALSE;
+
+ WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, BthHfpDeviceNotificationWorkItemContext);
+ attributes.ParentObject = Adapter->GetWdfDevice();
+ ntStatus = WdfWorkItemCreate(&wiConfig,
+ &attributes,
+ &m_WorkItem);
+ IF_FAILED_ACTION_JUMP(
+ ntStatus,
+ DPF(D_ERROR, ("Init: WdfWorkItemCreate failed: 0x%x", ntStatus)),
+ Done);
+
+ wiCtx = GetBthHfpDeviceNotificationWorkItemContext(m_WorkItem);
+ wiCtx->BthHfpDevice = this; // weak ref.
+
+ //
+ // Allocate a collection to hold notification requests for the notification work-item.
+ //
+ WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
+ attributes.ParentObject = m_Adapter->GetWdfDevice();
+ ntStatus = WdfCollectionCreate(
+ &attributes,
+ &m_ReqCollection);
+
+ IF_FAILED_ACTION_JUMP(
+ ntStatus,
+ DPF(D_ERROR, ("Init: WdfCollectionCreate failed: 0x%x", ntStatus)),
+ Done);
+
+ //
+ // Open the target interface.
+ //
+ WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
+ attributes.ParentObject = m_Adapter->GetWdfDevice();
+ ntStatus = WdfIoTargetCreate(m_Adapter->GetWdfDevice(),
+ &attributes,
+ &m_WdfIoTarget);
+ IF_FAILED_ACTION_JUMP(
+ ntStatus,
+ DPF(D_ERROR, ("Init: WdfIoTargetCreate failed: 0x%x", ntStatus)),
+ Done);
+
+ WDF_IO_TARGET_OPEN_PARAMS_INIT_OPEN_BY_NAME(
+ &openParams,
+ SymbolicLinkName,
+ STANDARD_RIGHTS_ALL);
+
+ openParams.EvtIoTargetQueryRemove = EvtBthHfpTargetQueryRemove;
+ openParams.EvtIoTargetRemoveCanceled = EvtBthHfpTargetRemoveCanceled;
+ openParams.EvtIoTargetRemoveComplete = EvtBthHfpTargetRemoveComplete;
+
+ ntStatus = WdfIoTargetOpen(m_WdfIoTarget, &openParams);
+ IF_FAILED_ACTION_JUMP(
+ ntStatus,
+ DPF(D_ERROR, ("Init: WdfIoTargetOpen(%wZ) failed: 0x%x", SymbolicLinkName, ntStatus)),
+ Done);
+
+ //
+ // Make a copy of the symbolic link name.
+ //
+ m_SymbolicLinkName.MaximumLength = SymbolicLinkName->MaximumLength;
+ m_SymbolicLinkName.Length = SymbolicLinkName->Length;
+ m_SymbolicLinkName.Buffer = (PWSTR) ExAllocatePoolWithTag(NonPagedPoolNx,
+ SymbolicLinkName->MaximumLength,
+ MINADAPTER_POOLTAG);
+ if (m_SymbolicLinkName.Buffer == NULL)
+ {
+ ntStatus = STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ IF_FAILED_ACTION_JUMP(
+ ntStatus,
+ DPF(D_ERROR, ("Init: ExAllocatePoolWithTag failed, out of memory")),
+ Done);
+
+ RtlCopyUnicodeString(&m_SymbolicLinkName, SymbolicLinkName);
+
+ //
+ // Allocate the WDF requests for status notifications.
+ //
+
+ //
+ // IOCTL_BTHHFP_DEVICE_GET_NRECDISABLE_STATUS_UPDATE
+ //
+ WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, BthHfpDeviceNotificationReqContext);
+ attributes.ParentObject = m_Adapter->GetWdfDevice();
+ ntStatus = WdfRequestCreate(
+ &attributes,
+ m_WdfIoTarget,
+ &m_NRECDisableStatusReq);
+ IF_FAILED_ACTION_JUMP(
+ ntStatus,
+ DPF(D_ERROR, ("Init: WdfRequestCreate(Nrec-disable status) failed, 0x%x", ntStatus)),
+ Done);
+
+ // Init context.
+ reqCtx = GetBthHfpDeviceNotificationReqContext(m_NRECDisableStatusReq);
+ reqCtx->BthHfpDevice = this; // weak ref.
+
+ ntStatus = WdfMemoryCreatePreallocated(
+ WDF_NO_OBJECT_ATTRIBUTES,
+ &reqCtx->Buffer,
+ sizeof(reqCtx->Buffer.bImmediate),
+ &reqCtx->MemIn);
+ IF_FAILED_ACTION_JUMP(
+ ntStatus,
+ DPF(D_ERROR, ("Init: WdfMemoryCreatePreallocated failed, 0x%x", ntStatus)),
+ Done);
+
+ ntStatus = WdfMemoryCreatePreallocated(
+ WDF_NO_OBJECT_ATTRIBUTES,
+ &reqCtx->Buffer,
+ sizeof(reqCtx->Buffer.BoolStatus),
+ &reqCtx->MemOut);
+ IF_FAILED_ACTION_JUMP(
+ ntStatus,
+ DPF(D_ERROR, ("Init: WdfMemoryCreatePreallocated failed, 0x%x", ntStatus)),
+ Done);
+
+ //
+ // IOCTL_BTHHFP_SPEAKER_GET_VOLUME_STATUS_UPDATE
+ //
+ WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, BthHfpDeviceNotificationReqContext);
+ attributes.ParentObject = m_Adapter->GetWdfDevice();
+ ntStatus = WdfRequestCreate(
+ &attributes,
+ m_WdfIoTarget,
+ &m_SpeakerVolumeReq);
+ IF_FAILED_ACTION_JUMP(
+ ntStatus,
+ DPF(D_ERROR, ("Init: WdfRequestCreate(Speaker-Volume) failed, 0x%x", ntStatus)),
+ Done);
+
+ // Init context.
+ reqCtx = GetBthHfpDeviceNotificationReqContext(m_SpeakerVolumeReq);
+ reqCtx->BthHfpDevice = this; // weak ref.
+
+ ntStatus = WdfMemoryCreatePreallocated(
+ WDF_NO_OBJECT_ATTRIBUTES,
+ &reqCtx->Buffer,
+ sizeof(reqCtx->Buffer.bImmediate),
+ &reqCtx->MemIn);
+ IF_FAILED_ACTION_JUMP(
+ ntStatus,
+ DPF(D_ERROR, ("Init: WdfMemoryCreatePreallocated failed, 0x%x", ntStatus)),
+ Done);
+
+ ntStatus = WdfMemoryCreatePreallocated(
+ WDF_NO_OBJECT_ATTRIBUTES,
+ &reqCtx->Buffer,
+ sizeof(reqCtx->Buffer.Volume),
+ &reqCtx->MemOut);
+ IF_FAILED_ACTION_JUMP(
+ ntStatus,
+ DPF(D_ERROR, ("Init: WdfMemoryCreatePreallocated failed, 0x%x", ntStatus)),
+ Done);
+
+ //
+ // IOCTL_BTHHFP_MIC_GET_VOLUME_STATUS_UPDATE
+ //
+ WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, BthHfpDeviceNotificationReqContext);
+ attributes.ParentObject = m_Adapter->GetWdfDevice();
+ ntStatus = WdfRequestCreate(
+ &attributes,
+ m_WdfIoTarget,
+ &m_MicVolumeReq);
+ IF_FAILED_ACTION_JUMP(
+ ntStatus,
+ DPF(D_ERROR, ("Init: WdfRequestCreate(Mic-Volume) failed, 0x%x", ntStatus)),
+ Done);
+
+ // Init context.
+ reqCtx = GetBthHfpDeviceNotificationReqContext(m_MicVolumeReq);
+ reqCtx->BthHfpDevice = this; // weak ref.
+
+ ntStatus = WdfMemoryCreatePreallocated(
+ WDF_NO_OBJECT_ATTRIBUTES,
+ &reqCtx->Buffer,
+ sizeof(reqCtx->Buffer.bImmediate),
+ &reqCtx->MemIn);
+ IF_FAILED_ACTION_JUMP(
+ ntStatus,
+ DPF(D_ERROR, ("Init: WdfMemoryCreatePreallocated failed, 0x%x", ntStatus)),
+ Done);
+
+ ntStatus = WdfMemoryCreatePreallocated(
+ WDF_NO_OBJECT_ATTRIBUTES,
+ &reqCtx->Buffer,
+ sizeof(reqCtx->Buffer.Volume),
+ &reqCtx->MemOut);
+ IF_FAILED_ACTION_JUMP(
+ ntStatus,
+ DPF(D_ERROR, ("Init: WdfMemoryCreatePreallocated failed, 0x%x", ntStatus)),
+ Done);
+
+ //
+ // IOCTL_BTHHFP_DEVICE_GET_CONNECTION_STATUS_UPDATE
+ //
+ WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, BthHfpDeviceNotificationReqContext);
+ attributes.ParentObject = m_Adapter->GetWdfDevice();
+ ntStatus = WdfRequestCreate(
+ &attributes,
+ m_WdfIoTarget,
+ &m_ConnectionReq);
+ IF_FAILED_ACTION_JUMP(
+ ntStatus,
+ DPF(D_ERROR, ("Init: WdfRequestCreate(Connection-Status) failed, 0x%x", ntStatus)),
+ Done);
+
+ // Init context.
+ reqCtx = GetBthHfpDeviceNotificationReqContext(m_ConnectionReq);
+ reqCtx->BthHfpDevice = this; // weak ref.
+
+ ntStatus = WdfMemoryCreatePreallocated(
+ WDF_NO_OBJECT_ATTRIBUTES,
+ &reqCtx->Buffer,
+ sizeof(reqCtx->Buffer.bImmediate),
+ &reqCtx->MemIn);
+ IF_FAILED_ACTION_JUMP(
+ ntStatus,
+ DPF(D_ERROR, ("Init: WdfMemoryCreatePreallocated failed, 0x%x", ntStatus)),
+ Done);
+
+ ntStatus = WdfMemoryCreatePreallocated(
+ WDF_NO_OBJECT_ATTRIBUTES,
+ &reqCtx->Buffer,
+ sizeof(reqCtx->Buffer.BoolStatus),
+ &reqCtx->MemOut);
+ IF_FAILED_ACTION_JUMP(
+ ntStatus,
+ DPF(D_ERROR, ("Init: WdfMemoryCreatePreallocated failed, 0x%x", ntStatus)),
+ Done);
+
+ //
+ // IOCTL_BTHHFP_STREAM_GET_STATUS_UPDATE
+ //
+ WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, BthHfpDeviceNotificationReqContext);
+ attributes.ParentObject = m_Adapter->GetWdfDevice();
+ ntStatus = WdfRequestCreate(
+ &attributes,
+ m_WdfIoTarget,
+ &m_StreamReq);
+ IF_FAILED_ACTION_JUMP(
+ ntStatus,
+ DPF(D_ERROR, ("Init: WdfRequestCreate(Stream-Status) failed, 0x%x", ntStatus)),
+ Done);
+
+ // Init context.
+ reqCtx = GetBthHfpDeviceNotificationReqContext(m_StreamReq);
+ reqCtx->BthHfpDevice = this; // weak ref.
+
+ ntStatus = WdfMemoryCreatePreallocated(
+ WDF_NO_OBJECT_ATTRIBUTES,
+ &reqCtx->Buffer,
+ sizeof(reqCtx->Buffer.bImmediate),
+ &reqCtx->MemIn);
+ IF_FAILED_ACTION_JUMP(
+ ntStatus,
+ DPF(D_ERROR, ("Init: WdfMemoryCreatePreallocated failed, 0x%x", ntStatus)),
+ Done);
+
+ ntStatus = WdfMemoryCreatePreallocated(
+ WDF_NO_OBJECT_ATTRIBUTES,
+ &reqCtx->Buffer,
+ sizeof(reqCtx->Buffer.NtStatus),
+ &reqCtx->MemOut);
+ IF_FAILED_ACTION_JUMP(
+ ntStatus,
+ DPF(D_ERROR, ("Init: WdfMemoryCreatePreallocated failed, 0x%x", ntStatus)),
+ Done);
+
+ //
+ // Create wave and filter names unique to this HFP device
+ //
+ ntStatus = CreateFilterNames(SymbolicLinkName);
+ IF_FAILED_ACTION_JUMP(
+ ntStatus,
+ DPF(D_ERROR, ("Init: Creating unqie filter names for the hfp device failed, 0x%x", ntStatus)),
+ Done);
+
+ //
+ // This remote device is now in running state. No need to use interlock operations
+ // b/c at this time this is the only thread accessing this info.
+ //
+ m_State = eBthHfpStateRunning;
+
+ //
+ // Init successful.
+ //
+ ntStatus = STATUS_SUCCESS;
+
+Done:
+ return ntStatus;
+}
+
+//=============================================================================
+#pragma code_seg("PAGE")
+BthHfpDevice::~BthHfpDevice
+(
+ void
+)
+/*++
+
+Routine Description:
+
+Destructor for BthHfpDevice.
+
+Arguments:
+
+Return Value:
+
+void
+
+--*/
+{
+ PAGED_CODE();
+ DPF_ENTER(("[BthHfpDevice::~BthHfpDevice]"));
+
+ ASSERT(m_State != eBthHfpStateRunning);
+ ASSERT(IsListEmpty(&m_ListEntry));
+
+ //
+ // Release ref to remote stack.
+ //
+ if (m_WdfIoTarget != NULL)
+ {
+ WdfObjectDelete(m_WdfIoTarget);
+ m_WdfIoTarget = NULL;
+ }
+
+ //
+ // Free symbolic links.
+ //
+ if (m_SymbolicLinkName.Buffer != NULL)
+ {
+ ExFreePoolWithTag(m_SymbolicLinkName.Buffer, MINADAPTER_POOLTAG);
+ RtlZeroMemory(&m_SymbolicLinkName, sizeof(m_SymbolicLinkName));
+ }
+
+ DeleteCustomEndpointMinipair(m_SpeakerMiniports);
+ m_SpeakerMiniports = NULL;
+
+ DeleteCustomEndpointMinipair(m_MicMiniports);
+ m_MicMiniports = NULL;
+
+ if (m_Descriptor != NULL)
+ {
+ ExFreePoolWithTag(m_Descriptor, MINADAPTER_POOLTAG);
+ m_Descriptor = NULL;
+ }
+
+ if (m_VolumePropValues != NULL)
+ {
+ ExFreePoolWithTag(m_VolumePropValues, MINADAPTER_POOLTAG);
+ m_VolumePropValues = NULL;
+ }
+
+ //
+ // Free Irps.
+ //
+ if (m_SpeakerVolumeReq != NULL)
+ {
+ BthHfpDeviceNotificationReqContext * ctx;
+
+ // Delete the associated memory objects.
+ ctx = GetBthHfpDeviceNotificationReqContext(m_SpeakerVolumeReq);
+ if (ctx->MemIn != NULL)
+ {
+ WdfObjectDelete(ctx->MemIn);
+ ctx->MemIn = NULL;
+ }
+
+ if (ctx->MemOut != NULL)
+ {
+ WdfObjectDelete(ctx->MemOut);
+ ctx->MemOut = NULL;
+ }
+
+ // Delete the request.
+ WdfObjectDelete(m_SpeakerVolumeReq);
+ m_SpeakerVolumeReq = NULL;
+ }
+
+ if (m_MicVolumeReq != NULL)
+ {
+ BthHfpDeviceNotificationReqContext * ctx;
+
+ // Delete the associated memory objects.
+ ctx = GetBthHfpDeviceNotificationReqContext(m_MicVolumeReq);
+ if (ctx->MemIn != NULL)
+ {
+ WdfObjectDelete(ctx->MemIn);
+ ctx->MemIn = NULL;
+ }
+
+ if (ctx->MemOut != NULL)
+ {
+ WdfObjectDelete(ctx->MemOut);
+ ctx->MemOut = NULL;
+ }
+
+ // Delete the request.
+ WdfObjectDelete(m_MicVolumeReq);
+ m_MicVolumeReq = NULL;
+ }
+
+ if (m_ConnectionReq != NULL)
+ {
+ BthHfpDeviceNotificationReqContext * ctx;
+
+ // Delete the associated memory objects.
+ ctx = GetBthHfpDeviceNotificationReqContext(m_ConnectionReq);
+ if (ctx->MemIn != NULL)
+ {
+ WdfObjectDelete(ctx->MemIn);
+ ctx->MemIn = NULL;
+ }
+
+ if (ctx->MemOut != NULL)
+ {
+ WdfObjectDelete(ctx->MemOut);
+ ctx->MemOut = NULL;
+ }
+
+ // Delete the request.
+ WdfObjectDelete(m_ConnectionReq);
+ m_ConnectionReq = NULL;
+ }
+
+ if (m_StreamReq != NULL)
+ {
+ BthHfpDeviceNotificationReqContext * ctx;
+
+ // Delete the associated memory objects.
+ ctx = GetBthHfpDeviceNotificationReqContext(m_StreamReq);
+ if (ctx->MemIn != NULL)
+ {
+ WdfObjectDelete(ctx->MemIn);
+ ctx->MemIn = NULL;
+ }
+
+ if (ctx->MemOut != NULL)
+ {
+ WdfObjectDelete(ctx->MemOut);
+ ctx->MemOut = NULL;
+ }
+
+ // Delete the request.
+ WdfObjectDelete(m_StreamReq);
+ m_StreamReq = NULL;
+ }
+
+ //
+ // Notification work-item.
+ //
+ if (m_WorkItem != NULL)
+ {
+ WdfObjectDelete(m_WorkItem);
+ m_WorkItem = NULL;
+ }
+
+ //
+ // Notification req. collection.
+ //
+ if (m_ReqCollection != NULL)
+ {
+ WdfObjectDelete(m_ReqCollection);
+ m_ReqCollection = NULL;
+ }
+
+ ASSERT(m_UnknownSpeakerTopology == NULL);
+ SAFE_RELEASE(m_UnknownSpeakerTopology);
+
+ ASSERT(m_UnknownSpeakerWave == NULL);
+ SAFE_RELEASE(m_UnknownSpeakerWave);
+
+ ASSERT(m_UnknownMicTopology == NULL);
+ SAFE_RELEASE(m_UnknownMicTopology);
+
+ ASSERT(m_UnknownMicWave == NULL);
+ SAFE_RELEASE(m_UnknownMicWave);
+
+ ASSERT(m_nStreams == 0);
+
+ ASSERT(m_SpeakerVolumeCallback.Handler == NULL);
+ ASSERT(m_SpeakerConnectionStatusCallback.Handler == NULL);
+ ASSERT(m_MicVolumeCallback.Handler == NULL);
+ ASSERT(m_MicConnectionStatusCallback.Handler == NULL);
+ ASSERT(m_SpeakerFormatChangeCallback.Handler == NULL);
+ ASSERT(m_MicFormatChangeCallback.Handler == NULL);
+} // ~BthHfpDevice
+
+//
+// ISidebandDeviceCommon implementation.
+//
+
+//=============================================================================
+#pragma code_seg("PAGE")
+BOOL
+BthHfpDevice::IsVolumeSupported
+(
+ _In_ eDeviceType deviceType
+)
+{
+ UNREFERENCED_PARAMETER(deviceType);
+ PAGED_CODE();
+ DPF_ENTER(("[BthHfpDevice::IsVolumeSupported]"));
+
+ return m_Descriptor->SupportsVolume;
+}
+
+//=============================================================================
+#pragma code_seg("PAGE")
+PVOID
+BthHfpDevice::GetVolumeSettings
+(
+ _In_ eDeviceType deviceType,
+ _Out_ PULONG Size
+)
+{
+ UNREFERENCED_PARAMETER(deviceType);
+ PAGED_CODE();
+ DPF_ENTER(("[BthHfpDevice::GetVolumeSettings]"));
+
+ ASSERT(Size != NULL);
+
+ *Size = m_Descriptor->VolumePropertyValuesSize;
+
+ return m_VolumePropValues;
+}
+
+//=============================================================================
+#pragma code_seg("PAGE")
+NTSTATUS
+BthHfpDevice::GetVolume
+(
+ _In_ eDeviceType DeviceType,
+ _In_ LONG Channel,
+ _Out_ LONG *pVolume
+)
+{
+ PAGED_CODE();
+ UNREFERENCED_PARAMETER(Channel);
+ DPF_ENTER(("[BthHfpDevice::GetSpeakerVolume]"));
+
+ NTSTATUS status = STATUS_SUCCESS;
+
+ ASSERT(pVolume);
+
+ if (eBthHfpSpeakerDevice == DeviceType)
+ {
+ status = GetBthHfpSpeakerVolume(pVolume);
+ IF_FAILED_ACTION_JUMP(
+ status,
+ DPF(D_ERROR, ("Start: GetBthHfpSpeakerVolume: failed, 0x%x", status)),
+ Done);
+
+ InterlockedExchange(&m_SpeakerVolumeLevel, *pVolume);
+ }
+ else if(eBthHfpMicDevice == DeviceType)
+ {
+ status = GetBthHfpMicVolume(pVolume);
+ IF_FAILED_ACTION_JUMP(
+ status,
+ DPF(D_ERROR, ("Start: GetBthHfpMicVolume: failed, 0x%x", status)),
+ Done);
+
+ InterlockedExchange(&m_MicVolumeLevel, *pVolume);
+ }
+ else
+ {
+ ASSERTMSG("Invalid device type", FALSE);
+ status = STATUS_INVALID_PARAMETER;
+ }
+
+Done:
+ return status;
+}
+
+//=============================================================================
+#pragma code_seg("PAGE")
+NTSTATUS
+BthHfpDevice::SetVolume
+(
+ _In_ eDeviceType DeviceType,
+ _In_ LONG Channel,
+ _In_ LONG Volume
+)
+{
+ PAGED_CODE();
+ UNREFERENCED_PARAMETER(Channel);
+ DPF_ENTER(("[BthHfpDevice::SetSpeakerVolume]"));
+
+ if (eBthHfpSpeakerDevice == DeviceType)
+ {
+ return SetBthHfpSpeakerVolume(Volume);
+ }
+ else if(eBthHfpMicDevice == DeviceType)
+ {
+ return SetBthHfpMicVolume(Volume);
+ }
+ else
+ {
+ ASSERTMSG("Invalid device type", FALSE);
+ return STATUS_INVALID_PARAMETER;
+ }
+}
+
+//=============================================================================
+#pragma code_seg("PAGE")
+BOOL
+BthHfpDevice::IsMuteSupported
+(
+ _In_ eDeviceType DeviceType
+)
+{
+ PAGED_CODE();
+ UNREFERENCED_PARAMETER(DeviceType);
+ DPF_ENTER(("[BthHfpDevice::IsMuteSupported]"));
+
+ return FALSE;
+}
+
+//=============================================================================
+#pragma code_seg("PAGE")
+PVOID
+BthHfpDevice::GetMuteSettings
+(
+ _In_ eDeviceType DeviceType,
+ _Out_ PULONG Size
+)
+{
+ PAGED_CODE();
+ UNREFERENCED_PARAMETER(DeviceType);
+ UNREFERENCED_PARAMETER(Size);
+ DPF_ENTER(("[BthHfpDevice::GetMuteSettings]"));
+
+ return NULL;
+}
+
+//=============================================================================
+#pragma code_seg("PAGE")
+LONG
+BthHfpDevice::GetMute
+(
+ _In_ eDeviceType DeviceType,
+ _In_ LONG Channel
+)
+{
+ PAGED_CODE();
+ UNREFERENCED_PARAMETER(DeviceType);
+ UNREFERENCED_PARAMETER(Channel);
+ DPF_ENTER(("[BthHfpDevice::GetMute]"));
+
+ return 0;
+}
+
+//=============================================================================
+#pragma code_seg("PAGE")
+NTSTATUS
+BthHfpDevice::SetMute
+(
+ _In_ eDeviceType DeviceType,
+ _In_ LONG Channel,
+ _In_ LONG Mute
+)
+{
+ PAGED_CODE();
+ UNREFERENCED_PARAMETER(DeviceType);
+ UNREFERENCED_PARAMETER(Channel);
+ UNREFERENCED_PARAMETER(Mute);
+ DPF_ENTER(("[BthHfpDevice::SetMute]"));
+
+ return STATUS_NOT_IMPLEMENTED;
+}
+
+//=============================================================================
+#pragma code_seg("PAGE")
+BOOL
+BthHfpDevice::GetConnectionStatus()
+{
+ PAGED_CODE();
+ DPF_ENTER(("[BthHfpDevice::GetConnectionStatus]"));
+
+ return (BOOL)InterlockedCompareExchange(&m_ConnectionStatusLong, 0, 0);
+}
+
+//=============================================================================
+#pragma code_seg("PAGE")
+NTSTATUS
+BthHfpDevice::GetBthHfpCodecId(_Out_ UCHAR * CodecId)
+{
+ PAGED_CODE();
+ DPF_ENTER(("[BthHfpDevice::GetBthHfpCodecId]"));
+
+ ASSERT(CodecId != NULL);
+
+ NTSTATUS ntStatus = STATUS_SUCCESS;
+
+ union {
+ HFP_BYPASS_CODEC_ID_V1 CodecIdV1;
+ HFP_BYPASS_CODEC_ID_VERSION Version;
+ } value;
+
+ *CodecId = 0;
+
+ value.Version = REQ_HFP_BYPASS_CODEC_ID_V1;
+
+ //
+ // Get the Bth HFP SCO Codec ID.
+ //
+ ntStatus = SendIoCtrlSynchronously(
+ NULL,
+ IOCTL_BTHHFP_DEVICE_GET_CODEC_ID,
+ sizeof(value.Version),
+ sizeof(value.CodecIdV1),
+ &value);
+
+ IF_FAILED_ACTION_JUMP(
+ ntStatus,
+ DPF(D_ERROR, ("GetBthHfpCodecId: SendIoCtrlSynchronously(IOCTL_BTHHFP_DEVICE_GET_CODEC_ID) failed, 0x%x", ntStatus)),
+ Done);
+
+ //
+ // All done.
+ //
+ *CodecId = value.CodecIdV1.CodecId;
+ ntStatus = STATUS_SUCCESS;
+
+Done:
+
+ return ntStatus;
+}
+
+//=============================================================================
+#pragma code_seg("PAGE")
+NTSTATUS
+BthHfpDevice::Connect()
+{
+ PAGED_CODE();
+ DPF_ENTER(("[BthHfpDevice::Connect]"));
+
+ return SetBthHfpConnect();
+}
+
+//=============================================================================
+#pragma code_seg("PAGE")
+NTSTATUS
+BthHfpDevice::Disconnect()
+{
+ PAGED_CODE();
+ DPF_ENTER(("[BthHfpDevice::Disconnect]"));
+
+ return SetBthHfpDisconnect();
+}
+
+//=============================================================================
+#pragma code_seg()
+BOOL
+BthHfpDevice::GetStreamStatus(_In_ eDeviceType deviceType)
+{
+ UNREFERENCED_PARAMETER(deviceType);
+ DPF_ENTER(("[BthHfpDevice::GetStreamStatus]"));
+
+ NTSTATUS ntStatus;
+
+ ntStatus = (NTSTATUS)InterlockedCompareExchange(&m_StreamStatusLong, 0, 0);
+
+ return NT_SUCCESS(ntStatus) ? TRUE : FALSE;
+}
+
+//=============================================================================
+#pragma code_seg("PAGE")
+NTSTATUS
+BthHfpDevice::StreamOpen(_In_ eDeviceType deviceType)
+{
+ PAGED_CODE();
+ UNREFERENCED_PARAMETER(deviceType);
+ DPF_ENTER(("[BthHfpDevice::StreamOpen]"));
+
+ // BTH HFP DDI has stream open and close.
+ // No start and suspend commands
+ // START = BTH HFP STREAM OPEN
+ // SUSPEND = BTH HFP STREAM CLOSE
+ return STATUS_SUCCESS;
+}
+
+//=============================================================================
+#pragma code_seg("PAGE")
+NTSTATUS
+BthHfpDevice::StreamStart
+(
+ _In_ eDeviceType deviceType
+)
+{
+ PAGED_CODE();
+ UNREFERENCED_PARAMETER(deviceType);
+ DPF_ENTER(("[BthHfpDevice::StreamStart]"));
+
+ NTSTATUS ntStatus = STATUS_SUCCESS;
+ LONG nStreams = 0;
+
+ ASSERT(m_nStreams >= 0);
+
+ nStreams = InterlockedIncrement(&m_nStreams);
+ if (nStreams == 1)
+ {
+ BOOLEAN streamStart = FALSE;
+
+ ntStatus = SetBthHfpStreamOpen();
+ if (NT_SUCCESS(ntStatus))
+ {
+ streamStart = TRUE;
+ m_StreamStatus = STATUS_SUCCESS;
+ ntStatus = EnableBthHfpStreamStatusNotification();
+ }
+
+ //
+ // Cleanup if any error.
+ //
+ if (!NT_SUCCESS(ntStatus))
+ {
+ nStreams = InterlockedDecrement(&m_nStreams);
+ ASSERT(nStreams == 0);
+ UNREFERENCED_VAR(nStreams);
+
+ if (streamStart)
+ {
+ SetBthHfpStreamClose();
+ }
+
+ m_StreamStatus = STATUS_INVALID_DEVICE_STATE;
+ }
+ }
+
+ return ntStatus;
+}
+
+//=============================================================================
+#pragma code_seg("PAGE")
+NTSTATUS
+BthHfpDevice::StreamSuspend
+(
+ _In_ eDeviceType deviceType
+)
+{
+ UNREFERENCED_PARAMETER(deviceType);
+ PAGED_CODE();
+ DPF_ENTER(("[BthHfpDevice::StreamSuspend]"));
+
+ NTSTATUS ntStatus = STATUS_SUCCESS;
+ LONG nStreams = 0;
+
+ ASSERT(m_nStreams > 0);
+
+ nStreams = InterlockedDecrement(&m_nStreams);
+ if (nStreams == 0)
+ {
+ ntStatus = SetBthHfpStreamClose();
+
+ StopBthHfpStreamStatusNotification();
+
+ m_StreamStatus = STATUS_INVALID_DEVICE_STATE;
+ }
+
+ return ntStatus;
+}
+
+//=============================================================================
+#pragma code_seg("PAGE")
+NTSTATUS
+BthHfpDevice::StreamClose
+(
+ _In_ eDeviceType deviceType
+)
+{
+ UNREFERENCED_PARAMETER(deviceType);
+ PAGED_CODE();
+ DPF_ENTER(("[BthHfpDevice::StreamClose]"));
+
+ // BTH HFP DDI has stream open and close.
+ // No start and suspend commands
+ // START = BTH HFP STREAM OPEN
+ // SUSPEND = BTH HFP STREAM CLOSE
+ return STATUS_SUCCESS;
+}
+
+//=============================================================================
+#pragma code_seg("PAGE")
+GUID
+BthHfpDevice::GetContainerId(_In_ eDeviceType deviceType)
+{
+ PAGED_CODE();
+ DPF_ENTER(("[BthHfpDevice::GetContainerId]"));
+
+ UNREFERENCED_PARAMETER(deviceType);
+
+ return m_Descriptor->ContainerId;
+}
+
+//=============================================================================
+#pragma code_seg("PAGE")
+VOID
+BthHfpDevice::SetVolumeHandler
+(
+ _In_ eDeviceType deviceType,
+ _In_opt_ PFNEVENTNOTIFICATION EventHandler,
+ _In_opt_ PVOID EventHandlerContext
+)
+{
+ PAGED_CODE();
+ DPF_ENTER(("[BthHfpDevice::SetVolumeHandler]"));
+
+ if (deviceType == eBthHfpSpeakerDevice)
+ {
+ ASSERT(EventHandler == NULL || m_SpeakerVolumeCallback.Handler == NULL);
+
+ m_SpeakerVolumeCallback.Handler = EventHandler; // weak ref.
+ m_SpeakerVolumeCallback.Context = EventHandlerContext;
+ }
+ else if (deviceType == eBthHfpMicDevice)
+ {
+ ASSERT(EventHandler == NULL || m_MicVolumeCallback.Handler == NULL);
+
+ m_MicVolumeCallback.Handler = EventHandler; // weak ref.
+ m_MicVolumeCallback.Context = EventHandlerContext;
+ }
+}
+
+//=============================================================================
+#pragma code_seg("PAGE")
+VOID
+BthHfpDevice::SetMuteHandler
+(
+ _In_ eDeviceType deviceType,
+ _In_opt_ PFNEVENTNOTIFICATION EventHandler,
+ _In_opt_ PVOID EventHandlerContext
+)
+{
+ PAGED_CODE();
+ DPF_ENTER(("[BthHfpDevice::SetMuteHandler]"));
+
+ if (deviceType == eBthHfpSpeakerDevice)
+ {
+ ASSERT(EventHandler == NULL || m_SpeakerMuteCallback.Handler == NULL);
+
+ m_SpeakerMuteCallback.Handler = EventHandler; // weak ref.
+ m_SpeakerMuteCallback.Context = EventHandlerContext;
+ }
+ else if (deviceType == eBthHfpMicDevice)
+ {
+ ASSERT(EventHandler == NULL || m_MicMuteCallback.Handler == NULL);
+
+ m_MicMuteCallback.Handler = EventHandler; // weak ref.
+ m_MicMuteCallback.Context = EventHandlerContext;
+ }
+}
+
+//=============================================================================
+#pragma code_seg("PAGE")
+VOID
+BthHfpDevice::SetConnectionStatusHandler
+(
+ _In_ eDeviceType deviceType,
+ _In_opt_ PFNEVENTNOTIFICATION EventHandler,
+ _In_opt_ PVOID EventHandlerContext
+)
+{
+ PAGED_CODE();
+ DPF_ENTER(("[BthHfpDevice::SetConnectionStatusHandler]"));
+
+ if (deviceType == eBthHfpSpeakerDevice)
+ {
+ ASSERT(EventHandler == NULL || m_SpeakerConnectionStatusCallback.Handler == NULL);
+
+ m_SpeakerConnectionStatusCallback.Handler = EventHandler; // weak ref.
+ m_SpeakerConnectionStatusCallback.Context = EventHandlerContext;
+ }
+ else if (deviceType == eBthHfpMicDevice)
+ {
+ ASSERT(EventHandler == NULL || m_MicConnectionStatusCallback.Handler == NULL);
+
+ m_MicConnectionStatusCallback.Handler = EventHandler; // weak ref.
+ m_MicConnectionStatusCallback.Context = EventHandlerContext;
+ }
+
+}
+
+//=============================================================================
+#pragma code_seg("PAGE")
+VOID
+BthHfpDevice::SetFormatChangeHandler
+(
+ _In_ eDeviceType deviceType,
+ _In_opt_ PFNEVENTNOTIFICATION EventHandler,
+ _In_opt_ PVOID EventHandlerContext
+)
+{
+ PAGED_CODE();
+ DPF_ENTER(("[BthHfpDevice::SetFormatChangeHandler]"));
+
+ if (deviceType == eBthHfpSpeakerDevice)
+ {
+ ASSERT(EventHandler == NULL || m_SpeakerFormatChangeCallback.Handler == NULL);
+
+ m_SpeakerFormatChangeCallback.Handler = EventHandler; // weak ref.
+ m_SpeakerFormatChangeCallback.Context = EventHandlerContext;
+ }
+ else if (deviceType == eBthHfpMicDevice)
+ {
+ ASSERT(EventHandler == NULL || m_MicFormatChangeCallback.Handler == NULL);
+
+ m_MicFormatChangeCallback.Handler = EventHandler; // weak ref.
+ m_MicFormatChangeCallback.Context = EventHandlerContext;
+ }
+
+}
+
+//=============================================================================
+#pragma code_seg("PAGE")
+PPIN_DEVICE_FORMATS_AND_MODES
+BthHfpDevice::GetFormatsAndModes
+(
+ _In_ eDeviceType deviceType
+)
+{
+ PPIN_DEVICE_FORMATS_AND_MODES pFormatsAndModes = NULL;
+ ULONG endpointIndex = 0;
+
+
+ // CVSD is the narrow band codec for SCO. Wideband codec IDs are any number higher than 1.
+ // mSBC is the only required wideband codec, though the controller+headset combination may
+ // support other wideband codecs.
+
+ enum
+ {
+ BTHHFP_CODEC_CVSD = 0,
+ BTHHFP_CODEC_mSBC,
+
+ BTHHFP_CODEC_INVALID
+ };
+
+ if (m_CodecId > BTHHFP_CODEC_CVSD)
+ {
+ // Use the miniport tables that support 16kHz
+ endpointIndex = 1;
+ }
+
+ if (deviceType == eBthHfpSpeakerDevice)
+ {
+ pFormatsAndModes = g_BthHfpRenderEndpoints[endpointIndex]->PinDeviceFormatsAndModes;
+ }
+ else if (deviceType == eBthHfpMicDevice)
+ {
+ pFormatsAndModes = g_BthHfpCaptureEndpoints[endpointIndex]->PinDeviceFormatsAndModes;
+ }
+
+ return pFormatsAndModes;
+}
+
+//=============================================================================
+#pragma code_seg("PAGE")
+BOOL
+BthHfpDevice::IsNRECSupported()
+{
+ PAGED_CODE();
+ DPF_ENTER(("[BthHfpDevice::IsNRECSupported]"));
+
+ return m_Descriptor->SupportsNREC;
+}
+
+//=============================================================================
+#pragma code_seg("PAGE")
+BOOL
+BthHfpDevice::GetNRECDisableStatus()
+{
+ PAGED_CODE();
+ DPF_ENTER(("[BthHfpDevice::GetNRECDisableStatus]"));
+
+ // Return TRUE if HF wants to disable the NREC on the AG.
+ return (BOOL)InterlockedCompareExchange(&m_NRECDisableStatusLong, 0, 0);
+}
+
+//
+// Helper functions.
+//
+
+//=============================================================================
+#pragma code_seg()
+NTSTATUS
+BthHfpDevice::SendIoCtrlAsynchronously
+(
+ _In_ WDFREQUEST Request,
+ _In_ ULONG IoControlCode,
+ _In_opt_ WDFMEMORY MemIn,
+ _In_opt_ WDFMEMORY MemOut,
+ _In_ PFN_WDF_REQUEST_COMPLETION_ROUTINE CompletionRoutine,
+ _In_ WDFCONTEXT Context
+)
+/*++
+
+Routine Description:
+
+This function aynchronously sends an I/O Ctrl request to the BTH HFP
+SCO Bypass device.
+
+--*/
+{
+ DPF_ENTER(("[BthHfpDevice::SendIoCtrlAsynchronously]"));
+
+ NTSTATUS ntStatus = STATUS_SUCCESS;
+ BOOLEAN fSent = FALSE;
+
+ //
+ // Format and send the request.
+ //
+ ntStatus = WdfIoTargetFormatRequestForIoctl(
+ m_WdfIoTarget,
+ Request,
+ IoControlCode,
+ MemIn,
+ NULL,
+ MemOut,
+ NULL);
+
+ IF_FAILED_ACTION_JUMP(
+ ntStatus,
+ DPF(D_ERROR, ("SendIoCtrlAsynchronously: WdfIoTargetFormatRequestForIoctl(0x%x) failed, 0x%x", IoControlCode, ntStatus)),
+ Done);
+
+ WdfRequestSetCompletionRoutine(
+ Request,
+ CompletionRoutine,
+ Context);
+
+ fSent = WdfRequestSend(Request, m_WdfIoTarget, NULL); // no options.
+ if (fSent == FALSE)
+ {
+ ntStatus = WdfRequestGetStatus(Request);
+ if (NT_SUCCESS(ntStatus))
+ {
+ ntStatus = STATUS_INVALID_DEVICE_STATE;
+ }
+
+ DPF(D_ERROR, ("SendIoCtrlAsynchronously: WdfRequestSend(0x%x) failed, 0x%x", IoControlCode, ntStatus));
+ goto Done;
+ }
+
+ //
+ // All Done.
+ //
+ ntStatus = STATUS_SUCCESS;
+
+Done:
+
+ return ntStatus;
+}
+
+//=============================================================================
+#pragma code_seg("PAGE")
+NTSTATUS
+BthHfpDevice::SendIoCtrlSynchronously
+(
+ _In_opt_ WDFREQUEST Request,
+ _In_ ULONG IoControlCode,
+ _In_ ULONG InLength,
+ _In_ ULONG OutLength,
+ _When_(InLength > 0 || OutLength > 0, _In_)
+ _When_(InLength == 0 && OutLength == 0, _In_opt_)
+ PVOID Buffer
+)
+/*++
+
+Routine Description:
+
+This function inits and synchronously sends an I/O Ctrl request to the BTH HFP
+SCO Bypass device.
+
+--*/
+{
+ PAGED_CODE();
+ DPF_ENTER(("[BthHfpDevice::SendIoCtrlSynchronously]"));
+
+ NTSTATUS ntStatus = STATUS_SUCCESS;
+ PWDF_MEMORY_DESCRIPTOR memInPtr = NULL;
+ PWDF_MEMORY_DESCRIPTOR memOutPtr = NULL;
+ WDF_MEMORY_DESCRIPTOR memIn;
+ WDF_MEMORY_DESCRIPTOR memOut;
+ WDF_REQUEST_SEND_OPTIONS reqOpts;
+
+ //
+ // Format and send the request.
+ //
+ if (InLength)
+ {
+ WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&memIn, Buffer, InLength);
+ memInPtr = &memIn;
+ }
+
+ if (OutLength)
+ {
+ WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&memOut, Buffer, OutLength);
+ memOutPtr = &memOut;
+ }
+
+ WDF_REQUEST_SEND_OPTIONS_INIT(
+ &reqOpts,
+ WDF_REQUEST_SEND_OPTION_TIMEOUT |
+ WDF_REQUEST_SEND_OPTION_SYNCHRONOUS);
+
+ reqOpts.Timeout = WDF_REL_TIMEOUT_IN_SEC(BTH_HFP_SYNC_REQ_TIMEOUT_IN_SEC);
+
+ ntStatus = WdfIoTargetSendIoctlSynchronously(
+ m_WdfIoTarget,
+ Request,
+ IoControlCode,
+ memInPtr,
+ memOutPtr,
+ &reqOpts,
+ NULL); // bytes returned.
+
+ IF_FAILED_ACTION_JUMP(
+ ntStatus,
+ DPF(D_VERBOSE, ("SendIoCtrlSynchronously: WdfIoTargetSendIoctlSynchronously(0x%x) failed, 0x%x", IoControlCode, ntStatus)),
+ Done);
+
+Done:
+
+ return ntStatus;
+}
+
+//=============================================================================
+#pragma code_seg()
+VOID
+BthHfpDevice::EvtBthHfpDeviceNotificationStatusWorkItem
+(
+ _In_ WDFWORKITEM WorkItem
+)
+/*++
+
+Routine Description:
+
+The function processes status notification updates.
+
+Arguments:
+
+WorkItem - WDF work-item object.
+
+--*/
+{
+ DPF_ENTER(("[BthHfpDevice::EvtBthHfpDeviceNotificationStatusWorkItem]"));
+
+ NTSTATUS ntStatus = STATUS_SUCCESS;
+ BthHfpDevice * This;
+ KIRQL oldIrql;
+
+ if (WorkItem == NULL)
+ {
+ return;
+ }
+
+ This = GetBthHfpDeviceNotificationWorkItemContext(WorkItem)->BthHfpDevice;
+ ASSERT(This != NULL);
+
+ for (;;)
+ {
+ BOOL resend = TRUE;
+ WDFREQUEST req = NULL;
+ BthHfpDeviceNotificationReqContext * reqCtx;
+ WDF_REQUEST_COMPLETION_PARAMS params;
+
+ //
+ // Retrieve a task.
+ //
+ KeAcquireSpinLock(&This->m_Lock, &oldIrql);
+ req = (WDFREQUEST)WdfCollectionGetFirstItem(This->m_ReqCollection);
+ if (req != NULL)
+ {
+ WdfCollectionRemove(This->m_ReqCollection, req);
+ }
+ KeReleaseSpinLock(&This->m_Lock, oldIrql);
+
+ if (req == NULL)
+ {
+ break;
+ }
+
+ //
+ // Get request parameters and context.
+ //
+ WDF_REQUEST_COMPLETION_PARAMS_INIT(&params);
+ WdfRequestGetCompletionParams(req, &params);
+
+ reqCtx = GetBthHfpDeviceNotificationReqContext(req);
+ ASSERT(reqCtx != NULL);
+
+ //
+ // Handle this notification.
+ //
+ if (NT_SUCCESS(params.IoStatus.Status))
+ {
+ switch (params.Parameters.Ioctl.IoControlCode)
+ {
+ case IOCTL_BTHHFP_DEVICE_GET_NRECDISABLE_STATUS_UPDATE:
+ {
+ InterlockedExchange(&This->m_NRECDisableStatusLong, (LONG)reqCtx->Buffer.BoolStatus);
+ }
+ break;
+
+ case IOCTL_BTHHFP_SPEAKER_GET_VOLUME_STATUS_UPDATE:
+ {
+ LONG oldVolume;
+
+ oldVolume = InterlockedExchange(&This->m_SpeakerVolumeLevel, reqCtx->Buffer.Volume);
+ if (reqCtx->Buffer.Volume != oldVolume)
+ {
+ // Notify audio miniport about this change.
+ if (This->m_SpeakerVolumeCallback.Handler != NULL)
+ {
+ This->m_SpeakerVolumeCallback.Handler(
+ This->m_SpeakerVolumeCallback.Context);
+ }
+ }
+ }
+ break;
+
+ case IOCTL_BTHHFP_MIC_GET_VOLUME_STATUS_UPDATE:
+ {
+ LONG oldVolume;
+
+ oldVolume = InterlockedExchange(&This->m_MicVolumeLevel, reqCtx->Buffer.Volume);
+ if (reqCtx->Buffer.Volume != oldVolume)
+ {
+ // Notify audio miniport about this change.
+ if (This->m_MicVolumeCallback.Handler != NULL)
+ {
+ This->m_MicVolumeCallback.Handler(
+ This->m_MicVolumeCallback.Context);
+ }
+ }
+ }
+ break;
+
+ case IOCTL_BTHHFP_DEVICE_GET_CONNECTION_STATUS_UPDATE:
+ {
+ BOOL oldStatus;
+ //
+
+ //
+ // Get codec id (if non-zero, connection supports Wideband Speech)
+ //
+ UCHAR codecId = 0;
+ UCHAR oldCodecId = 0;
+ if (reqCtx->Buffer.BoolStatus)
+ {
+ ntStatus = This->GetBthHfpCodecId(&codecId);
+ if (ntStatus == STATUS_INVALID_DEVICE_REQUEST)
+ {
+ // GetBthHfpCodecId fails with STATUS_INVALID_DEVICE_REQUEST if the system doesn't
+ // support Wideband Speech (currently only Mobile supports this call)
+ ntStatus = STATUS_SUCCESS;
+ }
+
+ if (NT_SUCCESS(ntStatus))
+ {
+ oldCodecId = (UCHAR)InterlockedExchange(&This->m_CodecId, codecId);
+ if (codecId != oldCodecId)
+ {
+ // Notify audio miniport about this change.
+ if (This->m_SpeakerFormatChangeCallback.Handler != NULL)
+ {
+ This->m_SpeakerFormatChangeCallback.Handler(
+ This->m_SpeakerFormatChangeCallback.Context);
+ }
+
+ if (This->m_MicFormatChangeCallback.Handler != NULL)
+ {
+ This->m_MicFormatChangeCallback.Handler(
+ This->m_MicFormatChangeCallback.Context);
+ }
+ }
+ }
+ }
+
+ oldStatus = (BOOL)InterlockedExchange(&This->m_ConnectionStatusLong, (LONG)reqCtx->Buffer.BoolStatus);
+ if (reqCtx->Buffer.BoolStatus != oldStatus)
+ {
+ // Notify audio miniport about this change.
+ if (This->m_SpeakerConnectionStatusCallback.Handler != NULL)
+ {
+ This->m_SpeakerConnectionStatusCallback.Handler(
+ This->m_SpeakerConnectionStatusCallback.Context);
+ }
+
+ if (This->m_MicConnectionStatusCallback.Handler != NULL)
+ {
+ This->m_MicConnectionStatusCallback.Handler(
+ This->m_MicConnectionStatusCallback.Context);
+ }
+ }
+ }
+ break;
+
+ default:
+ // This should never happen.
+ resend = FALSE;
+ DPF(D_ERROR, ("EvtBthHfpDeviceNotificationStatusWorkItem: invalid request ctrl 0x%x",
+ params.Parameters.Ioctl.IoControlCode));
+ break;
+ }
+ }
+
+ if (resend)
+ {
+ WDF_REQUEST_REUSE_PARAMS reuseParams;
+
+ WDF_REQUEST_REUSE_PARAMS_INIT(
+ &reuseParams,
+ WDF_REQUEST_REUSE_NO_FLAGS,
+ STATUS_SUCCESS);
+
+ ntStatus = WdfRequestReuse(req, &reuseParams);
+ if (!NT_SUCCESS(ntStatus))
+ {
+ DPF(D_ERROR, ("EvtBthHfpDeviceNotificationStatusWorkItem: WdfRequestReuse failed, 0x%x", ntStatus));
+ break;
+ }
+
+ // Resend status notification request.
+ reqCtx->Buffer.bImmediate = FALSE;
+
+ ntStatus = This->SendIoCtrlAsynchronously(
+ req,
+ params.Parameters.Ioctl.IoControlCode,
+ reqCtx->MemIn,
+ reqCtx->MemOut,
+ EvtBthHfpDeviceNotificationStatusCompletion,
+ This);
+
+ if (!NT_SUCCESS(ntStatus))
+ {
+ DPF(D_ERROR, ("EvtBthHfpDeviceNotificationStatusWorkItem: SendIoCtrlAsynchronously"
+ "(0x%x) failed, 0x%x",
+ params.Parameters.Ioctl.IoControlCode, ntStatus));
+ break;
+ }
+ }
+ }
+}
+
+//=============================================================================
+#pragma code_seg()
+void
+BthHfpDevice::EvtBthHfpDeviceNotificationStatusCompletion
+(
+ _In_ WDFREQUEST Request,
+ _In_ WDFIOTARGET Target,
+ _In_ PWDF_REQUEST_COMPLETION_PARAMS Params,
+ _In_ WDFCONTEXT Context
+)
+{
+ DPF_ENTER(("[BthHfpDevice::EvtBthHfpDeviceNotificationStatusCompletion]"));
+
+ NTSTATUS ntStatus = STATUS_SUCCESS;
+ BthHfpDeviceNotificationReqContext * ctx = NULL;
+ BthHfpDevice * This = NULL;
+ KIRQL oldIrql;
+
+ UNREFERENCED_PARAMETER(Target);
+ UNREFERENCED_PARAMETER(Context);
+
+ ctx = GetBthHfpDeviceNotificationReqContext(Request);
+ This = ctx->BthHfpDevice;
+ ASSERT(This != NULL);
+
+ ntStatus = Params->IoStatus.Status;
+ if (ntStatus == STATUS_CANCELLED)
+ {
+ // BTH HFP device is shutting down. Do not re-send this request.
+ goto Done;
+ }
+
+ //
+ // If something is wrong with the HFP interface, do not loop forever.
+ //
+ if (!NT_SUCCESS(ntStatus))
+ {
+ if (++ctx->Errors > BTH_HFP_NOTIFICATION_MAX_ERROR_COUNT)
+ {
+ // Too many errors. Do not re-send this request.
+ goto Done;
+ }
+ }
+ else
+ {
+ // reset the # of errors.
+ ctx->Errors = 0;
+ }
+
+ //
+ // Let the work-item thread process this request.
+ //
+ KeAcquireSpinLock(&This->m_Lock, &oldIrql);
+
+ ntStatus = WdfCollectionAdd(This->m_ReqCollection, Request);
+ if (NT_SUCCESS(ntStatus))
+ {
+ WdfWorkItemEnqueue(This->m_WorkItem);
+ }
+
+ KeReleaseSpinLock(&This->m_Lock, oldIrql);
+
+Done:;
+}
+
+//=============================================================================
+#pragma code_seg("PAGE")
+NTSTATUS
+BthHfpDevice::SetBthHfpDeviceCapabilities
+(
+ _In_ BOOL bSupports16kHzSampling
+
+)
+/*++
+
+Routine Description:
+
+This function synchronously informs the Audio Driver capabilities to BthHfp stack.
+
+--*/
+{
+ PAGED_CODE();
+ DPF_ENTER(("[BthHfpDevice::SetBthHfpDeviceCapabilities]"));
+
+ NTSTATUS ntStatus = STATUS_SUCCESS;
+ BTHHFP_AUDIO_DEVICE_CAPABILTIES deviceCaps = { 0 };
+
+ BTHHFP_AUDIO_DEVICE_CAPABILTIES_INIT(&deviceCaps);
+ deviceCaps.Supports16kHzSampling = bSupports16kHzSampling;
+
+ //
+ // Get the Bth HFP SCO Bypass speaker volume.
+ //
+ ntStatus = SendIoCtrlSynchronously(
+ NULL,
+ IOCTL_BTHHFP_DEVICE_INDICATE_AUDIO_DEVICE_CAPABILITIES,
+ sizeof(BTHHFP_AUDIO_DEVICE_CAPABILTIES),
+ 0,
+ &deviceCaps);
+
+ IF_FAILED_ACTION_JUMP(
+ ntStatus,
+ DPF(D_ERROR, ("SetBthHfpDeviceCapabilities: SendIoCtrlSynchronously(IOCTL_BTHHFP_DEVICE_INDICATE_AUDIO_DEVICE_CAPABILITIES) failed, 0x%x", ntStatus)),
+ Done);
+
+ //
+ // All done.
+ //
+ ntStatus = STATUS_SUCCESS;
+
+Done:
+
+ return ntStatus;
+}
+
+//=============================================================================
+#pragma code_seg("PAGE")
+NTSTATUS
+BthHfpDevice::GetBthHfpDescriptor
+(
+ _Out_ PBTHHFP_DESCRIPTOR2 * Descriptor
+)
+/*++
+
+Routine Description:
+
+This function synchronously gets the remote Bluetooth Hands-Free Profile SCO
+Bypass descriptor.
+
+--*/
+{
+ PAGED_CODE();
+ DPF_ENTER(("[BthHfpDevice::GetBthHfpDescriptor]"));
+
+ NTSTATUS ntStatus = STATUS_SUCCESS;
+ WDFREQUEST req = NULL;
+ PBTHHFP_DESCRIPTOR2 descriptor = NULL;
+ ULONG length = 0;
+ ULONG_PTR information = 0;
+ WDF_REQUEST_REUSE_PARAMS reuseParams;
+ WDF_OBJECT_ATTRIBUTES attributes;
+
+ *Descriptor = NULL;
+
+ //
+ // Allocate and format a WDF request.
+ //
+ WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
+ attributes.ParentObject = m_Adapter->GetWdfDevice();
+ ntStatus = WdfRequestCreate(
+ &attributes,
+ m_WdfIoTarget,
+ &req);
+ IF_FAILED_ACTION_JUMP(
+ ntStatus,
+ DPF(D_ERROR, ("GetBthHfpDescriptor: WdfRequestCreate failed, 0x%x", ntStatus)),
+ Done);
+
+ //
+ // Get the size of the buffer.
+ //
+ ntStatus = SendIoCtrlSynchronously(
+ req,
+ IOCTL_BTHHFP_DEVICE_GET_DESCRIPTOR2,
+ NULL,
+ NULL,
+ NULL);
+
+ if (ntStatus != STATUS_BUFFER_TOO_SMALL)
+ {
+ if (NT_SUCCESS(ntStatus))
+ {
+ ntStatus = STATUS_INVALID_DEVICE_STATE;
+ }
+
+ DPF(D_ERROR, ("GetBthHfpDescriptor: SendIoCtrlSynchronously(IOCTL_BTHHFP_DEVICE_GET_DESCRIPTOR2): failed, 0x%x", ntStatus));
+ goto Done;
+ }
+
+ ntStatus = STATUS_SUCCESS;
+
+ information = WdfRequestGetInformation(req);
+ if (information == 0 || information > ULONG_MAX)
+ {
+ ntStatus = STATUS_INVALID_DEVICE_STATE;
+ DPF(D_ERROR, ("GetBthHfpDescriptor: IOCTL_BTHHFP_DEVICE_GET_DESCRIPTOR2 buffer too big (%Id): 0x%x", information, ntStatus));
+ goto Done;
+ }
+
+ length = (ULONG)information;
+
+ //
+ // Allocate memory needed to hold the info.
+ //
+ descriptor = (PBTHHFP_DESCRIPTOR2)ExAllocatePoolWithTag(NonPagedPoolNx, length, MINADAPTER_POOLTAG);
+ if (descriptor == NULL)
+ {
+ ntStatus = STATUS_INSUFFICIENT_RESOURCES;
+ }
+ IF_FAILED_ACTION_JUMP(
+ ntStatus,
+ DPF(D_ERROR, ("GetBthHfpDescriptor: ExAllocatePoolWithTag failed, out of memory")),
+ Done);
+
+ //
+ // Get the Bth HFP SCO Bypass descriptor.
+ //
+ WDF_REQUEST_REUSE_PARAMS_INIT(
+ &reuseParams,
+ WDF_REQUEST_REUSE_NO_FLAGS,
+ STATUS_SUCCESS);
+
+ ntStatus = WdfRequestReuse(req, &reuseParams);
+ IF_FAILED_ACTION_JUMP(
+ ntStatus,
+ DPF(D_ERROR, ("GetBthHfpDescriptor: WdfRequestReuse failed, 0x%x", ntStatus)),
+ Done);
+
+ ntStatus = SendIoCtrlSynchronously(
+ req,
+ IOCTL_BTHHFP_DEVICE_GET_DESCRIPTOR2,
+ NULL,
+ length,
+ descriptor);
+ IF_FAILED_ACTION_JUMP(
+ ntStatus,
+ DPF(D_ERROR, ("GetBthHfpDescriptor: SendIoCtrlSynchronously(IOCTL_BTHHFP_DEVICE_GET_DESCRIPTOR2) failed, 0x%x", ntStatus)),
+ Done);
+
+ //
+ // All done.
+ //
+ *Descriptor = descriptor;
+ ntStatus = STATUS_SUCCESS;
+
+Done:
+ if (!NT_SUCCESS(ntStatus))
+ {
+ if (descriptor != NULL)
+ {
+ ExFreePoolWithTag(descriptor, MINADAPTER_POOLTAG);
+ }
+ }
+
+ if (req != NULL)
+ {
+ WdfObjectDelete(req);
+ req = NULL;
+ }
+
+ return ntStatus;
+}
+
+//=============================================================================
+#pragma code_seg()
+NTSTATUS
+BthHfpDevice::EnableBthHfpNrecDisableStatusNotification()
+/*++
+
+Routine Description:
+
+This function registers for Bluetooth Hands-Free Profile SCO Bypass NREC-Disable
+status change notification.
+
+--*/
+{
+ DPF_ENTER(("[BthHfpDevice::EnableBthHfpNrecDisableStatusNotification]"));
+
+ NTSTATUS ntStatus = STATUS_SUCCESS;
+ BthHfpDeviceNotificationReqContext * ctx = NULL;
+
+ ctx = GetBthHfpDeviceNotificationReqContext(m_NRECDisableStatusReq);
+
+ //
+ // This is a notification request.
+ //
+ ctx->Buffer.bImmediate = FALSE;
+
+ //
+ // Get the Bth HFP SCO Bypass NREC-Disable status (async).
+ //
+ ntStatus = SendIoCtrlAsynchronously(
+ m_NRECDisableStatusReq,
+ IOCTL_BTHHFP_DEVICE_GET_NRECDISABLE_STATUS_UPDATE,
+ ctx->MemIn,
+ ctx->MemOut,
+ EvtBthHfpDeviceNotificationStatusCompletion,
+ this);
+
+ IF_FAILED_ACTION_JUMP(
+ ntStatus,
+ DPF(D_ERROR, ("EnableBthHfpNrecDisableStatusNotification: SendIoCtrlAsynchronously(IOCTL_BTHHFP_DEVICE_GET_NRECDISABLE_STATUS_UPDATE) failed, 0x%x", ntStatus)),
+ Done);
+
+ //
+ // All done.
+ //
+ ntStatus = STATUS_SUCCESS;
+
+Done:
+
+ return ntStatus;
+}
+
+//=============================================================================
+#pragma code_seg("PAGE")
+NTSTATUS
+BthHfpDevice::GetBthHfpVolumePropertyValues
+(
+ _In_ ULONG Length,
+ _Out_ PKSPROPERTY_VALUES * PropValues
+)
+/*++
+
+Routine Description:
+
+This function synchronously gets the remote Bluetooth Hands-Free Profile SCO
+Bypass volume values.
+
+--*/
+{
+ PAGED_CODE();
+ DPF_ENTER(("[BthHfpDevice::GetBthHfpVolumePropertyValues]"));
+
+ NTSTATUS ntStatus = STATUS_SUCCESS;
+ PKSPROPERTY_VALUES propValues = NULL;
+
+ *PropValues = NULL;
+
+ //
+ // Allocate memory.
+ //
+ propValues = (PKSPROPERTY_VALUES)ExAllocatePoolWithTag(NonPagedPoolNx, Length, MINADAPTER_POOLTAG);
+ if (propValues == NULL)
+ {
+ ntStatus = STATUS_INSUFFICIENT_RESOURCES;
+ }
+ IF_FAILED_ACTION_JUMP(
+ ntStatus,
+ DPF(D_ERROR, ("GetBthHfpVolumePropertyValues: ExAllocatePoolWithTag failed, out of memory")),
+ Done);
+
+ //
+ // Get the Bth HFP SCO Bypass descriptor.
+ //
+ ntStatus = SendIoCtrlSynchronously(
+ NULL,
+ IOCTL_BTHHFP_DEVICE_GET_VOLUMEPROPERTYVALUES,
+ 0,
+ Length,
+ propValues);
+
+ IF_FAILED_ACTION_JUMP(
+ ntStatus,
+ DPF(D_ERROR, ("GetBthHfpVolumePropertyValues: SendIoCtrlSynchronously(IOCTL_BTHHFP_DEVICE_GET_VOLUMEPROPERTYVALUES) failed, 0x%x", ntStatus)),
+ Done);
+
+ //
+ // All done.
+ //
+ *PropValues = propValues;
+ ntStatus = STATUS_SUCCESS;
+
+Done:
+ if (!NT_SUCCESS(ntStatus))
+ {
+ if (propValues != NULL)
+ {
+ ExFreePoolWithTag(propValues, MINADAPTER_POOLTAG);
+ }
+ }
+
+ return ntStatus;
+}
+
+//=============================================================================
+#pragma code_seg("PAGE")
+NTSTATUS
+BthHfpDevice::SetBthHfpSpeakerVolume
+(
+ _In_ LONG Volume
+)
+/*++
+
+Routine Description:
+
+This function synchronously sets the remote Bluetooth Hands-Free Profile SCO
+Bypass speaker volume.
+
+--*/
+{
+ PAGED_CODE();
+ DPF_ENTER(("[BthHfpDevice::SetBthHfpSpeakerVolume]"));
+
+ NTSTATUS ntStatus = STATUS_SUCCESS;
+
+ //
+ // Get the Bth HFP SCO Bypass speaker volume.
+ //
+ ntStatus = SendIoCtrlSynchronously(
+ NULL,
+ IOCTL_BTHHFP_SPEAKER_SET_VOLUME,
+ sizeof(Volume),
+ 0,
+ &Volume);
+
+ IF_FAILED_ACTION_JUMP(
+ ntStatus,
+ DPF(D_ERROR, ("SetBthHfpSpeakerVolume: SendIoCtrlSynchronously(IOCTL_BTHHFP_SPEAKER_SET_VOLUME) failed, 0x%x", ntStatus)),
+ Done);
+
+ //
+ // All done.
+ //
+ ntStatus = STATUS_SUCCESS;
+
+Done:
+
+ return ntStatus;
+}
+
+//=============================================================================
+#pragma code_seg("PAGE")
+NTSTATUS
+BthHfpDevice::GetBthHfpSpeakerVolume
+(
+ _Out_ LONG * Volume
+)
+/*++
+
+Routine Description:
+
+This function synchronously gets the remote Bluetooth Hands-Free Profile SCO
+Bypass speaker volume.
+
+--*/
+{
+ PAGED_CODE();
+ DPF_ENTER(("[BthHfpDevice::GetBthHfpSpeakerVolume]"));
+
+ NTSTATUS ntStatus = STATUS_SUCCESS;
+ BthHfpDeviceNotificationBuffer buffer = { 0 };
+
+ *Volume = 0;
+
+ buffer.bImmediate = TRUE;
+
+ //
+ // Get the Bth HFP SCO Bypass speaker volume.
+ //
+ ntStatus = SendIoCtrlSynchronously(
+ NULL,
+ IOCTL_BTHHFP_SPEAKER_GET_VOLUME_STATUS_UPDATE,
+ sizeof(buffer.bImmediate),
+ sizeof(buffer.Volume),
+ &buffer);
+
+ IF_FAILED_ACTION_JUMP(
+ ntStatus,
+ DPF(D_ERROR, ("GetBthHfpSpeakerVolume: SendIoCtrlSynchronously(IOCTL_BTHHFP_SPEAKER_GET_VOLUME_STATUS_UPDATE) failed, 0x%x", ntStatus)),
+ Done);
+
+ //
+ // All done.
+ //
+ *Volume = buffer.Volume;
+ ntStatus = STATUS_SUCCESS;
+
+Done:
+
+ return ntStatus;
+}
+
+//=============================================================================
+#pragma code_seg()
+NTSTATUS
+BthHfpDevice::EnableBthHfpSpeakerVolumeStatusNotification()
+/*++
+
+Routine Description:
+
+This function registers for Bluetooth Hands-Free Profile SCO Bypass speaker
+volume change notification.
+
+--*/
+{
+ DPF_ENTER(("[BthHfpDevice::EnableBthHfpSpeakerVolumeStatusNotification]"));
+
+ NTSTATUS ntStatus = STATUS_SUCCESS;
+ BthHfpDeviceNotificationReqContext * ctx = NULL;
+
+ ctx = GetBthHfpDeviceNotificationReqContext(m_SpeakerVolumeReq);
+
+ //
+ // This is a notification request.
+ //
+ ctx->Buffer.bImmediate = FALSE;
+
+ //
+ // Register for speaker volume updates.
+ //
+ ntStatus = SendIoCtrlAsynchronously(
+ m_SpeakerVolumeReq,
+ IOCTL_BTHHFP_SPEAKER_GET_VOLUME_STATUS_UPDATE,
+ ctx->MemIn,
+ ctx->MemOut,
+ EvtBthHfpDeviceNotificationStatusCompletion,
+ this);
+
+ IF_FAILED_ACTION_JUMP(
+ ntStatus,
+ DPF(D_ERROR, ("EnableBthHfpSpeakerVolumeStatusNotification: SendIoCtrlAsynchronously(IOCTL_BTHHFP_SPEAKER_GET_VOLUME_STATUS_UPDATE) failed, 0x%x", ntStatus)),
+ Done);
+
+ //
+ // All done.
+ //
+ ntStatus = STATUS_SUCCESS;
+
+Done:
+
+ return ntStatus;
+}
+
+//=============================================================================
+#pragma code_seg("PAGE")
+NTSTATUS
+BthHfpDevice::SetBthHfpMicVolume
+(
+ _In_ LONG Volume
+)
+/*++
+
+Routine Description:
+
+This function synchronously sets the remote Bluetooth Hands-Free Profile SCO
+Bypass mic volume.
+
+--*/
+{
+ PAGED_CODE();
+ DPF_ENTER(("[BthHfpDevice::SetBthHfpMicVolume]"));
+
+ NTSTATUS ntStatus = STATUS_SUCCESS;
+
+ //
+ // Get the Bth HFP SCO Bypass mic volume.
+ //
+ ntStatus = SendIoCtrlSynchronously(
+ NULL,
+ IOCTL_BTHHFP_MIC_SET_VOLUME,
+ sizeof(Volume),
+ 0,
+ &Volume);
+
+ IF_FAILED_ACTION_JUMP(
+ ntStatus,
+ DPF(D_ERROR, ("SetBthHfpMicVolume: SendIoCtrlSynchronously(IOCTL_BTHHFP_MIC_SET_VOLUME) failed, 0x%x", ntStatus)),
+ Done);
+
+ //
+ // All done.
+ //
+ ntStatus = STATUS_SUCCESS;
+
+Done:
+
+ return ntStatus;
+}
+
+//=============================================================================
+#pragma code_seg("PAGE")
+NTSTATUS
+BthHfpDevice::GetBthHfpMicVolume
+(
+ _Out_ LONG * Volume
+)
+/*++
+
+Routine Description:
+
+This function synchronously gets the remote Bluetooth Hands-Free Profile SCO
+Bypass mic volume.
+
+--*/
+{
+ PAGED_CODE();
+ DPF_ENTER(("[BthHfpDevice::GetBthHfpMicVolume]"));
+
+ NTSTATUS ntStatus = STATUS_SUCCESS;
+ BthHfpDeviceNotificationBuffer buffer = { 0 };
+
+ *Volume = 0;
+
+ buffer.bImmediate = TRUE;
+
+ //
+ // Get the Bth HFP SCO Bypass mic volume.
+ //
+ ntStatus = SendIoCtrlSynchronously(
+ NULL,
+ IOCTL_BTHHFP_MIC_GET_VOLUME_STATUS_UPDATE,
+ sizeof(buffer.bImmediate),
+ sizeof(buffer.Volume),
+ &buffer);
+
+ IF_FAILED_ACTION_JUMP(
+ ntStatus,
+ DPF(D_ERROR, ("GetBthHfpMicVolume: SendIoCtrlSynchronously(IOCTL_BTHHFP_MIC_GET_VOLUME_STATUS_UPDATE) failed, 0x%x", ntStatus)),
+ Done);
+
+ //
+ // All done.
+ //
+ *Volume = buffer.Volume;
+ ntStatus = STATUS_SUCCESS;
+
+Done:
+
+ return ntStatus;
+}
+
+//=============================================================================
+#pragma code_seg()
+NTSTATUS
+BthHfpDevice::EnableBthHfpMicVolumeStatusNotification()
+/*++
+
+Routine Description:
+
+This function registers for Bluetooth Hands-Free Profile SCO Bypass mic
+volume change notification.
+
+--*/
+{
+ DPF_ENTER(("[BthHfpDevice::EnableBthHfpMicVolumeStatusNotification]"));
+
+ NTSTATUS ntStatus = STATUS_SUCCESS;
+ BthHfpDeviceNotificationReqContext * ctx = NULL;
+
+ ctx = GetBthHfpDeviceNotificationReqContext(m_MicVolumeReq);
+
+ //
+ // This is a notification request.
+ //
+ ctx->Buffer.bImmediate = FALSE;
+
+ //
+ // Register for mic volume updates.
+ //
+ ntStatus = SendIoCtrlAsynchronously(
+ m_MicVolumeReq,
+ IOCTL_BTHHFP_MIC_GET_VOLUME_STATUS_UPDATE,
+ ctx->MemIn,
+ ctx->MemOut,
+ EvtBthHfpDeviceNotificationStatusCompletion,
+ this);
+
+ IF_FAILED_ACTION_JUMP(
+ ntStatus,
+ DPF(D_ERROR, ("EnableBthHfpMicVolumeStatusNotification: SendIoCtrlAsynchronously(IOCTL_BTHHFP_MIC_GET_VOLUME_STATUS_UPDATE) failed, 0x%x", ntStatus)),
+ Done);
+
+ //
+ // All done.
+ //
+ ntStatus = STATUS_SUCCESS;
+
+Done:
+
+ return ntStatus;
+}
+
+//=============================================================================
+#pragma code_seg("PAGE")
+NTSTATUS
+BthHfpDevice::GetBthHfpConnectionStatus
+(
+ _Out_ BOOL * ConnectionStatus
+)
+/*++
+
+Routine Description:
+
+This function synchronously gets the remote Bluetooth Hands-Free Profile SCO
+Bypass connection status.
+
+--*/
+{
+ PAGED_CODE();
+ DPF_ENTER(("[BthHfpDevice::GetBthHfpConnectionStatus]"));
+
+ NTSTATUS ntStatus = STATUS_SUCCESS;
+ BOOL bValue = TRUE; // In: bImmediate, Out: value.
+
+ *ConnectionStatus = 0;
+
+ //
+ // Get the Bth HFP SCO Bypass connection status.
+ //
+ ntStatus = SendIoCtrlSynchronously(
+ NULL,
+ IOCTL_BTHHFP_DEVICE_GET_CONNECTION_STATUS_UPDATE,
+ sizeof(bValue),
+ sizeof(bValue),
+ &bValue);
+
+ IF_FAILED_ACTION_JUMP(
+ ntStatus,
+ DPF(D_ERROR, ("GetBthHfpConnectionStatus: SendIoCtrlSynchronously(IOCTL_BTHHFP_DEVICE_GET_CONNECTION_STATUS_UPDATE) failed, 0x%x", ntStatus)),
+ Done);
+
+ //
+ // All done.
+ //
+ *ConnectionStatus = bValue;
+ ntStatus = STATUS_SUCCESS;
+
+Done:
+
+ return ntStatus;
+}
+
+//=============================================================================
+#pragma code_seg()
+NTSTATUS
+BthHfpDevice::EnableBthHfpConnectionStatusNotification()
+/*++
+
+Routine Description:
+
+This function registers for Bluetooth Hands-Free Profile SCO Bypass
+connection status notification.
+
+--*/
+{
+ DPF_ENTER(("[BthHfpDevice::EnableBthHfpConnectionStatusNotification]"));
+
+ NTSTATUS ntStatus = STATUS_SUCCESS;
+ BthHfpDeviceNotificationReqContext * ctx = NULL;
+
+ ctx = GetBthHfpDeviceNotificationReqContext(m_ConnectionReq);
+
+ //
+ // Make sure this obj is alive while the IRP is active.
+ //
+ ctx->Buffer.bImmediate = FALSE;
+
+ //
+ // Get the Bth HFP SCO Bypass connection status.
+ //
+ ntStatus = SendIoCtrlAsynchronously(
+ m_ConnectionReq,
+ IOCTL_BTHHFP_DEVICE_GET_CONNECTION_STATUS_UPDATE,
+ ctx->MemIn,
+ ctx->MemOut,
+ EvtBthHfpDeviceNotificationStatusCompletion,
+ this);
+
+ IF_FAILED_ACTION_JUMP(
+ ntStatus,
+ DPF(D_ERROR, ("EnableBthHfpConnectionStatusNotification: SendIoCtrlAsynchronously(IOCTL_BTHHFP_DEVICE_GET_CONNECTION_STATUS_UPDATE) failed, 0x%x", ntStatus)),
+ Done);
+
+ //
+ // All done.
+ //
+ ntStatus = STATUS_SUCCESS;
+
+Done:
+
+ return ntStatus;
+}
+
+//=============================================================================
+#pragma code_seg("PAGE")
+NTSTATUS
+BthHfpDevice::SetBthHfpConnect()
+/*++
+
+Routine Description:
+
+This function synchronously requests a Bluetooth Hands-Free Profile level
+connection to the paired Bluetooth device.
+
+This request initiates the Service Level Connection establishment procedure
+and completes without waiting for the connection procedure to complete.
+Connection status can be determined using IOCTL_BTHHFP_GET_CONNECTION_STATUS_UPDATE.
+
+--*/
+{
+ PAGED_CODE();
+ DPF_ENTER(("[BthHfpDevice::SetBthHfpConnect]"));
+
+ NTSTATUS ntStatus = STATUS_SUCCESS;
+
+ ntStatus = SendIoCtrlSynchronously(
+ NULL,
+ IOCTL_BTHHFP_DEVICE_REQUEST_CONNECT,
+ 0,
+ 0,
+ NULL);
+
+ IF_FAILED_ACTION_JUMP(
+ ntStatus,
+ DPF(D_ERROR, ("SetBthHfpConnect: SendIoCtrlSynchronously(IOCTL_BTHHFP_DEVICE_REQUEST_CONNECT) failed, 0x%x", ntStatus)),
+ Done);
+
+ //
+ // All done.
+ //
+ ntStatus = STATUS_SUCCESS;
+
+Done:
+
+ return ntStatus;
+}
+
+//=============================================================================
+#pragma code_seg("PAGE")
+NTSTATUS
+BthHfpDevice::SetBthHfpDisconnect()
+/*++
+
+Routine Description:
+
+This function synchronously requests a Bluetooth Hands-Free Profile level
+connection to the paired Bluetooth device.
+
+This request initiates disconnection of the Service Level Connection and
+completes without waiting for the disconnection to complete. Connection
+status can be determined using IOCTL_BTHHFP_GET_CONNECTION_STATUS_UPDATE.
+
+--*/
+{
+ PAGED_CODE();
+ DPF_ENTER(("[BthHfpDevice::SetBthHfpDisconnect]"));
+
+ NTSTATUS ntStatus = STATUS_SUCCESS;
+
+ ntStatus = SendIoCtrlSynchronously(
+ NULL,
+ IOCTL_BTHHFP_DEVICE_REQUEST_DISCONNECT,
+ 0,
+ 0,
+ NULL);
+
+ IF_FAILED_ACTION_JUMP(
+ ntStatus,
+ DPF(D_ERROR, ("SetBthHfpDisconnect: SendIoCtrlSynchronously(IOCTL_BTHHFP_DEVICE_REQUEST_DISCONNECT) failed, 0x%x", ntStatus)),
+ Done);
+
+ //
+ // All done.
+ //
+ ntStatus = STATUS_SUCCESS;
+
+Done:
+
+ return ntStatus;
+}
+
+//=============================================================================
+#pragma code_seg()
+void
+BthHfpDevice::EvtBthHfpDeviceStreamStatusCompletion
+(
+ _In_ WDFREQUEST Request,
+ _In_ WDFIOTARGET Target,
+ _In_ PWDF_REQUEST_COMPLETION_PARAMS Params,
+ _In_ WDFCONTEXT Context
+)
+/*++
+
+Routine Description:
+
+Completion callback for the Bluetooth Hands-Free Profile SCO Bypass
+stream status notification.
+
+--*/
+{
+ DPF_ENTER(("[BthHfpDevice::EvtBthHfpDeviceStreamStatusCompletion]"));
+
+ NTSTATUS ntStatus = STATUS_SUCCESS;
+ BthHfpDeviceNotificationReqContext * reqCtx = NULL;
+ BthHfpDevice * This = NULL;
+ NTSTATUS ntResult = STATUS_SUCCESS;
+
+ UNREFERENCED_PARAMETER(Target);
+ UNREFERENCED_PARAMETER(Context);
+
+ //
+ // Get the SCO stream status.
+ //
+ reqCtx = GetBthHfpDeviceNotificationReqContext(Request);
+ This = reqCtx->BthHfpDevice;
+ ASSERT(This != NULL);
+
+ ntStatus = Params->IoStatus.Status;
+ if (!NT_SUCCESS(ntStatus))
+ {
+ ntResult = STATUS_INVALID_DEVICE_STATE;
+ }
+ else
+ {
+ ntResult = reqCtx->Buffer.NtStatus;
+ }
+
+ InterlockedExchange(&This->m_StreamStatusLong, (LONG)ntResult);
+
+ //
+ // Let the stop routine know we are done. Stop routine will
+ // re-init the request.
+ //
+ KeSetEvent(&This->m_StreamStatusEvent, IO_NO_INCREMENT, FALSE);
+}
+
+//=============================================================================
+#pragma code_seg()
+NTSTATUS
+BthHfpDevice::EnableBthHfpStreamStatusNotification()
+/*++
+
+Routine Description:
+
+This function registers for Bluetooth Hands-Free Profile SCO Bypass
+stream status notification.
+
+--*/
+{
+ DPF_ENTER(("[BthHfpDevice::EnableBthHfpStreamStatusNotification]"));
+
+ NTSTATUS ntStatus = STATUS_SUCCESS;
+ BthHfpDeviceNotificationReqContext * ctx = NULL;
+
+ ASSERT(m_nStreams > 0);
+
+ ctx = GetBthHfpDeviceNotificationReqContext(m_StreamReq);
+ ctx->Buffer.bImmediate = FALSE;
+
+ KeClearEvent(&m_StreamStatusEvent);
+
+ //
+ // Get the Bth HFP SCO Bypass connection status.
+ //
+ ntStatus = SendIoCtrlAsynchronously(
+ m_StreamReq,
+ IOCTL_BTHHFP_STREAM_GET_STATUS_UPDATE,
+ ctx->MemIn,
+ ctx->MemOut,
+ EvtBthHfpDeviceStreamStatusCompletion,
+ this);
+
+ if (!NT_SUCCESS(ntStatus))
+ {
+ KeSetEvent(&m_StreamStatusEvent, IO_NO_INCREMENT, FALSE);
+ DPF(D_ERROR, ("EnableBthHfpStreamStatusNotification: SendIoCtrlAsynchronously(IOCTL_BTHHFP_STREAM_GET_STATUS_UPDATE) failed, 0x%x", ntStatus));
+ goto Done;
+ }
+
+ //
+ // All done.
+ //
+ ntStatus = STATUS_SUCCESS;
+
+Done:
+
+ return ntStatus;
+}
+
+//=============================================================================
+#pragma code_seg("PAGE")
+NTSTATUS
+BthHfpDevice::StopBthHfpStreamStatusNotification()
+/*++
+
+Routine Description:
+
+This function stops the Bluetooth Hands-Free Profile SCO Bypass
+connection status notification.
+The function waits for the request to be done before returning.
+
+--*/
+{
+ PAGED_CODE();
+ DPF_ENTER(("[BthHfpDevice::StopBthHfpStreamStatusNotification]"));
+
+ NTSTATUS ntStatus = STATUS_SUCCESS;
+ BthHfpDeviceNotificationReqContext * reqCtx = NULL;
+ WDF_REQUEST_REUSE_PARAMS reuseParams;
+
+ WdfRequestCancelSentRequest(m_StreamReq);
+ KeWaitForSingleObject(&m_StreamStatusEvent, Executive, KernelMode, FALSE, NULL);
+
+ reqCtx = GetBthHfpDeviceNotificationReqContext(m_StreamReq);
+ ASSERT(reqCtx != NULL);
+ UNREFERENCED_VAR(reqCtx);
+
+ //
+ // Re-init the request for later.
+ //
+ WDF_REQUEST_REUSE_PARAMS_INIT(
+ &reuseParams,
+ WDF_REQUEST_REUSE_NO_FLAGS,
+ STATUS_SUCCESS);
+
+ ntStatus = WdfRequestReuse(m_StreamReq, &reuseParams);
+ if (!NT_SUCCESS(ntStatus))
+ {
+ DPF(D_ERROR, ("StopBthHfpStreamStatusNotification: WdfRequestReuse failed, 0x%x", ntStatus));
+ }
+
+ return STATUS_SUCCESS;
+}
+
+//=============================================================================
+#pragma code_seg("PAGE")
+NTSTATUS
+BthHfpDevice::SetBthHfpStreamOpen()
+/*++
+
+Routine Description:
+
+This function synchronously requests an open SCO channel to transmit audio
+data over the air.
+
+--*/
+{
+ PAGED_CODE();
+ DPF_ENTER(("[BthHfpDevice::SetBthHfpStreamOpen]"));
+
+ NTSTATUS ntStatus = STATUS_SUCCESS;
+
+ ntStatus = SendIoCtrlSynchronously(
+ NULL,
+ IOCTL_BTHHFP_STREAM_OPEN,
+ 0,
+ 0,
+ NULL);
+
+ if (ntStatus == STATUS_DEVICE_BUSY)
+ {
+ // The stream channel is already open.
+ DPF(D_VERBOSE, ("SetBthHfpStreamOpen: the stream channel is already open"));
+ ntStatus = STATUS_SUCCESS;
+ }
+
+ IF_FAILED_ACTION_JUMP(
+ ntStatus,
+ DPF(D_ERROR, ("SetBthHfpStreamOpen: SendIoCtrlSynchronously(IOCTL_BTHHFP_STREAM_OPEN) failed, 0x%x", ntStatus)),
+ Done);
+
+ //
+ // All done.
+ //
+ ntStatus = STATUS_SUCCESS;
+
+Done:
+
+ return ntStatus;
+}
+
+//=============================================================================
+#pragma code_seg("PAGE")
+NTSTATUS
+BthHfpDevice::SetBthHfpStreamClose()
+/*++
+
+Routine Description:
+
+This function synchronously requests to close the SCO channel.
+
+--*/
+{
+ PAGED_CODE();
+ DPF_ENTER(("[BthHfpDevice::SetBthHfpStreamClose]"));
+
+ NTSTATUS ntStatus = STATUS_SUCCESS;
+
+ ntStatus = SendIoCtrlSynchronously(
+ NULL,
+ IOCTL_BTHHFP_STREAM_CLOSE,
+ 0,
+ 0,
+ NULL);
+
+ IF_FAILED_ACTION_JUMP(
+ ntStatus,
+ DPF(D_ERROR, ("SetBthHfpStreamClose: SendIoCtrlSynchronously(IOCTL_BTHHFP_STREAM_CLOSE) failed, 0x%x", ntStatus)),
+ Done);
+
+ //
+ // All done.
+ //
+ ntStatus = STATUS_SUCCESS;
+
+Done:
+
+ return ntStatus;
+}
+
+//=============================================================================
+#pragma code_seg("PAGE")
+VOID
+BthHfpDevice::Start()
+/*++
+
+Routine Description:
+
+Asynchronously called to start the audio device.
+
+--*/
+{
+ PAGED_CODE();
+ DPF_ENTER(("[BthHfpDevice::Start]"));
+
+ NTSTATUS ntStatus = STATUS_SUCCESS;
+ BOOL connStatus = FALSE;
+ UINT bthMiniportsIndex = 0;
+
+ // Indicate audio driver capabilities indicating support for 16KHz sampling rate
+ ntStatus = SetBthHfpDeviceCapabilities(TRUE);
+ IF_FAILED_ACTION_JUMP(
+ ntStatus,
+ DPF(D_ERROR, ("Start: SetBthHfpDeviceCapabilities: failed to set Wideband Support, 0x%x", ntStatus)),
+ Done);
+
+ //
+ // Get bth hfp descriptor
+ //
+ ntStatus = GetBthHfpDescriptor(&m_Descriptor);
+ IF_FAILED_ACTION_JUMP(
+ ntStatus,
+ DPF(D_ERROR, ("Start: GetBthHfpDescriptor: failed to retrieve BTHHFP_DESCRIPTOR2, 0x%x", ntStatus)),
+ Done);
+
+ //
+ // Get valume settings.
+ //
+ if (m_Descriptor->SupportsVolume)
+ {
+ PKSPROPERTY_VALUES volumePropValues = NULL;
+ LONG volume = 0;
+
+ // Volume settings.
+ ntStatus = GetBthHfpVolumePropertyValues(
+ m_Descriptor->VolumePropertyValuesSize,
+ &volumePropValues);
+
+ IF_FAILED_ACTION_JUMP(
+ ntStatus,
+ DPF(D_ERROR, ("Start: GetBthHfpVolumePropertyValues: failed to retrieve KSPROPERTY_VALUES, 0x%x", ntStatus)),
+ Done);
+
+ m_VolumePropValues = volumePropValues;
+
+ // Speaker volume.
+ ntStatus = GetBthHfpSpeakerVolume(&volume);
+ IF_FAILED_ACTION_JUMP(
+ ntStatus,
+ DPF(D_ERROR, ("Start: GetBthHfpSpeakerVolume: failed, 0x%x", ntStatus)),
+ Done);
+
+ m_SpeakerVolumeLevel = volume;
+
+ // Mic volume.
+ ntStatus = GetBthHfpMicVolume(&volume);
+ IF_FAILED_ACTION_JUMP(
+ ntStatus,
+ DPF(D_ERROR, ("Start: GetBthHfpMicVolume: failed, 0x%x", ntStatus)),
+ Done);
+
+ m_MicVolumeLevel = volume;
+ }
+
+ //
+ // Get connection status.
+ //
+ ntStatus = GetBthHfpConnectionStatus(&connStatus);
+ IF_FAILED_ACTION_JUMP(
+ ntStatus,
+ DPF(D_ERROR, ("Start: GetBthHfpConnectionStatus: failed, 0x%x", ntStatus)),
+ Done);
+
+ m_ConnectionStatus = connStatus;
+
+ //
+ // Get codec id (if non-zero, connection supports Wideband Speech)
+ //
+ UCHAR codecId = 0;
+ if (connStatus)
+ {
+ ntStatus = GetBthHfpCodecId(&codecId);
+ if (ntStatus == STATUS_INVALID_DEVICE_REQUEST)
+ {
+ // GetBthHfpCodecId fails with STATUS_INVALID_DEVICE_REQUEST if the system doesn't
+ // support Wideband Speech (currently only Mobile supports this call)
+ ntStatus = STATUS_SUCCESS;
+ }
+ IF_FAILED_ACTION_JUMP(
+ ntStatus,
+ DPF(D_ERROR, ("Start: GetBthHfpCodecId: failed, 0x%x", ntStatus)),
+ Done);
+ }
+
+ m_CodecId = codecId;
+
+ enum
+ {
+ BTHHFP_CODEC_CVSD = 0,
+ BTHHFP_CODEC_mSBC,
+
+ BTHHFP_CODEC_INVALID
+ };
+
+ if (codecId > BTHHFP_CODEC_CVSD)
+ {
+ // Use the miniport tables that support 16kHz
+ bthMiniportsIndex = 1;
+ }
+
+
+ //
+ // Customize the topology/wave descriptors for this instance
+ //
+ ntStatus = CreateCustomEndpointMinipair(
+ g_BthHfpRenderEndpoints[bthMiniportsIndex],
+ &m_Descriptor->FriendlyName,
+ &m_Descriptor->OutputPinCategory,
+ &m_SpeakerMiniports);
+ IF_FAILED_ACTION_JUMP(
+ ntStatus,
+ DPF(D_ERROR, ("Start: CreateCustomEndpointMinipair for Render: failed, 0x%x", ntStatus)),
+ Done);
+ m_SpeakerMiniports->TopoName = m_SpeakerTopologyNameBuffer;
+ m_SpeakerMiniports->WaveName = m_SpeakerWaveNameBuffer;
+
+ ntStatus = CreateCustomEndpointMinipair(
+ g_BthHfpCaptureEndpoints[bthMiniportsIndex],
+ &m_Descriptor->FriendlyName,
+ &m_Descriptor->InputPinCategory,
+ &m_MicMiniports);
+ IF_FAILED_ACTION_JUMP(
+ ntStatus,
+ DPF(D_ERROR, ("Start: CreateCustomEndpointMinipair for Capture: failed, 0x%x", ntStatus)),
+ Done);
+ m_MicMiniports->TopoName = m_MicTopologyNameBuffer;
+ m_MicMiniports->WaveName = m_MicWaveNameBuffer;
+
+
+ ASSERT(m_SpeakerMiniports != NULL);
+ ASSERT(m_MicMiniports != NULL);
+ _Analysis_assume_(m_SpeakerMiniports != NULL);
+ _Analysis_assume_(m_MicMiniports != NULL);
+
+ //
+ // Register topology and wave filters.
+ //
+ ntStatus = m_Adapter->InstallEndpointFilters(
+ NULL,
+ m_SpeakerMiniports,
+ PSIDEBANDDEVICECOMMON(this),
+ &m_UnknownSpeakerTopology,
+ &m_UnknownSpeakerWave, NULL, NULL
+ );
+
+ IF_FAILED_ACTION_JUMP(
+ ntStatus,
+ DPF(D_ERROR, ("Start: InstallEndpointRenderFilters (Bth HFP SCO-Bypass): failed, 0x%x", ntStatus)),
+ Done);
+
+ ntStatus = m_Adapter->InstallEndpointFilters(
+ NULL,
+ m_MicMiniports,
+ PSIDEBANDDEVICECOMMON(this),
+ &m_UnknownMicTopology,
+ &m_UnknownMicWave, NULL, NULL
+ );
+
+ IF_FAILED_ACTION_JUMP(
+ ntStatus,
+ DPF(D_ERROR, ("Start: InstallEndpointCaptureFilters (Bth HFP SCO-Bypass): failed, 0x%x", ntStatus)),
+ Done);
+
+ ntStatus = m_Adapter->NotifyEndpointPair(
+ m_SpeakerTopologyNameBuffer,
+ SIZEOF_ARRAY(m_SpeakerTopologyNameBuffer),
+ KSPIN_TOPO_LINEOUT_DEST,
+ m_MicTopologyNameBuffer,
+ SIZEOF_ARRAY(m_MicTopologyNameBuffer),
+ KSPIN_TOPO_MIC_ELEMENTS
+ );
+
+ IF_FAILED_ACTION_JUMP(
+ ntStatus,
+ DPF(D_ERROR, ("Start: NotifyEndpointPair (Bth HFP SCO-Bypass): failed, 0x%x", ntStatus)),
+ Done);
+
+ //
+ // Pend status notifications.
+ //
+
+ // NREC disable AudioGateway (AG) status.
+ ntStatus = EnableBthHfpNrecDisableStatusNotification();
+ IF_FAILED_ACTION_JUMP(
+ ntStatus,
+ DPF(D_ERROR, ("Start: EnableBthHfpNrecDisableStatusNotification: failed, 0x%x", ntStatus)),
+ Done);
+
+ // Volume speaker status.
+ ntStatus = EnableBthHfpSpeakerVolumeStatusNotification();
+ IF_FAILED_ACTION_JUMP(
+ ntStatus,
+ DPF(D_ERROR, ("Start: EnableBthHfpSpeakerVolumeStatusNotification: failed, 0x%x", ntStatus)),
+ Done);
+
+ // Volume mic status.
+ ntStatus = EnableBthHfpMicVolumeStatusNotification();
+ IF_FAILED_ACTION_JUMP(
+ ntStatus,
+ DPF(D_ERROR, ("Start: EnableBthHfpMicVolumeStatusNotification: failed, 0x%x", ntStatus)),
+ Done);
+
+ // Connection status.
+ ntStatus = EnableBthHfpConnectionStatusNotification();
+ IF_FAILED_ACTION_JUMP(
+ ntStatus,
+ DPF(D_ERROR, ("Start: EnableBthHfpConnectionStatusNotification: failed, 0x%x", ntStatus)),
+ Done);
+
+ //
+ // All done.
+ //
+ ntStatus = STATUS_SUCCESS;
+
+Done:
+ if (!NT_SUCCESS(ntStatus))
+ {
+ InterlockedExchange((PLONG)&m_State, eBthHfpStateFailed);
+ }
+}
+
+//=============================================================================
+#pragma code_seg("PAGE")
+NTSTATUS
+BthHfpDevice::CreateCustomEndpointMinipair
+(
+ _In_ PENDPOINT_MINIPAIR pBaseMinipair,
+ _In_ PUNICODE_STRING FriendlyName,
+ _In_ PGUID pCategory,
+ _Outptr_ PENDPOINT_MINIPAIR *ppCustomMinipair
+)
+{
+ NTSTATUS ntStatus;
+ PENDPOINT_MINIPAIR pNewMinipair = NULL;
+ SYSVAD_DEVPROPERTY* pProperties = NULL;
+ PPCFILTER_DESCRIPTOR pNewTopoFilterDesc = NULL;
+ PPCPIN_DESCRIPTOR pNewTopoPins = NULL;
+ ULONG cProperties;
+ ULONG cTopoPins;
+
+ PAGED_CODE();
+
+ //
+ // This routine will add one more property to whatever the base minipair describes for the topo filter interface properties
+ // It will also allocate and set up custom filter and pin descriptors to allow changing the KSNODETYPE for the hfp device
+ //
+ cTopoPins = pBaseMinipair->TopoDescriptor->PinCount;
+ cProperties = pBaseMinipair->TopoInterfacePropertyCount + 1;
+ pProperties = (SYSVAD_DEVPROPERTY*)ExAllocatePoolWithTag(NonPagedPoolNx, cProperties * sizeof(SYSVAD_DEVPROPERTY), SYSVAD_POOLTAG);
+ pNewMinipair = (ENDPOINT_MINIPAIR*)ExAllocatePoolWithTag(NonPagedPoolNx, sizeof(ENDPOINT_MINIPAIR), SYSVAD_POOLTAG);
+ pNewTopoFilterDesc = (PCFILTER_DESCRIPTOR*)ExAllocatePoolWithTag(NonPagedPoolNx, sizeof(PCFILTER_DESCRIPTOR), SYSVAD_POOLTAG);
+ pNewTopoPins = (PCPIN_DESCRIPTOR*)ExAllocatePoolWithTag(NonPagedPoolNx, cTopoPins * sizeof(PCPIN_DESCRIPTOR), SYSVAD_POOLTAG);
+
+ if ((pProperties != NULL) && (pNewMinipair != NULL) && (pNewTopoFilterDesc != NULL) && (pNewTopoPins != NULL))
+ {
+ SYSVAD_DEVPROPERTY *pLastProperty;
+
+ // Copy base minipair properties to new property list
+ if (pBaseMinipair->TopoInterfacePropertyCount > 0)
+ {
+ RtlCopyMemory(pProperties, pBaseMinipair->TopoInterfaceProperties, (cProperties - 1) * sizeof(SYSVAD_DEVPROPERTY));
+ }
+
+ // Add friendly name property to the list
+ NT_ASSERT(FriendlyName->Length + sizeof(UNICODE_NULL) <= FriendlyName->MaximumLength); // Assuming NULL terminated string
+ pLastProperty = &pProperties[cProperties - 1];
+ pLastProperty->PropertyKey = &DEVPKEY_DeviceInterface_FriendlyName;
+ pLastProperty->Type = DEVPROP_TYPE_STRING_INDIRECT;
+ pLastProperty->BufferSize = FriendlyName->Length + sizeof(UNICODE_NULL);
+ pLastProperty->Buffer = FriendlyName->Buffer;
+
+ // Copy base minipair structure
+ RtlCopyMemory(pNewMinipair, pBaseMinipair, sizeof(ENDPOINT_MINIPAIR));
+
+ RtlCopyMemory(pNewTopoFilterDesc, pBaseMinipair->TopoDescriptor, sizeof(PCFILTER_DESCRIPTOR));
+ RtlCopyMemory(pNewTopoPins, pBaseMinipair->TopoDescriptor->Pins, cTopoPins * sizeof(PCPIN_DESCRIPTOR));
+
+ pNewTopoFilterDesc->Pins = pNewTopoPins;
+ pNewMinipair->TopoDescriptor = pNewTopoFilterDesc;
+
+ // Update it to point to new property list
+ pNewMinipair->TopoInterfacePropertyCount = cProperties;
+ pNewMinipair->TopoInterfaceProperties = pProperties;
+
+ ntStatus = UpdateCustomEndpointCategory(pNewTopoFilterDesc, pNewTopoPins, pCategory);
+ if (!NT_SUCCESS(ntStatus))
+ {
+ DPF(D_ERROR, ("UpdateCustomEndpointCategory: failed, 0x%x", ntStatus));
+ }
+ else
+ {
+ *ppCustomMinipair = pNewMinipair;
+
+ pProperties = NULL;
+ pNewMinipair = NULL;
+ pNewTopoFilterDesc = NULL;
+ pNewTopoPins = NULL;
+
+ ntStatus = STATUS_SUCCESS;
+ }
+ }
+ else
+ {
+ ntStatus = STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ if (pProperties != NULL)
+ {
+ ExFreePoolWithTag(pProperties, SYSVAD_POOLTAG);
+ }
+ if (pNewMinipair != NULL)
+ {
+ ExFreePoolWithTag(pNewMinipair, SYSVAD_POOLTAG);
+ }
+ if (pNewTopoFilterDesc != NULL)
+ {
+ ExFreePoolWithTag(pNewTopoFilterDesc, SYSVAD_POOLTAG);
+ }
+ if (pNewTopoPins != NULL)
+ {
+ ExFreePoolWithTag(pNewTopoPins, SYSVAD_POOLTAG);
+ }
+
+ return ntStatus;
+}
+//=============================================================================
+#pragma code_seg("PAGE")
+NTSTATUS
+BthHfpDevice::UpdateCustomEndpointCategory
+(
+ _In_ PPCFILTER_DESCRIPTOR pCustomMinipairTopoFilter,
+ _In_ PPCPIN_DESCRIPTOR pCustomMinipairTopoPins,
+ _In_ PGUID pCategory
+)
+{
+ NTSTATUS ntStatus = STATUS_NOT_FOUND;
+ ULONG cPinCount = 0;
+ BOOL FoundCategoryAudio = FALSE;
+ BOOL FoundNodeType = FALSE;
+
+ PAGED_CODE();
+
+ cPinCount = pCustomMinipairTopoFilter->PinCount;
+
+ // Find the right pin: There should be two pins, one with Category KSCATEGORY_AUDIO,
+ // and one with a KSNODETYPE_* Category. We need to modify the KSNODETYPE category.
+ for (ULONG i = 0; i < cPinCount; ++i)
+ {
+ if (IsEqualGUID(*pCustomMinipairTopoPins[i].KsPinDescriptor.Category, KSCATEGORY_AUDIO))
+ {
+ ASSERT(FoundCategoryAudio == FALSE);
+ if (FoundCategoryAudio)
+ {
+ ntStatus = STATUS_INVALID_DEVICE_STATE;
+ DPF(D_ERROR, ("UpdateCustomEndpointCategory: KSCATEGORY_AUDIO found more than once, 0x%x", ntStatus));
+ break;
+ }
+
+ FoundCategoryAudio = TRUE;
+ continue;
+ }
+
+ ASSERT(FoundNodeType == FALSE);
+ if (FoundNodeType)
+ {
+ ntStatus = STATUS_INVALID_DEVICE_STATE;
+ DPF(D_ERROR, ("UpdateCustomEndpointCategory: Found more than one applicable Pin, 0x%x", ntStatus));
+ break;
+ }
+
+ pCustomMinipairTopoPins[i].KsPinDescriptor.Category = pCategory;
+ FoundNodeType = TRUE;
+ ntStatus = STATUS_SUCCESS;
+ }
+
+ return ntStatus;
+}
+//=============================================================================
+#pragma code_seg("PAGE")
+VOID
+BthHfpDevice::DeleteCustomEndpointMinipair
+(
+ _In_ PENDPOINT_MINIPAIR pCustomMinipair
+)
+{
+ PAGED_CODE();
+
+ if (pCustomMinipair != NULL)
+ {
+ if (pCustomMinipair->TopoInterfaceProperties != NULL)
+ {
+ ExFreePoolWithTag(const_cast<SYSVAD_DEVPROPERTY*>(pCustomMinipair->TopoInterfaceProperties), SYSVAD_POOLTAG);
+ pCustomMinipair->TopoInterfaceProperties = NULL;
+ }
+ if (pCustomMinipair->TopoDescriptor != NULL)
+ {
+ if (pCustomMinipair->TopoDescriptor->Pins != NULL)
+ {
+ ExFreePoolWithTag((PVOID)pCustomMinipair->TopoDescriptor->Pins, SYSVAD_POOLTAG);
+ pCustomMinipair->TopoDescriptor->Pins = NULL;
+ }
+ ExFreePoolWithTag(pCustomMinipair->TopoDescriptor, SYSVAD_POOLTAG);
+ pCustomMinipair->TopoDescriptor = NULL;
+ }
+ ExFreePoolWithTag(pCustomMinipair, SYSVAD_POOLTAG);
+ }
+}
+
+//=============================================================================
+#pragma code_seg("PAGE")
+VOID
+BthHfpDevice::Stop()
+/*++
+
+Routine Description:
+
+Asynchronously called to stop the audio device.
+After returning from this function, there are no more async notifications
+pending (volume, connection, etc.).
+
+--*/
+{
+ PAGED_CODE();
+ DPF_ENTER(("[BthHfpDevice::Stop]"));
+
+ NTSTATUS ntStatus = STATUS_SUCCESS;
+ eBthHfpState state = eBthHfpStateInvalid;
+
+ state = (eBthHfpState)InterlockedExchange((PLONG)&m_State, eBthHfpStateStopping);
+ ASSERT(state == eBthHfpStateRunning || state == eBthHfpStateFailed);
+ UNREFERENCED_VAR(state);
+
+ //
+ // Stop async notifications.
+ //
+ WdfIoTargetPurge(m_WdfIoTarget, WdfIoTargetPurgeIoAndWait);
+
+ //
+ // Wait for work-item.
+ //
+ WdfWorkItemFlush(m_WorkItem);
+
+ //
+ // Remove the topology and wave render filters.
+ //
+ if (m_UnknownSpeakerTopology || m_UnknownSpeakerWave)
+ {
+ ntStatus = m_Adapter->RemoveEndpointFilters(
+ m_SpeakerMiniports,
+ m_UnknownSpeakerTopology,
+ m_UnknownSpeakerWave);
+
+ if (!NT_SUCCESS(ntStatus))
+ {
+ DPF(D_ERROR, ("RemoveEndpointFilters (Bth HFP SCO-Bypass Speaker): failed, 0x%x", ntStatus));
+ }
+ }
+
+ //
+ // Remove the topology and wave capture filters.
+ //
+ if (m_UnknownMicTopology || m_UnknownMicWave)
+ {
+ ntStatus = m_Adapter->RemoveEndpointFilters(
+ m_MicMiniports,
+ m_UnknownMicTopology,
+ m_UnknownMicWave);
+
+ if (!NT_SUCCESS(ntStatus))
+ {
+ DPF(D_ERROR, ("RemoveEndpointFilters (Bth HFP SCO-Bypass Capture): failed, 0x%x", ntStatus));
+ }
+ }
+
+ //
+ // Release port/miniport pointers.
+ //
+ SAFE_RELEASE(m_UnknownSpeakerTopology);
+ SAFE_RELEASE(m_UnknownSpeakerWave);
+ SAFE_RELEASE(m_UnknownMicTopology);
+ SAFE_RELEASE(m_UnknownMicWave);
+
+ //
+ // The device is in the stopped state.
+ //
+ InterlockedExchange((PLONG)&m_State, eBthHfpStateStopped);
+
+}
+
+#pragma code_seg("PAGE")
+NTSTATUS BthHfpDevice::CreateFilterNames(
+ PUNICODE_STRING HfpDeviceSymbolicLinkName
+)
+/*++
+
+Routine Description:
+
+Creates unique wave and topology filter reference names.
+
+Since each subdevice representing a HFP sideband interface arrival needs to have a unique
+reference string, this function generates a hash on 'HfpDeviceSymbolicLinkName' parameter
+and appends to static interface strings.
+
+--*/
+{
+ PAGED_CODE();
+ DPF_ENTER(("[BthHfpDevice::CreateAudioInterfaces]"));
+
+ NTSTATUS status = STATUS_SUCCESS;
+ ULONG hashValue = 0;
+
+ status = RtlHashUnicodeString(HfpDeviceSymbolicLinkName, TRUE, HASH_STRING_ALGORITHM_X65599, &hashValue);
+ IF_FAILED_ACTION_JUMP(
+ status,
+ DPF(D_ERROR, ("Failed to create KSCATEGORY_REALTIME wave interface: 0x%x", status)),
+ End);
+
+ // create wave interfaces for speaker
+ RtlStringCbPrintfW(m_SpeakerWaveNameBuffer, sizeof(m_SpeakerWaveNameBuffer), L"%s-%lu", BTHHFP_SPEAKER_WAVE_NAME, hashValue);
+ RtlUnicodeStringInit(&m_SpeakerWaveRefString, m_SpeakerWaveNameBuffer);
+
+ // create topology interfaces for speaker
+ RtlStringCbPrintfW(m_SpeakerTopologyNameBuffer, sizeof(m_SpeakerTopologyNameBuffer), L"%s-%lu", BTHHFP_SPEAKER_TOPO_NAME, hashValue);
+ RtlUnicodeStringInit(&m_SpeakerTopologyRefString, m_SpeakerTopologyNameBuffer);
+
+ // create wave interfaces for mic
+ RtlStringCbPrintfW(m_MicWaveNameBuffer, sizeof(m_MicWaveNameBuffer), L"%s-%lu", BTHHFP_MIC_WAVE_NAME, hashValue);
+ RtlUnicodeStringInit(&m_MicWaveRefString, m_MicWaveNameBuffer);
+
+ // create topology interfaces for mic
+ RtlStringCbPrintfW(m_MicTopologyNameBuffer, sizeof(m_MicTopologyNameBuffer), L"%s-%lu", BTHHFP_MIC_TOPO_NAME, hashValue);
+ RtlUnicodeStringInit(&m_MicTopologyRefString, m_MicTopologyNameBuffer);
+End:
+ return status;
+}
+
+#endif // SYSVAD_BTH_BYPASS
diff --git a/audio/sysvad/BthhfpDevice.h b/audio/sysvad/BthhfpDevice.h
new file mode 100644
index 00000000..c22fe0fa
--- /dev/null
+++ b/audio/sysvad/BthhfpDevice.h
@@ -0,0 +1,476 @@
+//
+// This class represents a the Bluetooth Hands-Free Profile SCO Bypass device.
+// There is one class for each interface (id = symbolic-link-name).
+//
+#ifdef SYSVAD_BTH_BYPASS
+
+//=====================================================================
+//
+// CAdapterCommon: Bluetooth Hands-Free Profile SCO Bypass definitions.
+//
+
+class CAdapterCommon;
+class BthHfpDevice;
+
+struct BthHfpWorkItemContext
+{
+ CAdapterCommon * Adapter;
+};
+
+WDF_DECLARE_CONTEXT_TYPE_WITH_NAME
+(
+ BthHfpWorkItemContext,
+ GetBthHfpWorkItemContext
+)
+
+// start/stop the device
+enum eBthHfpTaskAction
+{
+ eBthHfpTaskStart = 1,
+ eBthHfpTaskStop = 2,
+};
+
+struct BthHfpWorkTask
+{
+ LIST_ENTRY ListEntry;
+ BthHfpDevice * Device;
+ eBthHfpTaskAction Action;
+};
+
+
+//=====================================================================
+//
+// Device: Bluetooth Hands-Free Profile SCO Bypass definitions.
+//
+
+// BTH HFP device's notification work-item context.
+struct BthHfpDeviceNotificationWorkItemContext
+{
+ BthHfpDevice * BthHfpDevice;
+};
+
+WDF_DECLARE_CONTEXT_TYPE_WITH_NAME
+(
+ BthHfpDeviceNotificationWorkItemContext,
+ GetBthHfpDeviceNotificationWorkItemContext
+)
+
+// BTH HFP device's notification request context.
+union BthHfpDeviceNotificationBuffer
+{
+ BOOL bImmediate;
+ LONG Volume;
+ BOOL BoolStatus;
+ NTSTATUS NtStatus;
+};
+
+struct BthHfpDeviceNotificationReqContext
+{
+ BthHfpDevice * BthHfpDevice;
+ LONG Errors;
+ BthHfpDeviceNotificationBuffer Buffer;
+ WDFMEMORY MemIn;
+ WDFMEMORY MemOut;
+};
+
+WDF_DECLARE_CONTEXT_TYPE_WITH_NAME
+(
+ BthHfpDeviceNotificationReqContext,
+ GetBthHfpDeviceNotificationReqContext
+)
+
+enum eBthHfpState
+{
+ eBthHfpStateInvalid = 0,
+ eBthHfpStateInitializing = 1,
+ eBthHfpStateRunning = 2,
+ eBthHfpStateStopping = 3,
+ eBthHfpStateStopped = 4,
+ eBthHfpStateFailed = 5,
+};
+
+// To support event notification.
+struct BthHfpEventCallback
+{
+ PFNEVENTNOTIFICATION Handler;
+ PVOID Context;
+};
+
+//
+// This class represents a the Bluetooth Hands-Free Profile SCO Bypass device.
+// There is one class for each interface (id = symbolic-link-name).
+//
+class BthHfpDevice :
+ ISidebandDeviceCommon,
+ public CUnknown
+{
+private:
+ eBthHfpState m_State;
+
+ IAdapterCommon * m_Adapter;
+ WDFIOTARGET m_WdfIoTarget;
+
+ LIST_ENTRY m_ListEntry;
+ UNICODE_STRING m_SymbolicLinkName;
+ WCHAR m_SpeakerWaveNameBuffer[BTHHFP_INTERFACE_REFSTRING_MAX_LENGTH];
+ UNICODE_STRING m_SpeakerWaveRefString;
+ WCHAR m_SpeakerTopologyNameBuffer[BTHHFP_INTERFACE_REFSTRING_MAX_LENGTH];
+ UNICODE_STRING m_SpeakerTopologyRefString;
+ WCHAR m_MicWaveNameBuffer[BTHHFP_INTERFACE_REFSTRING_MAX_LENGTH];
+ UNICODE_STRING m_MicWaveRefString;
+ WCHAR m_MicTopologyNameBuffer[BTHHFP_INTERFACE_REFSTRING_MAX_LENGTH];
+ UNICODE_STRING m_MicTopologyRefString;
+
+ //
+ // The Topo Filter Desc and Topo Pins structures referenced from
+ // the Miniports structure are deep copies: they start as copies of the
+ // static structures and are modified to allow per-SCO-Device pin
+ // categories based on the info obtained from
+ // IOCTL_BTHHFP_DEVICE_GET_DESCRIPTOR2
+ //
+ PENDPOINT_MINIPAIR m_SpeakerMiniports;
+ PENDPOINT_MINIPAIR m_MicMiniports;
+
+ PUNKNOWN m_UnknownSpeakerTopology;
+ PUNKNOWN m_UnknownSpeakerWave;
+ PUNKNOWN m_UnknownMicTopology;
+ PUNKNOWN m_UnknownMicWave;
+ LONG m_CodecId;
+
+ PBTHHFP_DESCRIPTOR2 m_Descriptor;
+ PKSPROPERTY_VALUES m_VolumePropValues;
+ LONG m_SpeakerVolumeLevel;
+ LONG m_MicVolumeLevel;
+ union {
+ BOOL m_ConnectionStatus;
+ LONG m_ConnectionStatusLong;
+ }; // unnamed.
+
+ union {
+ NTSTATUS m_StreamStatus;
+ LONG m_StreamStatusLong;
+ }; // unnamed.
+
+ KEVENT m_StreamStatusEvent;
+
+ //
+ // Set to TRUE when the HF (remote device) wants to disable the
+ // NR + EC of the AG (local system).
+ //
+ LONG m_NRECDisableStatusLong;
+
+ WDFREQUEST m_StreamReq;
+ WDFREQUEST m_SpeakerVolumeReq;
+ WDFREQUEST m_MicVolumeReq;
+ WDFREQUEST m_ConnectionReq;
+ WDFREQUEST m_NRECDisableStatusReq;
+ WDFWORKITEM m_WorkItem;
+ WDFCOLLECTION m_ReqCollection;
+ KSPIN_LOCK m_Lock;
+
+ LONG m_nStreams; // # of open streams.
+
+ BthHfpEventCallback m_SpeakerVolumeCallback;
+ BthHfpEventCallback m_SpeakerMuteCallback;
+ BthHfpEventCallback m_SpeakerConnectionStatusCallback;
+ BthHfpEventCallback m_SpeakerFormatChangeCallback;
+ BthHfpEventCallback m_MicVolumeCallback;
+ BthHfpEventCallback m_MicMuteCallback;
+ BthHfpEventCallback m_MicConnectionStatusCallback;
+ BthHfpEventCallback m_MicFormatChangeCallback;
+
+public:
+ //=====================================================================
+ // Default CUnknown
+ DECLARE_STD_UNKNOWN();
+ DEFINE_STD_CONSTRUCTOR(BthHfpDevice);
+ ~BthHfpDevice();
+
+ NTSTATUS Init
+ (
+ _In_ IAdapterCommon *Adapter,
+ _In_ PUNICODE_STRING SymbolicLinkName
+ );
+
+public:
+ //=====================================================================
+ //
+ // Public functions used by CAdapterCommon object.
+ //
+ VOID Start();
+ VOID Stop();
+
+ PLIST_ENTRY GetListEntry()
+ {
+ return &m_ListEntry;
+ }
+
+ PUNICODE_STRING GetSymbolicLinkName()
+ {
+ return &m_SymbolicLinkName;
+ }
+
+ static
+ BthHfpDevice *
+ GetBthHfpDevice
+ (
+ _In_ PLIST_ENTRY le
+ )
+ {
+ return CONTAINING_RECORD(le, BthHfpDevice, m_ListEntry);
+ }
+
+public:
+ //=====================================================================
+ //
+ // ISidebandDeviceCommon functions.
+ //
+ STDMETHODIMP_(BOOL) IsVolumeSupported
+ (
+ _In_ eDeviceType deviceType
+ );
+
+ STDMETHODIMP_(PVOID) GetVolumeSettings
+ (
+ _In_ eDeviceType DeviceType,
+ _Out_ PULONG Size
+ );
+
+ STDMETHODIMP_(NTSTATUS) GetVolume
+ (
+ _In_ eDeviceType DeviceType,
+ _In_ LONG Channel,
+ _Out_ LONG *pVolume
+ );
+
+ STDMETHODIMP_(NTSTATUS) SetVolume
+ (
+ _In_ eDeviceType DeviceType,
+ _In_ LONG Channel,
+ _In_ LONG Volume
+ );
+
+ STDMETHODIMP_(BOOL) IsMuteSupported
+ (
+ _In_ eDeviceType deviceType
+ );
+
+ STDMETHODIMP_(PVOID) GetMuteSettings
+ (
+ _In_ eDeviceType DeviceType,
+ _Out_ PULONG Size
+ );
+
+ STDMETHODIMP_(LONG) GetMute
+ (
+ _In_ eDeviceType DeviceType,
+ _In_ LONG Channel
+ );
+
+ STDMETHODIMP_(NTSTATUS) SetMute
+ (
+ _In_ eDeviceType DeviceType,
+ _In_ LONG Channel,
+ _In_ LONG Mute
+ );
+
+ STDMETHODIMP_(BOOL) GetConnectionStatus();
+
+ STDMETHODIMP_(NTSTATUS) Connect();
+
+ STDMETHODIMP_(NTSTATUS) Disconnect();
+
+ STDMETHODIMP_(BOOL) GetStreamStatus(_In_ eDeviceType deviceType);
+
+ STDMETHODIMP_(NTSTATUS) StreamOpen(_In_ eDeviceType deviceType);
+
+ STDMETHODIMP_(NTSTATUS) StreamStart(_In_ eDeviceType deviceType);
+
+ STDMETHODIMP_(NTSTATUS) StreamSuspend(_In_ eDeviceType deviceType);
+
+ STDMETHODIMP_(NTSTATUS) StreamClose(_In_ eDeviceType deviceType);
+
+ STDMETHODIMP_(GUID) GetContainerId(_In_ eDeviceType deviceType);
+
+ STDMETHODIMP_(VOID) SetVolumeHandler
+ (
+ _In_ eDeviceType deviceType,
+ _In_opt_ PFNEVENTNOTIFICATION EventHandler,
+ _In_opt_ PVOID EventHandlerContext
+ );
+
+ STDMETHODIMP_(VOID) SetMuteHandler
+ (
+ _In_ eDeviceType deviceType,
+ _In_opt_ PFNEVENTNOTIFICATION EventHandler,
+ _In_opt_ PVOID EventHandlerContext
+ );
+
+ STDMETHODIMP_(VOID) SetConnectionStatusHandler
+ (
+ _In_ eDeviceType deviceType,
+ _In_opt_ PFNEVENTNOTIFICATION EventHandler,
+ _In_opt_ PVOID EventHandlerContext
+ );
+
+ STDMETHODIMP_(VOID) SetFormatChangeHandler
+ (
+ _In_ eDeviceType deviceType,
+ _In_opt_ PFNEVENTNOTIFICATION EventHandler,
+ _In_opt_ PVOID EventHandlerContext
+ );
+
+ STDMETHODIMP_(PPIN_DEVICE_FORMATS_AND_MODES) GetFormatsAndModes
+ (
+ _In_ eDeviceType deviceType
+ );
+
+ STDMETHODIMP_(BOOL) IsNRECSupported();
+
+ STDMETHODIMP_(BOOL) GetNRECDisableStatus();
+
+private:
+ //=====================================================================
+ //
+ // Helper functions.
+ //
+ NTSTATUS SendIoCtrlSynchronously
+ (
+ _In_opt_ WDFREQUEST Request,
+ _In_ ULONG IoControlCode,
+ _In_ ULONG InLength,
+ _In_ ULONG OutLength,
+ _When_(InLength > 0 || OutLength > 0, _In_)
+ _When_(InLength == 0 && OutLength == 0, _In_opt_)
+ PVOID Buffer
+ );
+
+ NTSTATUS SendIoCtrlAsynchronously
+ (
+ _In_ WDFREQUEST Request,
+ _In_ ULONG IoControlCode,
+ _In_opt_ WDFMEMORY MemIn,
+ _In_opt_ WDFMEMORY MemOut,
+ _In_ PFN_WDF_REQUEST_COMPLETION_ROUTINE CompletionRoutine,
+ _In_ WDFCONTEXT Context
+ );
+
+ NTSTATUS SetBthHfpDeviceCapabilities
+ (
+ _In_ BOOL bSupports16kHzSampling
+ );
+
+ NTSTATUS GetBthHfpDescriptor
+ (
+ _Out_ PBTHHFP_DESCRIPTOR2 * Descriptor
+ );
+
+ NTSTATUS EnableBthHfpNrecDisableStatusNotification();
+
+ NTSTATUS GetBthHfpVolumePropertyValues
+ (
+ _In_ ULONG Length,
+ _Out_ PKSPROPERTY_VALUES * PropValues
+ );
+
+ NTSTATUS SetBthHfpSpeakerVolume
+ (
+ _In_ LONG Volume
+ );
+
+ NTSTATUS GetBthHfpSpeakerVolume
+ (
+ _Out_ LONG * Volume
+ );
+
+ NTSTATUS EnableBthHfpSpeakerVolumeStatusNotification();
+
+ NTSTATUS SetBthHfpMicVolume
+ (
+ _In_ LONG Volume
+ );
+
+ NTSTATUS GetBthHfpMicVolume
+ (
+ _Out_ LONG * Volume
+ );
+
+ NTSTATUS EnableBthHfpMicVolumeStatusNotification();
+
+ NTSTATUS GetBthHfpConnectionStatus
+ (
+ _Out_ BOOL * ConnectionStatus
+ );
+
+ NTSTATUS EnableBthHfpConnectionStatusNotification();
+
+ static
+ NTSTATUS CreateCustomEndpointMinipair
+ (
+ _In_ PENDPOINT_MINIPAIR pBaseMinipair,
+ _In_ PUNICODE_STRING FriendlyName,
+ _In_ PGUID pCategory,
+ _Outptr_ PENDPOINT_MINIPAIR *ppCustomMinipair
+ );
+
+ static
+ NTSTATUS UpdateCustomEndpointCategory
+ (
+ _In_ PPCFILTER_DESCRIPTOR pCustomMinipairTopoFilter,
+ _In_ PPCPIN_DESCRIPTOR pCustomMinipairTopoPins,
+ _In_ PGUID pCategory
+ );
+
+ static
+ VOID DeleteCustomEndpointMinipair
+ (
+ _In_ PENDPOINT_MINIPAIR CustomMinipair
+ );
+
+ NTSTATUS GetBthHfpCodecId
+ (
+ _Out_ UCHAR * CodecId
+ );
+
+ NTSTATUS SetBthHfpConnect();
+
+ NTSTATUS SetBthHfpDisconnect();
+
+ NTSTATUS SetBthHfpStreamOpen();
+
+ NTSTATUS SetBthHfpStreamClose();
+
+ NTSTATUS EnableBthHfpStreamStatusNotification();
+
+ NTSTATUS StopBthHfpStreamStatusNotification();
+
+ NTSTATUS CreateFilterNames(
+ _In_ PUNICODE_STRING HfpDeviceSymbolicLinkName
+ );
+
+ //
+ // WDF I/O Target callback.
+ //
+ static
+ EVT_WDF_IO_TARGET_QUERY_REMOVE EvtBthHfpTargetQueryRemove;
+
+ static
+ EVT_WDF_IO_TARGET_REMOVE_CANCELED EvtBthHfpTargetRemoveCanceled;
+
+ static
+ EVT_WDF_IO_TARGET_REMOVE_COMPLETE EvtBthHfpTargetRemoveComplete;
+
+ //
+ // Status notifications callbacks.
+ //
+ static
+ EVT_WDF_REQUEST_COMPLETION_ROUTINE EvtBthHfpDeviceStreamStatusCompletion;
+
+ static
+ EVT_WDF_REQUEST_COMPLETION_ROUTINE EvtBthHfpDeviceNotificationStatusCompletion;
+
+ static
+ EVT_WDF_WORKITEM EvtBthHfpDeviceNotificationStatusWorkItem;
+};
+
+#endif // SYSVAD_BTH_BYPASS
diff --git a/audio/sysvad/ContosoKeywordDetector.h b/audio/sysvad/ContosoKeywordDetector.h
index fce0f3df..e23daf15 100644
--- a/audio/sysvad/ContosoKeywordDetector.h
+++ b/audio/sysvad/ContosoKeywordDetector.h
@@ -31,4 +31,6 @@ typedef struct
{
SOUNDDETECTOR_PATTERNHEADER Header;
LONGLONG ContosoDetectorResultData;
+ ULONGLONG KeywordStartTimestamp;
+ ULONGLONG KeywordStopTimestamp;
} CONTOSO_KEYWORDDETECTIONRESULT;
diff --git a/audio/sysvad/EndpointsCommon/EndpointsCommon.vcxproj b/audio/sysvad/EndpointsCommon/EndpointsCommon.vcxproj
index 4fb3fda6..255bb57a 100644
--- a/audio/sysvad/EndpointsCommon/EndpointsCommon.vcxproj
+++ b/audio/sysvad/EndpointsCommon/EndpointsCommon.vcxproj
@@ -94,8 +94,8 @@
<PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_;SYSVAD_BTH_BYPASS</PreprocessorDefinitions>
</ResourceCompile>
<ClCompile>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_;SYSVAD_BTH_BYPASS</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..;.</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_;SYSVAD_BTH_BYPASS;_NEW_DELETE_OPERATORS_</PreprocessorDefinitions>
<ExceptionHandling>
</ExceptionHandling>
<DisableSpecificWarnings>4595;%(DisableSpecificWarnings)</DisableSpecificWarnings>
@@ -111,8 +111,8 @@
<PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_;SYSVAD_BTH_BYPASS</PreprocessorDefinitions>
</ResourceCompile>
<ClCompile>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_;SYSVAD_BTH_BYPASS</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..;.</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_;SYSVAD_BTH_BYPASS;_NEW_DELETE_OPERATORS_</PreprocessorDefinitions>
<ExceptionHandling>
</ExceptionHandling>
<DisableSpecificWarnings>4595;%(DisableSpecificWarnings)</DisableSpecificWarnings>
@@ -128,8 +128,8 @@
<PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_;SYSVAD_BTH_BYPASS</PreprocessorDefinitions>
</ResourceCompile>
<ClCompile>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_;SYSVAD_BTH_BYPASS</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..;.</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_;SYSVAD_BTH_BYPASS;_NEW_DELETE_OPERATORS_</PreprocessorDefinitions>
<ExceptionHandling>
</ExceptionHandling>
<DisableSpecificWarnings>4595;%(DisableSpecificWarnings)</DisableSpecificWarnings>
@@ -145,8 +145,8 @@
<PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_;SYSVAD_BTH_BYPASS</PreprocessorDefinitions>
</ResourceCompile>
<ClCompile>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_;SYSVAD_BTH_BYPASS</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..;.</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_;SYSVAD_BTH_BYPASS;_NEW_DELETE_OPERATORS_</PreprocessorDefinitions>
<ExceptionHandling>
</ExceptionHandling>
<DisableSpecificWarnings>4595;%(DisableSpecificWarnings)</DisableSpecificWarnings>
@@ -168,6 +168,7 @@
<ClCompile Include="mintopo.cpp" />
<ClCompile Include="minwavert.cpp" />
<ClCompile Include="minwavertstream.cpp" />
+ <ClCompile Include="NewDelete.cpp" />
<ClCompile Include="speakerhptopo.cpp" />
<ClCompile Include="speakertopo.cpp" />
</ItemGroup>
diff --git a/audio/sysvad/EndpointsCommon/EndpointsCommon.vcxproj.Filters b/audio/sysvad/EndpointsCommon/EndpointsCommon.vcxproj.Filters
index 0579c299..413cac13 100644
--- a/audio/sysvad/EndpointsCommon/EndpointsCommon.vcxproj.Filters
+++ b/audio/sysvad/EndpointsCommon/EndpointsCommon.vcxproj.Filters
@@ -19,44 +19,13 @@
</Filter>
</ItemGroup>
<ItemGroup>
- <ClCompile Include="AudioModuleHelper.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="bthhfpmictopo.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="bthhfpminwavert.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="bthhfpspeakertopo.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="bthhfptopo.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="micarraytopo.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="MiniportAudioEngineNode.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="MiniportStreamAudioEngineNode.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="mintopo.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="minwavert.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="minwavertstream.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="speakerhptopo.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="speakertopo.cpp">
+ <ClCompile Include="*.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
</Project> \ No newline at end of file
diff --git a/audio/sysvad/EndpointsCommon/MiniportAudioEngineNode.cpp b/audio/sysvad/EndpointsCommon/MiniportAudioEngineNode.cpp
index db3fda39..c3a77d1f 100644
--- a/audio/sysvad/EndpointsCommon/MiniportAudioEngineNode.cpp
+++ b/audio/sysvad/EndpointsCommon/MiniportAudioEngineNode.cpp
@@ -171,7 +171,7 @@ Parameters:
_In_ _ulNodeId: node id for the target audio engine node
_In_ eEngineFormatType: format target to indicate which format size is being asked
- _Out_ pulFormatSize: a pointer to a ULONG variable for receiving returned szize information
+ _Out_ pulFormatSize: a pointer to a ULONG variable for receiving returned szize information
Return Value:
@@ -230,7 +230,7 @@ Parameters:
_In_ _ulNodeId: node id for the target audio engine node
_Out_ pFormat: a buffer pointer for receiving the mix format information being asked
- _In_ ulBufferSize: a pointer to a ULONG variable that has the size of the buffer pointed by pFormat
+ _In_ ulBufferSize: a pointer to a ULONG variable that has the size of the buffer pointed by pFormat
Return Value:
@@ -242,7 +242,7 @@ Remarks
This is a read only operation; the HW Audio Engine mix format is determined by the HW Audio Engine alone.
-------------------------------------------------------------------------------------------------------------------------*/
-STDMETHODIMP_(NTSTATUS) CMiniportWaveRT::GetMixFormat(_In_ ULONG _ulNodeId, _Out_ KSDATAFORMAT_WAVEFORMATEX *_pFormat, _In_ ULONG _ulBufferSize)
+STDMETHODIMP_(NTSTATUS) CMiniportWaveRT::GetMixFormat(_In_ ULONG _ulNodeId, _Out_ KSDATAFORMAT_WAVEFORMATEX *_pFormat, _In_ ULONG _ulBufferSize)
{
NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;
@@ -277,7 +277,7 @@ Parameters:
_In_ _ulNodeId: node id for the target audio engine node
_Out_ pFormat: a buffer pointer for receiving the device format information being asked
- _In_ ulBufferSize: a pointer to a ULONG variable that has the size of the buffer pointed by pFormat
+ _In_ ulBufferSize: a pointer to a ULONG variable that has the size of the buffer pointed by pFormat
Return Value:
@@ -325,7 +325,7 @@ Parameters:
_In_ _ulNodeId: node id for the target audio engine node
_Out_ pFormat: a buffer pointer with the device format to be set to the hw Audio Engine
- _In_ ulBufferSize: a pointer to a ULONG variable that has the size of the buffer pointed by pFormat
+ _In_ ulBufferSize: a pointer to a ULONG variable that has the size of the buffer pointed by pFormat
Return Value:
@@ -367,7 +367,7 @@ Parameters:
_In_ _ulNodeId: node id for the target audio engine node
_Out_ pFormat: a buffer pointer for receiving the supported device formats
- _In_ ulBufferSize: a pointer to a ULONG variable that has the size of the buffer pointed by pFormat
+ _In_ ulBufferSize: a pointer to a ULONG variable that has the size of the buffer pointed by pFormat
Return Value:
@@ -419,7 +419,7 @@ Parameters:
_In_ _ulNodeId: node id for the target audio engine node
_In_ _targetType: the query target (volume. mute, or peak meter)
- _Out_ _pulChannelCount: a pointer to a UINT32 variable for receiving returned channel count information
+ _Out_ _pulChannelCount: a pointer to a UINT32 variable for receiving returned channel count information
Return Value:
@@ -433,9 +433,9 @@ Remarks
#pragma code_seg("PAGE")
NTSTATUS CMiniportWaveRT::GetDeviceChannelCount
(
- _In_ ULONG _ulNodeId,
- _In_ eChannelTargetType _targetType,
- _Out_ UINT32 *_pulChannelCount
+ _In_ ULONG _ulNodeId,
+ _In_ eChannelTargetType _targetType,
+ _Out_ UINT32 *_pulChannelCount
)
{
NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;
@@ -479,7 +479,7 @@ Parameters:
_In_ _ulNodeId: node id for the target audio engine node
_In_ _targetType: the query target (volume. mute, or peak meter)
- _Out_ _pKsPropMembHead: a pointer to a PKSPROPERTY_STEPPING_LONG variable for receiving returned channel count information
+ _Out_ _pKsPropMembHead: a pointer to a PKSPROPERTY_STEPPING_LONG variable for receiving returned channel count information
_In_ ulBufferSize: a pointer to a ULONG variable that has the size of the buffer pointed by _pKsPropMembHead
Return Value:
@@ -531,7 +531,7 @@ Parameters:
_In_ _ulNodeId: node id for the target audio engine node
_In_ _uiChannel: the target channel for this GET volume operation
- _Out_ _pVolume: a pointer to a LONG variable for receiving returned information
+ _Out_ _pVolume: a pointer to a LONG variable for receiving returned information
Return Value:
@@ -570,7 +570,7 @@ Parameters:
_In_ _ulNodeId: node id for the target audio engine node
_In_ _uiChannel: the target channel for this GET volume operation
- _In_ _Volume: volume value to set
+ _In_ _Volume: volume value to set
Return Value:
@@ -647,7 +647,7 @@ Parameters:
_In_ _ulNodeId: node id for the target audio engine node
_In_ _uiChannel: the target channel for this GET volume operation
- _Out_ _pbMute: a pointer to a BOOL variable for receiving returned information
+ _Out_ _pbMute: a pointer to a BOOL variable for receiving returned information
Return Value:
@@ -686,7 +686,7 @@ Parameters:
_In_ _ulNodeId: node id for the target audio engine node
_In_ _uiChannel: the target channel for this GET volume operation
- _In_ _bMute: volume value to set
+ _In_ _bMute: volume value to set
Return Value:
@@ -764,35 +764,102 @@ NTSTATUS CMiniportWaveRT::GetBufferSizeRange(_In_ ULONG _ulNodeId, _In_ KSDATAF
NTSTATUS CMiniportWaveRT::GetVolumeChannelCount(_Out_ UINT32 *_pulChannelCount)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
+ BOOL bHandledInSideband = FALSE;
PAGED_CODE ();
ASSERT (_pulChannelCount);
DPF_ENTER(("[CMiniportWaveRT::GetVolumeChannelCount]"));
- *_pulChannelCount = m_DeviceMaxChannels;
+
+ if (IsSidebandDevice())
+ {
+ if (m_pSidebandDevice->IsVolumeSupported(m_DeviceType))
+ {
+ ULONG propSize = 0;
+ PKSPROPERTY_DESCRIPTION pPropDesc = (PKSPROPERTY_DESCRIPTION)m_pSidebandDevice->GetVolumeSettings(m_DeviceType, &propSize);
+ ASSERT(propSize >= sizeof(KSPROPERTY_DESCRIPTION) + sizeof(KSPROPERTY_MEMBERSHEADER) + sizeof(KSPROPERTY_STEPPING_LONG));
+ PKSPROPERTY_MEMBERSHEADER pMembers = (PKSPROPERTY_MEMBERSHEADER)(pPropDesc + 1);
+ *_pulChannelCount = pMembers->MembersCount;
+
+ bHandledInSideband = TRUE;
+ }
+ }
+
+ if(!bHandledInSideband)
+ {
+ *_pulChannelCount = m_DeviceMaxChannels;
+ }
return ntStatus;
}
+
#pragma code_seg("PAGE")
NTSTATUS CMiniportWaveRT::GetVolumeSteppings(_Out_writes_bytes_(_ui32DataSize) PKSPROPERTY_STEPPING_LONG _pKsPropStepLong, _In_ UINT32 _ui32DataSize)
{
PAGED_CODE ();
UINT32 ulChannelCount = _ui32DataSize / sizeof(KSPROPERTY_STEPPING_LONG);
+ BOOL bHandledInSideband = FALSE;
ASSERT (_pKsPropStepLong);
DPF_ENTER(("[CMiniportWaveRT::GetVolumeSteppings]"));
- ASSERT(ulChannelCount <= m_DeviceMaxChannels);
- if (ulChannelCount > m_DeviceMaxChannels)
+ if (IsSidebandDevice())
{
- return STATUS_INVALID_PARAMETER;
+ if (m_pSidebandDevice->IsVolumeSupported(m_DeviceType))
+ {
+ // For Sideband Devices copy values from the Sideband DDI property descriptor
+ ULONG propSize = 0;
+ PKSPROPERTY_DESCRIPTION pPropDesc = (PKSPROPERTY_DESCRIPTION)m_pSidebandDevice->GetVolumeSettings(m_DeviceType, &propSize);
+
+ ASSERT(propSize >= sizeof(KSPROPERTY_DESCRIPTION) + sizeof(KSPROPERTY_MEMBERSHEADER) + sizeof(KSPROPERTY_STEPPING_LONG));
+
+ PKSPROPERTY_MEMBERSHEADER pMembers = (PKSPROPERTY_MEMBERSHEADER)(pPropDesc + 1);
+
+ ASSERT(ulChannelCount <= pMembers->MembersCount);
+
+ if (ulChannelCount > pMembers->MembersCount)
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ PKSPROPERTY_STEPPING_LONG pRange = (PKSPROPERTY_STEPPING_LONG)(pMembers + 1);
+
+ for (UINT i = 0; i < ulChannelCount; i++)
+ {
+ RtlCopyMemory(&_pKsPropStepLong[i], &pRange[i], sizeof(KSPROPERTY_STEPPING_LONG));
+ }
+
+ bHandledInSideband = TRUE;
+ }
}
- for(UINT i = 0; i < ulChannelCount; i++)
+ if(!bHandledInSideband)
{
- _pKsPropStepLong[i].SteppingDelta = VOLUME_STEPPING_DELTA;
- _pKsPropStepLong[i].Bounds.SignedMaximum = VOLUME_SIGNED_MAXIMUM;
- _pKsPropStepLong[i].Bounds.SignedMinimum = VOLUME_SIGNED_MINIMUM;
+ ASSERT(ulChannelCount <= m_DeviceMaxChannels);
+ if (ulChannelCount > m_DeviceMaxChannels)
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ for (UINT i = 0; i < ulChannelCount; i++)
+ {
+ _pKsPropStepLong[i].SteppingDelta = VOLUME_STEPPING_DELTA;
+ _pKsPropStepLong[i].Bounds.SignedMaximum = VOLUME_SIGNED_MAXIMUM;
+ _pKsPropStepLong[i].Bounds.SignedMinimum = VOLUME_SIGNED_MINIMUM;
+ }
}
return STATUS_SUCCESS;
}
+
+//=============================================================================
+// The volume control should be implemented as follows:
+//
+// #1 If the Sideband device supports volume control, then the audio driver should
+// pipe the volume change requests through the Sideband Interface
+//
+// #2 If the Sideband device does not implement a hardware volume, and the codec
+// (or DSP) has a hardware volume, the audio driver should handle the volume
+// control on the codec (or DSP).
+//
+// This sample assumes #1 #2.
+//
#pragma code_seg("PAGE")
NTSTATUS CMiniportWaveRT::GetChannelVolume(_In_ UINT32 _uiChannel, _Out_ LONG *_pVolume)
{
@@ -800,16 +867,37 @@ NTSTATUS CMiniportWaveRT::GetChannelVolume(_In_ UINT32 _uiChannel, _Out_ LONG *
ASSERT (_pVolume);
DPF_ENTER(("[CMiniportWaveRT::GetChannelVolume]"));
- if (_uiChannel == ALL_CHANNELS_ID)
+ NTSTATUS status = STATUS_SUCCESS;
+
+ BOOL bHandledInSideband = FALSE;
+
+ if (IsSidebandDevice())
{
- *_pVolume = m_plVolumeLevel[0];
+ if (m_pSidebandDevice->IsVolumeSupported(m_DeviceType))
+ {
+ if (m_pSidebandDevice->IsVolumeSupported(m_DeviceType))
+ {
+ status = m_pSidebandDevice->GetVolume(m_DeviceType, _uiChannel, _pVolume);
+ }
+
+ bHandledInSideband = TRUE;
+ }
}
- else
+
+ if(!bHandledInSideband)
{
- ASSERT(_uiChannel <= m_DeviceMaxChannels);
- *_pVolume = m_plVolumeLevel[_uiChannel];
+ if (_uiChannel == ALL_CHANNELS_ID)
+ {
+ *_pVolume = m_plVolumeLevel[0];
+ }
+ else
+ {
+ ASSERT(_uiChannel <= m_DeviceMaxChannels);
+ *_pVolume = m_plVolumeLevel[_uiChannel];
+ }
}
- return STATUS_SUCCESS;
+
+ return status;
}
#pragma code_seg("PAGE")
NTSTATUS CMiniportWaveRT::SetChannelVolume(_In_ UINT32 _uiChannel, _In_ LONG _Volume)
@@ -817,9 +905,18 @@ NTSTATUS CMiniportWaveRT::SetChannelVolume(_In_ UINT32 _uiChannel, _In_ LONG _
PAGED_CODE ();
DPF_ENTER(("[CMiniportWaveRT::SetChannelVolume]"));
+ if (IsSidebandDevice())
+ {
+ if (m_pSidebandDevice->IsVolumeSupported(m_DeviceType))
+ {
+ return m_pSidebandDevice->SetVolume(m_DeviceType, _uiChannel, _Volume);
+ }
+ }
+
+ // Will reach here only if not handled through Sideband
if (_uiChannel == ALL_CHANNELS_ID)
{
- for (int i=0; i<m_DeviceMaxChannels; i++)
+ for (int i = 0; i < m_DeviceMaxChannels; i++)
{
m_plVolumeLevel[i] = _Volume;
}
@@ -899,11 +996,30 @@ NTSTATUS CMiniportWaveRT::GetChannelPeakMeter(_In_ UINT32 _uiChannel, _Out_ LO
NTSTATUS CMiniportWaveRT::GetMuteChannelCount(_Out_ UINT32 *_pulChannelCount)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
+ BOOL bHandledInSideband = FALSE;
PAGED_CODE ();
ASSERT (_pulChannelCount);
DPF_ENTER(("[CMiniportWaveRT::GetMuteChannelCount]"));
- *_pulChannelCount = m_DeviceMaxChannels;
+
+ if (IsSidebandDevice())
+ {
+ if (m_pSidebandDevice->IsMuteSupported(m_DeviceType))
+ {
+ ULONG propSize = 0;
+ PKSPROPERTY_DESCRIPTION pPropDesc = (PKSPROPERTY_DESCRIPTION)m_pSidebandDevice->GetMuteSettings(m_DeviceType, &propSize);
+ ASSERT(propSize >= sizeof(KSPROPERTY_DESCRIPTION) + sizeof(KSPROPERTY_MEMBERSHEADER) + sizeof(KSPROPERTY_STEPPING_LONG));
+ PKSPROPERTY_MEMBERSHEADER pMembers = (PKSPROPERTY_MEMBERSHEADER)(pPropDesc + 1);
+ *_pulChannelCount = pMembers->MembersCount;
+
+ bHandledInSideband = TRUE;
+ }
+ }
+
+ if(!bHandledInSideband)
+ {
+ *_pulChannelCount = m_DeviceMaxChannels;
+ }
return ntStatus;
}
#pragma code_seg("PAGE")
@@ -911,22 +1027,57 @@ NTSTATUS CMiniportWaveRT::GetMuteSteppings(_Out_writes_bytes_(_ui32DataSize) PK
{
PAGED_CODE ();
UINT32 ulChannelCount = _ui32DataSize / sizeof(KSPROPERTY_STEPPING_LONG);
+ BOOL bHandledInSideband = FALSE;
ASSERT (_pKsPropStepLong);
DPF_ENTER(("[CMiniportWaveRT::GetMuteSteppings]"));
- ASSERT(ulChannelCount <= m_DeviceMaxChannels);
-
- if (ulChannelCount > m_DeviceMaxChannels)
+ if (IsSidebandDevice())
{
- return STATUS_INVALID_PARAMETER;
+ if (m_pSidebandDevice->IsMuteSupported(m_DeviceType))
+ {
+ // For Sideband Devices copy values from the Sideband DDI property descriptor
+ ULONG propSize = 0;
+ PKSPROPERTY_DESCRIPTION pPropDesc = (PKSPROPERTY_DESCRIPTION)m_pSidebandDevice->GetMuteSettings(m_DeviceType, &propSize);
+
+ ASSERT(propSize >= sizeof(KSPROPERTY_DESCRIPTION) + sizeof(KSPROPERTY_MEMBERSHEADER) + sizeof(KSPROPERTY_STEPPING_LONG));
+
+ PKSPROPERTY_MEMBERSHEADER pMembers = (PKSPROPERTY_MEMBERSHEADER)(pPropDesc + 1);
+
+ ASSERT(ulChannelCount <= pMembers->MembersCount);
+
+ if (ulChannelCount > pMembers->MembersCount)
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ PKSPROPERTY_STEPPING_LONG pRange = (PKSPROPERTY_STEPPING_LONG)(pMembers + 1);
+
+ for (UINT i = 0; i < ulChannelCount; i++)
+ {
+ RtlCopyMemory(&_pKsPropStepLong[i], &pRange[i], sizeof(KSPROPERTY_STEPPING_LONG));
+ }
+
+ bHandledInSideband = TRUE;
+ }
+
}
- for(UINT i = 0; i < ulChannelCount; i++)
+ if(!bHandledInSideband)
{
- _pKsPropStepLong[i].SteppingDelta = 1;
- _pKsPropStepLong[i].Bounds.SignedMaximum = TRUE;
- _pKsPropStepLong[i].Bounds.SignedMinimum = FALSE;
+ ASSERT(ulChannelCount <= m_DeviceMaxChannels);
+
+ if (ulChannelCount > m_DeviceMaxChannels)
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ for (UINT i = 0; i < ulChannelCount; i++)
+ {
+ _pKsPropStepLong[i].SteppingDelta = 1;
+ _pKsPropStepLong[i].Bounds.SignedMaximum = TRUE;
+ _pKsPropStepLong[i].Bounds.SignedMinimum = FALSE;
+ }
}
return STATUS_SUCCESS;
}
@@ -937,15 +1088,29 @@ NTSTATUS CMiniportWaveRT::GetChannelMute(_In_ UINT32 _uiChannel, _Out_ BOOL *_
ASSERT (_pbMute);
DPF_ENTER(("[CMiniportWaveRT::GetChannelMute]"));
+ BOOL bHandledInSideband = FALSE;
- if (_uiChannel == ALL_CHANNELS_ID)
+ if (IsSidebandDevice())
{
- *_pbMute = m_pbMuted[0];
+ if (m_pSidebandDevice->IsMuteSupported(m_DeviceType))
+ {
+ *_pbMute = m_pSidebandDevice->GetMute(m_DeviceType, _uiChannel);
+
+ bHandledInSideband = TRUE;
+ }
}
- else
+
+ if (!bHandledInSideband)
{
- ASSERT(_uiChannel <= m_DeviceMaxChannels);
- *_pbMute = m_pbMuted[_uiChannel];
+ if (_uiChannel == ALL_CHANNELS_ID)
+ {
+ *_pbMute = m_pbMuted[0];
+ }
+ else
+ {
+ ASSERT(_uiChannel <= m_DeviceMaxChannels);
+ *_pbMute = m_pbMuted[_uiChannel];
+ }
}
return STATUS_SUCCESS;
@@ -954,8 +1119,17 @@ NTSTATUS CMiniportWaveRT::GetChannelMute(_In_ UINT32 _uiChannel, _Out_ BOOL *_
NTSTATUS CMiniportWaveRT::SetChannelMute(_In_ UINT32 _uiChannel, _In_ BOOL _bMute)
{
PAGED_CODE ();
- DPF_ENTER(("[CMiniportWaveRT::SetChannelVolume]"));
+ DPF_ENTER(("[CMiniportWaveRT::SetChannelMute]"));
+
+ if (IsSidebandDevice())
+ {
+ if (m_pSidebandDevice->IsMuteSupported(m_DeviceType))
+ {
+ return m_pSidebandDevice->SetMute(m_DeviceType, _uiChannel, _bMute);
+ }
+ }
+ // Will reach here only if not handled through Sideband
if (_uiChannel == ALL_CHANNELS_ID)
{
for (int i=0; i<m_DeviceMaxChannels; i++)
diff --git a/audio/sysvad/EndpointsCommon/MiniportStreamAudioEngineNode.cpp b/audio/sysvad/EndpointsCommon/MiniportStreamAudioEngineNode.cpp
index 0f772155..c3da83b9 100644
--- a/audio/sysvad/EndpointsCommon/MiniportStreamAudioEngineNode.cpp
+++ b/audio/sysvad/EndpointsCommon/MiniportStreamAudioEngineNode.cpp
@@ -98,7 +98,7 @@ Decscription:
Parameters:
_In_ _uiChannel: the target channel for this GET volume operation
- _Out_ _pVolume: a pointer to a LONG variable for receiving returned information
+ _Out_ _pVolume: a pointer to a LONG variable for receiving returned information
Return Value:
@@ -131,7 +131,7 @@ Decscription:
Parameters:
_In_ _uiChannel: the target channel for this GET volume operation
- _Out_ _pbMute: a pointer to a BOOL variable for receiving returned information
+ _Out_ _pbMute: a pointer to a BOOL variable for receiving returned information
Return Value:
@@ -167,7 +167,7 @@ Decscription:
Parameters:
_In_ _targetType: the query target (volume. mute, or peak meter)
- _Out_ _pKsPropMembHead: a pointer to a PKSPROPERTY_STEPPING_LONG variable for receiving returned channel count information
+ _Out_ _pKsPropMembHead: a pointer to a PKSPROPERTY_STEPPING_LONG variable for receiving returned channel count information
_In_ ulBufferSize: a pointer to a ULONG variable that has the size of the buffer pointed by _pKsPropMembHead
Return Value:
@@ -233,7 +233,7 @@ Remarks
STDMETHODIMP_(NTSTATUS) CMiniportWaveRTStream::SetStreamChannelVolume
(
_In_ UINT32 Channel,
- _In_ LONG TargetVolume,
+ _In_ LONG TargetVolume,
_In_ AUDIO_CURVE_TYPE CurveType,
_In_ ULONGLONG CurveDuration
)
@@ -277,7 +277,7 @@ Decscription:
Parameters:
_In_ _uiChannel: the target channel for this GET peak meter operation
- _Out_ _pPeakMeterValue: a pointer to a LONG variable for receiving returned information
+ _Out_ _pPeakMeterValue: a pointer to a LONG variable for receiving returned information
Return Value:
@@ -313,7 +313,7 @@ Decscription:
Parameters:
_In_ _uiChannel: the target channel for this Set mute operation
- _In_ _bMute: mute value to set
+ _In_ _bMute: mute value to set
Return Value:
@@ -359,7 +359,7 @@ Decscription:
Parameters:
- _Out_ pPresentationPosition: a pointer to a KSAUDIO_PRESENTATION_POSITION variable for receiving returned information
+ _Out_ pPresentationPosition: a pointer to a KSAUDIO_PRESENTATION_POSITION variable for receiving returned information
Return Value:
@@ -394,7 +394,7 @@ Decscription:
Parameters:
- _In_ ulCurrentWritePosition: a position value indicating the last valid byte in the buffer
+ _In_ ulCurrentWritePosition: a position value indicating the last valid byte in the buffer
Return Value:
@@ -437,7 +437,7 @@ Decscription:
Parameters:
- _Out_ pullLinearBufferPosition: a pointer to a ULONGLONG variable for receiving returned information
+ _Out_ pullLinearBufferPosition: a pointer to a ULONGLONG variable for receiving returned information
Return Value:
@@ -472,7 +472,7 @@ Decscription:
protection option
Parameters:
- _In_ protectionOption: protection option
+ _In_ protectionOption: protection option
CONSTRICTOR_OPTION_DISABLE: Turn protection off.
CONSTRICTOR_OPTION_MUTE: Mute the loopback stream
Return Value:
@@ -513,7 +513,7 @@ Decscription:
Parameters:
_In_ _targetType: the query target (volume, mute, or peak meter)
- _Out_ _pulChannelCount: a pointer to a UINT32 variable for receiving returned channel count information
+ _Out_ _pulChannelCount: a pointer to a UINT32 variable for receiving returned channel count information
Return Value:
@@ -524,7 +524,7 @@ Called at PASSIVE_LEVEL
Remarks
-------------------------------------------------------------------------------------------------------------------------*/
-NTSTATUS CMiniportWaveRTStream::GetStreamChannelCount(_In_ eChannelTargetType _targetType,_Out_ UINT32 *_pulChannelCount)
+NTSTATUS CMiniportWaveRTStream::GetStreamChannelCount(_In_ eChannelTargetType _targetType,_Out_ UINT32 *_pulChannelCount)
{
NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;
@@ -750,23 +750,22 @@ NTSTATUS CMiniportWaveRTStream::GetPresentationPosition(_Out_ KSAUDIO_PRESENTAT
status = GetPositions(&ullLinearPosition, &ullPresentationPosition, &timeStamp);
if (!NT_SUCCESS(status))
{
- return status;
+ return status;
}
_pPresentationPosition->u64PositionInBlocks = ullPresentationPosition * m_pWfExt->Format.nSamplesPerSec / m_pWfExt->Format.nAvgBytesPerSec;
_pPresentationPosition->u64QPCPosition = (UINT64)timeStamp.QuadPart;
//Event type: eMINIPORT_GET_PRESENTATION_POSITION
- //Parameter 1: Current linear buffer position
- //Parameter 2: the previous WaveRtBufferWritePosition that the drive received
+ //Parameter 1: Current linear buffer position
+ //Parameter 2: Previous WaveRtBufferWritePosition that the driver received
//Parameter 3: Presentation position
- //Parameter 4:0
- pAdapterComm->WriteEtwEvent(eMINIPORT_GET_PRESENTATION_POSITION,
- ullLinearPosition, // replace with the correct "Current linear buffer position"
+ //Parameter 4: 0
+ pAdapterComm->WriteEtwEvent(eMINIPORT_GET_PRESENTATION_POSITION,
+ ullLinearPosition, // replace with the correct "Current linear buffer position"
m_ulCurrentWritePosition,
- _pPresentationPosition->u64PositionInBlocks,
+ _pPresentationPosition->u64PositionInBlocks,
0); // always zero
-
return STATUS_SUCCESS;
}
@@ -777,13 +776,13 @@ NTSTATUS CMiniportWaveRTStream::SetCurrentWritePosition(_In_ ULONG _ulCurrentWr
NTSTATUS ntStatus;
-#ifdef SYSVAD_BTH_BYPASS
- if (m_ScoOpen)
+#if defined(SYSVAD_BTH_BYPASS)
+ if (m_SidebandStarted)
{
- ntStatus = GetScoStreamNtStatus();
+ ntStatus = GetSidebandStreamNtStatus();
IF_FAILED_JUMP(ntStatus, Done);
}
-#endif // SYSVAD_BTH_BYPASS
+#endif // defined(SYSVAD_BTH_BYPASS)
//
// Basic validation. WritePosition indicates the position (1-based) of the last valid byte.
@@ -808,6 +807,13 @@ NTSTATUS CMiniportWaveRTStream::SetCurrentWritePositionInternal(_In_ ULONG _ulC
{
DPF_ENTER(("[CMiniportWaveRTStream::SetCurrentWritePositionInternal]"));
+ ASSERT(m_bEoSReceived == FALSE);
+
+ if (m_bEoSReceived)
+ {
+ return STATUS_INVALID_DEVICE_REQUEST;
+ }
+
if (_ulCurrentWritePosition > m_ulDmaBufferSize)
{
return STATUS_INVALID_DEVICE_REQUEST;
@@ -816,19 +822,18 @@ NTSTATUS CMiniportWaveRTStream::SetCurrentWritePositionInternal(_In_ ULONG _ulC
PADAPTERCOMMON pAdapterComm = m_pMiniport->GetAdapterCommObj();
//Event type: eMINIPORT_SET_WAVERT_BUFFER_WRITE_POSITION
- //Parameter 1: Current linear buffer position
- //Parameter 2: the previous WaveRtBufferWritePosition that the drive received
+ //Parameter 1: Current linear buffer position
+ //Parameter 2: Previous WaveRtBufferWritePosition that the driver received
//Parameter 3: Target WaveRtBufferWritePosition received from portcls
- //Parameter 4:0
+ //Parameter 4: 0
pAdapterComm->WriteEtwEvent(eMINIPORT_SET_WAVERT_BUFFER_WRITE_POSITION,
- 100, // replace with the correct "Current linear buffer position"
+ m_ullLinearPosition, // replace with the correct "Current linear buffer position"
m_ulCurrentWritePosition,
- _ulCurrentWritePosition, // this is the passed in parameter
- 0); // always zero
-
+ _ulCurrentWritePosition, // this is new write position
+ 0); // always zero
//
- // Check for eMINIPORT_GLITCH_REPORT - 'same writert buffer' only when in event mode.
+ // Check for eMINIPORT_GLITCH_REPORT - Same WaveRT buffer write during event driven mode.
//
if (m_ulNotificationIntervalMs > 0)
{
@@ -836,14 +841,14 @@ NTSTATUS CMiniportWaveRTStream::SetCurrentWritePositionInternal(_In_ ULONG _ulC
{
//Event type: eMINIPORT_GLITCH_REPORT
//Parameter 1: Current linear buffer position
- //Parameter 2: the previous WaveRtBufferWritePosition that the drive received
- //Parameter 3: major glitch code: 3:receive the same wavert buffer two in a row in event driven mode
- //Parameter 4: minor code for the glitch cause
+ //Parameter 2: Previous WaveRtBufferWritePosition that the driver received
+ //Parameter 3: Major glitch code: 3: Received same WaveRT buffer twice in a row during event driven mode
+ //Parameter 4: Minor code for the glitch cause
pAdapterComm->WriteEtwEvent(eMINIPORT_GLITCH_REPORT,
- 100, // replace with the correct "Current linear buffer position"
+ m_ullLinearPosition, // replace with the correct "Current linear buffer position"
m_ulCurrentWritePosition,
- 3, // receive the same wavert buffer two in a row in event driven mode
- _ulCurrentWritePosition);
+ 3, // received same WaveRT buffer twice in a row during event driven mode
+ _ulCurrentWritePosition);
}
}
@@ -855,24 +860,25 @@ NTSTATUS CMiniportWaveRTStream::SetCurrentWritePositionInternal(_In_ ULONG _ulC
//linear and presentation positions
#pragma code_seg()
-NTSTATUS CMiniportWaveRTStream::GetPositions(
+NTSTATUS CMiniportWaveRTStream::GetPositions
+(
_Out_opt_ ULONGLONG * _pullLinearBufferPosition,
_Out_opt_ ULONGLONG * _pullPresentationPosition,
_Out_opt_ LARGE_INTEGER * _pliQPCTime
- )
+)
{
DPF_ENTER(("[CMiniportWaveRTStream::GetPositions]"));
NTSTATUS ntStatus;
LARGE_INTEGER ilQPC;
KIRQL oldIrql;
-#ifdef SYSVAD_BTH_BYPASS
- if (m_ScoOpen)
+#if defined(SYSVAD_BTH_BYPASS)
+ if (m_SidebandStarted)
{
- ntStatus = GetScoStreamNtStatus();
+ ntStatus = GetSidebandStreamNtStatus();
IF_FAILED_JUMP(ntStatus, Done);
}
-#endif // SYSVAD_BTH_BYPASS
+#endif // defined(SYSVAD_BTH_BYPASS)
// Update *_pullLinearBufferPosition with the the number of bytes fetched from waveRT ever since a stream got set into RUN
// state.
@@ -903,9 +909,9 @@ NTSTATUS CMiniportWaveRTStream::GetPositions(
ntStatus = STATUS_SUCCESS;
-#ifdef SYSVAD_BTH_BYPASS
+#if defined(SYSVAD_BTH_BYPASS)
Done:
-#endif // SYSVAD_BTH_BYPASS
+#endif // defined(SYSVAD_BTH_BYPASS)
return ntStatus;
}
@@ -919,7 +925,7 @@ Decscription:
protection option
Parameters:
- _In_ protectionOption: protection option
+ _In_ protectionOption: protection option
CONSTRICTOR_OPTION_DISABLE: Turn protection off.
CONSTRICTOR_OPTION_MUTE: Mute the loopback stream
Return Value:
@@ -979,8 +985,6 @@ NTSTATUS CMiniportWaveRTStream::SetStreamCurrentWritePositionForLastBuffer(_In_
NTSTATUS ntStatus;
KIRQL oldIrql;
- ASSERT(m_bEoSReceived == FALSE);
-
KeAcquireSpinLock(&m_PositionSpinLock, &oldIrql);
// Miniport driver needs to prepare to signal buffer completion event
diff --git a/audio/sysvad/EndpointsCommon/NewDelete.cpp b/audio/sysvad/EndpointsCommon/NewDelete.cpp
new file mode 100644
index 00000000..7a4f89d6
--- /dev/null
+++ b/audio/sysvad/EndpointsCommon/NewDelete.cpp
@@ -0,0 +1,157 @@
+/*****************************************************************************
+* NewDelete.cpp - CPP placement new and delete operators implementation
+*****************************************************************************
+* Copyright (c) Microsoft Corporation All Rights Reserved
+*
+* Module Name:
+*
+* NewDelete.cpp
+*
+* Abstract:
+*
+* Definition of placement new and delete operators.
+*
+*/
+
+#ifdef _NEW_DELETE_OPERATORS_
+#ifdef __cplusplus
+extern "C" {
+#include <wdm.h>
+}
+#else
+#include <wdm.h>
+#endif
+
+#include "newDelete.h"
+#include "sysvad.h"
+
+#pragma code_seg()
+/*****************************************************************************
+* Functions
+*/
+
+/*****************************************************************************
+* ::new()
+*****************************************************************************
+* New function for creating objects with a specified allocation tag.
+*/
+PVOID operator new
+(
+ size_t iSize,
+ _When_((poolType & NonPagedPoolMustSucceed) != 0,
+ __drv_reportError("Must succeed pool allocations are forbidden. "
+ "Allocation failures cause a system crash"))
+ POOL_TYPE poolType,
+ ULONG tag
+)
+{
+ PVOID result = ExAllocatePoolWithTag(poolType, iSize, tag);
+
+ if (result)
+ {
+ RtlZeroMemory(result, iSize);
+ }
+
+ return result;
+}
+
+
+/*****************************************************************************
+* ::new()
+*****************************************************************************
+* New function for creating objects with a specified allocation tag.
+*/
+PVOID operator new
+(
+ size_t iSize,
+ _When_((poolType & NonPagedPoolMustSucceed) != 0,
+ __drv_reportError("Must succeed pool allocations are forbidden. "
+ "Allocation failures cause a system crash"))
+ POOL_TYPE poolType
+)
+{
+ PVOID result = ExAllocatePoolWithTag(poolType, iSize, SYSVAD_POOLTAG);
+
+ if (result)
+ {
+ RtlZeroMemory(result, iSize);
+ }
+
+ return result;
+}
+
+
+/*****************************************************************************
+* ::delete()
+*****************************************************************************
+* Delete with tag function.
+*/
+void __cdecl operator delete
+(
+ PVOID pVoid,
+ ULONG tag
+)
+{
+ if (pVoid)
+ {
+ ExFreePoolWithTag(pVoid, tag);
+ }
+}
+
+
+/*****************************************************************************
+* ::delete()
+*****************************************************************************
+* Sized Delete function.
+*/
+void __cdecl operator delete
+(
+ _Pre_maybenull_ __drv_freesMem(Mem) PVOID pVoid,
+ _In_ size_t cbSize
+)
+{
+ UNREFERENCED_PARAMETER(cbSize);
+
+ if (pVoid)
+ {
+ ExFreePoolWithTag(pVoid, SYSVAD_POOLTAG);
+ }
+}
+
+
+/*****************************************************************************
+* ::delete()
+*****************************************************************************
+* Sized Array Delete function.
+*/
+void __cdecl operator delete[]
+(
+ _Pre_maybenull_ __drv_freesMem(Mem) PVOID pVoid,
+ _In_ size_t cbSize
+)
+{
+ UNREFERENCED_PARAMETER(cbSize);
+
+ if (pVoid)
+ {
+ ExFreePoolWithTag(pVoid, SYSVAD_POOLTAG);
+ }
+}
+
+
+/*****************************************************************************
+* ::delete()
+*****************************************************************************
+* Array Delete function.
+*/
+void __cdecl operator delete[]
+(
+ _Pre_maybenull_ __drv_freesMem(Mem) PVOID pVoid
+)
+{
+ if (pVoid)
+ {
+ ExFreePoolWithTag(pVoid, SYSVAD_POOLTAG);
+ }
+}
+#endif//_NEW_DELETE_OPERATORS_
diff --git a/audio/sysvad/EndpointsCommon/NewDelete.h b/audio/sysvad/EndpointsCommon/NewDelete.h
new file mode 100644
index 00000000..288634d4
--- /dev/null
+++ b/audio/sysvad/EndpointsCommon/NewDelete.h
@@ -0,0 +1,116 @@
+/*++
+
+Copyright (c) Microsoft Corporation All Rights Reserved
+
+Module Name:
+
+NewDelete.h
+
+Abstract:
+
+Declaration of placement new and delete operators.
+
+//@@BEGIN_DDKSPLIT
+Revision History:
+
+//@@END_DDKSPLIT
+
+--*/
+#pragma once
+
+#ifdef _NEW_DELETE_OPERATORS_
+
+/*****************************************************************************
+* Functions
+*/
+
+/*****************************************************************************
+* ::new()
+*****************************************************************************
+* New function for creating objects with a specified allocation tag and
+* pool type
+*/
+PVOID operator new
+(
+ size_t iSize,
+ _When_((poolType & NonPagedPoolMustSucceed) != 0,
+ __drv_reportError("Must succeed pool allocations are forbidden. "
+ "Allocation failures cause a system crash"))
+ POOL_TYPE poolType,
+ ULONG tag
+);
+
+
+/*****************************************************************************
+* ::new()
+*****************************************************************************
+* New function for creating objects with a specified pool type.
+*/
+PVOID operator new
+(
+ size_t iSize,
+ _When_((poolType & NonPagedPoolMustSucceed) != 0,
+ __drv_reportError("Must succeed pool allocations are forbidden. "
+ "Allocation failures cause a system crash"))
+ POOL_TYPE poolType
+);
+
+
+/*****************************************************************************
+* ::delete()
+*****************************************************************************
+* Delete with tag function.
+*/
+void __cdecl operator delete
+(
+ PVOID pVoid,
+ ULONG tag
+);
+
+
+/*****************************************************************************
+* ::delete()
+*****************************************************************************
+* Sized Delete function.
+*/
+void __cdecl operator delete
+(
+ _Pre_maybenull_ __drv_freesMem(Mem) PVOID pVoid,
+ _In_ size_t cbSize
+);
+
+
+/*****************************************************************************
+* ::delete()
+*****************************************************************************
+* Basic Delete function.
+*/
+void __cdecl operator delete
+(
+ PVOID pVoid
+);
+
+
+/*****************************************************************************
+* ::delete()
+*****************************************************************************
+* Sized Array Delete function.
+*/
+void __cdecl operator delete[]
+(
+ _Pre_maybenull_ __drv_freesMem(Mem) PVOID pVoid,
+ _In_ size_t cbSize
+);
+
+
+/*****************************************************************************
+* ::delete()
+*****************************************************************************
+* Array Delete function.
+*/
+void __cdecl operator delete[]
+(
+ _Pre_maybenull_ __drv_freesMem(Mem) PVOID pVoid
+);
+
+#endif//_NEW_DELETE_OPERATORS_
diff --git a/audio/sysvad/EndpointsCommon/bthhfpmictopo.cpp b/audio/sysvad/EndpointsCommon/bthhfpmictopo.cpp
index ec3f4367..01eb156b 100644
--- a/audio/sysvad/EndpointsCommon/bthhfpmictopo.cpp
+++ b/audio/sysvad/EndpointsCommon/bthhfpmictopo.cpp
@@ -136,13 +136,13 @@ Return Value:
NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;
PCMiniportTopology miniport = (PCMiniportTopology)PropertyRequest->MajorTarget;
- PBTHHFPDEVICECOMMON bthHfpDevice = NULL;
+ PSIDEBANDDEVICECOMMON bthHfpDevice = NULL;
ULONG channel = (ULONG)-1;
- bthHfpDevice = miniport->GetBthHfpDevice(); // weak ref.
+ bthHfpDevice = miniport->GetSidebandDevice(); // weak ref.
ASSERT(bthHfpDevice != NULL);
- if (bthHfpDevice->IsVolumeSupported() == FALSE)
+ if (bthHfpDevice->IsVolumeSupported(miniport->m_DeviceType) == FALSE)
{
ntStatus = miniport->PropertyHandlerGeneric(PropertyRequest);
}
@@ -174,14 +174,11 @@ Return Value:
if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET)
{
- *volume = bthHfpDevice->GetMicVolume();
-
- ntStatus = STATUS_SUCCESS;
-
+ ntStatus = bthHfpDevice->GetVolume(eBthHfpMicDevice, channel, volume);
}
else if (PropertyRequest->Verb & KSPROPERTY_TYPE_SET)
{
- ntStatus = bthHfpDevice->SetMicVolume(*volume);
+ ntStatus = bthHfpDevice->SetVolume(eBthHfpMicDevice, *volume, channel);
}
}
}
@@ -278,4 +275,3 @@ PropertyHandler_BthHfpMicTopoFilterEvent
#pragma code_seg()
#endif // SYSVAD_BTH_BYPASS
-
diff --git a/audio/sysvad/EndpointsCommon/bthhfpmicwavtable.h b/audio/sysvad/EndpointsCommon/bthhfpmicwavtable.h
index fe28f3f3..cdec96a9 100644
--- a/audio/sysvad/EndpointsCommon/bthhfpmicwavtable.h
+++ b/audio/sysvad/EndpointsCommon/bthhfpmicwavtable.h
@@ -24,7 +24,7 @@ NTSTATUS PropertyHandler_BthHfpWaveFilter(_In_ PPCPROPERTY_REQUEST PropertyReque
// Bluetooth Headset Mic (external) range.
//
#define BTHHFPMIC_DEVICE_MAX_CHANNELS 1 // Max Channels.
-#define BTHHFPMIC_MIN_BITS_PER_SAMPLE_PCM 8 // Min Bits Per Sample
+#define BTHHFPMIC_MIN_BITS_PER_SAMPLE_PCM 16 // Min Bits Per Sample
#define BTHHFPMIC_MAX_BITS_PER_SAMPLE_PCM 16 // Max Bits Per Sample
#define BTHHFPMIC_MIN_SAMPLE_RATE 8000 // Min Sample Rate
#define BTHHFPMIC_MAX_SAMPLE_RATE 8000 // Max Sample Rate
@@ -49,31 +49,6 @@ KSDATAFORMAT_WAVEFORMATEXTENSIBLE BthHfpMicPinSupportedDeviceFormats[] =
WAVE_FORMAT_EXTENSIBLE,
1,
8000,
- 8000,
- 1,
- 8,
- sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)
- },
- 8,
- KSAUDIO_SPEAKER_MONO,
- STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM)
- }
- },
- {
- {
- sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE),
- 0,
- 0,
- 0,
- STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
- STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM),
- STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
- },
- {
- {
- WAVE_FORMAT_EXTENSIBLE,
- 1,
- 8000,
16000,
2,
16,
@@ -258,7 +233,13 @@ PCPROPERTY_ITEM PropertiesBthHfpMicWaveFilter[] =
{
&KSPROPSETID_Pin,
KSPROPERTY_PIN_PROPOSEDATAFORMAT,
- KSPROPERTY_TYPE_SET | KSPROPERTY_TYPE_BASICSUPPORT,
+ KSPROPERTY_TYPE_SET | KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_BASICSUPPORT,
+ PropertyHandler_BthHfpWaveFilter
+ },
+ {
+ &KSPROPSETID_Pin,
+ KSPROPERTY_PIN_PROPOSEDATAFORMAT2,
+ KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_BASICSUPPORT,
PropertyHandler_BthHfpWaveFilter
},
{
@@ -269,7 +250,20 @@ PCPROPERTY_ITEM PropertiesBthHfpMicWaveFilter[] =
}
};
-DEFINE_PCAUTOMATION_TABLE_PROP(AutomationBthHfpMicWaveFilter, PropertiesBthHfpMicWaveFilter);
+NTSTATUS CMiniportWaveRT_EventHandler_PinCapsChange(
+ _In_ PPCEVENT_REQUEST EventRequest
+ );
+
+static PCEVENT_ITEM BthHfpMicFormatChangePinEvent[] = {
+ {
+ &KSEVENTSETID_PinCapsChange,
+ KSEVENT_PINCAPS_FORMATCHANGE,
+ KSEVENT_TYPE_ENABLE | KSEVENT_TYPE_BASICSUPPORT,
+ CMiniportWaveRT_EventHandler_PinCapsChange
+ }
+};
+
+DEFINE_PCAUTOMATION_TABLE_PROP_EVENT(AutomationBthHfpMicWaveFilter, PropertiesBthHfpMicWaveFilter, BthHfpMicFormatChangePinEvent);
//=============================================================================
static
diff --git a/audio/sysvad/EndpointsCommon/bthhfpmicwbwavtable.h b/audio/sysvad/EndpointsCommon/bthhfpmicwbwavtable.h
index 9a41f460..e94c5d20 100644
--- a/audio/sysvad/EndpointsCommon/bthhfpmicwbwavtable.h
+++ b/audio/sysvad/EndpointsCommon/bthhfpmicwbwavtable.h
@@ -24,11 +24,11 @@ NTSTATUS PropertyHandler_BthHfpWaveFilter(_In_ PPCPROPERTY_REQUEST PropertyReque
//
// Bluetooth Headset Mic (external) range.
//
-#define BTHHFPMICWB_DEVICE_MAX_CHANNELS 1 // Max Channels.
-#define BTHHFPMICWB_MIN_BITS_PER_SAMPLE_PCM 8 // Min Bits Per Sample
-#define BTHHFPMICWB_MAX_BITS_PER_SAMPLE_PCM 16 // Max Bits Per Sample
-#define BTHHFPMICWB_MIN_SAMPLE_RATE 8000 // Min Sample Rate
-#define BTHHFPMICWB_MAX_SAMPLE_RATE 16000 // Max Sample Rate
+#define BTHHFPMICWB_DEVICE_MAX_CHANNELS 1 // Max Channels.
+#define BTHHFPMICWB_MIN_BITS_PER_SAMPLE_PCM 16 // Min Bits Per Sample
+#define BTHHFPMICWB_MAX_BITS_PER_SAMPLE_PCM 16 // Max Bits Per Sample
+#define BTHHFPMICWB_MIN_SAMPLE_RATE 16000 // Min Sample Rate
+#define BTHHFPMICWB_MAX_SAMPLE_RATE 16000 // Max Sample Rate
//=============================================================================
@@ -49,81 +49,6 @@ KSDATAFORMAT_WAVEFORMATEXTENSIBLE BthHfpMicWBPinSupportedDeviceFormats[] =
{
WAVE_FORMAT_EXTENSIBLE,
1,
- 8000,
- 8000,
- 1,
- 8,
- sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)
- },
- 8,
- KSAUDIO_SPEAKER_MONO,
- STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM)
- }
- },
- {
- {
- sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE),
- 0,
- 0,
- 0,
- STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
- STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM),
- STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
- },
- {
- {
- WAVE_FORMAT_EXTENSIBLE,
- 1,
- 8000,
- 16000,
- 2,
- 16,
- sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)
- },
- 16,
- KSAUDIO_SPEAKER_MONO,
- STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM)
- }
- },
- {
- {
- sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE),
- 0,
- 0,
- 0,
- STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
- STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM),
- STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
- },
- {
- {
- WAVE_FORMAT_EXTENSIBLE,
- 1,
- 16000,
- 16000,
- 1,
- 8,
- sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)
- },
- 8,
- KSAUDIO_SPEAKER_MONO,
- STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM)
- }
- },
- {
- {
- sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE),
- 0,
- 0,
- 0,
- STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
- STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM),
- STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
- },
- {
- {
- WAVE_FORMAT_EXTENSIBLE,
- 1,
16000,
32000,
2,
@@ -198,22 +123,6 @@ KSDATARANGE_AUDIO BthHfpMicWBPinDataRangesStream[] =
STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM),
STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
},
- BTHHFPMICWB_DEVICE_MAX_CHANNELS,
- BTHHFPMICWB_MIN_BITS_PER_SAMPLE_PCM,
- BTHHFPMICWB_MAX_BITS_PER_SAMPLE_PCM,
- BTHHFPMICWB_MIN_SAMPLE_RATE,
- BTHHFPMICWB_MIN_SAMPLE_RATE
- },
- {
- {
- sizeof(KSDATARANGE_AUDIO),
- KSDATARANGE_ATTRIBUTES, // An attributes list follows this data range
- 0,
- 0,
- STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
- STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM),
- STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
- },
BTHHFPMICWB_DEVICE_MAX_CHANNELS,
BTHHFPMICWB_MIN_BITS_PER_SAMPLE_PCM,
BTHHFPMICWB_MAX_BITS_PER_SAMPLE_PCM,
@@ -226,8 +135,6 @@ static
PKSDATARANGE BthHfpMicWBPinDataRangePointersStream[] =
{
PKSDATARANGE(&BthHfpMicWBPinDataRangesStream[0]),
- PKSDATARANGE(&PinDataRangeAttributeList),
- PKSDATARANGE(&BthHfpMicWBPinDataRangesStream[1]),
PKSDATARANGE(&PinDataRangeAttributeList)
};
@@ -331,6 +238,12 @@ PCPROPERTY_ITEM PropertiesBthHfpMicWBWaveFilter[] =
PropertyHandler_BthHfpWaveFilter
},
{
+ &KSPROPSETID_Pin,
+ KSPROPERTY_PIN_PROPOSEDATAFORMAT2,
+ KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_BASICSUPPORT,
+ PropertyHandler_BthHfpWaveFilter
+ },
+ {
&KSPROPSETID_AudioEffectsDiscovery,
KSPROPERTY_AUDIOEFFECTSDISCOVERY_EFFECTSLIST,
KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_BASICSUPPORT,
diff --git a/audio/sysvad/EndpointsCommon/bthhfpminipairs.h b/audio/sysvad/EndpointsCommon/bthhfpminipairs.h
index 7d2b82f7..1ec7bd5a 100644
--- a/audio/sysvad/EndpointsCommon/bthhfpminipairs.h
+++ b/audio/sysvad/EndpointsCommon/bthhfpminipairs.h
@@ -69,50 +69,66 @@ static
PHYSICALCONNECTIONTABLE BthHfpSpeakerTopologyPhysicalConnections[] =
{
{
- KSPIN_TOPO_WAVEOUT_SOURCE, // TopologyIn
- KSPIN_WAVE_RENDER_SOURCE, // WaveOut
+ KSPIN_TOPO_WAVEOUT_SOURCE, // TopologyIn
+ KSPIN_WAVE_RENDER3_SOURCE, // WaveOut
CONNECTIONTYPE_WAVE_OUTPUT
}
};
+// A subdevice is created for each HFP device using the reference string in the form of:
+// <Base_Reference_String>-<Hashcode>
+// where Base_Reference_String is one of the following template names
+#define BTHHFP_SPEAKER_TOPO_NAME L"TopologyBthHfpSpeaker"
+#define BTHHFP_SPEAKER_WAVE_NAME L"WaveBthHfpSpeaker"
+#define BTHHFP_MIC_TOPO_NAME L"TopologyBthHfpMic"
+#define BTHHFP_MIC_WAVE_NAME L"WaveBthHfpMic"
+// And Hashcode is 8-character long hexadecimal value
+
+// A reference string max length is being set to a value to accommodate them both
+#define BTHHFP_INTERFACE_REFSTRING_MAX_LENGTH 100
+
static
ENDPOINT_MINIPAIR BthHfpSpeakerMiniports =
{
eBthHfpSpeakerDevice,
- L"TopologyBthHfpSpeaker", // make sure this name matches with SYSVAD.TopologyBthHfpSpeaker.szPname in the inf's [Strings] section
+ NULL, // Will be generated based on BTHHFP_SPEAKER_TOPO_NAME and made unique for each side band interface
+ BTHHFP_SPEAKER_TOPO_NAME, // template name matches with KSNAME_TopologyBthHfpSpeaker in the inf's [Strings] section
CreateMiniportTopologySYSVAD,
&BthHfpSpeakerTopoMiniportFilterDescriptor,
- 0, NULL, // Interface properties
- L"WaveBthHfpSpeaker", // make sure this name matches with SYSVAD.WaveBthHfpSpeaker.szPname in the inf's [Strings] section
+ 0, NULL, // Interface properties
+ NULL, // Will be generated based on BTHHFP_SPEAKER_WAVE_NAME and made unique for each side band interface
+ BTHHFP_SPEAKER_WAVE_NAME, // template name matches with KSNAME_WaveBthHfpSpeaker in the inf's [Strings] section
CreateMiniportWaveRTSYSVAD,
&BthHfpSpeakerWaveMiniportFilterDescriptor,
- 0, NULL, // Interface properties
+ 0, NULL, // Interface properties
1,
BthHfpSpeakerPinDeviceFormatsAndModes,
SIZEOF_ARRAY(BthHfpSpeakerPinDeviceFormatsAndModes),
BthHfpSpeakerTopologyPhysicalConnections,
SIZEOF_ARRAY(BthHfpSpeakerTopologyPhysicalConnections),
- ENDPOINT_OFFLOAD_SUPPORTED
+ ENDPOINT_NO_FLAGS
};
static
ENDPOINT_MINIPAIR BthHfpSpeakerWBMiniports =
{
eBthHfpSpeakerDevice,
- L"TopologyBthHfpSpeaker", // make sure this name matches with SYSVAD.TopologyBthHfpSpeaker.szPname in the inf's [Strings] section
+ NULL, // Will be generated based on BTHHFP_SPEAKER_TOPO_NAME and made unique for each side band interface
+ BTHHFP_SPEAKER_TOPO_NAME, // Template name that matches with KSNAME_TopologyBthHfpSpeaker in the inf's [Strings] section
CreateMiniportTopologySYSVAD,
&BthHfpSpeakerTopoMiniportFilterDescriptor,
- 0, NULL, // Interface properties
- L"WaveBthHfpSpeaker", // make sure this name matches with SYSVAD.WaveBthHfpSpeaker.szPname in the inf's [Strings] section
+ 0, NULL, // Interface properties
+ NULL, // Will be generated based on BTHHFP_SPEAKER_WAVE_NAME and made unique for each side band interface
+ BTHHFP_SPEAKER_WAVE_NAME, // Template name matches with KSNAME_WaveBthHfpSpeaker in the inf's [Strings] section
CreateMiniportWaveRTSYSVAD,
&BthHfpSpeakerWBWaveMiniportFilterDescriptor,
- 0, NULL, // Interface properties
+ 0, NULL, // Interface properties
1,
BthHfpSpeakerWBPinDeviceFormatsAndModes,
SIZEOF_ARRAY(BthHfpSpeakerWBPinDeviceFormatsAndModes),
BthHfpSpeakerTopologyPhysicalConnections,
SIZEOF_ARRAY(BthHfpSpeakerTopologyPhysicalConnections),
- ENDPOINT_OFFLOAD_SUPPORTED
+ ENDPOINT_NO_FLAGS
};
//
@@ -133,8 +149,8 @@ static
PHYSICALCONNECTIONTABLE BthHfpMicTopologyPhysicalConnections[] =
{
{
- KSPIN_TOPO_BRIDGE, // TopologyOut
- KSPIN_WAVE_BRIDGE, // WaveIn
+ KSPIN_TOPO_BRIDGE, // TopologyOut
+ KSPIN_WAVE_BRIDGE, // WaveIn
CONNECTIONTYPE_TOPOLOGY_OUTPUT
}
};
@@ -143,14 +159,16 @@ static
ENDPOINT_MINIPAIR BthHfpMicMiniports =
{
eBthHfpMicDevice,
- L"TopologyBthHfpMic", // make sure this name matches with SYSVAD.TopologyBthHfpMic.szPname in the inf's [Strings] section
+ NULL, // Will be generated based on BTHHFP_MIC_TOPO_NAME and made unique for each side band interface
+ BTHHFP_MIC_TOPO_NAME, // template name matches with KSNAME_TopologyBthHfpMic in the inf's [Strings] section
CreateMiniportTopologySYSVAD,
&BthHfpMicTopoMiniportFilterDescriptor,
- 0, NULL, // Interface properties
- L"WaveBthHfpMic", // make sure this name matches with SYSVAD.WaveBthHfpMic.szPname in the inf's [Strings] section
+ 0, NULL, // Interface properties
+ NULL, // Will be generated based on BTHHFP_SPEAKER_WAVE_NAME and made unique for each side band interface
+ BTHHFP_MIC_WAVE_NAME, // template name matches with KSNAME_WaveBthHfpMic in the inf's [Strings] section
CreateMiniportWaveRTSYSVAD,
&BthHfpMicWaveMiniportFilterDescriptor,
- 0, NULL, // Interface properties
+ 0, NULL, // Interface properties
1,
BthHfpMicPinDeviceFormatsAndModes,
SIZEOF_ARRAY(BthHfpMicPinDeviceFormatsAndModes),
@@ -163,14 +181,16 @@ static
ENDPOINT_MINIPAIR BthHfpMicWBMiniports =
{
eBthHfpMicDevice,
- L"TopologyBthHfpMic", // make sure this name matches with SYSVAD.TopologyBthHfpMic.szPname in the inf's [Strings] section
+ NULL, // Will be generated based on BTHHFP_MIC_TOPO_NAME and made unique for each side band interface
+ BTHHFP_MIC_TOPO_NAME, // template name matches with KSNAME_TopologyBthHfpMic in the inf's [Strings] section
CreateMiniportTopologySYSVAD,
&BthHfpMicTopoMiniportFilterDescriptor,
- 0, NULL, // Interface properties
- L"WaveBthHfpMic", // make sure this name matches with SYSVAD.WaveBthHfpMic.szPname in the inf's [Strings] section
+ 0, NULL, // Interface properties
+ NULL, // Will be generated based on BTHHFP_SPEAKER_WAVE_NAME and made unique for each side band interface
+ BTHHFP_MIC_WAVE_NAME, // template name matches with KSNAME_WaveBthHfpMic in the inf's [Strings] section
CreateMiniportWaveRTSYSVAD,
&BthHfpMicWBWaveMiniportFilterDescriptor,
- 0, NULL, // Interface properties
+ 0, NULL, // Interface properties
1,
BthHfpMicWBPinDeviceFormatsAndModes,
SIZEOF_ARRAY(BthHfpMicWBPinDeviceFormatsAndModes),
@@ -215,10 +235,14 @@ C_ASSERT(g_cBthHfpCaptureEndpoints == 2);
//
// Total miniports = # endpoints * 2 (topology + wave) / 2 (since we have one each for narrowband-only and wideband)
//
-#define g_MaxBthHfpMiniports ((g_cBthHfpRenderEndpoints + g_cBthHfpCaptureEndpoints))
+//
+// Allow 10 Bluetooth hands-free profile devices.
+//
+#define MAX_BTHHFP_DEVICES (10)
+#define g_MaxBthHfpMiniports ((g_cBthHfpRenderEndpoints + g_cBthHfpCaptureEndpoints) * MAX_BTHHFP_DEVICES)
// g_MaxBthHfpMiniports is used when calculating the MaxObjects inside AddDevice.
-C_ASSERT(g_MaxBthHfpMiniports == 4);
+C_ASSERT(g_MaxBthHfpMiniports == 40);
#endif // _SYSVAD_BTHHFPMINIPAIRS_H_
diff --git a/audio/sysvad/EndpointsCommon/bthhfpminwavert.cpp b/audio/sysvad/EndpointsCommon/bthhfpminwavert.cpp
index 77f12e41..db705a68 100644
--- a/audio/sysvad/EndpointsCommon/bthhfpminwavert.cpp
+++ b/audio/sysvad/EndpointsCommon/bthhfpminwavert.cpp
@@ -92,18 +92,18 @@ Return Value:
}
else if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET)
{
- ASSERT(m_BthHfpDevice != NULL);
+ ASSERT(m_pSidebandDevice != NULL);
//
- // bHfpNrecPresent is set to TRUE when the HF (remote device) handles NR + EC.
+ // bSidebandNrecPresent is set to TRUE when the HF (remote device) handles NR + EC.
// Note that GetNRECDisableStatus() returns TRUE if the HF notified the AG to disable
// the NR + EC locally.
//
- BOOL bHfpNrecPresent = m_BthHfpDevice->IsNRECSupported() && m_BthHfpDevice->GetNRECDisableStatus();
+ BOOL bSidebandNrecPresent = m_pSidebandDevice->IsNRECSupported() && m_pSidebandDevice->GetNRECDisableStatus();
// If it is HFP render pin (data flow in) or if the NR-EC is not supported,
// return size 0 effect list
- if (IsSystemRenderPin(nPinId) || !bHfpNrecPresent)
+ if (IsSystemRenderPin(nPinId) || !bSidebandNrecPresent)
{
PropertyRequest->ValueSize = 0;
ntStatus = STATUS_SUCCESS;
@@ -182,6 +182,13 @@ Return Value:
case KSPROPERTY_PIN_PROPOSEDATAFORMAT:
ntStatus = waveRt->PropertyHandlerProposedFormat(PropertyRequest);
break;
+
+ case KSPROPERTY_PIN_PROPOSEDATAFORMAT2:
+ ntStatus = waveRt->PropertyHandlerProposedFormat2(PropertyRequest);
+ break;
+
+ default:
+ DPF(D_TERSE, ("[PropertyHandler_BthHfpWaveFilter: Invalid Device Request]"));
}
}
else if (IsEqualGUIDAligned(*PropertyRequest->PropertyItem->Set, KSPROPSETID_AudioEffectsDiscovery))
@@ -191,6 +198,9 @@ Return Value:
case KSPROPERTY_AUDIOEFFECTSDISCOVERY_EFFECTSLIST:
ntStatus = waveRt->PropertyHandler_BthHfpAudioEffectsDiscoveryEffectsList(PropertyRequest);
break;
+
+ default:
+ DPF(D_TERSE, ("[PropertyHandler_BthHfpWaveFilter: Invalid Device Request]"));
}
}
@@ -204,3 +214,4 @@ Return Value:
+
diff --git a/audio/sysvad/EndpointsCommon/bthhfpspeakertopo.cpp b/audio/sysvad/EndpointsCommon/bthhfpspeakertopo.cpp
index 8697d973..5672b342 100644
--- a/audio/sysvad/EndpointsCommon/bthhfpspeakertopo.cpp
+++ b/audio/sysvad/EndpointsCommon/bthhfpspeakertopo.cpp
@@ -136,13 +136,13 @@ Return Value:
NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;
PCMiniportTopology miniport = (PCMiniportTopology)PropertyRequest->MajorTarget;
- PBTHHFPDEVICECOMMON bthHfpDevice = NULL;
+ PSIDEBANDDEVICECOMMON bthHfpDevice = NULL;
ULONG channel = (ULONG)-1;
- bthHfpDevice = miniport->GetBthHfpDevice(); // weak ref.
+ bthHfpDevice = miniport->GetSidebandDevice(); // weak ref.
ASSERT(bthHfpDevice != NULL);
- if (bthHfpDevice->IsVolumeSupported() == FALSE)
+ if (bthHfpDevice->IsVolumeSupported(miniport->m_DeviceType) == FALSE)
{
ntStatus = miniport->PropertyHandlerGeneric(PropertyRequest);
}
@@ -174,14 +174,11 @@ Return Value:
if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET)
{
- *volume = bthHfpDevice->GetSpeakerVolume();
-
- ntStatus = STATUS_SUCCESS;
-
+ ntStatus = bthHfpDevice->GetVolume(eBthHfpSpeakerDevice, channel, volume);
}
else if (PropertyRequest->Verb & KSPROPERTY_TYPE_SET)
{
- ntStatus = bthHfpDevice->SetSpeakerVolume(*volume);
+ ntStatus = bthHfpDevice->SetVolume(eBthHfpSpeakerDevice, *volume, channel);
}
}
}
@@ -279,3 +276,4 @@ PropertyHandler_BthHfpSpeakerTopoFilterEvent
#endif // SYSVAD_BTH_BYPASS
+
diff --git a/audio/sysvad/EndpointsCommon/bthhfpspeakertoptable.h b/audio/sysvad/EndpointsCommon/bthhfpspeakertoptable.h
index 48b66f03..14519878 100644
--- a/audio/sysvad/EndpointsCommon/bthhfpspeakertoptable.h
+++ b/audio/sysvad/EndpointsCommon/bthhfpspeakertoptable.h
@@ -249,8 +249,8 @@ PCEVENT_ITEM BthHfpSpeakerPropertiesTopoFilterEvent[] =
};
DEFINE_PCAUTOMATION_TABLE_PROP_EVENT(AutomationBthHfpSpeakerTopoFilterWithEvent,
- BthHfpSpeakerPropertiesTopoFilter,
- BthHfpSpeakerPropertiesTopoFilterEvent);
+ BthHfpSpeakerPropertiesTopoFilter,
+ BthHfpSpeakerPropertiesTopoFilterEvent);
//=============================================================================
static
diff --git a/audio/sysvad/EndpointsCommon/bthhfpspeakerwavtable.h b/audio/sysvad/EndpointsCommon/bthhfpspeakerwavtable.h
index 68f23205..855d6268 100644
--- a/audio/sysvad/EndpointsCommon/bthhfpspeakerwavtable.h
+++ b/audio/sysvad/EndpointsCommon/bthhfpspeakerwavtable.h
@@ -22,88 +22,13 @@ NTSTATUS PropertyHandler_BthHfpWaveFilter(_In_ PPCPROPERTY_REQUEST PropertyReque
-#define BTHHFPSPEAKER_DEVICE_MAX_CHANNELS 1 // Max Channels.
+#define BTHHFPSPEAKER_DEVICE_MAX_CHANNELS 1 // Max Channels.
-#define BTHHFPSPEAKER_HOST_MAX_CHANNELS 1 // Max Channels.
-#define BTHHFPSPEAKER_HOST_MIN_BITS_PER_SAMPLE 8 // Min Bits Per Sample
-#define BTHHFPSPEAKER_HOST_MAX_BITS_PER_SAMPLE 16 // Max Bits Per Sample
-#define BTHHFPSPEAKER_HOST_MIN_SAMPLE_RATE 8000 // Min Sample Rate
-#define BTHHFPSPEAKER_HOST_MAX_SAMPLE_RATE 8000 // Max Sample Rate
-
-#define BTHHFPSPEAKER_OFFLOAD_MAX_CHANNELS 1 // Max Channels.
-#define BTHHFPSPEAKER_OFFLOAD_MIN_BITS_PER_SAMPLE 8 // Min Bits Per Sample
-#define BTHHFPSPEAKER_OFFLOAD_MAX_BITS_PER_SAMPLE 16 // Max Bits Per Sample
-#define BTHHFPSPEAKER_OFFLOAD_MIN_SAMPLE_RATE 8000 // Min Sample Rate
-#define BTHHFPSPEAKER_OFFLOAD_MAX_SAMPLE_RATE 8000 // Max Sample Rate
-
-#define BTHHFPSPEAKER_LOOPBACK_MAX_CHANNELS BTHHFPSPEAKER_HOST_MAX_CHANNELS // Must be equal to host pin's Max Channels.
-#define BTHHFPSPEAKER_LOOPBACK_MIN_BITS_PER_SAMPLE BTHHFPSPEAKER_HOST_MIN_BITS_PER_SAMPLE // Must be equal to host pin's Min Bits Per Sample
-#define BTHHFPSPEAKER_LOOPBACK_MAX_BITS_PER_SAMPLE BTHHFPSPEAKER_HOST_MAX_BITS_PER_SAMPLE // Must be equal to host pin's Max Bits Per Sample
-#define BTHHFPSPEAKER_LOOPBACK_MIN_SAMPLE_RATE BTHHFPSPEAKER_HOST_MIN_SAMPLE_RATE // Must be equal to host pin's Min Sample Rate
-#define BTHHFPSPEAKER_LOOPBACK_MAX_SAMPLE_RATE BTHHFPSPEAKER_HOST_MAX_SAMPLE_RATE // Must be equal to host pin's Max Sample Rate
-
-#define BTHHFPSPEAKER_DOLBY_DIGITAL_MAX_CHANNELS 1 // Max Channels.
-#define BTHHFPSPEAKER_DOLBY_DIGITAL_MIN_BITS_PER_SAMPLE 8 // Min Bits Per Sample
-#define BTHHFPSPEAKER_DOLBY_DIGITAL_MAX_BITS_PER_SAMPLE 16 // Max Bits Per Sample
-#define BTHHFPSPEAKER_DOLBY_DIGITAL_MIN_SAMPLE_RATE 8000 // Min Sample Rate
-#define BTHHFPSPEAKER_DOLBY_DIGITAL_MAX_SAMPLE_RATE 8000 // Max Sample Rate
-
-
-//=============================================================================
-static
-KSDATAFORMAT_WAVEFORMATEXTENSIBLE BthHfpSpeakerAudioEngineSupportedDeviceFormats[] =
-{
- { // 0
- {
- sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE),
- 0,
- 0,
- 0,
- STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
- STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM),
- STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
- },
- {
- {
- WAVE_FORMAT_EXTENSIBLE,
- 1,
- 8000,
- 8000,
- 1,
- 8,
- sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)
- },
- 8,
- KSAUDIO_SPEAKER_MONO,
- STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM)
- }
- },
- { // 1
- {
- sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE),
- 0,
- 0,
- 0,
- STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
- STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM),
- STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
- },
- {
- {
- WAVE_FORMAT_EXTENSIBLE,
- 1,
- 8000,
- 16000,
- 2,
- 16,
- sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)
- },
- 16,
- KSAUDIO_SPEAKER_MONO,
- STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM)
- }
- }
-};
+#define BTHHFPSPEAKER_HOST_MAX_CHANNELS 1 // Max Channels.
+#define BTHHFPSPEAKER_HOST_MIN_BITS_PER_SAMPLE 16 // Min Bits Per Sample
+#define BTHHFPSPEAKER_HOST_MAX_BITS_PER_SAMPLE 16 // Max Bits Per Sample
+#define BTHHFPSPEAKER_HOST_MIN_SAMPLE_RATE 8000 // Min Sample Rate
+#define BTHHFPSPEAKER_HOST_MAX_SAMPLE_RATE 8000 // Max Sample Rate
static
KSDATAFORMAT_WAVEFORMATEXTENSIBLE BthHfpSpeakerHostPinSupportedDeviceFormats[] =
@@ -123,86 +48,6 @@ KSDATAFORMAT_WAVEFORMATEXTENSIBLE BthHfpSpeakerHostPinSupportedDeviceFormats[] =
WAVE_FORMAT_EXTENSIBLE,
1,
8000,
- 8000,
- 1,
- 8,
- sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)
- },
- 8,
- KSAUDIO_SPEAKER_MONO,
- STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM)
- }
- },
- { // 1
- {
- sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE),
- 0,
- 0,
- 0,
- STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
- STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM),
- STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
- },
- {
- {
- WAVE_FORMAT_EXTENSIBLE,
- 1,
- 8000,
- 16000,
- 2,
- 16,
- sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)
- },
- 16,
- KSAUDIO_SPEAKER_MONO,
- STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM)
- }
- }
-};
-
-static
-KSDATAFORMAT_WAVEFORMATEXTENSIBLE BthHfpSpeakerOffloadPinSupportedDeviceFormats[] =
-{
- { // 0
- {
- sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE),
- 0,
- 0,
- 0,
- STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
- STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM),
- STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
- },
- {
- {
- WAVE_FORMAT_EXTENSIBLE,
- 1,
- 8000,
- 8000,
- 1,
- 8,
- sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)
- },
- 8,
- KSAUDIO_SPEAKER_MONO,
- STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM)
- }
- },
- { // 1
- {
- sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE),
- 0,
- 0,
- 0,
- STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
- STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM),
- STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
- },
- {
- {
- WAVE_FORMAT_EXTENSIBLE,
- 1,
- 8000,
16000,
2,
16,
@@ -227,15 +72,6 @@ MODE_AND_DEFAULT_FORMAT BthHfpSpeakerHostPinSupportedDeviceModes[] =
}
};
-static
-MODE_AND_DEFAULT_FORMAT BthHfpSpeakerOffloadPinSupportedDeviceModes[] =
-{
- {
- STATIC_AUDIO_SIGNALPROCESSINGMODE_RAW,
- &BthHfpSpeakerHostPinSupportedDeviceFormats[SIZEOF_ARRAY(BthHfpSpeakerHostPinSupportedDeviceFormats)-1].DataFormat
- }
-};
-
//
// The entries here must follow the same order as the filter's pin
// descriptor array.
@@ -251,32 +87,11 @@ PIN_DEVICE_FORMATS_AND_MODES BthHfpSpeakerPinDeviceFormatsAndModes[] =
SIZEOF_ARRAY(BthHfpSpeakerHostPinSupportedDeviceModes)
},
{
- OffloadRenderPin,
- BthHfpSpeakerOffloadPinSupportedDeviceFormats,
- SIZEOF_ARRAY(BthHfpSpeakerOffloadPinSupportedDeviceFormats),
- BthHfpSpeakerOffloadPinSupportedDeviceModes,
- SIZEOF_ARRAY(BthHfpSpeakerOffloadPinSupportedDeviceModes),
- },
- {
- RenderLoopbackPin,
- BthHfpSpeakerHostPinSupportedDeviceFormats, // Must support all the formats supported by host pin
- SIZEOF_ARRAY(BthHfpSpeakerHostPinSupportedDeviceFormats),
- NULL, // loopback doesn't support modes.
- 0
- },
- {
BridgePin,
NULL,
0,
NULL,
0
- },
- {
- NoPin, // For convenience, offload engine device formats appended here
- BthHfpSpeakerAudioEngineSupportedDeviceFormats,
- SIZEOF_ARRAY(BthHfpSpeakerAudioEngineSupportedDeviceFormats),
- NULL, // no modes for this entry.
- 0
}
};
@@ -299,38 +114,6 @@ KSDATARANGE_AUDIO BthHfpSpeakerPinDataRangesStream[] =
BTHHFPSPEAKER_HOST_MAX_BITS_PER_SAMPLE,
BTHHFPSPEAKER_HOST_MIN_SAMPLE_RATE,
BTHHFPSPEAKER_HOST_MAX_SAMPLE_RATE
- },
- { // 1
- {
- sizeof(KSDATARANGE_AUDIO),
- KSDATARANGE_ATTRIBUTES, // An attributes list follows this data range
- 0,
- 0,
- STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
- STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM),
- STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
- },
- BTHHFPSPEAKER_OFFLOAD_MAX_CHANNELS,
- BTHHFPSPEAKER_OFFLOAD_MIN_BITS_PER_SAMPLE,
- BTHHFPSPEAKER_OFFLOAD_MAX_BITS_PER_SAMPLE,
- BTHHFPSPEAKER_OFFLOAD_MIN_SAMPLE_RATE,
- BTHHFPSPEAKER_OFFLOAD_MAX_SAMPLE_RATE
- },
- { // 2
- {
- sizeof(KSDATARANGE_AUDIO),
- 0,
- 0,
- 0,
- STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
- STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM),
- STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
- },
- BTHHFPSPEAKER_LOOPBACK_MAX_CHANNELS,
- BTHHFPSPEAKER_LOOPBACK_MIN_BITS_PER_SAMPLE,
- BTHHFPSPEAKER_LOOPBACK_MAX_BITS_PER_SAMPLE,
- BTHHFPSPEAKER_LOOPBACK_MIN_SAMPLE_RATE,
- BTHHFPSPEAKER_LOOPBACK_MAX_SAMPLE_RATE
}
};
@@ -341,19 +124,6 @@ PKSDATARANGE BthHfpSpeakerPinDataRangePointersStream[] =
PKSDATARANGE(&PinDataRangeAttributeList)
};
-static
-PKSDATARANGE BthHfpSpeakerPinDataRangePointersOffloadStream[] =
-{
- PKSDATARANGE(&BthHfpSpeakerPinDataRangesStream[1]),
- PKSDATARANGE(&PinDataRangeAttributeList)
-};
-
-static
-PKSDATARANGE BthHfpSpeakerPinDataRangePointersLoopbackStream[] =
-{
- PKSDATARANGE(&BthHfpSpeakerPinDataRangesStream[2])
-};
-
//=============================================================================
static
KSDATARANGE BthHfpSpeakerPinDataRangesBridge[] =
@@ -376,27 +146,6 @@ PKSDATARANGE BthHfpSpeakerPinDataRangePointersBridge[] =
};
//=============================================================================
-
-static
-PCPROPERTY_ITEM PropertiesBthHfpSpeakerOffloadPin[] =
-{
- {
- &KSPROPSETID_OffloadPin, // define new property set
- KSPROPERTY_OFFLOAD_PIN_GET_STREAM_OBJECT_POINTER, // define properties
- KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_BASICSUPPORT,
- PropertyHandler_OffloadPin
- },
- {
- &KSPROPSETID_OffloadPin, // define new property set
- KSPROPERTY_OFFLOAD_PIN_VERIFY_STREAM_OBJECT_POINTER, // define properties
- KSPROPERTY_TYPE_SET | KSPROPERTY_TYPE_BASICSUPPORT,
- PropertyHandler_OffloadPin
- }
-};
-
-DEFINE_PCAUTOMATION_TABLE_PROP(AutomationBthHfpSpeakerOffloadPin, PropertiesBthHfpSpeakerOffloadPin);
-
-//=============================================================================
static
PCPIN_DESCRIPTOR BthHfpSpeakerWaveMiniportPins[] =
{
@@ -420,46 +169,6 @@ PCPIN_DESCRIPTOR BthHfpSpeakerWaveMiniportPins[] =
0
}
},
- // Wave Out Streaming Pin (Renderer) KSPIN_WAVE_RENDER_SINK_OFFLOAD
- {
- MAX_INPUT_OFFLOAD_STREAMS,
- MAX_INPUT_OFFLOAD_STREAMS,
- 0,
- &AutomationBthHfpSpeakerOffloadPin, // AutomationTable
- {
- 0,
- NULL,
- 0,
- NULL,
- SIZEOF_ARRAY(BthHfpSpeakerPinDataRangePointersOffloadStream),
- BthHfpSpeakerPinDataRangePointersOffloadStream,
- KSPIN_DATAFLOW_IN,
- KSPIN_COMMUNICATION_SINK,
- &KSCATEGORY_AUDIO,
- NULL,
- 0
- }
- },
- // Wave Out Streaming Pin (Renderer) KSPIN_WAVE_RENDER_SINK_LOOPBACK
- {
- MAX_OUTPUT_LOOPBACK_STREAMS,
- MAX_OUTPUT_LOOPBACK_STREAMS,
- 0,
- NULL,
- {
- 0,
- NULL,
- 0,
- NULL,
- SIZEOF_ARRAY(BthHfpSpeakerPinDataRangePointersLoopbackStream),
- BthHfpSpeakerPinDataRangePointersLoopbackStream,
- KSPIN_DATAFLOW_OUT,
- KSPIN_COMMUNICATION_SINK,
- &KSNODETYPE_AUDIO_LOOPBACK,
- NULL,
- 0
- }
- },
// Wave Out Bridge Pin (Renderer) KSPIN_WAVE_RENDER_SOURCE
{
0,
@@ -486,30 +195,21 @@ PCPIN_DESCRIPTOR BthHfpSpeakerWaveMiniportPins[] =
static
PCNODE_DESCRIPTOR BthHfpSpeakerWaveMiniportNodes[] =
{
- // KSNODE_WAVE_AUDIO_ENGINE
+ // KSNODE_WAVE_DAC
{
0, // Flags
NULL, // AutomationTable
- &KSNODETYPE_AUDIO_ENGINE, // Type KSNODETYPE_AUDIO_ENGINE
+ &KSNODETYPE_DAC, // Type KSNODETYPE_DAC
NULL // Name
}
};
+
//=============================================================================
-//
-// ----------------------------
-// | |
-// System Pin 0-->| |--> 2 Loopback Pin
-// | HW Audio Engine node |
-// Offload Pin 1-->| |--> 3 KSPIN_WAVE_RENDER_SOURCE
-// | |
-// ----------------------------
static
PCCONNECTION_DESCRIPTOR BthHfpSpeakerWaveMiniportConnections[] =
{
- { PCFILTER_NODE, KSPIN_WAVE_RENDER_SINK_SYSTEM, KSNODE_WAVE_AUDIO_ENGINE, 1 },
- { PCFILTER_NODE, KSPIN_WAVE_RENDER_SINK_OFFLOAD, KSNODE_WAVE_AUDIO_ENGINE, 2 },
- { KSNODE_WAVE_AUDIO_ENGINE, 3, PCFILTER_NODE, KSPIN_WAVE_RENDER_SINK_LOOPBACK },
- { KSNODE_WAVE_AUDIO_ENGINE, 0, PCFILTER_NODE, KSPIN_WAVE_RENDER_SOURCE },
+ { PCFILTER_NODE, KSPIN_WAVE_RENDER3_SINK_SYSTEM, KSNODE_WAVE_DAC, 1 },
+ { KSNODE_WAVE_DAC, 0, PCFILTER_NODE, KSPIN_WAVE_RENDER3_SOURCE },
};
//=============================================================================
@@ -519,7 +219,13 @@ PCPROPERTY_ITEM PropertiesBthHfpSpeakerWaveFilter[] =
{
&KSPROPSETID_Pin,
KSPROPERTY_PIN_PROPOSEDATAFORMAT,
- KSPROPERTY_TYPE_SET | KSPROPERTY_TYPE_BASICSUPPORT,
+ KSPROPERTY_TYPE_SET | KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_BASICSUPPORT,
+ PropertyHandler_BthHfpWaveFilter
+ },
+ {
+ &KSPROPSETID_Pin,
+ KSPROPERTY_PIN_PROPOSEDATAFORMAT2,
+ KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_BASICSUPPORT,
PropertyHandler_BthHfpWaveFilter
},
{
@@ -530,7 +236,21 @@ PCPROPERTY_ITEM PropertiesBthHfpSpeakerWaveFilter[] =
}
};
-DEFINE_PCAUTOMATION_TABLE_PROP(AutomationBthHfpSpeakerWaveFilter, PropertiesBthHfpSpeakerWaveFilter);
+NTSTATUS CMiniportWaveRT_EventHandler_PinCapsChange(
+ _In_ PPCEVENT_REQUEST EventRequest
+ );
+
+static PCEVENT_ITEM BthHfpSpeakerFormatChangePinEvent[] = {
+ {
+ &KSEVENTSETID_PinCapsChange,
+ KSEVENT_PINCAPS_FORMATCHANGE,
+ KSEVENT_TYPE_ENABLE | KSEVENT_TYPE_BASICSUPPORT,
+ CMiniportWaveRT_EventHandler_PinCapsChange
+ }
+};
+
+DEFINE_PCAUTOMATION_TABLE_PROP_EVENT(AutomationBthHfpSpeakerWaveFilter, PropertiesBthHfpSpeakerWaveFilter, BthHfpSpeakerFormatChangePinEvent);
+
//=============================================================================
static
diff --git a/audio/sysvad/EndpointsCommon/bthhfpspeakerwbwavtable.h b/audio/sysvad/EndpointsCommon/bthhfpspeakerwbwavtable.h
index acff7c43..9c91f84d 100644
--- a/audio/sysvad/EndpointsCommon/bthhfpspeakerwbwavtable.h
+++ b/audio/sysvad/EndpointsCommon/bthhfpspeakerwbwavtable.h
@@ -26,137 +26,13 @@ NTSTATUS PropertyHandler_BthHfpWaveFilter(_In_ PPCPROPERTY_REQUEST PropertyReque
#define BTHHFPSPEAKERWB_DEVICE_MAX_CHANNELS 1 // Max Channels.
#define BTHHFPSPEAKERWB_HOST_MAX_CHANNELS 1 // Max Channels.
-#define BTHHFPSPEAKERWB_HOST_MIN_BITS_PER_SAMPLE 8 // Min Bits Per Sample
+#define BTHHFPSPEAKERWB_HOST_MIN_BITS_PER_SAMPLE 16 // Min Bits Per Sample
#define BTHHFPSPEAKERWB_HOST_MAX_BITS_PER_SAMPLE 16 // Max Bits Per Sample
-#define BTHHFPSPEAKERWB_HOST_MIN_SAMPLE_RATE 8000 // Min Sample Rate
+#define BTHHFPSPEAKERWB_HOST_MIN_SAMPLE_RATE 16000 // Min Sample Rate
#define BTHHFPSPEAKERWB_HOST_MAX_SAMPLE_RATE 16000 // Max Sample Rate
-#define BTHHFPSPEAKERWB_OFFLOAD_MAX_CHANNELS 1 // Max Channels.
-#define BTHHFPSPEAKERWB_OFFLOAD_MIN_BITS_PER_SAMPLE 8 // Min Bits Per Sample
-#define BTHHFPSPEAKERWB_OFFLOAD_MAX_BITS_PER_SAMPLE 16 // Max Bits Per Sample
-#define BTHHFPSPEAKERWB_OFFLOAD_MIN_SAMPLE_RATE 8000 // Min Sample Rate
-#define BTHHFPSPEAKERWB_OFFLOAD_MAX_SAMPLE_RATE 16000 // Max Sample Rate
-
-#define BTHHFPSPEAKERWB_LOOPBACK_MAX_CHANNELS BTHHFPSPEAKERWB_HOST_MAX_CHANNELS // Must be equal to host pin's Max Channels.
-#define BTHHFPSPEAKERWB_LOOPBACK_MIN_BITS_PER_SAMPLE BTHHFPSPEAKERWB_HOST_MIN_BITS_PER_SAMPLE // Must be equal to host pin's Min Bits Per Sample
-#define BTHHFPSPEAKERWB_LOOPBACK_MAX_BITS_PER_SAMPLE BTHHFPSPEAKERWB_HOST_MAX_BITS_PER_SAMPLE // Must be equal to host pin's Max Bits Per Sample
-#define BTHHFPSPEAKERWB_LOOPBACK_MIN_SAMPLE_RATE BTHHFPSPEAKERWB_HOST_MIN_SAMPLE_RATE // Must be equal to host pin's Min Sample Rate
-#define BTHHFPSPEAKERWB_LOOPBACK_MAX_SAMPLE_RATE BTHHFPSPEAKERWB_HOST_MAX_SAMPLE_RATE // Must be equal to host pin's Max Sample Rate
-
-#define BTHHFPSPEAKERWB_DOLBY_DIGITAL_MAX_CHANNELS 1 // Max Channels.
-#define BTHHFPSPEAKERWB_DOLBY_DIGITAL_MIN_BITS_PER_SAMPLE 8 // Min Bits Per Sample
-#define BTHHFPSPEAKERWB_DOLBY_DIGITAL_MAX_BITS_PER_SAMPLE 16 // Max Bits Per Sample
-#define BTHHFPSPEAKERWB_DOLBY_DIGITAL_MIN_SAMPLE_RATE 8000 // Min Sample Rate
-#define BTHHFPSPEAKERWB_DOLBY_DIGITAL_MAX_SAMPLE_RATE 16000 // Max Sample Rate
-
-
//=============================================================================
static
-KSDATAFORMAT_WAVEFORMATEXTENSIBLE BthHfpSpeakerWBAudioEngineSupportedDeviceFormats[] =
-{
- { // 0
- {
- sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE),
- 0,
- 0,
- 0,
- STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
- STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM),
- STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
- },
- {
- {
- WAVE_FORMAT_EXTENSIBLE,
- 1,
- 8000,
- 8000,
- 1,
- 8,
- sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)
- },
- 8,
- KSAUDIO_SPEAKER_MONO,
- STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM)
- }
- },
- { // 1
- {
- sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE),
- 0,
- 0,
- 0,
- STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
- STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM),
- STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
- },
- {
- {
- WAVE_FORMAT_EXTENSIBLE,
- 1,
- 8000,
- 16000,
- 2,
- 16,
- sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)
- },
- 16,
- KSAUDIO_SPEAKER_MONO,
- STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM)
- }
- },
- { // 2
- {
- sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE),
- 0,
- 0,
- 0,
- STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
- STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM),
- STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
- },
- {
- {
- WAVE_FORMAT_EXTENSIBLE,
- 1,
- 16000,
- 16000,
- 1,
- 8,
- sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)
- },
- 8,
- KSAUDIO_SPEAKER_MONO,
- STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM)
- }
- },
- { // 3
- {
- sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE),
- 0,
- 0,
- 0,
- STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
- STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM),
- STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
- },
- {
- {
- WAVE_FORMAT_EXTENSIBLE,
- 1,
- 16000,
- 32000,
- 2,
- 16,
- sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)
- },
- 16,
- KSAUDIO_SPEAKER_MONO,
- STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM)
- }
- }
-};
-
-static
KSDATAFORMAT_WAVEFORMATEXTENSIBLE BthHfpSpeakerWBHostPinSupportedDeviceFormats[] =
{
{ // 0
@@ -173,186 +49,6 @@ KSDATAFORMAT_WAVEFORMATEXTENSIBLE BthHfpSpeakerWBHostPinSupportedDeviceFormats[]
{
WAVE_FORMAT_EXTENSIBLE,
1,
- 8000,
- 8000,
- 1,
- 8,
- sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)
- },
- 8,
- KSAUDIO_SPEAKER_MONO,
- STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM)
- }
- },
- { // 1
- {
- sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE),
- 0,
- 0,
- 0,
- STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
- STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM),
- STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
- },
- {
- {
- WAVE_FORMAT_EXTENSIBLE,
- 1,
- 8000,
- 16000,
- 2,
- 16,
- sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)
- },
- 16,
- KSAUDIO_SPEAKER_MONO,
- STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM)
- }
- },
- { // 2
- {
- sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE),
- 0,
- 0,
- 0,
- STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
- STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM),
- STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
- },
- {
- {
- WAVE_FORMAT_EXTENSIBLE,
- 1,
- 16000,
- 16000,
- 1,
- 8,
- sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)
- },
- 8,
- KSAUDIO_SPEAKER_MONO,
- STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM)
- }
- },
- { // 3
- {
- sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE),
- 0,
- 0,
- 0,
- STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
- STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM),
- STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
- },
- {
- {
- WAVE_FORMAT_EXTENSIBLE,
- 1,
- 16000,
- 32000,
- 2,
- 16,
- sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)
- },
- 16,
- KSAUDIO_SPEAKER_MONO,
- STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM)
- }
- }
-};
-
-static
-KSDATAFORMAT_WAVEFORMATEXTENSIBLE BthHfpSpeakerWBOffloadPinSupportedDeviceFormats[] =
-{
- { // 0
- {
- sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE),
- 0,
- 0,
- 0,
- STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
- STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM),
- STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
- },
- {
- {
- WAVE_FORMAT_EXTENSIBLE,
- 1,
- 8000,
- 8000,
- 1,
- 8,
- sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)
- },
- 8,
- KSAUDIO_SPEAKER_MONO,
- STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM)
- }
- },
- { // 1
- {
- sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE),
- 0,
- 0,
- 0,
- STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
- STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM),
- STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
- },
- {
- {
- WAVE_FORMAT_EXTENSIBLE,
- 1,
- 8000,
- 16000,
- 2,
- 16,
- sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)
- },
- 16,
- KSAUDIO_SPEAKER_MONO,
- STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM)
- }
- },
- { // 2
- {
- sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE),
- 0,
- 0,
- 0,
- STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
- STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM),
- STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
- },
- {
- {
- WAVE_FORMAT_EXTENSIBLE,
- 1,
- 16000,
- 16000,
- 1,
- 8,
- sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)
- },
- 8,
- KSAUDIO_SPEAKER_MONO,
- STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM)
- }
- },
- { // 3
- {
- sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE),
- 0,
- 0,
- 0,
- STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
- STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM),
- STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
- },
- {
- {
- WAVE_FORMAT_EXTENSIBLE,
- 1,
16000,
32000,
2,
@@ -378,15 +74,6 @@ MODE_AND_DEFAULT_FORMAT BthHfpSpeakerWBHostPinSupportedDeviceModes[] =
}
};
-static
-MODE_AND_DEFAULT_FORMAT BthHfpSpeakerWBOffloadPinSupportedDeviceModes[] =
-{
- {
- STATIC_AUDIO_SIGNALPROCESSINGMODE_RAW,
- &BthHfpSpeakerWBHostPinSupportedDeviceFormats[SIZEOF_ARRAY(BthHfpSpeakerWBHostPinSupportedDeviceFormats)-1].DataFormat
- }
-};
-
//
// The entries here must follow the same order as the filter's pin
// descriptor array.
@@ -402,32 +89,11 @@ PIN_DEVICE_FORMATS_AND_MODES BthHfpSpeakerWBPinDeviceFormatsAndModes[] =
SIZEOF_ARRAY(BthHfpSpeakerWBHostPinSupportedDeviceModes)
},
{
- OffloadRenderPin,
- BthHfpSpeakerWBOffloadPinSupportedDeviceFormats,
- SIZEOF_ARRAY(BthHfpSpeakerWBOffloadPinSupportedDeviceFormats),
- BthHfpSpeakerWBOffloadPinSupportedDeviceModes,
- SIZEOF_ARRAY(BthHfpSpeakerWBOffloadPinSupportedDeviceModes),
- },
- {
- RenderLoopbackPin,
- BthHfpSpeakerWBHostPinSupportedDeviceFormats, // Must support all the formats supported by host pin
- SIZEOF_ARRAY(BthHfpSpeakerWBHostPinSupportedDeviceFormats),
- NULL, // loopback doesn't support modes.
- 0
- },
- {
BridgePin,
NULL,
0,
NULL,
0
- },
- {
- NoPin, // For convenience, offload engine device formats appended here
- BthHfpSpeakerWBAudioEngineSupportedDeviceFormats,
- SIZEOF_ARRAY(BthHfpSpeakerWBAudioEngineSupportedDeviceFormats),
- NULL, // no modes for this entry.
- 0
}
};
@@ -445,91 +111,11 @@ KSDATARANGE_AUDIO BthHfpSpeakerWBPinDataRangesStream[] =
STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM),
STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
},
- BTHHFPSPEAKERWB_HOST_MAX_CHANNELS,
- BTHHFPSPEAKERWB_HOST_MIN_BITS_PER_SAMPLE,
- BTHHFPSPEAKERWB_HOST_MAX_BITS_PER_SAMPLE,
- BTHHFPSPEAKERWB_HOST_MIN_SAMPLE_RATE,
- BTHHFPSPEAKERWB_HOST_MIN_SAMPLE_RATE
- },
- { // 1
- {
- sizeof(KSDATARANGE_AUDIO),
- KSDATARANGE_ATTRIBUTES, // An attributes list follows this data range
- 0,
- 0,
- STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
- STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM),
- STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
- },
BTHHFPSPEAKERWB_HOST_MAX_CHANNELS,
BTHHFPSPEAKERWB_HOST_MIN_BITS_PER_SAMPLE,
BTHHFPSPEAKERWB_HOST_MAX_BITS_PER_SAMPLE,
BTHHFPSPEAKERWB_HOST_MAX_SAMPLE_RATE,
BTHHFPSPEAKERWB_HOST_MAX_SAMPLE_RATE
- },
- { // 2
- {
- sizeof(KSDATARANGE_AUDIO),
- KSDATARANGE_ATTRIBUTES, // An attributes list follows this data range
- 0,
- 0,
- STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
- STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM),
- STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
- },
- BTHHFPSPEAKERWB_OFFLOAD_MAX_CHANNELS,
- BTHHFPSPEAKERWB_OFFLOAD_MIN_BITS_PER_SAMPLE,
- BTHHFPSPEAKERWB_OFFLOAD_MAX_BITS_PER_SAMPLE,
- BTHHFPSPEAKERWB_OFFLOAD_MIN_SAMPLE_RATE,
- BTHHFPSPEAKERWB_OFFLOAD_MIN_SAMPLE_RATE
- },
- { // 3
- {
- sizeof(KSDATARANGE_AUDIO),
- KSDATARANGE_ATTRIBUTES, // An attributes list follows this data range
- 0,
- 0,
- STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
- STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM),
- STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
- },
- BTHHFPSPEAKERWB_OFFLOAD_MAX_CHANNELS,
- BTHHFPSPEAKERWB_OFFLOAD_MIN_BITS_PER_SAMPLE,
- BTHHFPSPEAKERWB_OFFLOAD_MAX_BITS_PER_SAMPLE,
- BTHHFPSPEAKERWB_OFFLOAD_MAX_SAMPLE_RATE,
- BTHHFPSPEAKERWB_OFFLOAD_MAX_SAMPLE_RATE
- },
- { // 4
- {
- sizeof(KSDATARANGE_AUDIO),
- 0,
- 0,
- 0,
- STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
- STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM),
- STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
- },
- BTHHFPSPEAKERWB_LOOPBACK_MAX_CHANNELS,
- BTHHFPSPEAKERWB_LOOPBACK_MIN_BITS_PER_SAMPLE,
- BTHHFPSPEAKERWB_LOOPBACK_MAX_BITS_PER_SAMPLE,
- BTHHFPSPEAKERWB_LOOPBACK_MIN_SAMPLE_RATE,
- BTHHFPSPEAKERWB_LOOPBACK_MIN_SAMPLE_RATE
- },
- { // 5
- {
- sizeof(KSDATARANGE_AUDIO),
- 0,
- 0,
- 0,
- STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
- STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM),
- STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
- },
- BTHHFPSPEAKERWB_LOOPBACK_MAX_CHANNELS,
- BTHHFPSPEAKERWB_LOOPBACK_MIN_BITS_PER_SAMPLE,
- BTHHFPSPEAKERWB_LOOPBACK_MAX_BITS_PER_SAMPLE,
- BTHHFPSPEAKERWB_LOOPBACK_MAX_SAMPLE_RATE,
- BTHHFPSPEAKERWB_LOOPBACK_MAX_SAMPLE_RATE
}
};
@@ -537,27 +123,9 @@ static
PKSDATARANGE BthHfpSpeakerWBPinDataRangePointersStream[] =
{
PKSDATARANGE(&BthHfpSpeakerWBPinDataRangesStream[0]),
- PKSDATARANGE(&PinDataRangeAttributeList),
- PKSDATARANGE(&BthHfpSpeakerWBPinDataRangesStream[1]),
PKSDATARANGE(&PinDataRangeAttributeList)
};
-static
-PKSDATARANGE BthHfpSpeakerWBPinDataRangePointersOffloadStream[] =
-{
- PKSDATARANGE(&BthHfpSpeakerWBPinDataRangesStream[2]),
- PKSDATARANGE(&PinDataRangeAttributeList),
- PKSDATARANGE(&BthHfpSpeakerWBPinDataRangesStream[3]),
- PKSDATARANGE(&PinDataRangeAttributeList)
-};
-
-static
-PKSDATARANGE BthHfpSpeakerWBPinDataRangePointersLoopbackStream[] =
-{
- PKSDATARANGE(&BthHfpSpeakerWBPinDataRangesStream[4]),
- PKSDATARANGE(&BthHfpSpeakerWBPinDataRangesStream[5])
-};
-
//=============================================================================
static
KSDATARANGE BthHfpSpeakerWBPinDataRangesBridge[] =
@@ -580,27 +148,6 @@ PKSDATARANGE BthHfpSpeakerWBPinDataRangePointersBridge[] =
};
//=============================================================================
-
-static
-PCPROPERTY_ITEM PropertiesBthHfpSpeakerWBOffloadPin[] =
-{
- {
- &KSPROPSETID_OffloadPin, // define new property set
- KSPROPERTY_OFFLOAD_PIN_GET_STREAM_OBJECT_POINTER, // define properties
- KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_BASICSUPPORT,
- PropertyHandler_OffloadPin
- },
- {
- &KSPROPSETID_OffloadPin, // define new property set
- KSPROPERTY_OFFLOAD_PIN_VERIFY_STREAM_OBJECT_POINTER, // define properties
- KSPROPERTY_TYPE_SET | KSPROPERTY_TYPE_BASICSUPPORT,
- PropertyHandler_OffloadPin
- }
-};
-
-DEFINE_PCAUTOMATION_TABLE_PROP(AutomationBthHfpSpeakerWBOffloadPin, PropertiesBthHfpSpeakerWBOffloadPin);
-
-//=============================================================================
static
PCPIN_DESCRIPTOR BthHfpSpeakerWBWaveMiniportPins[] =
{
@@ -624,46 +171,6 @@ PCPIN_DESCRIPTOR BthHfpSpeakerWBWaveMiniportPins[] =
0
}
},
- // Wave Out Streaming Pin (Renderer) KSPIN_WAVE_RENDER_SINK_OFFLOAD
- {
- MAX_INPUT_OFFLOAD_STREAMS,
- MAX_INPUT_OFFLOAD_STREAMS,
- 0,
- &AutomationBthHfpSpeakerWBOffloadPin, // AutomationTable
- {
- 0,
- NULL,
- 0,
- NULL,
- SIZEOF_ARRAY(BthHfpSpeakerWBPinDataRangePointersOffloadStream),
- BthHfpSpeakerWBPinDataRangePointersOffloadStream,
- KSPIN_DATAFLOW_IN,
- KSPIN_COMMUNICATION_SINK,
- &KSCATEGORY_AUDIO,
- NULL,
- 0
- }
- },
- // Wave Out Streaming Pin (Renderer) KSPIN_WAVE_RENDER_SINK_LOOPBACK
- {
- MAX_OUTPUT_LOOPBACK_STREAMS,
- MAX_OUTPUT_LOOPBACK_STREAMS,
- 0,
- NULL,
- {
- 0,
- NULL,
- 0,
- NULL,
- SIZEOF_ARRAY(BthHfpSpeakerWBPinDataRangePointersLoopbackStream),
- BthHfpSpeakerWBPinDataRangePointersLoopbackStream,
- KSPIN_DATAFLOW_OUT,
- KSPIN_COMMUNICATION_SINK,
- &KSNODETYPE_AUDIO_LOOPBACK,
- NULL,
- 0
- }
- },
// Wave Out Bridge Pin (Renderer) KSPIN_WAVE_RENDER_SOURCE
{
0,
@@ -689,30 +196,21 @@ PCPIN_DESCRIPTOR BthHfpSpeakerWBWaveMiniportPins[] =
static
PCNODE_DESCRIPTOR BthHfpSpeakerWBWaveMiniportNodes[] =
{
- // KSNODE_WAVE_AUDIO_ENGINE
+ // KSNODE_WAVE_DAC
{
0, // Flags
NULL, // AutomationTable
- &KSNODETYPE_AUDIO_ENGINE, // Type KSNODETYPE_AUDIO_ENGINE
+ &KSNODETYPE_DAC, // Type KSNODETYPE_DAC
NULL // Name
}
};
+
//=============================================================================
-//
-// ----------------------------
-// | |
-// System Pin 0-->| |--> 2 Loopback Pin
-// | HW Audio Engine node |
-// Offload Pin 1-->| |--> 3 KSPIN_WAVE_RENDER_SOURCE
-// | |
-// ----------------------------
static
PCCONNECTION_DESCRIPTOR BthHfpSpeakerWBWaveMiniportConnections[] =
{
- { PCFILTER_NODE, KSPIN_WAVE_RENDER_SINK_SYSTEM, KSNODE_WAVE_AUDIO_ENGINE, 1 },
- { PCFILTER_NODE, KSPIN_WAVE_RENDER_SINK_OFFLOAD, KSNODE_WAVE_AUDIO_ENGINE, 2 },
- { KSNODE_WAVE_AUDIO_ENGINE, 3, PCFILTER_NODE, KSPIN_WAVE_RENDER_SINK_LOOPBACK },
- { KSNODE_WAVE_AUDIO_ENGINE, 0, PCFILTER_NODE, KSPIN_WAVE_RENDER_SOURCE },
+ { PCFILTER_NODE, KSPIN_WAVE_RENDER3_SINK_SYSTEM, KSNODE_WAVE_DAC, 1 },
+ { KSNODE_WAVE_DAC, 0, PCFILTER_NODE, KSPIN_WAVE_RENDER3_SOURCE },
};
//=============================================================================
@@ -726,6 +224,12 @@ PCPROPERTY_ITEM PropertiesBthHfpSpeakerWBWaveFilter[] =
PropertyHandler_BthHfpWaveFilter
},
{
+ &KSPROPSETID_Pin,
+ KSPROPERTY_PIN_PROPOSEDATAFORMAT2,
+ KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_BASICSUPPORT,
+ PropertyHandler_BthHfpWaveFilter
+ },
+ {
&KSPROPSETID_AudioEffectsDiscovery,
KSPROPERTY_AUDIOEFFECTSDISCOVERY_EFFECTSLIST,
KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_BASICSUPPORT,
diff --git a/audio/sysvad/EndpointsCommon/bthhfptopo.cpp b/audio/sysvad/EndpointsCommon/bthhfptopo.cpp
index 6847dc05..27d8410f 100644
--- a/audio/sysvad/EndpointsCommon/bthhfptopo.cpp
+++ b/audio/sysvad/EndpointsCommon/bthhfptopo.cpp
@@ -11,7 +11,7 @@ Abstract:
Implementation of topology miniport for the Bluetooth Hands-Free Profile (external).
--*/
-#ifdef SYSVAD_BTH_BYPASS
+ #ifdef SYSVAD_BTH_BYPASS
#pragma warning (disable : 4127)
@@ -20,17 +20,6 @@ Abstract:
#include "mintopo.h"
#include "bthhfptopo.h"
-typedef struct _BTHHFP_VOLUME_VALUES_BLOCK
-{
- KSPROPERTY_DESCRIPTION Description;
- KSPROPERTY_MEMBERSHEADER SteppingHeader;
- KSPROPERTY_STEPPING_LONG Stepping[1];
- KSPROPERTY_MEMBERSHEADER DefaultHeader;
- ULONG Default[1];
-
-} BTHHFP_VOLUME_VALUES_BLOCK, *PBTHHFP_VOLUME_VALUES_BLOCK;
-
-
//=============================================================================
#pragma code_seg("PAGE")
NTSTATUS
@@ -57,84 +46,50 @@ Return Value:
PAGED_CODE();
DPF_ENTER(("[PropertyHandler_BthHfpVolumeLevel_BasicSupport]"));
- NTSTATUS ntStatus = STATUS_SUCCESS;
+ NTSTATUS ntStatus = STATUS_SUCCESS;
+ ULONG cbDescriptionSize = sizeof(KSPROPERTY_DESCRIPTION);
ASSERT(PropertyRequest);
- if (PropertyRequest->ValueSize >= sizeof(KSPROPERTY_DESCRIPTION))
+ if (PropertyRequest->ValueSize >= cbDescriptionSize)
{
PCMiniportTopology miniport = (PCMiniportTopology)PropertyRequest->MajorTarget;
ULONG volumeSettingsSize = 0;
PKSPROPERTY_VALUES volumeSettings;
PKSPROPERTY_DESCRIPTION propDesc;
- PBTHHFPDEVICECOMMON bthHfpDevice;
- ULONG cbFullProperty = sizeof(BTHHFP_VOLUME_VALUES_BLOCK);
-
+ PSIDEBANDDEVICECOMMON bthHfpDevice;
+
propDesc = PKSPROPERTY_DESCRIPTION(PropertyRequest->Value);
- bthHfpDevice = miniport->GetBthHfpDevice(); // weak ref.
+ bthHfpDevice = miniport->GetSidebandDevice(); // weak ref.
ASSERT(bthHfpDevice != NULL);
- //
- // Convert the KSPROPERTY_VALUES into a BTHHFP_VOLUME_VALUES_BLOCK.
- //
- volumeSettings = bthHfpDevice->GetVolumeSettings(&volumeSettingsSize);
+ volumeSettings = (PKSPROPERTY_VALUES)bthHfpDevice->GetVolumeSettings(miniport->m_DeviceType, &volumeSettingsSize);
ASSERT(volumeSettings != NULL);
ASSERT(volumeSettingsSize != 0);
- if (volumeSettings->MembersListCount != 2 ||
- volumeSettings->MembersList[0].MembersHeader.MembersFlags != KSPROPERTY_MEMBER_STEPPEDRANGES ||
- volumeSettings->MembersList[1].MembersHeader.MembersFlags != KSPROPERTY_MEMBER_VALUES)
- {
- ntStatus = STATUS_NOT_SUPPORTED;
- DPF(D_ERROR, ("PropertyHandler_BthHfpVolumeLevel_BasicSupport: invalid KSPROPERTY_VALUES settings"));
- goto Done;
- }
-
+ ULONG cbMemberListSize = volumeSettingsSize - sizeof(KSPROPERTY_VALUES);
+ ULONG cbFullProperty = cbDescriptionSize + cbMemberListSize;
+
//
// Init description prop header.
//
propDesc->AccessFlags = KSPROPERTY_TYPE_ALL;
propDesc->DescriptionSize = cbFullProperty;
propDesc->PropTypeSet = volumeSettings->PropTypeSet;
- propDesc->MembersListCount = 2;
+ propDesc->MembersListCount = volumeSettings->MembersListCount;
propDesc->Reserved = 0;
- // if return buffer can also hold a range description, return it too
+ // if return buffer can hold range description, return it
if(PropertyRequest->ValueSize >= cbFullProperty)
{
- PBTHHFP_VOLUME_VALUES_BLOCK settings = (PBTHHFP_VOLUME_VALUES_BLOCK)propDesc;
-
- //
- // First entry is the range.
- //
- settings->SteppingHeader.MembersFlags = KSPROPERTY_MEMBER_STEPPEDRANGES;
- settings->SteppingHeader.MembersSize = sizeof(KSPROPERTY_STEPPING_LONG);
- settings->SteppingHeader.MembersCount = 1;
- settings->SteppingHeader.Flags = KSPROPERTY_MEMBER_FLAG_BASICSUPPORT_MULTICHANNEL;
-
- // fill in the stepped range.
- PKSPROPERTY_STEPPING_LONG ranges = (PKSPROPERTY_STEPPING_LONG)volumeSettings->MembersList[0].Members;
- settings->Stepping[0] = *ranges;
- //settings->Stepping[0].SteppingDelta = 2 * 0x10000; // 2 dB
- //settings->Stepping[0].Bounds.SignedMinimum = -15 * 0x10000; // -15 dB
-
- //
- // Second entry is the default value.
- //
- settings->DefaultHeader.MembersFlags = KSPROPERTY_MEMBER_VALUES;
- settings->DefaultHeader.MembersSize = sizeof(LONG);
- settings->DefaultHeader.MembersCount = 1;
- settings->DefaultHeader.Flags = KSPROPERTY_MEMBER_FLAG_DEFAULT;
-
- // fill in the default value.
- PLONG defValue = (PLONG) volumeSettings->MembersList[1].Members;
- settings->Default[0] = *defValue;
-
+ RtlCopyMemory((PVOID)(propDesc + 1), volumeSettings->MembersList, cbMemberListSize);
// set the return value size
PropertyRequest->ValueSize = cbFullProperty;
}
else
{
- PropertyRequest->ValueSize = sizeof(KSPROPERTY_DESCRIPTION);
+ // otherwise only return description header
+ // set the return value size
+ PropertyRequest->ValueSize = cbDescriptionSize;
}
}
else if(PropertyRequest->ValueSize >= sizeof(ULONG))
@@ -151,7 +106,6 @@ Return Value:
ntStatus = STATUS_BUFFER_TOO_SMALL;
}
-Done:
return ntStatus;
}
@@ -227,11 +181,11 @@ Return Value:
{
if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET)
{
- PBTHHFPDEVICECOMMON bthHfpDevice = NULL;
+ PSIDEBANDDEVICECOMMON bthHfpDevice = NULL;
PKSMULTIPLE_ITEM pMI = (PKSMULTIPLE_ITEM)PropertyRequest->Value;
PKSJACK_DESCRIPTION pDesc = (PKSJACK_DESCRIPTION)(pMI+1);
- bthHfpDevice = miniport->GetBthHfpDevice(); // weak ref.
+ bthHfpDevice = miniport->GetSidebandDevice(); // weak ref.
ASSERT(bthHfpDevice != NULL);
pMI->Size = cbNeeded;
@@ -437,14 +391,14 @@ Return Value:
{
if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET)
{
- PBTHHFPDEVICECOMMON bthHfpDevice = NULL;
+ PSIDEBANDDEVICECOMMON bthHfpDevice = NULL;
GUID* guid = (GUID *)PropertyRequest->Value;
- bthHfpDevice = miniport->GetBthHfpDevice(); // weak ref.
+ bthHfpDevice = miniport->GetSidebandDevice(); // weak ref.
ASSERT(bthHfpDevice != NULL);
- *guid = bthHfpDevice->GetContainerId();
+ *guid = bthHfpDevice->GetContainerId(miniport->m_DeviceType);
ntStatus = STATUS_SUCCESS;
}
@@ -500,9 +454,9 @@ Return Value:
}
else if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET)
{
- PBTHHFPDEVICECOMMON bthHfpDevice = NULL;
+ PSIDEBANDDEVICECOMMON bthHfpDevice = NULL;
- bthHfpDevice = miniport->GetBthHfpDevice(); // weak ref.
+ bthHfpDevice = miniport->GetSidebandDevice(); // weak ref.
ASSERT(bthHfpDevice != NULL);
ntStatus = bthHfpDevice->Connect();
@@ -555,9 +509,9 @@ Return Value:
}
else if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET)
{
- PBTHHFPDEVICECOMMON bthHfpDevice = NULL;
+ PSIDEBANDDEVICECOMMON bthHfpDevice = NULL;
- bthHfpDevice = miniport->GetBthHfpDevice(); // weak ref.
+ bthHfpDevice = miniport->GetSidebandDevice(); // weak ref.
ASSERT(bthHfpDevice != NULL);
ntStatus = bthHfpDevice->Disconnect();
@@ -621,3 +575,4 @@ PropertyHandler_BthHfpTopoNodeEvent
#endif // SYSVAD_BTH_BYPASS
+
diff --git a/audio/sysvad/EndpointsCommon/micarray1toptable.h b/audio/sysvad/EndpointsCommon/micarray1toptable.h
index ee73c854..4d2e3196 100644
--- a/audio/sysvad/EndpointsCommon/micarray1toptable.h
+++ b/audio/sysvad/EndpointsCommon/micarray1toptable.h
@@ -204,13 +204,13 @@ PCPROPERTY_ITEM MicArray1PropertiesTopoFilter[] =
},
{
&KSPROPSETID_Audio,
- KSPROPERTY_AUDIO_MIC_SENSITIVITY,
+ KSPROPERTY_AUDIO_MIC_SNR,
KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_BASICSUPPORT,
PropertyHandler_MicArrayTopoFilter
},
{
&KSPROPSETID_Audio,
- KSPROPERTY_AUDIO_MIC_SNR,
+ KSPROPERTY_AUDIO_MIC_SENSITIVITY2,
KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_BASICSUPPORT,
PropertyHandler_MicArrayTopoFilter
}
diff --git a/audio/sysvad/EndpointsCommon/micarraytopo.cpp b/audio/sysvad/EndpointsCommon/micarraytopo.cpp
index a8125a08..88431df1 100644
--- a/audio/sysvad/EndpointsCommon/micarraytopo.cpp
+++ b/audio/sysvad/EndpointsCommon/micarraytopo.cpp
@@ -20,6 +20,7 @@ Abstract:
#include "micarray1toptable.h"
constexpr float MICARRAY_SENSITIVITY = -46.5f;
+constexpr float MICARRAY_SENSITIVITY2 = -23.5f;
constexpr float MICARRAY_SNR = 66.0f;
constexpr inline LONG FloatToFixedPoint16_16(float fl)
@@ -514,8 +515,8 @@ CMicArrayMiniportTopology::PropertyHandlerMicProperties
Routine Description:
-Handles ( KSPROPSETID_Audio, KSPROPERTY_AUDIO_MIC_SENSITIVITY )
Handles ( KSPROPSETID_Audio, KSPROPERTY_AUDIO_MIC_SNR )
+Handles ( KSPROPSETID_Audio, KSPROPERTY_AUDIO_MIC_SENSITIVITY2 )
Arguments:
@@ -568,28 +569,26 @@ NT status code.
{
if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET)
{
- if (PropertyRequest->PropertyItem->Id == KSPROPERTY_AUDIO_MIC_SENSITIVITY)
+ if (PropertyRequest->PropertyItem->Id == KSPROPERTY_AUDIO_MIC_SNR)
{
- LONG* micSensitivity = (LONG*)PropertyRequest->Value;
-
+ LONG* micSNR = (LONG*)PropertyRequest->Value;
fstatus = KeSaveFloatingPointState(&saveData);
if (NT_SUCCESS(fstatus))
{
- // Return microphone sensitivity information.
- *micSensitivity = FloatToFixedPoint16_16(MICARRAY_SENSITIVITY); // convert float dBFS to fixed point arithmetic
+ // Return microphone SNR information.
+ *micSNR = FloatToFixedPoint16_16(MICARRAY_SNR); // convert float dB to fixed point arithmetic
KeRestoreFloatingPointState(&saveData);
}
- PropertyRequest->ValueSize = sizeof(LONG);
ntStatus = STATUS_SUCCESS;
}
- else if (PropertyRequest->PropertyItem->Id == KSPROPERTY_AUDIO_MIC_SNR)
+ else if (PropertyRequest->PropertyItem->Id == KSPROPERTY_AUDIO_MIC_SENSITIVITY2)
{
- LONG* micSNR = (LONG*)PropertyRequest->Value;
+ LONG* micSensitivity2 = (LONG*)PropertyRequest->Value;
fstatus = KeSaveFloatingPointState(&saveData);
if (NT_SUCCESS(fstatus))
{
// Return microphone SNR information.
- *micSNR = FloatToFixedPoint16_16(MICARRAY_SNR); // convert float dB to fixed point arithmetic
+ *micSensitivity2 = FloatToFixedPoint16_16(MICARRAY_SENSITIVITY2); // convert float dB to fixed point arithmetic
KeRestoreFloatingPointState(&saveData);
}
ntStatus = STATUS_SUCCESS;
@@ -842,7 +841,7 @@ Return Value:
{
ntStatus = pMiniport->PropertyHandlerMicArrayGeometry(PropertyRequest);
}
- else if (PropertyRequest->PropertyItem->Id == KSPROPERTY_AUDIO_MIC_SENSITIVITY)
+ else if (PropertyRequest->PropertyItem->Id == KSPROPERTY_AUDIO_MIC_SENSITIVITY2)
{
ntStatus = pMiniport->PropertyHandlerMicProperties(PropertyRequest);
}
diff --git a/audio/sysvad/EndpointsCommon/micarraywavtable.h b/audio/sysvad/EndpointsCommon/micarraywavtable.h
index beda8742..0db6e6a0 100644
--- a/audio/sysvad/EndpointsCommon/micarraywavtable.h
+++ b/audio/sysvad/EndpointsCommon/micarraywavtable.h
@@ -309,6 +309,8 @@ MODE_AND_DEFAULT_FORMAT MicArrayPinSupportedDeviceModes[] =
static
KSDATAFORMAT_WAVEFORMATEXTENSIBLE KeywordPinSupportedDeviceFormats[] =
{
+ // 0 - Note the ENDPOINT_MINIPAIR structures for the mic arrays use this element as the proposed SPEECH format for KWD pin
+ // 16 KHz 16-bit mono
{
{
sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE),
@@ -327,7 +329,7 @@ KSDATAFORMAT_WAVEFORMATEXTENSIBLE KeywordPinSupportedDeviceFormats[] =
32000, // average bytes per second
2, // 2 bytes per frame
16, // 16 bits per sample container
- sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)
+ sizeof(WAVEFORMATEXTENSIBLE)-sizeof(WAVEFORMATEX)
},
16, // valid bits per sample
KSAUDIO_SPEAKER_MONO,
@@ -340,9 +342,9 @@ static
MODE_AND_DEFAULT_FORMAT KeywordPinSupportedDeviceModes[] =
{
{
- STATIC_AUDIO_SIGNALPROCESSINGMODE_RAW,
+ STATIC_AUDIO_SIGNALPROCESSINGMODE_SPEECH,
&KeywordPinSupportedDeviceFormats[SIZEOF_ARRAY(KeywordPinSupportedDeviceFormats) - 1].DataFormat
- }
+ },
};
//
@@ -604,7 +606,7 @@ KSDATARANGE_AUDIO KeywordPinDataRangesStream[] =
16, // max bits per sample
16000, // min sample rate
16000 // max sample rate
- }
+ },
};
static
@@ -753,6 +755,19 @@ SYSVADPROPERTY_ITEM PropertiesMicArrayWaveFilter[] =
},
{
{
+ &KSPROPSETID_AudioEffectsDiscovery,
+ KSPROPERTY_AUDIOEFFECTSDISCOVERY_EFFECTSLIST,
+ KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_BASICSUPPORT,
+ PropertyHandler_WaveFilter
+ },
+ 0,
+ 0,
+ NULL,
+ NULL,
+ NULL
+ },
+ {
+ {
&KSPROPSETID_SoundDetector,
KSPROPERTY_SOUNDDETECTOR_SUPPORTEDPATTERNS,
KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_BASICSUPPORT,
diff --git a/audio/sysvad/EndpointsCommon/mintopo.cpp b/audio/sysvad/EndpointsCommon/mintopo.cpp
index 42e61868..d0ecd848 100644
--- a/audio/sysvad/EndpointsCommon/mintopo.cpp
+++ b/audio/sysvad/EndpointsCommon/mintopo.cpp
@@ -110,30 +110,24 @@ Return Value:
DPF_ENTER(("[CMiniportTopology::~CMiniportTopology]"));
-#ifdef SYSVAD_BTH_BYPASS
- if (IsBthHfpDevice())
+#if defined(SYSVAD_BTH_BYPASS)
+ if (IsSidebandDevice())
{
- ASSERT(m_BthHfpDevice != NULL);
+ ASSERT(m_pSidebandDevice != NULL);
//
// Register with BthHfpDevice to get notification events.
//
- if (m_DeviceType == eBthHfpMicDevice)
- {
- m_BthHfpDevice->SetMicVolumeHandler(NULL, NULL);
- m_BthHfpDevice->SetMicConnectionStatusHandler(NULL, NULL);
- }
- else
+ if(IsSidebandDevice())
{
- ASSERT(m_DeviceType == eBthHfpSpeakerDevice);
-
- m_BthHfpDevice->SetSpeakerVolumeHandler(NULL, NULL);
- m_BthHfpDevice->SetSpeakerConnectionStatusHandler(NULL, NULL);
+ m_pSidebandDevice->SetVolumeHandler(m_DeviceType, NULL, NULL);
+ m_pSidebandDevice->SetMuteHandler(m_DeviceType, NULL, NULL);
+ m_pSidebandDevice->SetConnectionStatusHandler(m_DeviceType, NULL, NULL);
}
- SAFE_RELEASE(m_BthHfpDevice); // IBthHfpDeviceCommon
+ SAFE_RELEASE(m_pSidebandDevice); // ISidebandDeviceCommon
}
-#endif // SYSVAD_BTH_BYPASS
+#endif // defined(SYSVAD_BTH_BYPASS)
} // ~CMiniportTopology
@@ -287,24 +281,26 @@ Return Value:
DPF(D_ERROR, ("Init: CMiniportTopologySYSVAD::Init failed, 0x%x", ntStatus)),
Done);
-#ifdef SYSVAD_BTH_BYPASS
- if (IsBthHfpDevice())
+#if defined(SYSVAD_BTH_BYPASS)
+ if (IsSidebandDevice())
{
- PBTHHFPDEVICECOMMON bthHfpDevice = NULL;
+ PSIDEBANDDEVICECOMMON sidebandDevice = NULL;
- bthHfpDevice = GetBthHfpDevice(); // weak ref.
- ASSERT(bthHfpDevice != NULL);
+ sidebandDevice = GetSidebandDevice(); // weak ref.
+ ASSERT(sidebandDevice != NULL);
//
// Register with BthHfpDevice to get notification events.
//
if (m_DeviceType == eBthHfpMicDevice)
{
- bthHfpDevice->SetMicVolumeHandler(
+ sidebandDevice->SetVolumeHandler(
+ m_DeviceType,
EvtMicVolumeHandler, // handler
PCMiniportTopology(this)); // context.
- bthHfpDevice->SetMicConnectionStatusHandler(
+ sidebandDevice->SetConnectionStatusHandler(
+ m_DeviceType,
EvtMicConnectionStatusHandler, // handler
PCMiniportTopology(this)); // context.
}
@@ -312,16 +308,18 @@ Return Value:
{
ASSERT(m_DeviceType == eBthHfpSpeakerDevice);
- bthHfpDevice->SetSpeakerVolumeHandler(
+ sidebandDevice->SetVolumeHandler(
+ m_DeviceType,
EvtSpeakerVolumeHandler, // handler
PCMiniportTopology(this)); // context.
- bthHfpDevice->SetSpeakerConnectionStatusHandler(
+ sidebandDevice->SetConnectionStatusHandler(
+ m_DeviceType,
EvtSpeakerConnectionStatusHandler, // handler
PCMiniportTopology(this)); // context.
}
}
-#endif // SYSVAD_BTH_BYPASS
+#endif // defined(SYSVAD_BTH_BYPASS)
Done:
return ntStatus;
@@ -583,7 +581,7 @@ Return Value:
return ntStatus;
}
-#ifdef SYSVAD_BTH_BYPASS
+#if defined(SYSVAD_BTH_BYPASS)
//=============================================================================
#pragma code_seg()
VOID
@@ -687,7 +685,7 @@ CMiniportTopology::EvtMicConnectionStatusHandler
FALSE, // do not use node ID.
ULONG(-1)); // node ID, not used.
}
-#endif // SYSVAD_BTH_BYPASS
+#endif // defined(SYSVAD_BTH_BYPASS)
//=============================================================================
#pragma code_seg("PAGE")
diff --git a/audio/sysvad/EndpointsCommon/mintopo.h b/audio/sysvad/EndpointsCommon/mintopo.h
index e73cdd04..f25d0991 100644
--- a/audio/sysvad/EndpointsCommon/mintopo.h
+++ b/audio/sysvad/EndpointsCommon/mintopo.h
@@ -35,9 +35,9 @@ class CMiniportTopology :
eDeviceType m_DeviceType;
union {
PVOID m_DeviceContext;
-#ifdef SYSVAD_BTH_BYPASS
- PBTHHFPDEVICECOMMON m_BthHfpDevice;
-#endif // SYSVAD_BTH_BYPASS
+#if defined(SYSVAD_BTH_BYPASS)
+ PSIDEBANDDEVICECOMMON m_pSidebandDevice;
+#endif // defined(SYSVAD_BTH_BYPASS)
};
public:
@@ -55,16 +55,16 @@ public:
m_DeviceType(DeviceType),
m_DeviceContext(DeviceContext)
{
-#ifdef SYSVAD_BTH_BYPASS
- if (IsBthHfpDevice())
+#if defined(SYSVAD_BTH_BYPASS)
+ if (IsSidebandDevice())
{
- if (m_BthHfpDevice != NULL)
+ if (m_pSidebandDevice != NULL)
{
// This ref is released on dtor.
- m_BthHfpDevice->AddRef(); // strong ref.
+ m_pSidebandDevice->AddRef(); // strong ref.
}
}
-#endif // SYSVAD_BTH_BYPASS
+#endif // defined(SYSVAD_BTH_BYPASS)
}
~CMiniportTopology();
@@ -86,27 +86,27 @@ public:
_In_ DWORD JackCapabilities
);
-#ifdef SYSVAD_BTH_BYPASS
- BOOL IsBthHfpDevice()
+#if defined(SYSVAD_BTH_BYPASS)
+ BOOL IsSidebandDevice()
{
return (m_DeviceType == eBthHfpMicDevice ||
m_DeviceType == eBthHfpSpeakerDevice) ? TRUE : FALSE;
}
// Returns a weak ref to the Bluetooth HFP device.
- PBTHHFPDEVICECOMMON GetBthHfpDevice()
+ PSIDEBANDDEVICECOMMON GetSidebandDevice()
{
- PBTHHFPDEVICECOMMON bthHfpDevice = NULL;
+ PSIDEBANDDEVICECOMMON sidebandDevice = NULL;
- if (IsBthHfpDevice())
+ if (IsSidebandDevice())
{
- if (m_BthHfpDevice != NULL)
+ if (m_pSidebandDevice != NULL)
{
- bthHfpDevice = m_BthHfpDevice;
+ sidebandDevice = m_pSidebandDevice;
}
}
- return bthHfpDevice;
+ return sidebandDevice;
}
static
@@ -136,9 +136,20 @@ public:
(
_In_opt_ PVOID Context
);
-#endif // SYSVAD_BTH_BYPASS
+#endif // defined(SYSVAD_BTH_BYPASS)
PVOID GetDeviceContext() { return m_DeviceContext; }
+
+ friend NTSTATUS PropertyHandler_BthHfpVolumeLevel_BasicSupport(
+ _In_ PPCPROPERTY_REQUEST PropertyRequest);
+ friend NTSTATUS PropertyHandler_BthHfpJackContainerId(
+ _In_ PPCPROPERTY_REQUEST PropertyRequest,
+ _In_ ULONG cJackDescriptions,
+ _In_reads_(cJackDescriptions) PKSJACK_DESCRIPTION * JackDescriptions);
+ friend NTSTATUS PropertyHandler_BthHfpMicVolumeLevel(
+ _In_ PPCPROPERTY_REQUEST PropertyRequest);
+ friend NTSTATUS PropertyHandler_BthHfpSpeakerVolumeLevel(
+ _In_ PPCPROPERTY_REQUEST PropertyRequest);
};
typedef CMiniportTopology *PCMiniportTopology;
@@ -150,3 +161,4 @@ NTSTATUS CMiniportTopology_EventHandler_JackState
#endif // _SYSVAD_MINTOPO_H_
+
diff --git a/audio/sysvad/EndpointsCommon/minwavert.cpp b/audio/sysvad/EndpointsCommon/minwavert.cpp
index 35923619..8ad0e09d 100644
--- a/audio/sysvad/EndpointsCommon/minwavert.cpp
+++ b/audio/sysvad/EndpointsCommon/minwavert.cpp
@@ -16,6 +16,7 @@ Abstract:
#include <sysvad.h>
#include <limits.h>
+#include <MsApoFxProxy.h>
#include "ContosoKeywordDetector.h"
#include "SysVadShared.h"
#include "simple.h"
@@ -25,6 +26,8 @@ Abstract:
#include "AudioModuleHelper.h"
+#define EFFECTS_LIST_COUNT 2
+
//=============================================================================
// CMiniportWaveRT
//=============================================================================
@@ -193,12 +196,13 @@ Return Value:
m_pAudioModules = NULL;
}
-#ifdef SYSVAD_BTH_BYPASS
- if (IsBthHfpDevice())
+#if defined(SYSVAD_BTH_BYPASS)
+ if (IsSidebandDevice())
{
- SAFE_RELEASE(m_BthHfpDevice);
+ m_pSidebandDevice->SetFormatChangeHandler(m_DeviceType, NULL, NULL);
+ SAFE_RELEASE(m_pSidebandDevice);
}
-#endif // SYSVAD_BTH_BYPASS
+#endif // defined(SYSVAD_BTH_BYPASS)
} // ~CMiniportWaveRT
@@ -387,23 +391,21 @@ Return Value:
//
// Init class data members
//
- m_ulLoopbackAllocated = 0;
- m_ulSystemAllocated = 0;
- m_ulOffloadAllocated = 0;
- m_dwCaptureAllocatedModes = 0;
- m_dwBiDiCaptureAllocatedModes = 0;
- m_dwSystemAllocatedModes = 0;
- m_SystemStreams = NULL;
- m_OffloadStreams = NULL;
- m_LoopbackStreams = NULL;
- m_bGfxEnabled = FALSE;
- m_pbMuted = NULL;
- m_plVolumeLevel = NULL;
- m_plPeakMeter = NULL;
- m_pMixFormat = NULL;
- m_pDeviceFormat = NULL;
- m_ulMixDrmContentId = 0;
- m_LoopbackProtection = CONSTRICTOR_OPTION_DISABLE;
+ m_ulLoopbackAllocated = 0;
+ m_ulSystemAllocated = 0;
+ m_ulOffloadAllocated = 0;
+ m_ulKeywordDetectorAllocated = 0;
+ m_SystemStreams = NULL;
+ m_OffloadStreams = NULL;
+ m_LoopbackStreams = NULL;
+ m_bGfxEnabled = FALSE;
+ m_pbMuted = NULL;
+ m_plVolumeLevel = NULL;
+ m_plPeakMeter = NULL;
+ m_pMixFormat = NULL;
+ m_pDeviceFormat = NULL;
+ m_ulMixDrmContentId = 0;
+ m_LoopbackProtection = CONSTRICTOR_OPTION_DISABLE;
RtlZeroMemory(&m_MixDrmRights, sizeof(m_MixDrmRights));
//
@@ -485,9 +487,7 @@ Return Value:
//
if (IsRenderDevice())
{
- // Basic validation
- if (m_ulMaxSystemStreams == 0 ||
- m_ulMaxLoopbackStreams == 0)
+ if (m_ulMaxSystemStreams == 0 )
{
return STATUS_INVALID_DEVICE_STATE;
}
@@ -501,16 +501,23 @@ Return Value:
}
RtlZeroMemory(m_SystemStreams, size);
- // Loopback streams.
- size = sizeof(PCMiniportWaveRTStream) * m_ulMaxLoopbackStreams;
- m_LoopbackStreams = (PCMiniportWaveRTStream *)ExAllocatePoolWithTag(NonPagedPoolNx, size, MINWAVERT_POOLTAG);
- if (m_LoopbackStreams == NULL)
+ if (IsLoopbackSupported())
{
- return STATUS_INSUFFICIENT_RESOURCES;
+ if (m_ulMaxLoopbackStreams == 0)
+ {
+ return STATUS_INVALID_DEVICE_STATE;
+ }
+
+ // Loopback streams.
+ size = sizeof(PCMiniportWaveRTStream) * m_ulMaxLoopbackStreams;
+ m_LoopbackStreams = (PCMiniportWaveRTStream *)ExAllocatePoolWithTag(NonPagedPoolNx, size, MINWAVERT_POOLTAG);
+ if (m_LoopbackStreams == NULL)
+ {
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+ RtlZeroMemory(m_LoopbackStreams, size);
}
- RtlZeroMemory(m_LoopbackStreams, size);
- // Basic validation
if (IsOffloadSupported())
{
PKSDATAFORMAT_WAVEFORMATEXTENSIBLE pDeviceFormats;
@@ -608,6 +615,25 @@ Return Value:
{
m_pPortEvents = NULL;
}
+
+ // Format change handler is only required for bluetooth HFP implementation
+#ifdef SYSVAD_BTH_BYPASS
+ if (IsSidebandDevice())
+ {
+ PSIDEBANDDEVICECOMMON sidebandDevice = NULL;
+
+ sidebandDevice = GetSidebandDevice(); // weak ref.
+ ASSERT(sidebandDevice != NULL);
+
+ //
+ // Register with BthHfpDevice to get notification events.
+ //
+ sidebandDevice->SetFormatChangeHandler(
+ m_DeviceType,
+ EvtFormatChangeHandler, // handler
+ PCMiniportWaveRT(this)); // context.
+ }
+#endif // #ifdef SYSVAD_BTH_BYPASS
return ntStatus;
} // Init
@@ -676,7 +702,7 @@ Return Value:
//
if (NT_SUCCESS(ntStatus))
{
- ntStatus = ValidateStreamCreate(Pin, Capture, signalProcessingMode);
+ ntStatus = ValidateStreamCreate(Pin, Capture);
}
// Determine if the format is valid.
@@ -911,8 +937,7 @@ NTSTATUS
CMiniportWaveRT::ValidateStreamCreate
(
_In_ ULONG _Pin,
- _In_ BOOLEAN _Capture,
- _In_ GUID _SignalProcessingMode
+ _In_ BOOLEAN _Capture
)
{
PAGED_CODE();
@@ -925,44 +950,26 @@ CMiniportWaveRT::ValidateStreamCreate
{
if (IsLoopbackPin(_Pin))
{
- if (m_ulLoopbackAllocated < m_ulMaxLoopbackStreams)
- {
- ntStatus = STATUS_SUCCESS;
- }
- else
- {
- ntStatus = STATUS_INSUFFICIENT_RESOURCES;
- }
- }
- else if (IsSystemCapturePin(_Pin))
- {
- VERIFY_MODE_RESOURCES_AVAILABLE(m_dwCaptureAllocatedModes, _SignalProcessingMode, ntStatus)
+ VERIFY_PIN_INSTANCE_RESOURCES_AVAILABLE(ntStatus, m_ulLoopbackAllocated, m_ulMaxLoopbackStreams);
}
- else if (IsCellularBiDiCapturePin(_Pin))
+ else if (IsSystemCapturePin(_Pin) || IsCellularBiDiCapturePin(_Pin))
{
- VERIFY_MODE_RESOURCES_AVAILABLE(m_dwBiDiCaptureAllocatedModes, _SignalProcessingMode, ntStatus)
+ VERIFY_PIN_INSTANCE_RESOURCES_AVAILABLE(ntStatus, m_ulSystemAllocated, m_ulMaxSystemStreams);
}
- else if (m_DeviceFormatsAndModes[_Pin].PinType == PINTYPE::KeywordCapturePin)
+ else if (IsKeywordDetectorPin(_Pin))
{
- ntStatus = STATUS_SUCCESS;
+ VERIFY_PIN_INSTANCE_RESOURCES_AVAILABLE(ntStatus, m_ulKeywordDetectorAllocated, m_ulMaxKeywordDetectorStreams);
}
}
else
{
if (IsSystemRenderPin(_Pin))
{
- VERIFY_MODE_RESOURCES_AVAILABLE(m_dwSystemAllocatedModes, _SignalProcessingMode, ntStatus)
+ VERIFY_PIN_INSTANCE_RESOURCES_AVAILABLE(ntStatus, m_ulSystemAllocated, m_ulMaxSystemStreams);
}
else if (IsOffloadPin(_Pin))
{
- if (m_ulOffloadAllocated < m_ulMaxOffloadStreams)
- {
- ntStatus = STATUS_SUCCESS;
- }
- else
- {
- ntStatus = STATUS_INSUFFICIENT_RESOURCES;
- }
+ VERIFY_PIN_INSTANCE_RESOURCES_AVAILABLE(ntStatus, m_ulOffloadAllocated, m_ulMaxOffloadStreams);
}
}
@@ -983,35 +990,34 @@ CMiniportWaveRT::StreamCreated
PCMiniportWaveRTStream * streams = NULL;
ULONG count = 0;
- DPF_ENTER(("[CMiniportWaveRT::StreamOpened]"));
+ DPF_ENTER(("[CMiniportWaveRT::StreamCreated]"));
- if (IsSystemCapturePin(_Pin))
+ if (IsSystemCapturePin(_Pin) || IsCellularBiDiCapturePin(_Pin))
{
- ALLOCATE_MODE_RESOURCES(m_dwCaptureAllocatedModes, _Stream->GetSignalProcessingMode())
+ ALLOCATE_PIN_INSTANCE_RESOURCES(m_ulSystemAllocated);
return STATUS_SUCCESS;
}
- if (IsCellularBiDiCapturePin(_Pin))
+ if (IsKeywordDetectorPin(_Pin))
{
- ALLOCATE_MODE_RESOURCES(m_dwBiDiCaptureAllocatedModes, _Stream->GetSignalProcessingMode())
+ ALLOCATE_PIN_INSTANCE_RESOURCES(m_ulKeywordDetectorAllocated);
return STATUS_SUCCESS;
}
else if (IsLoopbackPin(_Pin))
{
- m_ulLoopbackAllocated++;
+ ALLOCATE_PIN_INSTANCE_RESOURCES(m_ulLoopbackAllocated);
streams = m_LoopbackStreams;
count = m_ulMaxLoopbackStreams;
_Stream->m_SaveData.Disable(m_MixDrmRights.CopyProtect);
}
else if (IsSystemRenderPin(_Pin))
{
- ALLOCATE_MODE_RESOURCES(m_dwSystemAllocatedModes, _Stream->GetSignalProcessingMode())
- m_ulSystemAllocated++;
+ ALLOCATE_PIN_INSTANCE_RESOURCES(m_ulSystemAllocated);
streams = m_SystemStreams;
count = m_ulMaxSystemStreams;
}
else if (IsOffloadPin(_Pin))
{
- m_ulOffloadAllocated++;
+ ALLOCATE_PIN_INSTANCE_RESOURCES(m_ulOffloadAllocated);
streams = m_OffloadStreams;
count = m_ulMaxOffloadStreams;
}
@@ -1053,33 +1059,32 @@ CMiniportWaveRT::StreamClosed
DPF_ENTER(("[CMiniportWaveRT::StreamClosed]"));
- if (IsSystemCapturePin(_Pin))
+ if (IsSystemCapturePin(_Pin) || IsCellularBiDiCapturePin(_Pin))
{
- FREE_MODE_RESOURCES(m_dwCaptureAllocatedModes, _Stream->GetSignalProcessingMode())
+ FREE_PIN_INSTANCE_RESOURCES(m_ulSystemAllocated);
return STATUS_SUCCESS;
}
- if (IsCellularBiDiCapturePin(_Pin))
+ if (IsKeywordDetectorPin(_Pin))
{
- FREE_MODE_RESOURCES(m_dwBiDiCaptureAllocatedModes, _Stream->GetSignalProcessingMode())
+ FREE_PIN_INSTANCE_RESOURCES(m_ulKeywordDetectorAllocated);
return STATUS_SUCCESS;
}
else if (IsLoopbackPin(_Pin))
{
- m_ulLoopbackAllocated--;
+ FREE_PIN_INSTANCE_RESOURCES(m_ulLoopbackAllocated);
streams = m_LoopbackStreams;
count = m_ulMaxLoopbackStreams;
}
else if (IsSystemRenderPin(_Pin))
{
- FREE_MODE_RESOURCES(m_dwSystemAllocatedModes, _Stream->GetSignalProcessingMode())
- m_ulSystemAllocated--;
+ FREE_PIN_INSTANCE_RESOURCES(m_ulSystemAllocated);
streams = m_SystemStreams;
count = m_ulMaxSystemStreams;
updateDrmRights = true;
}
else if (IsOffloadPin(_Pin))
{
- m_ulOffloadAllocated--;
+ FREE_PIN_INSTANCE_RESOURCES(m_ulOffloadAllocated);
streams = m_OffloadStreams;
count = m_ulMaxOffloadStreams;
updateDrmRights = true;
@@ -1278,7 +1283,74 @@ CMiniportWaveRT::IsFormatSupported
}
return ntStatus;
-}
+}
+
+#ifdef SYSVAD_BTH_BYPASS
+//=============================================================================
+#pragma code_seg()
+VOID
+CMiniportWaveRT::EvtFormatChangeHandler
+(
+ _In_opt_ PVOID Context
+)
+{
+ DPF_ENTER(("[CMiniportWaveRT::EvtFormatChangeHandler]"));
+
+ PCMiniportWaveRT This = PCMiniportWaveRT(Context);
+ if (This == NULL)
+ {
+ DPF(D_ERROR, ("EvtFormatChangeHandler: context is null"));
+ return;
+ }
+
+ /*
+ _In_opt_ GUID *Set,
+ _In_ ULONG EventId,
+ _In_ BOOL PinEvent,
+ _In_ ULONG PinId,
+ _In_ BOOL NodeEvent,
+ _In_ ULONG NodeId
+ */
+
+ if (This->IsSidebandDevice())
+ {
+ if (This->m_DeviceType == eBthHfpMicDevice)
+ {
+ // swap the device formats and modes for bt
+ ExAcquireFastMutex(&This->m_DeviceFormatsAndModesLock);
+
+ This->m_DeviceFormatsAndModes = This->m_pSidebandDevice->GetFormatsAndModes(This->m_DeviceType);
+
+ ExReleaseFastMutex(&This->m_DeviceFormatsAndModesLock);
+
+ This->GenerateEventList(
+ (GUID*)&KSEVENTSETID_PinCapsChange,
+ KSEVENT_PINCAPS_FORMATCHANGE,
+ TRUE,
+ 1,
+ FALSE,
+ ULONG(-1));
+ }
+ else if(This->m_DeviceType == eBthHfpSpeakerDevice)
+ {
+ // swap the device formats and modes for bt
+ ExAcquireFastMutex(&This->m_DeviceFormatsAndModesLock);
+
+ This->m_DeviceFormatsAndModes = This->m_pSidebandDevice->GetFormatsAndModes(This->m_DeviceType);
+
+ ExReleaseFastMutex(&This->m_DeviceFormatsAndModesLock);
+
+ This->GenerateEventList(
+ (GUID*)&KSEVENTSETID_PinCapsChange,
+ KSEVENT_PINCAPS_FORMATCHANGE,
+ TRUE,
+ 0,
+ FALSE,
+ ULONG(-1));
+ }
+ }
+}
+#endif // #ifdef SYSVAD_BTH_BYPASS
//=============================================================================
#pragma code_seg("PAGE")
@@ -1314,7 +1386,8 @@ CMiniportWaveRT::PropertyHandlerProposedFormat
if (IsSystemRenderPin(kspPin->PinId) ||
IsLoopbackPin(kspPin->PinId) ||
IsOffloadPin(kspPin->PinId) ||
- IsSystemCapturePin(kspPin->PinId)||
+ IsSystemCapturePin(kspPin->PinId) ||
+ IsKeywordDetectorPin(kspPin->PinId) ||
IsCellularBiDiCapturePin(kspPin->PinId))
{
ntStatus = STATUS_SUCCESS;
@@ -1354,35 +1427,257 @@ CMiniportWaveRT::PropertyHandlerProposedFormat
return STATUS_BUFFER_TOO_SMALL;
}
+#if 0
// Only SET is supported for this property
if ((PropertyRequest->Verb & KSPROPERTY_TYPE_SET) == 0)
{
return STATUS_INVALID_DEVICE_REQUEST;
}
+#endif
- pKsFormat = (PKSDATAFORMAT)PropertyRequest->Value;
- ntStatus = IsFormatSupported(kspPin->PinId,
- IsSystemCapturePin(kspPin->PinId) || IsCellularBiDiCapturePin(kspPin->PinId) ||
- IsLoopbackPin(kspPin->PinId),
- pKsFormat);
- if (!NT_SUCCESS(ntStatus))
+ if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET)
{
- return ntStatus;
- }
+ ntStatus = STATUS_INVALID_DEVICE_REQUEST;
+#if defined(SYSVAD_BTH_BYPASS)
+ if (IsSidebandDevice())
+ {
+ if (m_DeviceType == eBthHfpMicDevice ||
+ m_DeviceType == eBthHfpSpeakerDevice)
+ {
+ KSDATAFORMAT_WAVEFORMATEXTENSIBLE *propFormat = (KSDATAFORMAT_WAVEFORMATEXTENSIBLE *)PropertyRequest->Value;
+ ULONG numModes = 0;
+ MODE_AND_DEFAULT_FORMAT *modeInfo = NULL;
+ MODE_AND_DEFAULT_FORMAT *modeInfo_RAW = NULL;
+ numModes = GetPinSupportedDeviceModes(kspPin->PinId, &modeInfo);
+ BOOL bFound = FALSE;
+ ULONG i = 0;
- //
- // Make sure there are enough resources to handle a new pin creation with
- // this format.
- //
- if (IsOffloadPin(kspPin->PinId))
+ // For loopback pin, get default format from host pin structures
+ if (IsLoopbackPin(kspPin->PinId))
+ {
+ for (i = 0; i < m_DeviceFormatsAndModesCount; i++)
+ {
+ if (m_DeviceFormatsAndModes[i].PinType == SystemRenderPin)
+ {
+ modeInfo = m_DeviceFormatsAndModes[i].ModeAndDefaultFormat;
+ numModes = m_DeviceFormatsAndModes[i].ModeAndDefaultFormatCount;
+ break;
+ }
+ }
+ }
+
+ // Iterate through FormatsAndModes to find the 'DefaultFormat' for the 'DEFAULT' processing mode
+ // Make note of the RAW format for cases where DEFAULT mode is not supported by endpoint
+ for (i = 0; i < numModes; i++, ++modeInfo)
+ {
+ if ((IsEqualGUIDAligned(modeInfo->Mode, AUDIO_SIGNALPROCESSINGMODE_DEFAULT)) &&
+ (modeInfo->DefaultFormat != NULL))
+ {
+ bFound = TRUE;
+ break;
+ }
+ else if ((IsEqualGUIDAligned(modeInfo->Mode, AUDIO_SIGNALPROCESSINGMODE_RAW)) &&
+ (modeInfo->DefaultFormat != NULL))
+ {
+ modeInfo_RAW = modeInfo;
+ }
+ }
+
+ if (!bFound &&
+ modeInfo_RAW)
+ {
+ modeInfo = modeInfo_RAW;
+ bFound = TRUE;
+ }
+
+ if (!bFound)
+ {
+ return STATUS_NOT_SUPPORTED;
+ }
+
+ RtlCopyMemory(propFormat, modeInfo->DefaultFormat, modeInfo->DefaultFormat->FormatSize);
+ PropertyRequest->ValueSize = modeInfo->DefaultFormat->FormatSize;
+ ntStatus = STATUS_SUCCESS;
+ }
+ }
+#endif // defined(SYSVAD_BTH_BYPASS)
+ }
+ else if (PropertyRequest->Verb & KSPROPERTY_TYPE_SET)
{
- ntStatus = ValidateStreamCreate(kspPin->PinId, FALSE, AUDIO_SIGNALPROCESSINGMODE_DEFAULT);
+ pKsFormat = (PKSDATAFORMAT)PropertyRequest->Value;
+ ntStatus = IsFormatSupported(kspPin->PinId,
+ IsSystemCapturePin(kspPin->PinId) || IsCellularBiDiCapturePin(kspPin->PinId) ||
+ IsLoopbackPin(kspPin->PinId),
+ pKsFormat);
+ if (!NT_SUCCESS(ntStatus))
+ {
+ return ntStatus;
+ }
+
+ //
+ // Make sure there are enough resources to handle a new pin creation with
+ // this format.
+ //
+ if (IsOffloadPin(kspPin->PinId))
+ {
+ ntStatus = ValidateStreamCreate(kspPin->PinId, FALSE);
+ }
}
return ntStatus;
} // PropertyHandlerProposedFormat
//=============================================================================
+#pragma code_seg()
+VOID
+CMiniportWaveRT::GenerateEventList
+(
+ _In_opt_ GUID *Set,
+ _In_ ULONG EventId,
+ _In_ BOOL PinEvent,
+ _In_ ULONG PinId,
+ _In_ BOOL NodeEvent,
+ _In_ ULONG NodeId
+)
+/*++
+
+Routine Description:
+
+ The GenerateEventList method notifies clients through the port driver's list
+ of event entries that a particular event has occurred.
+
+Arguments:
+
+ Set -
+
+ EventId -
+
+ PinEvent -
+
+ PinId -
+
+ NodeEvent -
+
+ NodeId -
+
+--*/
+{
+ DPF_ENTER(("[CMiniportWaveRT::GenerateEventList]"));
+
+ ASSERT(m_pPortEvents != NULL);
+
+ m_pPortEvents->GenerateEventList(
+ Set,
+ EventId,
+ PinEvent,
+ PinId,
+ NodeEvent,
+ NodeId);
+}
+
+//=============================================================================
+#pragma code_seg("PAGE")
+NTSTATUS
+CMiniportWaveRT::PropertyHandlerAudioEffectsDiscoveryEffectsList
+(
+ _In_ PPCPROPERTY_REQUEST PropertyRequest
+)
+{
+ PAGED_CODE();
+
+ DPF_ENTER(("[CMiniportWaveRT::PropertyHandlerAudioEffectsDiscoveryEffectsList]"));
+
+ PKSP_PIN kspPin = NULL;
+ NTSTATUS ntStatus = STATUS_INVALID_PARAMETER;
+ PKSP_PINMODE pKspPinmode = NULL;
+ GUID signalProcessingMode = AUDIO_SIGNALPROCESSINGMODE_DEFAULT;
+
+ // Verify instance data stores at least KSP_PIN fields beyond KSPPROPERTY.
+ if (PropertyRequest->InstanceSize < (sizeof(KSP_PIN) - RTL_SIZEOF_THROUGH_FIELD(KSP_PIN, Property)))
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ // Extract property descriptor from property request instance data
+ kspPin = CONTAINING_RECORD(PropertyRequest->Instance, KSP_PIN, PinId);
+
+ // Get the mode if specified.
+ pKspPinmode = (PKSP_PINMODE)kspPin;
+ signalProcessingMode = pKspPinmode->AudioProcessingMode;
+
+ if (PropertyRequest->InstanceSize >= sizeof(ULONG))
+ {
+ // This prop is only supported on Keyword Detector pins.
+ if (IsKeywordDetectorPin(kspPin->PinId))
+ {
+ ntStatus = STATUS_SUCCESS;
+ }
+ else
+ {
+ ntStatus = STATUS_NOT_SUPPORTED;
+ }
+ }
+
+ IF_FAILED_JUMP(ntStatus, Done);
+
+ // Valid actions: get and basicsupport.
+ ntStatus = STATUS_INVALID_PARAMETER;
+
+ if (PropertyRequest->Verb & KSPROPERTY_TYPE_BASICSUPPORT)
+ {
+ ntStatus =
+ PropertyHandler_BasicSupport
+ (
+ PropertyRequest,
+ KSPROPERTY_TYPE_BASICSUPPORT | KSPROPERTY_TYPE_GET,
+ VT_ILLEGAL
+ );
+ }
+ else if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET)
+ {
+ if (IsKeywordDetectorPin(kspPin->PinId))
+ {
+ // Compute total size, two effects: NS and EC (see below).
+ ULONG cbMinSize = 0;
+
+ if(signalProcessingMode == AUDIO_SIGNALPROCESSINGMODE_SPEECH)
+ {
+ cbMinSize = sizeof(GUID) * EFFECTS_LIST_COUNT;
+ }
+
+ if (PropertyRequest->ValueSize == 0)
+ {
+ PropertyRequest->ValueSize = cbMinSize;
+ ntStatus = STATUS_BUFFER_OVERFLOW;
+ }
+ else if (PropertyRequest->ValueSize < cbMinSize)
+ {
+ ntStatus = STATUS_BUFFER_TOO_SMALL;
+ }
+ else if (signalProcessingMode == AUDIO_SIGNALPROCESSINGMODE_SPEECH)
+ {
+ PGUID effectList = PGUID(PropertyRequest->Value);
+
+ *effectList = AUDIO_EFFECT_TYPE_ACOUSTIC_ECHO_CANCELLATION;
+ *(effectList + 1) = AUDIO_EFFECT_TYPE_NOISE_SUPPRESSION;
+
+ PropertyRequest->ValueSize = cbMinSize;
+ ntStatus = STATUS_SUCCESS;
+ }
+ else
+ {
+ PropertyRequest->ValueSize = 0;
+ ntStatus = STATUS_SUCCESS;
+ }
+ }
+ }
+
+Done:
+
+ return ntStatus;
+} // PropertyHandlerAudioEffectsDiscoveryEffectsList
+
+//=============================================================================
#pragma code_seg("PAGE")
NTSTATUS
CMiniportWaveRT::PropertyHandlerModulesListRequest
@@ -1439,6 +1734,70 @@ CMiniportWaveRT::PropertyHandlerModuleNotificationDeviceId
GetAudioModuleNotificationDeviceId());
} // PropertyHandlerModuleNotificationDeviceId
+//=============================================================================
+#pragma code_seg()
+NTSTATUS
+CMiniportWaveRT_EventHandler_PinCapsChange
+(
+_In_ PPCEVENT_REQUEST EventRequest
+)
+{
+ CMiniportWaveRT* miniport = reinterpret_cast<CMiniportWaveRT*>(EventRequest->MajorTarget);
+ return miniport->EventHandler_PinCapsChange(EventRequest);
+}
+
+//=============================================================================
+#pragma code_seg()
+NTSTATUS
+CMiniportWaveRT::EventHandler_PinCapsChange
+(
+_In_ PPCEVENT_REQUEST EventRequest
+)
+{
+ if (*EventRequest->EventItem->Set != KSEVENTSETID_PinCapsChange)
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ switch (EventRequest->Verb)
+ {
+ // Do we support event handling?!?
+ case PCEVENT_VERB_SUPPORT:
+ break;
+ // We should add the event now!
+ case PCEVENT_VERB_ADD:
+ // If we have the interface and EventEntry is defined ...
+ if (EventRequest->EventEntry)
+ {
+ switch (EventRequest->EventItem->Id)
+ {
+ // Add pincaps format change event to support the force sample rate feature
+ case KSEVENT_PINCAPS_FORMATCHANGE:
+ m_pPortEvents->AddEventToEventList(EventRequest->EventEntry);
+ break;
+ default:
+ return STATUS_INVALID_PARAMETER;
+ break;
+ }
+ }
+ else
+ {
+ return STATUS_UNSUCCESSFUL;
+ }
+ break;
+
+ case PCEVENT_VERB_REMOVE:
+ // We cannot remove the event but we can stop generating the
+ // events. However, it also doesn't hurt to always generate them ...
+ break;
+
+ default:
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ return STATUS_SUCCESS;
+}
+
//=============================================================================
#pragma code_seg("PAGE")
@@ -2188,6 +2547,8 @@ DEFINE_CLASSPROPERTYHANDLER(CMiniportWaveRT, Get_SoundDetectorMatchResult)
value->Header.Size = sizeof(CONTOSO_KEYWORDDETECTIONRESULT);
value->Header.PatternType = CONTOSO_KEYWORDCONFIGURATION_IDENTIFIER;
value->ContosoDetectorResultData = m_KeywordDetector.GetDetectorData();
+ value->KeywordStartTimestamp = m_KeywordDetector.GetStartTimestamp();
+ value->KeywordStopTimestamp = m_KeywordDetector.GetStopTimestamp();
PropertyRequest->ValueSize = sizeof(*value);
@@ -2217,7 +2578,6 @@ NTSTATUS CMiniportWaveRT::EventHandler_SoundDetectorMatchDetected
}
return STATUS_SUCCESS;
}
-
#pragma code_seg("PAGE")
NTSTATUS
PropertyHandler_WaveFilter
@@ -2297,6 +2657,18 @@ Return Value:
DPF(D_TERSE, ("[PropertyHandler_WaveFilter: Invalid Device Request]"));
}
}
+ else if (IsEqualGUIDAligned(*PropertyRequest->PropertyItem->Set, KSPROPSETID_AudioEffectsDiscovery))
+ {
+ switch(PropertyRequest->PropertyItem->Id)
+ {
+ case KSPROPERTY_AUDIOEFFECTSDISCOVERY_EFFECTSLIST:
+ ntStatus = pWaveHelper->PropertyHandlerAudioEffectsDiscoveryEffectsList(PropertyRequest);
+ break;
+
+ default:
+ DPF(D_TERSE, ("[PropertyHandler_WaveFilter: Invalid Device Request]"));
+ }
+ }
else if ((pWaveHelper->m_DeviceType == eHdmiRenderDevice ||
pWaveHelper->m_DeviceType == eCellularDevice ||
pWaveHelper->m_DeviceType == eHandsetSpeakerDevice) &&
@@ -2493,7 +2865,9 @@ CKeywordDetector::CKeywordDetector()
m_qpcStartCapture(0),
m_nLastQueuedPacket(-1),
m_SoundDetectorArmed(FALSE),
- m_SoundDetectorData(0)
+ m_SoundDetectorData(0),
+ m_ullKeywordStartTimestamp(0),
+ m_ullKeywordStopTimestamp(0)
{
PAGED_CODE();
@@ -2505,6 +2879,53 @@ CKeywordDetector::CKeywordDetector()
#pragma code_seg("PAGE")
_IRQL_requires_max_(PASSIVE_LEVEL)
+NTSTATUS CKeywordDetector::ReadKeywordTimestampRegistry()
+{
+ PAGED_CODE();
+
+ NTSTATUS ntStatus;
+ UNICODE_STRING parametersPath;
+
+ RTL_QUERY_REGISTRY_TABLE paramTable[] = {
+ // QueryRoutine Flags Name EntryContext DefaultType DefaultData DefaultLength
+ { NULL, RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_TYPECHECK, L"KeywordDetectorStartTimestamp", &m_ullKeywordStartTimestamp, (REG_QWORD << RTL_QUERY_REGISTRY_TYPECHECK_SHIFT) | REG_QWORD, &m_ullKeywordStartTimestamp, sizeof(ULONGLONG) },
+ { NULL, RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_TYPECHECK, L"KeywordDetectorStopTimestamp", &m_ullKeywordStopTimestamp, (REG_QWORD << RTL_QUERY_REGISTRY_TYPECHECK_SHIFT) | REG_QWORD, &m_ullKeywordStopTimestamp, sizeof(ULONGLONG) },
+ { NULL, 0, NULL, NULL, 0, NULL, 0 }
+ };
+
+ RtlInitUnicodeString(&parametersPath, NULL);
+
+ // The sizeof(WCHAR) is added to the maximum length, for allowing a space for null termination of the string.
+ parametersPath.MaximumLength =
+ g_RegistryPath.Length + sizeof(L"\\Parameters") + sizeof(WCHAR);
+
+ parametersPath.Buffer = (PWCH)ExAllocatePoolWithTag(PagedPool, parametersPath.MaximumLength, MINWAVERT_POOLTAG);
+ if (parametersPath.Buffer == NULL)
+ {
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ RtlZeroMemory(parametersPath.Buffer, parametersPath.MaximumLength);
+
+ RtlAppendUnicodeToString(&parametersPath, g_RegistryPath.Buffer);
+ RtlAppendUnicodeToString(&parametersPath, L"\\Parameters");
+
+ ntStatus = RtlQueryRegistryValues(
+ RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
+ parametersPath.Buffer,
+ &paramTable[0],
+ NULL,
+ NULL
+ );
+
+ ExFreePool(parametersPath.Buffer);
+
+ return ntStatus;
+}
+
+
+#pragma code_seg("PAGE")
+_IRQL_requires_max_(PASSIVE_LEVEL)
VOID CKeywordDetector::ResetDetector()
{
PAGED_CODE();
@@ -2532,6 +2953,24 @@ LONGLONG CKeywordDetector::GetDetectorData()
#pragma code_seg("PAGE")
_IRQL_requires_max_(PASSIVE_LEVEL)
+ULONGLONG CKeywordDetector::GetStartTimestamp()
+{
+ PAGED_CODE();
+
+ return m_ullKeywordStartTimestamp;
+}
+
+#pragma code_seg("PAGE")
+_IRQL_requires_max_(PASSIVE_LEVEL)
+ULONGLONG CKeywordDetector::GetStopTimestamp()
+{
+ PAGED_CODE();
+
+ return m_ullKeywordStopTimestamp;
+}
+
+#pragma code_seg("PAGE")
+_IRQL_requires_max_(PASSIVE_LEVEL)
VOID CKeywordDetector::ResetFifo()
{
PAGED_CODE();
@@ -2555,14 +2994,16 @@ NTSTATUS CKeywordDetector::SetArmed(_In_ BOOL Arm)
PAGED_CODE();
BOOL previousArming = m_SoundDetectorArmed;
+ NTSTATUS ntStatus = STATUS_SUCCESS;
m_SoundDetectorArmed = Arm;
if (Arm && !previousArming && m_qpcStartCapture == 0)
{
+ ntStatus = ReadKeywordTimestampRegistry();
StartBufferingStream();
}
- return STATUS_SUCCESS;
+ return ntStatus;
}
#pragma code_seg("PAGE")
@@ -2632,7 +3073,6 @@ VOID CKeywordDetector::DpcRoutine(_In_ LONGLONG PerformanceCounter, _In_ LONGLON
{
LIST_ENTRY* packetListEntry;
PACKET_ENTRY* packetEntry;
- LONGLONG* signature;
do
{
@@ -2656,12 +3096,6 @@ VOID CKeywordDetector::DpcRoutine(_In_ LONGLONG PerformanceCounter, _In_ LONGLON
RtlZeroMemory(&packetEntry->Samples[0], sizeof(packetEntry->Samples));
- // For test purposes, embed the packet number and sample time into the audio data
- signature = (LONGLONG*)(&packetEntry->Samples[0]);
-
- signature[0] = packetEntry->PacketNumber;
- signature[1] = packetEntry->QpcWhenSampled;
-
ExInterlockedInsertTailList(&PacketFifoHead, packetListEntry, &PacketFifoSpinLock);
packetsToQueue -= 1;
@@ -2718,3 +3152,6 @@ Exit:
return ntStatus;
}
+#pragma code_seg()
+
+
diff --git a/audio/sysvad/EndpointsCommon/minwavert.h b/audio/sysvad/EndpointsCommon/minwavert.h
index da31f172..0e91708b 100644
--- a/audio/sysvad/EndpointsCommon/minwavert.h
+++ b/audio/sysvad/EndpointsCommon/minwavert.h
@@ -46,6 +46,12 @@ public:
LONGLONG GetDetectorData();
_IRQL_requires_max_(PASSIVE_LEVEL)
+ ULONGLONG GetStartTimestamp();
+
+ _IRQL_requires_max_(PASSIVE_LEVEL)
+ ULONGLONG GetStopTimestamp();
+
+ _IRQL_requires_max_(PASSIVE_LEVEL)
NTSTATUS SetArmed(_In_ BOOL Arm);
_IRQL_requires_max_(PASSIVE_LEVEL)
@@ -68,6 +74,9 @@ private:
VOID ResetFifo();
_IRQL_requires_max_(PASSIVE_LEVEL)
+ NTSTATUS ReadKeywordTimestampRegistry();
+
+ _IRQL_requires_max_(PASSIVE_LEVEL)
VOID StartBufferingStream();
// The Contoso keyword detector processes 10ms packets of 16KHz 16-bit PCM
@@ -89,6 +98,9 @@ private:
LONGLONG m_qpcStartCapture;
LONGLONG m_nLastQueuedPacket;
+ ULONGLONG m_ullKeywordStartTimestamp;
+ ULONGLONG m_ullKeywordStopTimestamp;
+
KSPIN_LOCK PacketPoolSpinLock;
LIST_ENTRY PacketPoolHead;
PACKET_ENTRY PacketPool[1 * SamplesPerSecond / SamplesPerPacket]; // Enough storage for 1 second of audio data
@@ -111,13 +123,12 @@ private:
ULONG m_ulLoopbackAllocated;
ULONG m_ulSystemAllocated;
ULONG m_ulOffloadAllocated;
- DWORD m_dwCaptureAllocatedModes;
- DWORD m_dwBiDiCaptureAllocatedModes;
- DWORD m_dwSystemAllocatedModes;
+ ULONG m_ulKeywordDetectorAllocated;
ULONG m_ulMaxSystemStreams;
ULONG m_ulMaxOffloadStreams;
ULONG m_ulMaxLoopbackStreams;
+ ULONG m_ulMaxKeywordDetectorStreams;
// weak ref of running streams.
PCMiniportWaveRTStream * m_SystemStreams;
@@ -132,6 +143,7 @@ private:
PKSDATAFORMAT_WAVEFORMATEXTENSIBLE m_pDeviceFormat;
PCFILTER_DESCRIPTOR m_FilterDesc;
PIN_DEVICE_FORMATS_AND_MODES * m_DeviceFormatsAndModes;
+ FAST_MUTEX m_DeviceFormatsAndModesLock; // To serialize access.
ULONG m_DeviceFormatsAndModesCount;
USHORT m_DeviceMaxChannels;
PDRMPORT m_pDrmPort;
@@ -143,9 +155,9 @@ private:
union {
PVOID m_DeviceContext;
-#ifdef SYSVAD_BTH_BYPASS
- PBTHHFPDEVICECOMMON m_BthHfpDevice;
-#endif // SYSVAD_BTH_BYPASS
+#if defined(SYSVAD_BTH_BYPASS)
+ PSIDEBANDDEVICECOMMON m_pSidebandDevice;
+#endif // defined(SYSVAD_BTH_BYPASS)
};
AUDIOMODULE * m_pAudioModules;
@@ -165,6 +177,11 @@ public:
DECLARE_PROPERTYHANDLER(Get_SoundDetectorArmed);
DECLARE_PROPERTYHANDLER(Set_SoundDetectorArmed);
DECLARE_PROPERTYHANDLER(Get_SoundDetectorMatchResult);
+
+ NTSTATUS EventHandler_PinCapsChange
+ (
+ _In_ PPCEVENT_REQUEST EventRequest
+ );
NTSTATUS EventHandler_SoundDetectorMatchDetected
(
@@ -174,8 +191,7 @@ public:
NTSTATUS ValidateStreamCreate
(
_In_ ULONG _Pin,
- _In_ BOOLEAN _Capture,
- _In_ GUID _SignalProcessingMode
+ _In_ BOOLEAN _Capture
);
NTSTATUS StreamCreated
@@ -215,6 +231,21 @@ protected:
_In_ CONSTRICTOR_OPTION ulProtectionOption
);
+ VOID AddEventToEventList
+ (
+ _In_ PKSEVENT_ENTRY EventEntry
+ );
+
+ VOID GenerateEventList
+ (
+ _In_opt_ GUID *Set,
+ _In_ ULONG EventId,
+ _In_ BOOL PinEvent,
+ _In_ ULONG PinId,
+ _In_ BOOL NodeEvent,
+ _In_ ULONG NodeId
+ );
+
public:
DECLARE_STD_UNKNOWN();
@@ -223,13 +254,14 @@ public:
_In_ PUNKNOWN UnknownAdapter,
_In_ PENDPOINT_MINIPAIR MiniportPair,
_In_opt_ PVOID DeviceContext
- )
+ )
:CUnknown(0),
m_ulMaxSystemStreams(0),
m_ulMaxOffloadStreams(0),
m_ulMaxLoopbackStreams(0),
+ m_ulMaxKeywordDetectorStreams(0),
m_DeviceType(MiniportPair->DeviceType),
- m_DeviceContext(DeviceContext),
+ m_DeviceContext(DeviceContext),
m_DeviceMaxChannels(MiniportPair->DeviceMaxChannels),
m_DeviceFormatsAndModes(MiniportPair->PinDeviceFormatsAndModes),
m_DeviceFormatsAndModesCount(MiniportPair->PinDeviceFormatsAndModesCount),
@@ -241,7 +273,7 @@ public:
PAGED_CODE();
m_pAdapterCommon = (PADAPTERCOMMON)UnknownAdapter; // weak ref.
-
+
if (MiniportPair->WaveDescriptor)
{
RtlCopyMemory(&m_FilterDesc, MiniportPair->WaveDescriptor, sizeof(m_FilterDesc));
@@ -267,20 +299,48 @@ public:
m_ulMaxSystemStreams = m_FilterDesc.Pins[KSPIN_WAVE_RENDER2_SINK_SYSTEM].MaxFilterInstanceCount;
m_ulMaxLoopbackStreams = m_FilterDesc.Pins[KSPIN_WAVE_RENDER2_SINK_LOOPBACK].MaxFilterInstanceCount;
}
+ else if(m_FilterDesc.PinCount > KSPIN_WAVE_RENDER3_SOURCE)
+ {
+ m_ulMaxSystemStreams = m_FilterDesc.Pins[KSPIN_WAVE_RENDER3_SINK_SYSTEM].MaxFilterInstanceCount;
+ }
+ }
+ }
+ else
+ {
+ // cellular capture follows a different pin ordering than a standard wavein pin & bridge.
+ if (IsCellularDevice())
+ {
+ m_ulMaxSystemStreams = m_FilterDesc.Pins[KSPIN_WAVE_BIDI].MaxFilterInstanceCount;
+ }
+ else
+ {
+ //
+ // >= comparison here because capture bridge pin comes first in the enumeration
+ //
+ if (m_FilterDesc.PinCount >= KSPIN_WAVEIN_HOST)
+ {
+ m_ulMaxSystemStreams = m_FilterDesc.Pins[KSPIN_WAVEIN_HOST].MaxFilterInstanceCount;
+ }
+ if (m_FilterDesc.PinCount >= KSPIN_WAVEIN_KEYWORD)
+ {
+ m_ulMaxKeywordDetectorStreams = m_FilterDesc.Pins[KSPIN_WAVEIN_KEYWORD].MaxFilterInstanceCount;
+ }
}
}
}
-#ifdef SYSVAD_BTH_BYPASS
- if (IsBthHfpDevice())
+#if defined(SYSVAD_BTH_BYPASS)
+ if (IsSidebandDevice())
{
- if (m_BthHfpDevice != NULL)
+ if (m_pSidebandDevice != NULL)
{
// This ref is released on dtor.
- m_BthHfpDevice->AddRef(); // strong ref.
+ m_pSidebandDevice->AddRef(); // strong ref.
}
+
}
-#endif // SYSVAD_BTH_BYPASS
+ ExInitializeFastMutex(&m_DeviceFormatsAndModesLock);
+#endif // defined(SYSVAD_BTH_BYPASS)
}
#pragma code_seg()
@@ -320,6 +380,11 @@ public:
(
_In_ PPCPROPERTY_REQUEST PropertyRequest
);
+
+ NTSTATUS PropertyHandlerAudioEffectsDiscoveryEffectsList
+ (
+ _In_ PPCPROPERTY_REQUEST PropertyRequest
+ );
NTSTATUS PropertyHandlerModulesListRequest
(
@@ -441,16 +506,23 @@ private:
{
PAGED_CODE();
+ PPIN_DEVICE_FORMATS_AND_MODES pDeviceFormatsAndModes = NULL;
+
+ ExAcquireFastMutex(&m_DeviceFormatsAndModesLock);
+
+ pDeviceFormatsAndModes = m_DeviceFormatsAndModes;
ASSERT(m_DeviceFormatsAndModesCount > PinId);
- ASSERT(m_DeviceFormatsAndModes[PinId].WaveFormats != NULL);
- ASSERT(m_DeviceFormatsAndModes[PinId].WaveFormatsCount > 0);
+ ASSERT(pDeviceFormatsAndModes[PinId].WaveFormats != NULL);
+ ASSERT(pDeviceFormatsAndModes[PinId].WaveFormatsCount > 0);
if (ppFormats != NULL)
{
- *ppFormats = m_DeviceFormatsAndModes[PinId].WaveFormats;
+ *ppFormats = pDeviceFormatsAndModes[PinId].WaveFormats;
}
- return m_DeviceFormatsAndModes[PinId].WaveFormatsCount;
+ ExReleaseFastMutex(&m_DeviceFormatsAndModesLock);
+
+ return pDeviceFormatsAndModes[PinId].WaveFormatsCount;
}
//---------------------------------------------------------------------------
@@ -470,9 +542,14 @@ private:
ULONG GetAudioEngineSupportedDeviceFormats(_Outptr_opt_result_buffer_(return) KSDATAFORMAT_WAVEFORMATEXTENSIBLE **ppFormats)
{
ULONG i;
+ PPIN_DEVICE_FORMATS_AND_MODES pDeviceFormatsAndModes = NULL;
PAGED_CODE();
+ ExAcquireFastMutex(&m_DeviceFormatsAndModesLock);
+
+ pDeviceFormatsAndModes = m_DeviceFormatsAndModes;
+
// By convention, the audio engine node's device formats are the last
// entry in the PIN_DEVICE_FORMATS_AND_MODES list.
@@ -482,16 +559,17 @@ private:
i = m_DeviceFormatsAndModesCount - 1; // Index of last list entry
- ASSERT(m_DeviceFormatsAndModes[i].PinType == NoPin);
- ASSERT(m_DeviceFormatsAndModes[i].WaveFormats != NULL);
- ASSERT(m_DeviceFormatsAndModes[i].WaveFormatsCount > 0);
+ ASSERT(pDeviceFormatsAndModes[i].PinType == NoPin);
+ ASSERT(pDeviceFormatsAndModes[i].WaveFormats != NULL);
+ ASSERT(pDeviceFormatsAndModes[i].WaveFormatsCount > 0);
if (ppFormats != NULL)
{
- *ppFormats = m_DeviceFormatsAndModes[i].WaveFormats;
+ *ppFormats = pDeviceFormatsAndModes[i].WaveFormats;
}
- return m_DeviceFormatsAndModes[i].WaveFormatsCount;
+ ExReleaseFastMutex(&m_DeviceFormatsAndModesLock);
+ return pDeviceFormatsAndModes[i].WaveFormatsCount;
}
//---------------------------------------------------------------------------
@@ -514,6 +592,8 @@ private:
PAGED_CODE();
+ ExAcquireFastMutex(&m_DeviceFormatsAndModesLock);
+
ASSERT(m_DeviceFormatsAndModesCount > PinId);
ASSERT((m_DeviceFormatsAndModes[PinId].ModeAndDefaultFormatCount == 0) == (m_DeviceFormatsAndModes[PinId].ModeAndDefaultFormat == NULL));
@@ -524,8 +604,8 @@ private:
// Special handling for the SCO bypass endpoint, whose modes are determined at runtime
if (m_DeviceType == eBthHfpMicDevice)
{
- ASSERT(m_BthHfpDevice != NULL);
- if (m_BthHfpDevice->IsNRECSupported())
+ ASSERT(m_pSidebandDevice != NULL);
+ if (m_pSidebandDevice->IsNRECSupported())
{
modes = BthHfpMicPinSupportedDeviceModesNrec;
numModes = ARRAYSIZE(BthHfpMicPinSupportedDeviceModesNrec);
@@ -554,6 +634,7 @@ private:
}
}
+ ExReleaseFastMutex(&m_DeviceFormatsAndModesLock);
return numModes;
}
#pragma code_seg()
@@ -578,6 +659,16 @@ protected:
return (m_DeviceType == eCellularDevice) ? TRUE : FALSE;
}
+ BOOL IsLoopbackSupported()
+ {
+ PAGED_CODE();
+
+ //
+ // It is assumed that loopback is supported when offload is supported
+ //
+ return (m_DeviceFlags & (ENDPOINT_LOOPBACK_SUPPORTED | ENDPOINT_OFFLOAD_SUPPORTED)) ? TRUE : FALSE;
+ }
+
BOOL IsOffloadSupported()
{
PAGED_CODE();
@@ -586,40 +677,79 @@ protected:
BOOL IsSystemCapturePin(ULONG nPinId)
{
- PINTYPE pinType = m_DeviceFormatsAndModes[nPinId].PinType;
PAGED_CODE();
+ ExAcquireFastMutex(&m_DeviceFormatsAndModesLock);
+
+ PINTYPE pinType = m_DeviceFormatsAndModes[nPinId].PinType;
+
+ ExReleaseFastMutex(&m_DeviceFormatsAndModesLock);
return (pinType == SystemCapturePin);
}
BOOL IsCellularBiDiCapturePin(ULONG nPinId)
{
PAGED_CODE();
- return (m_DeviceFormatsAndModes[nPinId].PinType == TelephonyBidiPin);
+ ExAcquireFastMutex(&m_DeviceFormatsAndModesLock);
+
+ PINTYPE pinType = m_DeviceFormatsAndModes[nPinId].PinType;
+
+ ExReleaseFastMutex(&m_DeviceFormatsAndModesLock);
+ return (pinType == TelephonyBidiPin);
}
BOOL IsSystemRenderPin(ULONG nPinId)
{
- PINTYPE pinType = m_DeviceFormatsAndModes[nPinId].PinType;
PAGED_CODE();
+ ExAcquireFastMutex(&m_DeviceFormatsAndModesLock);
+
+ PINTYPE pinType = m_DeviceFormatsAndModes[nPinId].PinType;
+
+ ExReleaseFastMutex(&m_DeviceFormatsAndModesLock);
return (pinType == SystemRenderPin);
}
BOOL IsLoopbackPin(ULONG nPinId)
{
PAGED_CODE();
- return (m_DeviceFormatsAndModes[nPinId].PinType == RenderLoopbackPin);
+ ExAcquireFastMutex(&m_DeviceFormatsAndModesLock);
+
+ PINTYPE pinType = m_DeviceFormatsAndModes[nPinId].PinType;
+
+ ExReleaseFastMutex(&m_DeviceFormatsAndModesLock);
+ return (pinType == RenderLoopbackPin);
}
BOOL IsOffloadPin(ULONG nPinId)
{
PAGED_CODE();
- return (m_DeviceFormatsAndModes[nPinId].PinType == OffloadRenderPin);
+ ExAcquireFastMutex(&m_DeviceFormatsAndModesLock);
+
+ PINTYPE pinType = m_DeviceFormatsAndModes[nPinId].PinType;
+
+ ExReleaseFastMutex(&m_DeviceFormatsAndModesLock);
+ return (pinType == OffloadRenderPin);
}
BOOL IsBridgePin(ULONG nPinId)
{
PAGED_CODE();
- return (m_DeviceFormatsAndModes[nPinId].PinType == BridgePin);
+ ExAcquireFastMutex(&m_DeviceFormatsAndModesLock);
+
+ PINTYPE pinType = m_DeviceFormatsAndModes[nPinId].PinType;
+
+ ExReleaseFastMutex(&m_DeviceFormatsAndModesLock);
+ return (pinType == BridgePin);
+ }
+
+ BOOL IsKeywordDetectorPin(ULONG nPinId)
+ {
+ PAGED_CODE();
+ ExAcquireFastMutex(&m_DeviceFormatsAndModesLock);
+
+ PINTYPE pinType = m_DeviceFormatsAndModes[nPinId].PinType;
+
+ ExReleaseFastMutex(&m_DeviceFormatsAndModesLock);
+ return (pinType == KeywordCapturePin);
}
// These three pins are the pins used by the audio engine for host, loopback, and offload.
@@ -713,36 +843,46 @@ protected:
_In_ ULONG AudioModuleCount
);
-#ifdef SYSVAD_BTH_BYPASS
+#if defined(SYSVAD_BTH_BYPASS)
public:
-#pragma code_seg("PAGE")
- BOOL IsBthHfpDevice()
+#pragma code_seg()
+ BOOL IsSidebandDevice()
{
- PAGED_CODE();
return (m_DeviceType == eBthHfpMicDevice ||
- m_DeviceType == eBthHfpSpeakerDevice) ? TRUE : FALSE;
+ m_DeviceType == eBthHfpSpeakerDevice ) ? TRUE : FALSE;
}
// Returns a weak ref to the Bluetooth HFP device.
- PBTHHFPDEVICECOMMON GetBthHfpDevice()
+ PSIDEBANDDEVICECOMMON GetSidebandDevice()
{
- PBTHHFPDEVICECOMMON bthHfpDevice = NULL;
+ PSIDEBANDDEVICECOMMON sidebandDevice = NULL;
- PAGED_CODE();
- if (IsBthHfpDevice())
+ if (IsSidebandDevice())
{
- if (m_BthHfpDevice != NULL)
+ if (m_pSidebandDevice != NULL)
{
- bthHfpDevice = m_BthHfpDevice;
+ sidebandDevice = m_pSidebandDevice;
}
}
- return bthHfpDevice;
+ return sidebandDevice;
}
#pragma code_seg()
-#endif // SYSVAD_BTH_BYPASS
+#endif // defined(SYSVAD_BTH_BYPASS)
+
+#ifdef SYSVAD_BTH_BYPASS
+#pragma code_seg()
+ static
+ VOID
+ EvtFormatChangeHandler
+ (
+ _In_opt_ PVOID Context
+ );
+
+#endif //#ifdef SYSVAD_BTH_BYPASS
};
+
typedef CMiniportWaveRT *PCMiniportWaveRT;
#endif // _SYSVAD_MINWAVERT_H_
diff --git a/audio/sysvad/EndpointsCommon/minwavertstream.cpp b/audio/sysvad/EndpointsCommon/minwavertstream.cpp
index 1661b5fb..e5dad74f 100644
--- a/audio/sysvad/EndpointsCommon/minwavertstream.cpp
+++ b/audio/sysvad/EndpointsCommon/minwavertstream.cpp
@@ -35,7 +35,6 @@ Return Value:
--*/
{
PAGED_CODE();
-
if (NULL != m_pMiniport)
{
if (m_pAudioModules)
@@ -44,7 +43,7 @@ Return Value:
m_pAudioModules = NULL;
m_AudioModuleCount = 0;
}
-
+
if (m_bUnregisterStream)
{
m_pMiniport->StreamClosed(m_ulPin, this);
@@ -92,8 +91,13 @@ Return Value:
}
if (m_pNotificationTimer)
{
- KeCancelTimer(m_pNotificationTimer);
- ExFreePoolWithTag(m_pNotificationTimer, MINWAVERTSTREAM_POOLTAG);
+ ExDeleteTimer
+ (
+ m_pNotificationTimer,
+ TRUE, // Cancel the timer if it is currently set.
+ TRUE, // Wait for the timer to finish expiring and for any callback to a ExTimerCallback routine to finish.
+ NULL
+ );
}
// Since we just cancelled the notification timer, wait for all queued
@@ -101,13 +105,9 @@ Return Value:
//
KeFlushQueuedDpcs();
- if (m_pNotificationDpc)
- {
- ExFreePoolWithTag( m_pNotificationDpc, MINWAVERTSTREAM_POOLTAG );
- }
-
#ifdef SYSVAD_BTH_BYPASS
- ASSERT(m_ScoOpen == FALSE);
+ ASSERT(m_SidebandOpen == FALSE);
+ ASSERT(m_SidebandStarted == FALSE);
#endif // SYSVAD_BTH_BYPASS
DPF_ENTER(("[CMiniportWaveRTStream::~CMiniportWaveRTStream]"));
@@ -115,6 +115,55 @@ Return Value:
//=============================================================================
#pragma code_seg("PAGE")
+
+NTSTATUS CMiniportWaveRTStream::ReadRegistrySettings()
+{
+ NTSTATUS ntStatus;
+ UNICODE_STRING parametersPath;
+
+ RTL_QUERY_REGISTRY_TABLE paramTable[] = {
+ // QueryRoutine Flags Name EntryContext DefaultType DefaultData DefaultLength
+ { NULL, RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_TYPECHECK, L"HostCaptureToneFrequency", &m_ulHostCaptureToneFrequency, (REG_DWORD << RTL_QUERY_REGISTRY_TYPECHECK_SHIFT) | REG_DWORD, &m_ulHostCaptureToneFrequency, sizeof(DWORD) },
+ { NULL, RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_TYPECHECK, L"LoopbackCaptureToneFrequency", &m_ulLoopbackCaptureToneFrequency, (REG_DWORD << RTL_QUERY_REGISTRY_TYPECHECK_SHIFT) | REG_DWORD, &m_ulLoopbackCaptureToneFrequency, sizeof(DWORD) },
+ { NULL, RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_TYPECHECK, L"HostCaptureToneAmplitude", &m_dwHostCaptureToneAmplitude, (REG_DWORD << RTL_QUERY_REGISTRY_TYPECHECK_SHIFT) | REG_DWORD, &m_dwHostCaptureToneAmplitude, sizeof(DWORD) },
+ { NULL, RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_TYPECHECK, L"LoopbackCaptureToneAmplitude", &m_dwLoopbackCaptureToneAmplitude, (REG_DWORD << RTL_QUERY_REGISTRY_TYPECHECK_SHIFT) | REG_DWORD, &m_dwLoopbackCaptureToneAmplitude, sizeof(DWORD) },
+ { NULL, RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_TYPECHECK, L"HostCaptureToneDCOffset", &m_dwHostCaptureToneDCOffset, (REG_DWORD << RTL_QUERY_REGISTRY_TYPECHECK_SHIFT) | REG_DWORD, &m_dwHostCaptureToneDCOffset, sizeof(DWORD) },
+ { NULL, RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_TYPECHECK, L"LoopbackCaptureToneDCOffset", &m_dwLoopbackCaptureToneDCOffset, (REG_DWORD << RTL_QUERY_REGISTRY_TYPECHECK_SHIFT) | REG_DWORD, &m_dwLoopbackCaptureToneDCOffset, sizeof(DWORD) },
+ { NULL, RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_TYPECHECK, L"HostCaptureToneInitialPhase", &m_dwHostCaptureToneInitialPhase, (REG_DWORD << RTL_QUERY_REGISTRY_TYPECHECK_SHIFT) | REG_DWORD, &m_dwHostCaptureToneInitialPhase, sizeof(DWORD) },
+ { NULL, RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_TYPECHECK, L"LoopbackCaptureToneInitialPhase", &m_dwLoopbackCaptureToneInitialPhase, (REG_DWORD << RTL_QUERY_REGISTRY_TYPECHECK_SHIFT) | REG_DWORD, &m_dwLoopbackCaptureToneInitialPhase, sizeof(DWORD) },
+ { NULL, 0, NULL, NULL, 0, NULL, 0 }
+ };
+
+ RtlInitUnicodeString(&parametersPath, NULL);
+
+ // The sizeof(WCHAR) is added to the maximum length, for allowing a space for null termination of the string.
+ parametersPath.MaximumLength =
+ g_RegistryPath.Length + sizeof(L"\\Parameters") + sizeof(WCHAR);
+
+ parametersPath.Buffer = (PWCH)ExAllocatePoolWithTag(PagedPool, parametersPath.MaximumLength, MINWAVERT_POOLTAG);
+ if (parametersPath.Buffer == NULL)
+ {
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ RtlZeroMemory(parametersPath.Buffer, parametersPath.MaximumLength);
+
+ RtlAppendUnicodeToString(&parametersPath, g_RegistryPath.Buffer);
+ RtlAppendUnicodeToString(&parametersPath, L"\\Parameters");
+
+ ntStatus = RtlQueryRegistryValues(
+ RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
+ parametersPath.Buffer,
+ &paramTable[0],
+ NULL,
+ NULL
+ );
+
+ ExFreePool(parametersPath.Buffer);
+
+ return ntStatus;
+}
+
NTSTATUS
CMiniportWaveRTStream::Init
(
@@ -193,9 +242,20 @@ Return Value:
m_pAudioModules = NULL;
m_AudioModuleCount = 0;
-#ifdef SYSVAD_BTH_BYPASS
- m_ScoOpen = FALSE;
-#endif // SYSVAD_BTH_BYPASS
+ m_ulHostCaptureToneFrequency = IsEqualGUID(SignalProcessingMode, AUDIO_SIGNALPROCESSINGMODE_RAW) ? 1000 : 2000;
+ m_ulLoopbackCaptureToneFrequency = 3000; // 3 kHz
+ m_dwHostCaptureToneAmplitude = 50;
+ m_dwLoopbackCaptureToneAmplitude = 50;
+ m_dwHostCaptureToneDCOffset = 0;
+ m_dwLoopbackCaptureToneDCOffset = 0;
+ m_dwHostCaptureToneInitialPhase = 0;
+ m_dwLoopbackCaptureToneInitialPhase = 0;
+
+
+#if defined(SYSVAD_BTH_BYPASS)
+ m_SidebandOpen = FALSE;
+ m_SidebandStarted = FALSE;
+#endif // defined(SYSVAD_BTH_BYPASS)
m_pPortStream = PortStream_;
InitializeListHead(&m_NotificationList);
@@ -204,27 +264,16 @@ Return Value:
// Initialize the spinlock to synchronize position updates
KeInitializeSpinLock(&m_PositionSpinLock);
- m_pNotificationDpc = (PRKDPC)ExAllocatePoolWithTag(
- NonPagedPoolNx,
- sizeof(KDPC),
- MINWAVERTSTREAM_POOLTAG);
- if (!m_pNotificationDpc)
- {
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- m_pNotificationTimer = (PKTIMER)ExAllocatePoolWithTag(
- NonPagedPoolNx,
- sizeof(KTIMER),
- MINWAVERTSTREAM_POOLTAG);
+ m_pNotificationTimer = ExAllocateTimer(
+ TimerNotifyRT,
+ this,
+ EX_TIMER_HIGH_RESOLUTION
+ );
if (!m_pNotificationTimer)
{
return STATUS_INSUFFICIENT_RESOURCES;
}
- KeInitializeDpc(m_pNotificationDpc, TimerNotifyRT, this);
- KeInitializeTimerEx(m_pNotificationTimer, NotificationTimer);
-
pWfEx = GetWaveFormatEx(DataFormat_);
if (NULL == pWfEx)
{
@@ -292,25 +341,69 @@ Return Value:
if (m_bCapture)
{
- DWORD toneFrequency = 0;
+ ReadRegistrySettings();
+ DWORD toneFrequency = 0;
+ DWORD toneAmplitude = 0;
+ DWORD toneDCOffset = 0;
+ DWORD toneInitialPhase = 0;
- if (m_pMiniport->IsLoopbackPin(Pin_))
- {
- //
- // Loopbacks pins use a different frequency for test validation.
- //
- toneFrequency = 3000; // 3 kHz
- }
- else
- {
- //
- // Init sine wave generator. To exercise the SignalProcessingMode parameter
- // this sample driver selects the frequency based on the parameter.
- //
- toneFrequency = IsEqualGUID(SignalProcessingMode, AUDIO_SIGNALPROCESSINGMODE_RAW) ? 1000 : 2000;
- }
+ double toneAmplitudeDouble = 0;
+ double toneDCOffsetDouble = 0;
+ double toneInitialPhaseDouble = 0;
+
+ if (m_pMiniport->IsLoopbackPin(Pin_))
+ {
+ //
+ // Loopbacks pins use a different frequency for test validation.
+ //
+ toneFrequency = m_ulLoopbackCaptureToneFrequency;
+ toneAmplitude = m_dwLoopbackCaptureToneAmplitude;
+ toneDCOffset = m_dwLoopbackCaptureToneDCOffset;
+ toneInitialPhase = m_dwLoopbackCaptureToneInitialPhase;
+ }
+ else
+ {
+ //
+ // Init sine wave generator. To exercise the SignalProcessingMode parameter
+ // this sample driver selects the frequency based on the parameter.
+ //
+ toneFrequency = m_ulHostCaptureToneFrequency;
+ toneAmplitude = m_dwHostCaptureToneAmplitude;
+ toneDCOffset = m_dwHostCaptureToneDCOffset;
+ toneInitialPhase = m_dwHostCaptureToneInitialPhase;
+ }
+
+ if (labs(toneAmplitude) > 100)
+ {
+ toneAmplitude = toneAmplitude > 0 ? 100 : -100;
+ }
- ntStatus = m_ToneGenerator.Init(toneFrequency, m_pWfExt);
+ if (labs(toneDCOffset) > 100)
+ {
+ toneDCOffset = toneDCOffset > 0 ? 100 : -100;
+ }
+
+ DWORD abssum = labs(toneAmplitude) + labs(toneDCOffset);
+
+ if ( abssum > 100)
+ {
+ toneAmplitudeDouble = ((double)toneAmplitude) / abssum;
+ toneDCOffsetDouble = ((double)toneDCOffset) / abssum;
+ }
+ else
+ {
+ toneAmplitudeDouble = ((double)toneAmplitude) / 100.0;
+ toneDCOffsetDouble = ((double)toneDCOffset) / 100.0;
+ }
+
+ if (labs(toneInitialPhase) > 31416)
+ {
+ toneInitialPhase = toneInitialPhase > 0 ? 31416 : -31416;
+ }
+
+ toneInitialPhaseDouble = (double)toneInitialPhase / 10000;
+
+ ntStatus = m_ToneGenerator.Init(toneFrequency, toneAmplitudeDouble, toneDCOffsetDouble, toneInitialPhaseDouble, m_pWfExt);
if (!NT_SUCCESS(ntStatus))
{
return ntStatus;
@@ -393,9 +486,10 @@ Return Value:
// This interface is supported only on capture streams
*Object = PVOID(PMINIPORTWAVERTINPUTSTREAM(this));
}
- else if (IsEqualGUIDAligned(Interface, IID_IMiniportWaveRTOutputStream) && (!this->m_bCapture))
+ else if (IsEqualGUIDAligned(Interface, IID_IMiniportWaveRTOutputStream) && (!this->m_bCapture)
+ && (!this->m_pMiniport->IsOffloadPin(this->m_ulPin)))
{
- // This interface is supported only on render streams
+ // This interface is supported only on host render streams
*Object = PVOID(PMINIPORTWAVERTOUTPUTSTREAM(this));
}
else if (IsEqualGUIDAligned(Interface, IID_IMiniportStreamAudioEngineNode))
@@ -749,16 +843,16 @@ NTSTATUS CMiniportWaveRTStream::GetPosition
{
NTSTATUS ntStatus;
-#ifdef SYSVAD_BTH_BYPASS
- if (m_ScoOpen)
+#if defined(SYSVAD_BTH_BYPASS)
+ if (m_SidebandStarted)
{
- ntStatus = GetScoStreamNtStatus();
+ ntStatus = GetSidebandStreamNtStatus();
IF_FAILED_JUMP(ntStatus, Done);
}
-#endif // SYSVAD_BTH_BYPASS
+#endif // defined(SYSVAD_BTH_BYPASS)
// Return failure if this is the keyword detector pin
- if (m_pMiniport->m_DeviceFormatsAndModes[m_ulPin].PinType == PINTYPE::KeywordCapturePin)
+ if (m_pMiniport->IsKeywordDetectorPin(m_ulPin))
{
return STATUS_NOT_SUPPORTED;
}
@@ -782,9 +876,9 @@ NTSTATUS CMiniportWaveRTStream::GetPosition
ntStatus = STATUS_SUCCESS;
-#ifdef SYSVAD_BTH_BYPASS
+#if defined(SYSVAD_BTH_BYPASS)
Done:
-#endif // SYSVAD_BTH_BYPASS
+#endif // defined(SYSVAD_BTH_BYPASS)
return ntStatus;
}
@@ -806,7 +900,6 @@ Done:
//
// ISSUE-2014/10/4 Will this work correctly across pause/play?
#pragma code_seg()
-_IRQL_requires_max_(PASSIVE_LEVEL)
NTSTATUS CMiniportWaveRTStream::GetReadPacket
(
_Out_ ULONG *PacketNumber,
@@ -833,7 +926,7 @@ NTSTATUS CMiniportWaveRTStream::GetReadPacket
}
// If this is the keyword detector pin, then stream from the keyword FIFO
- if (m_pMiniport->m_DeviceFormatsAndModes[m_ulPin].PinType == PINTYPE::KeywordCapturePin)
+ if (m_pMiniport->IsKeywordDetectorPin(m_ulPin))
{
// FUTURE-2014/11/18 Drive this with packet counter
ntStatus = m_pMiniport->m_KeywordDetector.GetReadPacket(m_ulNotificationsPerBuffer, m_ulDmaBufferSize, m_pDmaBuffer, PacketNumber, PerformanceCounterValue, MoreData);
@@ -918,7 +1011,6 @@ NTSTATUS CMiniportWaveRTStream::GetReadPacket
}
#pragma code_seg()
-_IRQL_requires_max_(PASSIVE_LEVEL)
NTSTATUS CMiniportWaveRTStream::SetWritePacket
(
_In_ ULONG PacketNumber,
@@ -1011,7 +1103,6 @@ NTSTATUS CMiniportWaveRTStream::SetWritePacket
//=============================================================================
#pragma code_seg()
-_IRQL_requires_max_(PASSIVE_LEVEL)
NTSTATUS CMiniportWaveRTStream::GetOutputStreamPresentationPosition
(
_Out_ KSAUDIO_PRESENTATION_POSITION *pPresentationPosition
@@ -1030,7 +1121,6 @@ NTSTATUS CMiniportWaveRTStream::GetOutputStreamPresentationPosition
//=============================================================================
#pragma code_seg()
-_IRQL_requires_max_(PASSIVE_LEVEL)
NTSTATUS CMiniportWaveRTStream::GetPacketCount
(
_Out_ ULONG *pPacketCount
@@ -1076,16 +1166,40 @@ NTSTATUS CMiniportWaveRTStream::SetState
//Parameter 1: Current linear buffer position
//Parameter 2: Current WaveRtBufferWritePosition
//Parameter 3: Pin State 0->KS_STOP, 1->KS_ACQUIRE, 2->KS_PAUSE, 3->KS_RUN
- //Parameter 4:0
- pAdapterComm->WriteEtwEvent(eMINIPORT_PIN_STATE,
- 100, // replace with the correct "Current linear buffer position"
+ //Parameter 4: 0
+ pAdapterComm->WriteEtwEvent(eMINIPORT_PIN_STATE,
+ m_ullLinearPosition, // replace with the correct "Current linear buffer position"
m_ulCurrentWritePosition, // replace with the previous WaveRtBufferWritePosition that the driver received
State_, // replace with the correct "Data length completed"
- 0); // always zero
-
+ 0); // always zero
switch (State_)
{
case KSSTATE_STOP:
+ if (m_KsState == KSSTATE_ACQUIRE)
+ {
+ // Acquire stream resources
+#if defined(SYSVAD_BTH_BYPASS)
+ if (m_SidebandOpen)
+ {
+ PSIDEBANDDEVICECOMMON sidebandDevice;
+
+ ASSERT(m_pMiniport->IsSidebandDevice());
+ sidebandDevice = m_pMiniport->GetSidebandDevice(); // weak ref.
+ ASSERT(sidebandDevice != NULL);
+
+ //
+ // Close the Sideband connection.
+ //
+ ntStatus = sidebandDevice->StreamClose(m_pMiniport->m_DeviceType);
+ if (!NT_SUCCESS(ntStatus))
+ {
+ DPF(D_ERROR, ("SetState: KSSTATE_PAUSE, StreamClose failed, 0x%x", ntStatus));
+ }
+
+ m_SidebandOpen = FALSE;
+ }
+#endif // defined(SYSVAD_BTH_BYPASS)
+ }
KeAcquireSpinLock(&m_PositionSpinLock, &oldIrql);
// Reset DMA
m_llPacketCounter = 0;
@@ -1108,56 +1222,38 @@ NTSTATUS CMiniportWaveRTStream::SetState
{
m_SaveData.WaitAllWorkItems();
}
-
-#ifdef SYSVAD_BTH_BYPASS
- if (m_ScoOpen)
- {
- PBTHHFPDEVICECOMMON bthHfpDevice;
-
- ASSERT(m_pMiniport->IsBthHfpDevice());
- bthHfpDevice = m_pMiniport->GetBthHfpDevice(); // weak ref.
- ASSERT(bthHfpDevice != NULL);
-
- //
- // Close the SCO connection.
- //
- ntStatus = bthHfpDevice->StreamClose();
- if (!NT_SUCCESS(ntStatus))
- {
- DPF(D_ERROR, ("SetState: KSSTATE_STOP, StreamClose failed, 0x%x", ntStatus));
- }
-
- m_ScoOpen = FALSE;
- }
-#endif // SYSVAD_BTH_BYPASS
break;
case KSSTATE_ACQUIRE:
-#ifdef SYSVAD_BTH_BYPASS
- if (m_pMiniport->IsBthHfpDevice())
+ if (m_KsState == KSSTATE_STOP)
{
- if (m_ScoOpen == FALSE)
+ // Acquire stream resources
+#if defined(SYSVAD_BTH_BYPASS)
+ if (m_pMiniport->IsSidebandDevice())
{
- PBTHHFPDEVICECOMMON bthHfpDevice;
+ if (m_SidebandOpen == FALSE)
+ {
+ PSIDEBANDDEVICECOMMON sidebandDevice;
- bthHfpDevice = m_pMiniport->GetBthHfpDevice(); // weak ref.
- ASSERT(bthHfpDevice != NULL);
+ sidebandDevice = m_pMiniport->GetSidebandDevice(); // weak ref.
+ ASSERT(sidebandDevice != NULL);
- //
- // Open the SCO connection.
- //
- ntStatus = bthHfpDevice->StreamOpen();
- IF_FAILED_ACTION_JUMP(
- ntStatus,
- DPF(D_ERROR, ("SetState: KSSTATE_ACQUIRE, StreamOpen failed, 0x%x", ntStatus)),
- Done);
+ //
+ // Open the Sideband connection.
+ //
+ ntStatus = sidebandDevice->StreamOpen(m_pMiniport->m_DeviceType);
+ IF_FAILED_ACTION_JUMP(
+ ntStatus,
+ DPF(D_ERROR, ("SetState: KSSTATE_ACQUIRE, StreamOpen failed, 0x%x", ntStatus)),
+ Done);
- m_ScoOpen = TRUE;
+ m_SidebandOpen = TRUE;
+ }
}
+#endif // defined(SYSVAD_BTH_BYPASS)
}
-#endif // SYSVAD_BTH_BYPASS
break;
-
+
case KSSTATE_PAUSE:
if (m_KsState > KSSTATE_PAUSE)
@@ -1165,7 +1261,7 @@ NTSTATUS CMiniportWaveRTStream::SetState
//
// Run -> Pause
//
- if (m_pMiniport->m_DeviceFormatsAndModes[m_ulPin].PinType == PINTYPE::KeywordCapturePin)
+ if (m_pMiniport->IsKeywordDetectorPin(m_ulPin))
{
m_pMiniport->m_KeywordDetector.Stop();
}
@@ -1173,19 +1269,81 @@ NTSTATUS CMiniportWaveRTStream::SetState
// Pause DMA
if (m_ulNotificationIntervalMs > 0)
{
- KeCancelTimer(m_pNotificationTimer);
- ExSetTimerResolution(0, FALSE);
+ ExCancelTimer(m_pNotificationTimer, NULL);
KeFlushQueuedDpcs();
+
+ // If pin is transitioning from RUN, save the time since last buffer completion event was sent
+ // so if the pin goes to RUN state again we can send the buffer completion event at correct time.
+ if (m_ullLastDPCTimeStamp > 0)
+ {
+ LARGE_INTEGER qpc;
+ LARGE_INTEGER qpcFrequency;
+ LONGLONG hnsCurrentTime;
+
+ qpc = KeQueryPerformanceCounter(&qpcFrequency);
+
+ // Convert ticks to 100ns units.
+ hnsCurrentTime = KSCONVERT_PERFORMANCE_TIME(m_ullPerformanceCounterFrequency.QuadPart, qpc);
+ m_hnsDPCTimeCarryForward = hnsCurrentTime - m_ullLastDPCTimeStamp + m_hnsDPCTimeCarryForward;
+ }
+ }
+
+#if defined(SYSVAD_BTH_BYPASS)
+ if (m_SidebandStarted)
+ {
+ PSIDEBANDDEVICECOMMON sidebandDevice;
+
+ ASSERT(m_pMiniport->IsSidebandDevice());
+ sidebandDevice = m_pMiniport->GetSidebandDevice(); // weak ref.
+ ASSERT(sidebandDevice != NULL);
+
+ //
+ // Close the Sideband connection.
+ //
+ ntStatus = sidebandDevice->StreamSuspend(m_pMiniport->m_DeviceType);
+ if (!NT_SUCCESS(ntStatus))
+ {
+ DPF(D_ERROR, ("SetState: KSSTATE_PAUSE, StreamClose failed, 0x%x", ntStatus));
+ }
+
+ m_SidebandStarted = FALSE;
}
+#endif // defined(SYSVAD_BTH_BYPASS)
+
}
// This call updates the linear buffer and presentation positions.
GetPositions(NULL, NULL, NULL);
break;
case KSSTATE_RUN:
+
+#if defined(SYSVAD_BTH_BYPASS)
+ if (m_pMiniport->IsSidebandDevice())
+ {
+ if (m_SidebandStarted == FALSE)
+ {
+ PSIDEBANDDEVICECOMMON sidebandDevice;
+
+ sidebandDevice = m_pMiniport->GetSidebandDevice(); // weak ref.
+ ASSERT(sidebandDevice != NULL);
+
+ //
+ // Start the Sideband connection.
+ //
+ ntStatus = sidebandDevice->StreamStart(m_pMiniport->m_DeviceType);
+ IF_FAILED_ACTION_JUMP(
+ ntStatus,
+ DPF(D_ERROR, ("SetState: KSSTATE_RUN, StreamStart failed, 0x%x", ntStatus)),
+ Done);
+
+ m_SidebandStarted = TRUE;
+ }
+ }
+#endif // defined(SYSVAD_BTH_BYPASS)
+
// Start DMA
LARGE_INTEGER ullPerfCounterTemp;
- if (m_pMiniport->m_DeviceFormatsAndModes[m_ulPin].PinType == PINTYPE::KeywordCapturePin)
+ if (m_pMiniport->IsKeywordDetectorPin(m_ulPin))
{
m_pMiniport->m_KeywordDetector.Run();
}
@@ -1194,22 +1352,18 @@ NTSTATUS CMiniportWaveRTStream::SetState
if (m_ulNotificationIntervalMs > 0)
{
- LARGE_INTEGER delay;
-
- delay.QuadPart = (-1) * HNSTIME_PER_MILLISECOND;
-
- ExSetTimerResolution(HNSTIME_PER_MILLISECOND, TRUE);
// Set timer for 1 ms. This will cause DPC to run every 1 ms but driver will send out
// notification events only after notification interval. This timer is used by Sysvad to
// emulate hardware and send out notification event. Real hardware should not use this
// timer to fire notification event as it will drain power if the timer is running at 1 msec.
- KeSetTimerEx
+ ExSetTimer
(
m_pNotificationTimer,
- delay,
- 1, // 1 ms
- m_pNotificationDpc
- );
+ (-1) * HNSTIME_PER_MILLISECOND,
+ HNSTIME_PER_MILLISECOND, // 1 ms
+ NULL
+ );
+
}
break;
@@ -1217,9 +1371,9 @@ NTSTATUS CMiniportWaveRTStream::SetState
m_KsState = State_;
-#ifdef SYSVAD_BTH_BYPASS
+#if defined(SYSVAD_BTH_BYPASS)
Done:
-#endif // SYSVAD_BTH_BYPASS
+#endif // defined(SYSVAD_BTH_BYPASS)
return ntStatus;
}
@@ -1309,10 +1463,15 @@ VOID CMiniportWaveRTStream::UpdatePosition
{
m_bLastBufferRendered = TRUE;
PADAPTERCOMMON pAdapterComm = m_pMiniport->GetAdapterCommObj();
- pAdapterComm->WriteEtwEvent(eMINIPORT_LAST_BUFFER_RENDERED,
+ //Event type : eMINIPORT_LAST_BUFFER_RENDERED
+ //Parameter 1 : Current linear buffer position
+ //Parameter 2 : the very last WaveRtBufferWritePosition that the driver received
+ //Parameter 3 : 0
+ //Parameter 4 : 0
+ pAdapterComm->WriteEtwEvent(eMINIPORT_LAST_BUFFER_RENDERED,
m_ullLinearPosition + ByteDisplacement, // Current linear buffer position
m_ulCurrentWritePosition, // The very last WaveRtBufferWritePosition that the driver received
- 0,
+ 0,
0);
}
@@ -1349,8 +1508,7 @@ VOID CMiniportWaveRTStream::WriteBytes
Routine Description:
-This function writes the audio buffer using a sine wave generator.
-
+This function writes the audio buffer using a sine wave generator
Arguments:
ByteDisplacement - # of bytes to process.
@@ -1364,7 +1522,7 @@ ByteDisplacement - # of bytes to process.
while (ByteDisplacement > 0)
{
ULONG runWrite = min(ByteDisplacement, m_ulDmaBufferSize - bufferOffset);
- m_ToneGenerator.GenerateSine(m_pDmaBuffer + bufferOffset, runWrite);
+ m_ToneGenerator.GenerateSine(m_pDmaBuffer + bufferOffset, runWrite);
bufferOffset = (bufferOffset + runWrite) % m_ulDmaBufferSize;
ByteDisplacement -= runWrite;
}
@@ -1491,17 +1649,17 @@ Return Value:
return ntStatus;
} // SetContentId
-#ifdef SYSVAD_BTH_BYPASS
+#if defined(SYSVAD_BTH_BYPASS)
//=============================================================================
#pragma code_seg()
NTSTATUS
-CMiniportWaveRTStream::GetScoStreamNtStatus()
+CMiniportWaveRTStream::GetSidebandStreamNtStatus()
/*++
Routine Description:
- Checks if the Bluetooth SCO HFP connection is up, if not, an error is returned.
+ Checks if the Sideband stream connection is up, if not, an error is returned.
Return Value:
@@ -1509,19 +1667,19 @@ Return Value:
--*/
{
- DPF_ENTER(("[CMiniportWaveRTStream::GetScoStreamNtStatus]"));
+ DPF_ENTER(("[CMiniportWaveRTStream::GetSidebandStreamNtStatus]"));
NTSTATUS ntStatus = STATUS_INVALID_DEVICE_STATE;
- if (m_ScoOpen)
+ if (m_SidebandStarted)
{
- PBTHHFPDEVICECOMMON bthHfpDevice;
+ PSIDEBANDDEVICECOMMON sidebandDevice;
- ASSERT(m_pMiniport->IsBthHfpDevice());
- bthHfpDevice = m_pMiniport->GetBthHfpDevice(); // weak ref.
- ASSERT(bthHfpDevice != NULL);
+ ASSERT(m_pMiniport->IsSidebandDevice());
+ sidebandDevice = m_pMiniport->GetSidebandDevice(); // weak ref.
+ ASSERT(sidebandDevice != NULL);
- if (bthHfpDevice->GetStreamStatus())
+ if (sidebandDevice->GetStreamStatus(m_pMiniport->m_DeviceType))
{
ntStatus = STATUS_SUCCESS;
}
@@ -1529,7 +1687,7 @@ Return Value:
return ntStatus;
}
-#endif // SYSVAD_BTH_BYPASS
+#endif // defined(SYSVAD_BTH_BYPASS)
//=============================================================================
#pragma code_seg("PAGE")
@@ -1577,18 +1735,15 @@ CMiniportWaveRTStream::PropertyHandlerModuleCommand
void
TimerNotifyRT
(
- _In_ PKDPC Dpc,
- _In_opt_ PVOID DeferredContext,
- _In_opt_ PVOID SA1,
- _In_opt_ PVOID SA2
+ _In_ PEX_TIMER Timer,
+ _In_opt_ PVOID DeferredContext
)
{
LARGE_INTEGER qpc;
LARGE_INTEGER qpcFrequency;
+ BOOL bufferCompleted = FALSE;
- UNREFERENCED_PARAMETER(Dpc);
- UNREFERENCED_PARAMETER(SA1);
- UNREFERENCED_PARAMETER(SA2);
+ UNREFERENCED_PARAMETER(Timer);
_IRQL_limited_to_(DISPATCH_LEVEL);
@@ -1612,15 +1767,19 @@ TimerNotifyRT
ULONG TimeElapsedInMS = (ULONG)(hnsCurrentTime - _this->m_ullLastDPCTimeStamp + _this->m_hnsDPCTimeCarryForward)/10000;
- if (TimeElapsedInMS < _this->m_ulNotificationIntervalMs && !_this->m_bEoSReceived)
+ if (TimeElapsedInMS >= _this->m_ulNotificationIntervalMs)
{
- goto End;
+ // Carry forward the time greater than notification interval to adjust time to signal next buffer completion event accordingly.
+ _this->m_hnsDPCTimeCarryForward = hnsCurrentTime - _this->m_ullLastDPCTimeStamp + _this->m_hnsDPCTimeCarryForward - (_this->m_ulNotificationIntervalMs * 10000);
+ // Save the last time DPC ran at notification interval
+ _this->m_ullLastDPCTimeStamp = hnsCurrentTime;
+ bufferCompleted = TRUE;
}
- // Carry forward the time greater than notification interval to adjust time to signal next buffer completion event accordingly.
- _this->m_hnsDPCTimeCarryForward = hnsCurrentTime - _this->m_ullLastDPCTimeStamp + _this->m_hnsDPCTimeCarryForward - (_this->m_ulNotificationIntervalMs * 10000);
- // Save the last time DPC ran at notification interval
- _this->m_ullLastDPCTimeStamp = hnsCurrentTime;
+ if (!bufferCompleted && !_this->m_bEoSReceived)
+ {
+ goto End;
+ }
_this->UpdatePosition(qpc);
@@ -1629,15 +1788,15 @@ TimerNotifyRT
_this->m_llPacketCounter++;
}
-#ifdef SYSVAD_BTH_BYPASS
- if (_this->m_ScoOpen)
+#if defined(SYSVAD_BTH_BYPASS)
+ if (_this->m_SidebandStarted)
{
- if (!NT_SUCCESS(_this->GetScoStreamNtStatus()))
+ if (!NT_SUCCESS(_this->GetSidebandStreamNtStatus()))
{
goto End;
}
}
-#endif // SYSVAD_BTH_BYPASS
+#endif //defined(SYSVAD_BTH_BYPASS)
_this->m_pMiniport->DpcRoutine(qpc.QuadPart, qpcFrequency.QuadPart);
@@ -1653,18 +1812,22 @@ TimerNotifyRT
{
//Event type: eMINIPORT_GLITCH_REPORT
//Parameter 1: Current linear buffer position
- //Parameter 2: the previous WaveRtBufferWritePosition that the drive received
- //Parameter 3: major glitch code: 1:WaveRT buffer is underrun
- //Parameter 4: minor code for the glitch cause
+ //Parameter 2: Previous WaveRtBufferWritePosition that the driver received
+ //Parameter 3: Major glitch code: 1:WaveRT buffer is underrun
+ //Parameter 4: Minor code for the glitch cause
pAdapterComm->WriteEtwEvent(eMINIPORT_GLITCH_REPORT,
- 100, // replace with the correct "Current linear buffer position"
+ _this->m_ullLinearPosition,
_this->GetCurrentWaveRTWritePosition(),
1, // WaveRT buffer is underrun
0);
}
+ // Send buffer completion event if either of the following is true
+ // 1. Driver consumed a complete buffer for this stream
+ // 2. Driver consumed a partial buffer containing EoS for this stream
+
if (!IsListEmpty(&_this->m_NotificationList) &&
- (TimeElapsedInMS >= _this->m_ulNotificationIntervalMs || _this->m_bLastBufferRendered))
+ (bufferCompleted || _this->m_bLastBufferRendered))
{
PLIST_ENTRY leCurrent = _this->m_NotificationList.Flink;
while (leCurrent != &_this->m_NotificationList)
@@ -1672,16 +1835,14 @@ TimerNotifyRT
NotificationListEntry* nleCurrent = CONTAINING_RECORD( leCurrent, NotificationListEntry, ListEntry);
//Event type: eMINIPORT_BUFFER_COMPLETE
//Parameter 1: Current linear buffer position
- //Parameter 2: the previous WaveRtBufferWritePosition that the driver received
+ //Parameter 2: Previous WaveRtBufferWritePosition that the driver received
//Parameter 3: Data length completed
- //Parameter 4:0
-
- pAdapterComm->WriteEtwEvent(eMINIPORT_BUFFER_COMPLETE,
- 100, // replace with the correct "Current linear buffer position"
+ //Parameter 4: 0
+ pAdapterComm->WriteEtwEvent(eMINIPORT_BUFFER_COMPLETE,
+ _this->m_ullLinearPosition,
_this->GetCurrentWaveRTWritePosition(),
- 300, // replace with the correct "Data length completed"
- 0); // always zero
-
+ _this->m_ulDmaBufferSize/_this->m_ulNotificationsPerBuffer, // replace with the correct "Data length completed"
+ 0); // always zero
KeSetEvent(nleCurrent->NotificationEvent, 0, 0);
leCurrent = leCurrent->Flink;
@@ -1690,7 +1851,7 @@ TimerNotifyRT
if (_this->m_bLastBufferRendered)
{
- KeCancelTimer(_this->m_pNotificationTimer);
+ ExCancelTimer(_this->m_pNotificationTimer, NULL);
}
End:
@@ -1699,3 +1860,4 @@ End:
}
//=============================================================================
+
diff --git a/audio/sysvad/EndpointsCommon/minwavertstream.h b/audio/sysvad/EndpointsCommon/minwavertstream.h
index 3034d630..b1fc4628 100644
--- a/audio/sysvad/EndpointsCommon/minwavertstream.h
+++ b/audio/sysvad/EndpointsCommon/minwavertstream.h
@@ -4,7 +4,7 @@ Copyright (c) 1997-2010 Microsoft Corporation All Rights Reserved
Module Name:
- minwavert.h
+ minwavertstream.h
Abstract:
@@ -18,6 +18,7 @@ Abstract:
#include "savedata.h"
#include "tonegenerator.h"
+
//
// Structure to store notifications events in a protected list
//
@@ -27,7 +28,7 @@ typedef struct _NotificationListEntry
PKEVENT NotificationEvent;
} NotificationListEntry;
-KDEFERRED_ROUTINE TimerNotifyRT;
+EXT_CALLBACK TimerNotifyRT;
//=============================================================================
// Referenced Forward
@@ -55,8 +56,7 @@ class CMiniportWaveRTStream :
protected:
PPORTWAVERTSTREAM m_pPortStream;
LIST_ENTRY m_NotificationList;
- PKTIMER m_pNotificationTimer;
- PRKDPC m_pNotificationDpc;
+ PEX_TIMER m_pNotificationTimer;
ULONG m_ulNotificationIntervalMs;
ULONG m_ulCurrentWritePosition;
LONG m_IsCurrentWritePositionUpdated;
@@ -87,7 +87,7 @@ public:
// Friends
friend class CMiniportWaveRT;
- friend KDEFERRED_ROUTINE TimerNotifyRT;
+ friend EXT_CALLBACK TimerNotifyRT;
protected:
CMiniportWaveRT* m_pMiniport;
ULONG m_ulPin;
@@ -127,10 +127,23 @@ protected:
KSPIN_LOCK m_PositionSpinLock;
AUDIOMODULE * m_pAudioModules;
ULONG m_AudioModuleCount;
+ // Member variable as config params for tone generator
+ ULONG m_ulHostCaptureToneFrequency;
+ ULONG m_ulLoopbackCaptureToneFrequency;
+ // If abs(m_dwHostCaptureToneAmplitude) + abs(m_dwHostCaptureToneDCValue) > 100
+ // m_dwHostCaptureToneDCValue will be compensated to make the sum equal to 100
+ DWORD m_dwHostCaptureToneAmplitude; // must be between -100 to 100
+ DWORD m_dwLoopbackCaptureToneAmplitude; // must be between -100 to 100
+ DWORD m_dwHostCaptureToneDCOffset; // must be between -100 to 100
+ DWORD m_dwLoopbackCaptureToneDCOffset; // must be between -100 to 100
+ DWORD m_dwHostCaptureToneInitialPhase; // must be between -31416 to 31416
+ DWORD m_dwLoopbackCaptureToneInitialPhase; // must be between -31416 to 31416
+ // Member variable as config params for tone generator
-#ifdef SYSVAD_BTH_BYPASS
- BOOLEAN m_ScoOpen;
-#endif // SYSVAD_BTH_BYPASS
+#if defined(SYSVAD_BTH_BYPASS)
+ BOOL m_SidebandOpen;
+ BOOL m_SidebandStarted;
+#endif // defined(SYSVAD_BTH_BYPASS)
public:
@@ -294,12 +307,14 @@ private:
_Out_opt_ ULONGLONG * _pullPresentationPosition,
_Out_opt_ LARGE_INTEGER * _pliQPCTime
);
+ NTSTATUS ReadRegistrySettings();
-#ifdef SYSVAD_BTH_BYPASS
- NTSTATUS GetScoStreamNtStatus();
-#endif // SYSVAD_BTH_BYPASS
+#if defined(SYSVAD_BTH_BYPASS)
+ NTSTATUS GetSidebandStreamNtStatus();
+#endif // defined(SYSVAD_BTH_BYPASS)
};
typedef CMiniportWaveRTStream *PCMiniportWaveRTStream;
#endif // _SYSVAD_MINWAVERTSTREAM_H_
+
diff --git a/audio/sysvad/EndpointsCommon/simple.h b/audio/sysvad/EndpointsCommon/simple.h
index 55913cdc..a284acbc 100644
--- a/audio/sysvad/EndpointsCommon/simple.h
+++ b/audio/sysvad/EndpointsCommon/simple.h
@@ -40,6 +40,13 @@ enum
KSPIN_WAVE_RENDER_SOURCE
};
+// Wave pins - no mix, no offload
+enum
+{
+ KSPIN_WAVE_RENDER3_SINK_SYSTEM = 0,
+ KSPIN_WAVE_RENDER3_SOURCE
+};
+
// Wave Topology nodes - offloading supported.
enum
{
@@ -122,6 +129,12 @@ enum
KSNODE_WAVE_ADC = 0
};
+// Wave Topology nodes.
+enum
+{
+ KSNODE_WAVE_DAC = 0
+};
+
// topology pins.
enum
{
diff --git a/audio/sysvad/EndpointsCommon/sources b/audio/sysvad/EndpointsCommon/sources
index ab930dbd..18b2ddc4 100644
--- a/audio/sysvad/EndpointsCommon/sources
+++ b/audio/sysvad/EndpointsCommon/sources
@@ -27,20 +27,18 @@ MINIMUM_NT_TARGET_VERSION=$(_NT_TARGET_VERSION_WINTHRESHOLD)
KMDF_VERSION_MAJOR=1
-SOURCES=$(SOURCES) \
- mintopo.cpp \
- minwavert.cpp \
- minwavertstream.cpp \
- MiniportAudioEngineNode.cpp\
- MiniportStreamAudioEngineNode.cpp\
- micarraytopo.cpp \
- speakertopo.cpp \
- speakerhptopo.cpp \
- bthhfptopo.cpp \
- bthhfpmictopo.cpp \
- bthhfpspeakertopo.cpp \
- bthhfpminwavert.cpp \
- AudioModuleHelper.cpp \
-
-
+SOURCES=$(SOURCES) \
+ AudioModuleHelper.cpp \
+ bthhfptopo.cpp \
+ bthhfpmictopo.cpp \
+ bthhfpspeakertopo.cpp \
+ bthhfpminwavert.cpp \
+ micarraytopo.cpp \
+ MiniportAudioEngineNode.cpp \
+ MiniportStreamAudioEngineNode.cpp \
+ mintopo.cpp \
+ minwavert.cpp \
+ minwavertstream.cpp \
+ speakertopo.cpp \
+ speakerhptopo.cpp \
diff --git a/audio/sysvad/EndpointsCommon/speakerhptopo.cpp b/audio/sysvad/EndpointsCommon/speakerhptopo.cpp
index 96e899a0..76b82f13 100644
--- a/audio/sysvad/EndpointsCommon/speakerhptopo.cpp
+++ b/audio/sysvad/EndpointsCommon/speakerhptopo.cpp
@@ -216,6 +216,7 @@ Return Value:
return ntStatus;
}
+
//=============================================================================
NTSTATUS
PropertyHandler_SpeakerHpTopoFilter
diff --git a/audio/sysvad/EndpointsCommon/speakerhptoptable.h b/audio/sysvad/EndpointsCommon/speakerhptoptable.h
index 870fd02d..dece62fa 100644
--- a/audio/sysvad/EndpointsCommon/speakerhptoptable.h
+++ b/audio/sysvad/EndpointsCommon/speakerhptoptable.h
@@ -15,6 +15,8 @@ Abstract:
#ifndef _SYSVAD_SPEAKERHPTOPTABLE_H_
#define _SYSVAD_SPEAKERHPTOPTABLE_H_
+#include "mintopo.h"
+
//=============================================================================
static
KSJACK_DESCRIPTION SpeakerHpJackDesc =
@@ -132,7 +134,17 @@ PCPROPERTY_ITEM PropertiesSpeakerHpTopoFilter[] =
}
};
-DEFINE_PCAUTOMATION_TABLE_PROP(AutomationSpeakerHpTopoFilter, PropertiesSpeakerHpTopoFilter);
+static PCEVENT_ITEM SpeakerHpJackInfoChangeEvent[] =
+{
+ {
+ &KSEVENTSETID_PinCapsChange, // Something changed
+ KSEVENT_PINCAPS_JACKINFOCHANGE, // Jack Info Changes
+ KSEVENT_TYPE_ENABLE | KSEVENT_TYPE_BASICSUPPORT,
+ CMiniportTopology_EventHandler_JackState
+ }
+};
+
+DEFINE_PCAUTOMATION_TABLE_PROP_EVENT(AutomationSpeakerHpTopoFilter, PropertiesSpeakerHpTopoFilter, SpeakerHpJackInfoChangeEvent);
//=============================================================================
static
diff --git a/audio/sysvad/EndpointsCommon/speakerhpwavtable.h b/audio/sysvad/EndpointsCommon/speakerhpwavtable.h
index 66fc9c8a..e1cf1594 100644
--- a/audio/sysvad/EndpointsCommon/speakerhpwavtable.h
+++ b/audio/sysvad/EndpointsCommon/speakerhpwavtable.h
@@ -772,6 +772,12 @@ PCPROPERTY_ITEM PropertiesSpeakerHpWaveFilter[] =
PropertyHandler_WaveFilter
},
{
+ &KSPROPSETID_Pin,
+ KSPROPERTY_PIN_PROPOSEDATAFORMAT2,
+ KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_BASICSUPPORT,
+ PropertyHandler_WaveFilter
+ },
+ {
&KSPROPSETID_AudioModule,
KSPROPERTY_AUDIOMODULE_DESCRIPTORS,
KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_BASICSUPPORT,
diff --git a/audio/sysvad/EndpointsCommon/speakerwavtable.h b/audio/sysvad/EndpointsCommon/speakerwavtable.h
index 94f7863b..6fb058ab 100644
--- a/audio/sysvad/EndpointsCommon/speakerwavtable.h
+++ b/audio/sysvad/EndpointsCommon/speakerwavtable.h
@@ -773,6 +773,12 @@ PCPROPERTY_ITEM PropertiesSpeakerWaveFilter[] =
PropertyHandler_WaveFilter
},
{
+ &KSPROPSETID_Pin,
+ KSPROPERTY_PIN_PROPOSEDATAFORMAT2,
+ KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_BASICSUPPORT,
+ PropertyHandler_WaveFilter
+ },
+ {
&KSPROPSETID_SysVAD,
KSPROPERTY_SYSVAD_DEFAULTSTREAMEFFECTS,
KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_BASICSUPPORT,
diff --git a/audio/sysvad/KeywordDetectorAdapter/KeywordDetectorContosoAdapter.cpp b/audio/sysvad/KeywordDetectorAdapter/KeywordDetectorContosoAdapter.cpp
index 9bcdedee..088c0751 100644
--- a/audio/sysvad/KeywordDetectorAdapter/KeywordDetectorContosoAdapter.cpp
+++ b/audio/sysvad/KeywordDetectorAdapter/KeywordDetectorContosoAdapter.cpp
@@ -155,7 +155,7 @@ public:
contosoResult = (CONTOSO_KEYWORDDETECTIONRESULT*)Result;
// Do something with the result data to determine return parameters
- // PostProcessResult(contosoResult->ContosoDetectorResultData);
+ // PostProcessResult(contosoResult->ContosoDetectorResultData, contosoResult->KeywordStartTimestamp, contosoResult->KeywordStopTimestamp);
*KeywordId = KwVoiceAssistant;
*LangId = 0x0409;
diff --git a/audio/sysvad/Package/package.VcxProj b/audio/sysvad/Package/package.VcxProj
index cd7c9ddc..1188dbbd 100644
--- a/audio/sysvad/Package/package.VcxProj
+++ b/audio/sysvad/Package/package.VcxProj
@@ -25,10 +25,10 @@
<ProjectReference Include="..\PhoneAudioSample\PhoneAudioSample.vcxproj">
<Project>{FABA4668-DB5E-4F6C-9D25-A0B25AD084EE}</Project>
</ProjectReference>
- <ProjectReference Include="..\SwapAPO\APO\SwapAPO.vcxproj">
+ <ProjectReference Include="..\APO\SwapAPO\SwapAPO.vcxproj">
<Project>{691F1D0F-CA50-46CD-8BBA-A59E9E8EB601}</Project>
</ProjectReference>
- <ProjectReference Include="..\SwapAPO\DelayAPO\DelayAPO.vcxproj">
+ <ProjectReference Include="..\APO\DelayAPO\DelayAPO.vcxproj">
<Project>{8851AB85-70B3-4798-A149-BA366DF9EC25}</Project>
</ProjectReference>
<ProjectReference Include="..\TabletAudioSample\TabletAudioSample.vcxproj">
diff --git a/audio/sysvad/PhoneAudioSample/Cellulartopo.cpp b/audio/sysvad/PhoneAudioSample/Cellulartopo.cpp
index 250a03ba..7329a9f9 100644
--- a/audio/sysvad/PhoneAudioSample/Cellulartopo.cpp
+++ b/audio/sysvad/PhoneAudioSample/Cellulartopo.cpp
@@ -121,6 +121,9 @@ CCellularMiniportTopology::CCellularMiniportTopology
{
PAGED_CODE();
+ InitializeListHead(&m_EndpointPairs);
+
+ // populate the initial state
memcpy(&m_CellularRenderEndpoint, &(g_EndpointList[0].RenderEndpoint), sizeof(m_CellularRenderEndpoint));
memcpy(&m_CellularCaptureEndpoint, &(g_EndpointList[0].CaptureEndpoint), sizeof(m_CellularCaptureEndpoint));
}
@@ -147,6 +150,13 @@ Return Value:
{
PAGED_CODE();
+ while (!IsListEmpty(&m_EndpointPairs))
+ {
+ PLIST_ENTRY le = RemoveHeadList(&m_EndpointPairs);
+ ENDPOINT_PAIR_ENTRY *pRecord = CONTAINING_RECORD(le, ENDPOINT_PAIR_ENTRY, ListEntry);
+ delete pRecord;
+ }
+
DPF_ENTER(("[CCellularMiniportTopology::~CCellularMiniportTopology]"));
} // ~CCellularMiniportTopology
@@ -282,14 +292,36 @@ Return Value:
DPF_ENTER(("[CCellularMiniportTopology::Init]"));
- NTSTATUS ntStatus;
+ NTSTATUS ntStatus = STATUS_SUCCESS;
- ntStatus =
- CMiniportTopologySYSVAD::Init
- (
- UnknownAdapter,
- Port_
- );
+ ExInitializeFastMutex(&m_EndpointFastMutex);
+
+ // copy the full static list over to the dynamic list.
+ for (int i = 0; i < SIZEOF_ARRAY(g_EndpointList) && NT_SUCCESS(ntStatus); i++)
+ {
+ ENDPOINT_PAIR_ENTRY *newEntry = new(NonPagedPoolNx, MINADAPTER_POOLTAG) ENDPOINT_PAIR_ENTRY;
+
+ if (!newEntry)
+ {
+ DPF(D_TERSE, ("Insufficient memory to create endpoint pair"));
+ ntStatus = STATUS_INSUFFICIENT_RESOURCES;
+ }
+ else
+ {
+ memcpy(&(newEntry->data), &(g_EndpointList[i]), sizeof(KSTOPOLOGY_ENDPOINTIDPAIR));
+ InsertTailList(&m_EndpointPairs, &newEntry->ListEntry);
+ }
+ }
+
+ if (NT_SUCCESS(ntStatus))
+ {
+ ntStatus =
+ CMiniportTopologySYSVAD::Init
+ (
+ UnknownAdapter,
+ Port_
+ );
+ }
return ntStatus;
} // Init
@@ -325,7 +357,7 @@ Return Value:
if (IsEqualGUIDAligned(Interface, IID_IUnknown))
{
- *Object = PVOID(PUNKNOWN(this));
+ *Object = PVOID(PUNKNOWN(static_cast<IMiniportTopology*>( this )));
}
else if (IsEqualGUIDAligned(Interface, IID_IMiniport))
{
@@ -339,6 +371,10 @@ Return Value:
{
*Object = PVOID(PCELLULARTOPOLOGY(this));
}
+ else if (IsEqualGUIDAligned(Interface, IID_IMiniportChange))
+ {
+ *Object = PVOID(static_cast<PMINIPORTCHANGE>( this ));
+ }
else
{
*Object = NULL;
@@ -576,12 +612,22 @@ Return Value:
DPF_ENTER(("[PropertyHandlerTelephonyEndpointIdPair]"));
NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;
-
-
+
if (PropertyRequest->Verb & KSPROPERTY_TYPE_BASICSUPPORT)
{
ntStatus = STATUS_INVALID_PARAMETER;
- ULONG ulExpectedSize = (sizeof(KSPROPERTY_DESCRIPTION) + sizeof(KSPROPERTY_MEMBERSHEADER) + sizeof(g_EndpointList));
+ ULONG ulExpectedSize = (sizeof(KSPROPERTY_DESCRIPTION) + sizeof(KSPROPERTY_MEMBERSHEADER));
+
+ PLIST_ENTRY le = NULL;
+ int countOfValidEndpointPairs = 0;
+
+ ExAcquireFastMutex(&m_EndpointFastMutex);
+
+ for (le = m_EndpointPairs.Flink; le != &m_EndpointPairs; le = le->Flink)
+ {
+ countOfValidEndpointPairs++;
+ }
+ ulExpectedSize += (countOfValidEndpointPairs * sizeof(KSTOPOLOGY_ENDPOINTIDPAIR));
if (PropertyRequest->ValueSize >= sizeof(KSPROPERTY_DESCRIPTION))
{
@@ -594,8 +640,8 @@ Return Value:
PropDesc->DescriptionSize = ulExpectedSize;
PropDesc->PropTypeSet.Set = KSPROPSETID_TelephonyTopology;
PropDesc->PropTypeSet.Id = KSPROPERTY_TELEPHONY_ENDPOINTIDPAIR;
+ PropDesc->MembersListCount = 0;
PropDesc->PropTypeSet.Flags = 0;
- PropDesc->MembersListCount = 1;
PropDesc->Reserved = 0;
// buffer is big enough to hold the full data, add that
@@ -604,12 +650,23 @@ Return Value:
PKSPROPERTY_MEMBERSHEADER MembersHeader =
PKSPROPERTY_MEMBERSHEADER(PropDesc + 1);
+ // we're now adding the members header.
+ PropDesc->MembersListCount = 1;
+
MembersHeader->MembersFlags = KSPROPERTY_MEMBER_VALUES;
MembersHeader->MembersSize = sizeof(KSTOPOLOGY_ENDPOINTIDPAIR);
- MembersHeader->MembersCount = SIZEOF_ARRAY(g_EndpointList);
+ MembersHeader->MembersCount = countOfValidEndpointPairs;
MembersHeader->Flags = 0;
- memcpy(MembersHeader + 1, g_EndpointList, sizeof(g_EndpointList));
+ le = NULL;
+ PKSTOPOLOGY_ENDPOINTIDPAIR returnData = (PKSTOPOLOGY_ENDPOINTIDPAIR) (MembersHeader + 1);
+
+ for (le = m_EndpointPairs.Flink; le != &m_EndpointPairs; le = le->Flink)
+ {
+ ENDPOINT_PAIR_ENTRY *pRecord = CONTAINING_RECORD(le, ENDPOINT_PAIR_ENTRY, ListEntry);
+ memcpy(returnData, &(pRecord->data), sizeof(pRecord->data));
+ returnData++;
+ }
// tell them how much space we really used, which controls how much data is copied into the user buffer.
PropertyRequest->ValueSize = ulExpectedSize;
@@ -638,6 +695,8 @@ Return Value:
{
ntStatus = STATUS_BUFFER_TOO_SMALL;
}
+
+ ExReleaseFastMutex(&m_EndpointFastMutex);
}
else
{
@@ -667,16 +726,22 @@ Return Value:
else if (PropertyRequest->Verb & KSPROPERTY_TYPE_SET)
{
PKSTOPOLOGY_ENDPOINTIDPAIR EndpointIdPair = static_cast<PKSTOPOLOGY_ENDPOINTIDPAIR>(PropertyRequest->Value);
+ PLIST_ENTRY le = NULL;
// verify the requested combination is in the list of valid endpoint combinations, fail with
// invalid parameter if not found.
ntStatus = STATUS_INVALID_PARAMETER;
- for (int i = 0; i < SIZEOF_ARRAY(g_EndpointList); i++)
+
+ ExAcquireFastMutex(&m_EndpointFastMutex);
+
+ for (le = m_EndpointPairs.Flink; le != &m_EndpointPairs; le = le->Flink)
{
- if (g_EndpointList[i].RenderEndpoint.PinId == EndpointIdPair->RenderEndpoint.PinId &&
- 0 == _wcsnicmp(g_EndpointList[i].RenderEndpoint.TopologyName, EndpointIdPair->RenderEndpoint.TopologyName, MAX_PATH) &&
- g_EndpointList[i].CaptureEndpoint.PinId == EndpointIdPair->CaptureEndpoint.PinId &&
- 0 == _wcsnicmp(g_EndpointList[i].CaptureEndpoint.TopologyName, EndpointIdPair->CaptureEndpoint.TopologyName, MAX_PATH))
+ ENDPOINT_PAIR_ENTRY *pRecord = CONTAINING_RECORD(le, ENDPOINT_PAIR_ENTRY, ListEntry);
+
+ if (pRecord->data.RenderEndpoint.PinId == EndpointIdPair->RenderEndpoint.PinId &&
+ 0 == _wcsnicmp(pRecord->data.RenderEndpoint.TopologyName, EndpointIdPair->RenderEndpoint.TopologyName, MAX_PATH) &&
+ pRecord->data.CaptureEndpoint.PinId == EndpointIdPair->CaptureEndpoint.PinId &&
+ 0 == _wcsnicmp(pRecord->data.CaptureEndpoint.TopologyName, EndpointIdPair->CaptureEndpoint.TopologyName, MAX_PATH))
{
if (HOSTRENDER_PIN == EndpointIdPair->RenderEndpoint.PinId &&
0 == _wcsnicmp(HOSTRENDER_TOPONAME, EndpointIdPair->RenderEndpoint.TopologyName, MAX_PATH) &&
@@ -693,16 +758,17 @@ Return Value:
// Route cellular audio to these new endpoints (render and capture). This will update audio routing for
// all the active cellular calls.
}
-
+
memcpy(&m_CellularRenderEndpoint, &(EndpointIdPair->RenderEndpoint), sizeof(m_CellularRenderEndpoint));
memcpy(&m_CellularCaptureEndpoint, &(EndpointIdPair->CaptureEndpoint), sizeof(m_CellularCaptureEndpoint));
-
+
// we found the entry, so return success
ntStatus = STATUS_SUCCESS;
break;
}
}
+ ExReleaseFastMutex(&m_EndpointFastMutex);
}
else
{
@@ -865,7 +931,7 @@ Return Value:
// MajorTarget is a pointer to miniport object for miniports.
//
NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;
- PCCellularMiniportTopology pMiniport = (PCCellularMiniportTopology)PropertyRequest->MajorTarget;
+ PCCellularMiniportTopology pMiniport = reinterpret_cast<PCCellularMiniportTopology>(PropertyRequest->MajorTarget);
if (IsEqualGUIDAligned(*PropertyRequest->PropertyItem->Set, KSPROPSETID_Jack))
{
@@ -890,7 +956,6 @@ Return Value:
}
}
-
return ntStatus;
} // PropertyHandler_CellularTopoFilter
@@ -970,4 +1035,83 @@ NTSTATUS CCellularMiniportTopology::EventHandler_JackState
return STATUS_SUCCESS;
}
+#pragma code_seg("PAGE")
+STDMETHODIMP_(NTSTATUS)
+CCellularMiniportTopology::NotifyEndpointPair
+(
+ _In_ WCHAR *RenderEndpointTopoName,
+ _In_ ULONG RenderEndpointNameLen,
+ _In_ ULONG RenderPinId,
+ _In_ WCHAR *CaptureEndpointTopoName,
+ _In_ ULONG CaptureEndpointNameLen,
+ _In_ ULONG CapturePinId
+)
+{
+ PAGED_CODE ();
+
+ NTSTATUS ntStatus = STATUS_SUCCESS;
+
+ ENDPOINT_PAIR_ENTRY *newEntry = new(NonPagedPoolNx, MINADAPTER_POOLTAG) ENDPOINT_PAIR_ENTRY;
+
+ if (!newEntry)
+ {
+ DPF(D_TERSE, ("Insufficient memory to create endpoint pair"));
+ ntStatus = STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ if (NT_SUCCESS(ntStatus))
+ {
+ KSTOPOLOGY_ENDPOINTIDPAIR *endpointPair = &newEntry->data;
+
+ RtlStringCchCopyNW(endpointPair->RenderEndpoint.TopologyName,
+ SIZEOF_ARRAY(endpointPair->RenderEndpoint.TopologyName),
+ RenderEndpointTopoName,
+ RenderEndpointNameLen);
+ endpointPair->RenderEndpoint.PinId = RenderPinId;
+
+ RtlStringCchCopyNW(endpointPair->CaptureEndpoint.TopologyName,
+ SIZEOF_ARRAY(endpointPair->CaptureEndpoint.TopologyName),
+ CaptureEndpointTopoName,
+ CaptureEndpointNameLen);
+ endpointPair->CaptureEndpoint.PinId = CapturePinId;
+
+ ExAcquireFastMutex(&m_EndpointFastMutex);
+ InsertTailList(&m_EndpointPairs, &newEntry->ListEntry);
+ ExReleaseFastMutex(&m_EndpointFastMutex);
+
+ GenerateEventList(
+ (GUID*)&KSEVENTSETID_Telephony,
+ KSEVENT_TELEPHONY_ENDPOINTPAIRS_CHANGED,
+ FALSE,
+ NULL,
+ FALSE,
+ ULONG(-1));
+ }
+
+ return ntStatus;
+}
+
+#pragma code_seg()
+NTSTATUS CCellularMiniportWaveRT_EventHandler_Telephony
+(
+ _In_ PPCEVENT_REQUEST EventRequest
+)
+{
+ CCellularMiniportTopology* miniport = reinterpret_cast<CCellularMiniportTopology*>(EventRequest->MajorTarget);
+ return miniport->EventHandler_Telephony(EventRequest);
+}
+
+NTSTATUS CCellularMiniportTopology::EventHandler_Telephony
+(
+ _In_ PPCEVENT_REQUEST EventRequest
+)
+{
+ if (EventRequest->Verb == PCEVENT_VERB_ADD)
+ {
+ m_PortEvents->AddEventToEventList(EventRequest->EventEntry);
+ }
+
+ return STATUS_SUCCESS;
+}
+
diff --git a/audio/sysvad/PhoneAudioSample/Cellulartopo.h b/audio/sysvad/PhoneAudioSample/Cellulartopo.h
index bcd4aba7..b898741c 100644
--- a/audio/sysvad/PhoneAudioSample/Cellulartopo.h
+++ b/audio/sysvad/PhoneAudioSample/Cellulartopo.h
@@ -42,6 +42,12 @@ Abstract:
#define TELEPHONY_VOLUME_STEPPING (3 * 0x10000) // 10 steps
+typedef struct _ENDPOINT_PAIR_ENTRY
+{
+ LIST_ENTRY ListEntry;
+ KSTOPOLOGY_ENDPOINTIDPAIR data;
+} ENDPOINT_PAIR_ENTRY;
+
//=============================================================================
// Defines
//=============================================================================
@@ -80,6 +86,7 @@ typedef ICellularTopology *PCELLULARTOPOLOGY;
class CCellularMiniportTopology :
public CMiniportTopologySYSVAD,
public ICellularTopology,
+ public IMiniportChange,
public CUnknown
{
private:
@@ -87,6 +94,9 @@ class CCellularMiniportTopology :
KSTOPOLOGY_ENDPOINTID m_CellularCaptureEndpoint;
ULONG m_CellularVolume;
+ FAST_MUTEX m_EndpointFastMutex;
+ LIST_ENTRY m_EndpointPairs;
+
public:
DECLARE_STD_UNKNOWN();
CCellularMiniportTopology
@@ -135,6 +145,21 @@ class CCellularMiniportTopology :
_In_ ULONG TelephonyId,
_In_ BOOL NewState
);
+
+ NTSTATUS EventHandler_Telephony
+ (
+ _In_ PPCEVENT_REQUEST _pEventRequest
+ );
+
+ STDMETHODIMP_(NTSTATUS) NotifyEndpointPair
+ (
+ _In_ WCHAR *RenderEndpointTopoName,
+ _In_ ULONG RenderEndpointNameLen,
+ _In_ ULONG RenderPinId,
+ _In_ WCHAR *CaptureEndpointTopoName,
+ _In_ ULONG CaptureEndpointNameLen,
+ _In_ ULONG CapturePinId
+ );
};
typedef CCellularMiniportTopology *PCCellularMiniportTopology;
diff --git a/audio/sysvad/PhoneAudioSample/Cellulartoptable.h b/audio/sysvad/PhoneAudioSample/Cellulartoptable.h
index 9b6766ab..53eef9ae 100644
--- a/audio/sysvad/PhoneAudioSample/Cellulartoptable.h
+++ b/audio/sysvad/PhoneAudioSample/Cellulartoptable.h
@@ -214,13 +214,25 @@ NTSTATUS CCellularMiniportWaveRT_EventHandler_JackState
_In_ PPCEVENT_REQUEST EventRequest
);
-static PCEVENT_ITEM JackInfoChangeEvent[] =
+NTSTATUS CCellularMiniportWaveRT_EventHandler_Telephony
+(
+ _In_ PPCEVENT_REQUEST EventRequest
+);
+
+
+static PCEVENT_ITEM TelephonyEvents[] =
{
{
&KSEVENTSETID_PinCapsChange, // Something changed
KSEVENT_PINCAPS_JACKINFOCHANGE, // Jack Info Changes
KSEVENT_TYPE_ENABLE | KSEVENT_TYPE_BASICSUPPORT,
CCellularMiniportWaveRT_EventHandler_JackState
+ },
+ {
+ &KSEVENTSETID_Telephony,
+ KSEVENT_TELEPHONY_ENDPOINTPAIRS_CHANGED,
+ KSEVENT_TYPE_ENABLE | KSEVENT_TYPE_BASICSUPPORT,
+ CCellularMiniportWaveRT_EventHandler_Telephony
}
};
@@ -229,7 +241,7 @@ static PCEVENT_ITEM JackInfoChangeEvent[] =
*****************************************************************************
* Automation table for jack descripton/detection.
*/
-DEFINE_PCAUTOMATION_TABLE_PROP_EVENT(AutomationCellularTopoFilter, PropertiesCellularTopoFilter, JackInfoChangeEvent);
+DEFINE_PCAUTOMATION_TABLE_PROP_EVENT(AutomationCellularTopoFilter, PropertiesCellularTopoFilter, TelephonyEvents);
//=============================================================================
diff --git a/audio/sysvad/PhoneAudioSample/Cellularwavtable.h b/audio/sysvad/PhoneAudioSample/Cellularwavtable.h
index 7f9447ec..806cb05d 100644
--- a/audio/sysvad/PhoneAudioSample/Cellularwavtable.h
+++ b/audio/sysvad/PhoneAudioSample/Cellularwavtable.h
@@ -218,42 +218,42 @@ PCPROPERTY_ITEM PropertiesCellularWaveFilter[] =
KSPROPERTY_TYPE_SET | KSPROPERTY_TYPE_BASICSUPPORT,
PropertyHandler_WaveFilter
},
-
+ {
+ &KSPROPSETID_Pin,
+ KSPROPERTY_PIN_PROPOSEDATAFORMAT2,
+ KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_BASICSUPPORT,
+ PropertyHandler_WaveFilter
+ },
{
&KSPROPSETID_TelephonyControl,
KSPROPERTY_TELEPHONY_PROVIDERID,
KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_BASICSUPPORT,
PropertyHandler_CellularWaveFilter
},
-
{
&KSPROPSETID_TelephonyControl,
KSPROPERTY_TELEPHONY_CALLINFO,
KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_BASICSUPPORT,
PropertyHandler_CellularWaveFilter
},
-
{
&KSPROPSETID_TelephonyControl,
KSPROPERTY_TELEPHONY_CALLCONTROL,
KSPROPERTY_TYPE_SET | KSPROPERTY_TYPE_BASICSUPPORT,
PropertyHandler_CellularWaveFilter
},
-
{
&KSPROPSETID_TelephonyControl,
KSPROPERTY_TELEPHONY_PROVIDERCHANGE,
KSPROPERTY_TYPE_SET | KSPROPERTY_TYPE_BASICSUPPORT,
PropertyHandler_CellularWaveFilter
},
-
{
&KSPROPSETID_TelephonyControl,
KSPROPERTY_TELEPHONY_CALLHOLD,
KSPROPERTY_TYPE_SET | KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_BASICSUPPORT,
PropertyHandler_CellularWaveFilter
},
-
{
&KSPROPSETID_TelephonyControl,
KSPROPERTY_TELEPHONY_MUTE_TX,
diff --git a/audio/sysvad/PhoneAudioSample/FMWavTable.h b/audio/sysvad/PhoneAudioSample/FMWavTable.h
index 0fe0337c..6ef9fb46 100644
--- a/audio/sysvad/PhoneAudioSample/FMWavTable.h
+++ b/audio/sysvad/PhoneAudioSample/FMWavTable.h
@@ -216,7 +216,12 @@ PCPROPERTY_ITEM PropertiesFmWaveFilter[] =
KSPROPERTY_TYPE_SET | KSPROPERTY_TYPE_BASICSUPPORT,
PropertyHandler_WaveFilter
},
-
+ {
+ &KSPROPSETID_Pin,
+ KSPROPERTY_PIN_PROPOSEDATAFORMAT2,
+ KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_BASICSUPPORT,
+ PropertyHandler_WaveFilter
+ },
{
&KSPROPSETID_FMRXControl,
KSPROPERTY_FMRX_STATE,
diff --git a/audio/sysvad/sysvad.rc b/audio/sysvad/PhoneAudioSample/PhoneAudioSample.rc
index cd8f2faa..b81a3c58 100644
--- a/audio/sysvad/sysvad.rc
+++ b/audio/sysvad/PhoneAudioSample/PhoneAudioSample.rc
@@ -4,7 +4,7 @@ Copyright (c) Microsoft Corporation All Rights Reserved
Module Name:
- sysvad.rc
+ PhoneAudioSample.rc
Abstract:
@@ -17,9 +17,9 @@ Abstract:
#define VER_FILETYPE VFT_DRV
#define VER_FILESUBTYPE VFT2_DRV_SOUND
-#define VER_FILEDESCRIPTION_STR "Microsoft Virtual Audio Device Slate Sample Driver"
-#define VER_INTERNALNAME_STR "slateaudiosample.sys"
-#define VER_ORIGINALFILENAME_STR "slateaudiosample.sys"
+#define VER_FILEDESCRIPTION_STR "Microsoft Virtual Audio Phone Sample Driver"
+#define VER_INTERNALNAME_STR "PhoneAudioSample.sys"
+#define VER_ORIGINALFILENAME_STR "PhoneAudioSample.sys"
#define VER_LEGALCOPYRIGHT_YEARS "2013"
#define VER_LEGALCOPYRIGHT_STR "Copyright (C) Microsoft Corp." VER_LEGALCOPYRIGHT_YEARS
diff --git a/audio/sysvad/PhoneAudioSample/PhoneAudioSample.vcxproj b/audio/sysvad/PhoneAudioSample/PhoneAudioSample.vcxproj
index cf608ab0..eeb7b6c6 100644
--- a/audio/sysvad/PhoneAudioSample/PhoneAudioSample.vcxproj
+++ b/audio/sysvad/PhoneAudioSample/PhoneAudioSample.vcxproj
@@ -184,7 +184,7 @@
</Link>
<ClCompile>
<PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_;SYSVAD_BTH_BYPASS</PreprocessorDefinitions>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_IPortClsRuntimePower</PreprocessorDefinitions>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_IPortClsRuntimePower;_NEW_DELETE_OPERATORS_</PreprocessorDefinitions>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\EndpointsCommon</AdditionalIncludeDirectories>
<ExceptionHandling>
</ExceptionHandling>
@@ -207,7 +207,7 @@
</Link>
<ClCompile>
<PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_;SYSVAD_BTH_BYPASS</PreprocessorDefinitions>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_IPortClsRuntimePower</PreprocessorDefinitions>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_IPortClsRuntimePower;_NEW_DELETE_OPERATORS_</PreprocessorDefinitions>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\EndpointsCommon</AdditionalIncludeDirectories>
<ExceptionHandling>
</ExceptionHandling>
@@ -230,7 +230,7 @@
</Link>
<ClCompile>
<PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_;SYSVAD_BTH_BYPASS</PreprocessorDefinitions>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_IPortClsRuntimePower</PreprocessorDefinitions>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_IPortClsRuntimePower;_NEW_DELETE_OPERATORS_</PreprocessorDefinitions>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\EndpointsCommon</AdditionalIncludeDirectories>
<ExceptionHandling>
</ExceptionHandling>
@@ -253,7 +253,7 @@
</Link>
<ClCompile>
<PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_;SYSVAD_BTH_BYPASS</PreprocessorDefinitions>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_IPortClsRuntimePower</PreprocessorDefinitions>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_IPortClsRuntimePower;_NEW_DELETE_OPERATORS_</PreprocessorDefinitions>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\EndpointsCommon</AdditionalIncludeDirectories>
<ExceptionHandling>
</ExceptionHandling>
@@ -273,6 +273,7 @@
<ItemGroup>
<ClCompile Include="..\adapter.cpp" />
<ClCompile Include="..\basetopo.cpp" />
+ <ClCompile Include="..\BthhfpDevice.cpp" />
<ClCompile Include="..\common.cpp" />
<ClCompile Include="..\hw.cpp" />
<ClCompile Include="..\kshelper.cpp" />
@@ -286,10 +287,10 @@
<ClCompile Include="handsetspeakertopo.cpp" />
<ClCompile Include="michstopo.cpp" />
<ClCompile Include="speakerhstopo.cpp" />
- <ResourceCompile Include="..\sysvad.rc" />
+ <ResourceCompile Include="PhoneAudioSample.rc" />
</ItemGroup>
<ItemGroup>
- <Inf Exclude="@(Inf)" Include="*.inf" />
+ <Inf Exclude="@(Inx)" Include="*.inx" />
<FilesToPackage Include="$(TargetPath)" Condition="'$(ConfigurationType)'=='Driver' or '$(ConfigurationType)'=='DynamicLibrary'" />
</ItemGroup>
<ItemGroup>
diff --git a/audio/sysvad/PhoneAudioSample/PhoneAudioSample.vcxproj.Filters b/audio/sysvad/PhoneAudioSample/PhoneAudioSample.vcxproj.Filters
index 981f44c4..c6c87ad1 100644
--- a/audio/sysvad/PhoneAudioSample/PhoneAudioSample.vcxproj.Filters
+++ b/audio/sysvad/PhoneAudioSample/PhoneAudioSample.vcxproj.Filters
@@ -19,55 +19,26 @@
</Filter>
</ItemGroup>
<ItemGroup>
- <ClCompile Include="..\adapter.cpp">
+ <ClCompile Include="..\*.cpp">
<Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="..\basetopo.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="..\common.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="..\hw.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="..\kshelper.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="..\savedata.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="..\tonegenerator.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="cellulartopo.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="cellularwave.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="fmtopo.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="fmwave.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="handsetmictopo.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="handsetspeakertopo.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="michstopo.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="speakerhstopo.cpp">
+ <ClCompile Include="*.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
- <ResourceCompile Include="..\sysvad.rc">
+ <ResourceCompile Include="PhoneAudioSample.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <Inf Include="*.inx">
+ <Filter>Driver Files</Filter>
+ </Inf>
+ </ItemGroup>
</Project> \ No newline at end of file
diff --git a/audio/sysvad/PhoneAudioSample/handsetmictopo.cpp b/audio/sysvad/PhoneAudioSample/handsetmictopo.cpp
index d4854a90..4e181c62 100644
--- a/audio/sysvad/PhoneAudioSample/handsetmictopo.cpp
+++ b/audio/sysvad/PhoneAudioSample/handsetmictopo.cpp
@@ -204,7 +204,7 @@ Return Value:
// 0x00000001 - JACKDESC2_PRESENCE_DETECT_CAPABILITY
// 0x00000002 - JACKDESC2_DYNAMIC_FORMAT_CHANGE_CAPABILITY
//
- pDesc->JackCapabilities = JACKDESC2_PRESENCE_DETECT_CAPABILITY;
+ pDesc->JackCapabilities = 0;
ntStatus = STATUS_SUCCESS;
}
diff --git a/audio/sysvad/PhoneAudioSample/handsetmicwavtable.h b/audio/sysvad/PhoneAudioSample/handsetmicwavtable.h
index 45f35ce1..5470e521 100644
--- a/audio/sysvad/PhoneAudioSample/handsetmicwavtable.h
+++ b/audio/sysvad/PhoneAudioSample/handsetmicwavtable.h
@@ -415,6 +415,12 @@ PCPROPERTY_ITEM PropertiesHandsetMicWaveFilter[] =
KSPROPERTY_PIN_PROPOSEDATAFORMAT,
KSPROPERTY_TYPE_SET | KSPROPERTY_TYPE_BASICSUPPORT,
PropertyHandler_WaveFilter
+ },
+ {
+ &KSPROPSETID_Pin,
+ KSPROPERTY_PIN_PROPOSEDATAFORMAT2,
+ KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_BASICSUPPORT,
+ PropertyHandler_WaveFilter
}
};
diff --git a/audio/sysvad/PhoneAudioSample/handsetspeakertopo.cpp b/audio/sysvad/PhoneAudioSample/handsetspeakertopo.cpp
index 9e72ce85..161e5bf0 100644
--- a/audio/sysvad/PhoneAudioSample/handsetspeakertopo.cpp
+++ b/audio/sysvad/PhoneAudioSample/handsetspeakertopo.cpp
@@ -496,7 +496,7 @@ Return Value:
// 0x00000001 - JACKDESC2_PRESENCE_DETECT_CAPABILITY
// 0x00000002 - JACKDESC2_DYNAMIC_FORMAT_CHANGE_CAPABILITY
//
- pDesc->JackCapabilities = JACKDESC2_PRESENCE_DETECT_CAPABILITY;
+ pDesc->JackCapabilities = 0;
ntStatus = STATUS_SUCCESS;
}
diff --git a/audio/sysvad/PhoneAudioSample/handsetspeakerwavtable.h b/audio/sysvad/PhoneAudioSample/handsetspeakerwavtable.h
index 4eaa32ee..73548626 100644
--- a/audio/sysvad/PhoneAudioSample/handsetspeakerwavtable.h
+++ b/audio/sysvad/PhoneAudioSample/handsetspeakerwavtable.h
@@ -518,6 +518,12 @@ PCPROPERTY_ITEM PropertiesHandsetSpeakerWaveFilter[] =
KSPROPERTY_TYPE_SET | KSPROPERTY_TYPE_BASICSUPPORT,
PropertyHandler_WaveFilter
},
+ {
+ &KSPROPSETID_Pin,
+ KSPROPERTY_PIN_PROPOSEDATAFORMAT2,
+ KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_BASICSUPPORT,
+ PropertyHandler_WaveFilter
+ }
};
DEFINE_PCAUTOMATION_TABLE_PROP(AutomationHandsetSpeakerWaveFilter, PropertiesHandsetSpeakerWaveFilter);
diff --git a/audio/sysvad/PhoneAudioSample/michswavtable.h b/audio/sysvad/PhoneAudioSample/michswavtable.h
index 5b46eb43..4bfa66db 100644
--- a/audio/sysvad/PhoneAudioSample/michswavtable.h
+++ b/audio/sysvad/PhoneAudioSample/michswavtable.h
@@ -415,6 +415,12 @@ PCPROPERTY_ITEM PropertiesMicHsWaveFilter[] =
KSPROPERTY_PIN_PROPOSEDATAFORMAT,
KSPROPERTY_TYPE_SET | KSPROPERTY_TYPE_BASICSUPPORT,
PropertyHandler_WaveFilter
+ },
+ {
+ &KSPROPSETID_Pin,
+ KSPROPERTY_PIN_PROPOSEDATAFORMAT2,
+ KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_BASICSUPPORT,
+ PropertyHandler_WaveFilter
}
};
diff --git a/audio/sysvad/PhoneAudioSample/minipairs.h b/audio/sysvad/PhoneAudioSample/minipairs.h
index eaa7a240..6b219462 100644
--- a/audio/sysvad/PhoneAudioSample/minipairs.h
+++ b/audio/sysvad/PhoneAudioSample/minipairs.h
@@ -172,10 +172,12 @@ ENDPOINT_MINIPAIR SpeakerMiniports =
{
eSpeakerDevice,
SPEAKER_TOPONAME, // defined in cellulartopo.h for use with cellular routing control
+ NULL, // optional template name
CreateMiniportTopologySYSVAD,
&SpeakerTopoMiniportFilterDescriptor,
0, NULL, // Interface properties
- L"WaveSpeaker", // make sure this name matches with KSNAME_WaveSpeaker in the inf's [Strings] section
+ L"WaveSpeaker", // make sure this or the template name matches with KSNAME_WaveSpeaker in the inf's [Strings] section
+ NULL, // optional template name
CreateMiniportWaveRTSYSVAD,
&SpeakerWaveMiniportFilterDescriptor,
ARRAYSIZE(SysvadWaveFilterInterfacePropertiesRender), // Interface properties
@@ -218,10 +220,12 @@ ENDPOINT_MINIPAIR SpeakerHsMiniports =
{
eSpeakerHsDevice,
SPEAKER_HEADSET_TOPONAME, // defined in cellulartopo.h for use with cellular routing control
+ NULL, // optional template name
CreateMiniportTopologySYSVAD,
&SpeakerHsTopoMiniportFilterDescriptor, // use the speaker headset topo filter descriptor, not headset.
0, NULL, // Interface properties
- L"WaveSpeakerHeadset", // make sure this name matches with KSNAME_WaveSpeakerHeadset in the inf's [Strings] section
+ L"WaveSpeakerHeadset", // make sure this or the template name matches with KSNAME_WaveSpeakerHeadset in the inf's [Strings] section
+ NULL, // optional template name
CreateMiniportWaveRTSYSVAD,
&SpeakerHsWaveMiniportFilterDescriptor,
0, NULL, // Interface properties
@@ -263,10 +267,12 @@ ENDPOINT_MINIPAIR MicHsMiniports =
{
eMicHsDevice,
MIC_HEADSET_TOPONAME, // defined in cellulartopo.h for use with cellular routing control
+ NULL, // optional template name
CreateMiniportTopologySYSVAD,
&MicHsTopoMiniportFilterDescriptor,
0, NULL, // Interface properties
- L"WaveMicHeadset", // make sure this name matches with KSNAME_WaveMicHeadset in the inf's [Strings] section
+ L"WaveMicHeadset", // make sure this or the template name matches with KSNAME_WaveMicHeadset in the inf's [Strings] section
+ NULL, // optional template name
CreateMiniportWaveRTSYSVAD,
&MicHsWaveMiniportFilterDescriptor,
0, NULL, // Interface properties
@@ -308,11 +314,13 @@ static
ENDPOINT_MINIPAIR MicArray1Miniports =
{
eMicArrayDevice1,
- L"TopologyMicArray1", // make sure this name matches with KSNAME_TopologyMicArray1 in the inf's [Strings] section
+ L"TopologyMicArray1", // make sure this or the template name matches with KSNAME_TopologyMicArray1 in the inf's [Strings] section
+ NULL, // optional template name
CreateMicArrayMiniportTopology,
&MicArray1TopoMiniportFilterDescriptor,
0, NULL, // Interface properties
- L"WaveMicArray1", // make sure this name matches with KSNAME_WaveMicArray1 in the inf's [Strings] section
+ L"WaveMicArray1", // make sure this or the tempalte name matches with KSNAME_WaveMicArray1 in the inf's [Strings] section
+ NULL, // optional template name
CreateMiniportWaveRTSYSVAD,
&MicArrayWaveMiniportFilterDescriptor,
ARRAYSIZE(SysvadWaveFilterInterfacePropertiesCapture), // Interface properties
@@ -363,11 +371,13 @@ static
ENDPOINT_MINIPAIR CellularMiniports =
{
eCellularDevice,
- L"TopologyCellular", // make sure this name matches with KSNAME_TopologyCellular in the inf's [Strings] section
+ L"TopologyCellular", // make sure this or the template name matches with KSNAME_TopologyCellular in the inf's [Strings] section
+ NULL, // optional template name
CreateCellularMiniportTopology,
&CellularTopoMiniportFilterDescriptor,
0, NULL, // Interface properties
- L"WaveCellular", // make sure this name matches with KSNAME_WaveCellular in the inf's [Strings] section
+ L"WaveCellular", // make sure this or the template name matches with KSNAME_WaveCellular in the inf's [Strings] section
+ NULL, // optional template name
CreateCellularMiniportWaveRT,
&CellularWaveMiniportFilterDescriptor,
0, NULL, // Interface properties
@@ -395,11 +405,13 @@ static
ENDPOINT_MINIPAIR CellularMiniports2 =
{
eCellularDevice,
- L"TopologyCellular", // make sure this name matches with KSNAME_TopologyCellular in the inf's [Strings] section
+ L"TopologyCellular", // make sure this or the template name matches with KSNAME_TopologyCellular in the inf's [Strings] section
+ NULL, // optional template name
CreateCellularMiniportTopology,
&CellularTopoMiniportFilterDescriptor,
0, NULL, // Interface properties
- L"WaveCellular2", // make sure this name matches with KSNAME_WaveCellular in the inf's [Strings] section
+ L"WaveCellular2", // make sure this or the template name matches with KSNAME_WaveCellular in the inf's [Strings] section
+ NULL, // optional template name
CreateCellularMiniportWaveRT,
&CellularWaveMiniportFilterDescriptor,
0, NULL, // Interface properties
@@ -439,10 +451,12 @@ ENDPOINT_MINIPAIR HandsetSpeakerMiniports =
{
eHandsetSpeakerDevice,
HANDSET_SPEAKER_TOPONAME, // defined in cellulartopo.h for use with cellular routing control
+ NULL, // optional template name
CreateHandsetSpeakerMiniportTopology,
&HandsetSpeakerTopoMiniportFilterDescriptor,
0, NULL, // Interface properties
- L"WaveHandsetSpeaker", // make sure this name matches with KSNAME_WaveHandsetSpeaker in the inf's [Strings] section
+ L"WaveHandsetSpeaker", // make sure this or the template name matches with KSNAME_WaveHandsetSpeaker in the inf's [Strings] section
+ NULL, // optional template name
CreateMiniportWaveRTSYSVAD,
&HandsetSpeakerWaveMiniportFilterDescriptor,
0, NULL, // Interface properties
@@ -451,7 +465,7 @@ ENDPOINT_MINIPAIR HandsetSpeakerMiniports =
SIZEOF_ARRAY(HandsetSpeakerPinDeviceFormatsAndModes),
HandsetSpeakerTopologyPhysicalConnections,
SIZEOF_ARRAY(HandsetSpeakerTopologyPhysicalConnections),
- ENDPOINT_NO_FLAGS,
+ ENDPOINT_LOOPBACK_SUPPORTED,
NULL, 0, NULL, // audio module settings.
};
@@ -484,10 +498,12 @@ ENDPOINT_MINIPAIR HandsetMicMiniports =
{
eHandsetMicDevice,
HANDSET_MIC_TOPONAME, // defined in cellulartopo.h for use with cellular routing control
+ NULL, // optional template name
CreateMiniportTopologySYSVAD,
&HandsetMicTopoMiniportFilterDescriptor,
0, NULL, // Interface properties
- L"WaveHandsetMic", // make sure this name matches with KSNAME_WaveHandsetMic in the inf's [Strings] section
+ L"WaveHandsetMic", // make sure this or the template name matches with KSNAME_WaveHandsetMic in the inf's [Strings] section
+ NULL, // optional template name
CreateMiniportWaveRTSYSVAD,
&HandsetMicWaveMiniportFilterDescriptor,
0, NULL, // Interface properties
@@ -525,10 +541,12 @@ ENDPOINT_MINIPAIR FmRxMiniports =
{
eFmRxDevice,
L"TopologyFmRx", // make sure this name matches with KSNAME_TopologyFmRx
+ NULL, // optional template name
CreateFmMiniportTopology,
&FmTopoMiniportFilterDescriptor,
0, NULL, // Interface properties
- L"WaveFmRx", // make sure this name matches with KSNAME_WaveFmRx in the inf's [Strings] section
+ L"WaveFmRx", // make sure this or the template name matches with KSNAME_WaveFmRx in the inf's [Strings] section
+ NULL, // optional template name
CreateFmMiniportWaveRT,
&FmWaveMiniportFilterDescriptor,
0, NULL, // Interface properties
diff --git a/audio/sysvad/PhoneAudioSample/phoneaudiosample.inf b/audio/sysvad/PhoneAudioSample/phoneaudiosample.inx
index 5c7fb491..c7b6c110 100644
--- a/audio/sysvad/PhoneAudioSample/phoneaudiosample.inf
+++ b/audio/sysvad/PhoneAudioSample/phoneaudiosample.inx
Binary files differ
diff --git a/audio/sysvad/PhoneAudioSample/sources b/audio/sysvad/PhoneAudioSample/sources
index 0d1551ce..46aa7bad 100644
--- a/audio/sysvad/PhoneAudioSample/sources
+++ b/audio/sysvad/PhoneAudioSample/sources
@@ -35,19 +35,20 @@ KMDF_VERSION_MAJOR=1
C_DEFINES= $(C_DEFINES) -D_USE_IPortClsRuntimePower
#C_DEFINES= $(C_DEFINES) -D_USE_SingleComponentMultiFxStates
-INCLUDES= \
- $(INCLUDES); \
- ..\EndpointsCommon; \
+INCLUDES= \
+ $(INCLUDES); \
+ ..\EndpointsCommon; \
SOURCES=$(SOURCES) \
- cellulartopo.cpp \
- fmtopo.cpp \
- handsetspeakertopo.cpp \
- handsetmictopo.cpp \
- michstopo.cpp \
- speakerhstopo.cpp \
- cellularwave.cpp \
- fmwave.cpp \
+ cellulartopo.cpp \
+ fmtopo.cpp \
+ handsetspeakertopo.cpp \
+ handsetmictopo.cpp \
+ michstopo.cpp \
+ speakerhstopo.cpp \
+ cellularwave.cpp \
+ fmwave.cpp \
+ PhoneAudioSample.rc \
# Indicate that this module must be included in the driver package
DDK_NO_PACKAGE_PROJECT=0
diff --git a/audio/sysvad/PhoneAudioSample/speakerhswavtable.h b/audio/sysvad/PhoneAudioSample/speakerhswavtable.h
index 9cd103ef..cc7b55fc 100644
--- a/audio/sysvad/PhoneAudioSample/speakerhswavtable.h
+++ b/audio/sysvad/PhoneAudioSample/speakerhswavtable.h
@@ -722,6 +722,12 @@ PCPROPERTY_ITEM PropertiesSpeakerHsWaveFilter[] =
KSPROPERTY_PIN_PROPOSEDATAFORMAT,
KSPROPERTY_TYPE_SET | KSPROPERTY_TYPE_BASICSUPPORT,
PropertyHandler_WaveFilter
+ },
+ {
+ &KSPROPSETID_Pin,
+ KSPROPERTY_PIN_PROPOSEDATAFORMAT2,
+ KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_BASICSUPPORT,
+ PropertyHandler_WaveFilter
}
};
diff --git a/audio/sysvad/README.md b/audio/sysvad/README.md
index 8a5c7709..72a4c364 100644
--- a/audio/sysvad/README.md
+++ b/audio/sysvad/README.md
@@ -1,27 +1,25 @@
-<!---
- name: SysVAD Virtual Audio Device Driver Sample
- platform: WDM
- language: cpp
- category: Audio
- description: The Microsoft SysVAD Virtual Audio Device Driver (SYSVAD) shows how to develop a WDM audio driver that exposes support for multiple audio devices.
- samplefwlink: http://go.microsoft.com/fwlink/p/?LinkId=620183
---->
-
SysVAD Virtual Audio Device Driver Sample
========================================
The Microsoft SysVAD Virtual Audio Device Driver (SYSVAD) shows how to develop a WDM audio driver that exposes support for multiple audio devices.
-Some of these audio devices are embedded in the system (for example, speakers, microphone arrays) while others are pluggable (like headphones, speakers, microphones, Bluetooth headsets etc.). The driver uses WaveRT and audio offloading for rendering devices. The driver uses a "virtual audio device" instead of an actual hardware-based adapter, and highlights the different aspects of the audio offloading WDM audio driver architecture.
+Some of these audio devices are embedded in the system (for example, speakers, microphone arrays) while others are pluggable (like headphones, Bluetooth headsets etc.). The driver uses WaveRT and audio offloading for rendering devices. The driver uses a "virtual audio device" instead of an actual hardware-based adapter, and highlights the different aspects of the audio offloading WDM audio driver architecture.
Driver developers can use the framework in this sample to provide support for various audio devices without concern for hardware dependencies. The framework includes implementations of the following interfaces:
- The CAdapterCommon interface gives the miniports access to virtual mixer hardware. It also implements the **IAdapterPowerManagement** interface.
-- The CMiniportTopologyMSVAD interface is the base class for all sample topologies. It has very basic common functions. In addition, this class contains common topology property handlers.
+- The CMiniportTopologySYSVAD interface is the base class for all sample topologies. It has very basic common functions. In addition, this class contains common topology property handlers.
The following table shows the features that are implemented in the various subdirectories of this sample.
+Directory | Description
+-----|------------
+TabletAudioSample | Endpoints that are present in TabletAudioSample driver.
+PhoneAudioSample | Endpoints that are present in PhoneAudioSample driver.
+EndpointsCommon | Endpoints that are present in both TabletAudioSample and PhoneAudioSample. It also contains other common code shared by both sample drivers.
+SwapAPO | Sample APO.
+KeywordDetectorAdapter | Sample Keyword Detector Adapter.
For more information about the Windows audio engine, see [Exposing Hardware-Offloaded Audio Processing in Windows](http://msdn.microsoft.com/en-us/windows/hardware/br259116), and note that audio hardware that is offload-capable replicates the architecture that is presented in the diagram shown in the topic.
@@ -49,7 +47,7 @@ In Visual Studio, click **Build** \> **Build Solution**.
**4. Locate the built driver package**
-In File Explorer, navigate to the folder that contains the sample files. For example, you would navigate to *C:\\Documents\\Windows-driver-samples\\audio\\sysvad*, if that's the folder you specified in the preceding Step 1.
+In File Explorer, navigate to the folder that contains the sample files. For example, you would navigate to *C:\\Windows-driver-samples\\audio\\sysvad*, if that's the folder you specified in the preceding Step 1.
In the folder, the location of the driver package varies depending on the configuration and platform settings that you selected in the **Configuration Manager**. For example, if you left the default settings unchanged, then the built driver package will be saved to a folder named *Debug* inside the same folder as the sample files. Double-click the folder for the built driver package, and then double-click the folder named *package*.
@@ -63,6 +61,7 @@ DelayAPO.dll | A sample APO.
sysvad.cat | A signed catalog file, which serves as the signature for the entire package.
TabletAudioSample.inf | An information (INF) file that contains information needed to install the driver.
PhoneAudioSample.inf | An information (INF) file that contains information needed to install the driver.
+KeywordDetectorContosoAdapter.dll | Sample Keyword detector adapter.
Run the sample
--------------
@@ -97,7 +96,7 @@ If you haven't already done so, then preform the steps in the **Build the sample
In Visual Studio, in Solution Explorer, right click **package** (lower case), and choose **Properties**. Navigate to **Configuration Properties** \> **Driver Install** \> **Deployment**.
-Check , **Enable deployment** and check **Remove previous driver versions before deployment**. For **Target Computer Name**, select the name of a target computer that you provisioned previously. Select **Hardware ID Driver Update**, and enter *\*Root\sysvad_TabletAudioSample* for the hardware ID. Click **OK**.
+Check , **Enable deployment** and check **Remove previous driver versions before deployment**. For **Target Computer Name**, select the name of a target computer that you provisioned previously. Select **Hardware ID Driver Update**, and enter *ROOT\Sysvad_TabletAudioSample* for the hardware ID. Click **OK**.
On the **Build** menu, choose **Deploy Package** or **Build Solution**. This will deploy the sample driver to your target computer.
@@ -127,19 +126,17 @@ If you need more detailed instructions for setting up the target computer, see [
**2. Install the driver**
-The TabletAudioSample or PhoneAudioSample driver package contains a sample driver and 2 driver extension samples. The following instructions show you how to install and test the sample driver. Here's the general syntax for the devcon tool that you will use to install the driver:
-
-**devcon install \<*INF file*>\<*hardware ID*\>**
+The TabletAudioSample or PhoneAudioSample driver package contains a sample driver and 2 driver extension samples. The following instructions show you how to install and test the sample driver.
-The INF file required for installing this driver is *sysvad.inf*. Here's how to find the hardware ID for installing the *TabletAudioSample.sys or PhoneAudioSample* sample: On the target computer, navigate to the folder that contains the files for your driver (for example, *C:\\SysvadDriver*). Then right-click the INF file (*sysvad.inf*) and open it with Notepad. Use Ctrl+F to find the [MicrosoftDS] section. Note that there is a comma-separated element at the end of the row. The element after the comma shows the hardware ID. So for this sample, the hardware ID is \*ROOT\sysvad_TabletAudioSample.
+The INF file required for installing this driver is *TabletAudioSample.inf*.
On the target computer, open a Command Prompt window as Administrator. Navigate to your driver package folder, and enter the following command:
-**devcon install sysvad.inf \*ROOT\sysvad_TabletAudioSample*
+**devcon dp_add TabletAudioSample.inf**
If you get an error message about *devcon* not being recognized, try adding the path to the *devcon* tool. For example, if you copied it to a folder called *C:\\Tools*, then try using the following command:
-**c:\\tools\\devcon install sysvad.inf \*ROOT\sysvad_TabletAudioSample**
+**C:\\tools\\devcon dp_add TabletAudioSample.inf**
For more detailed instructions, see [Configuring a Computer for Driver Deployment, Testing, and Debugging](http://msdn.microsoft.com/en-us/library/windows/hardware/hh698272(v=vs.85).aspx).
diff --git a/audio/sysvad/SwapAPO/APO/SwapAPODll.cpp b/audio/sysvad/SwapAPO/APO/SwapAPODll.cpp
deleted file mode 100644
index e9a04889..00000000
--- a/audio/sysvad/SwapAPO/APO/SwapAPODll.cpp
+++ /dev/null
@@ -1,152 +0,0 @@
-//
-// SwapAPODll.cpp -- Copyright (c) Microsoft Corporation. All rights reserved.
-//
-// Author:
-//
-// Description:
-//
-// SwapAPODll.cpp : Implementation of DLL Exports.
-
-#include <atlbase.h>
-#include <atlcom.h>
-#include <atlcoll.h>
-#include <atlsync.h>
-#include <mmreg.h>
-
-#include "resource.h"
-#include "SwapAPODll.h"
-#include <SwapAPO.h>
-
-#include <SwapAPODll_i.c>
-
-//-------------------------------------------------------------------------
-// Array of APO_REG_PROPERTIES structures implemented in this module.
-// Each new APO implementation will be added to this array.
-//
-APO_REG_PROPERTIES const *gCoreAPOs[] =
-{
- &CSwapAPOMFX::sm_RegProperties.m_Properties,
- &CSwapAPOSFX::sm_RegProperties.m_Properties
-};
-
-// {secret}
-class CSwapAPODllModule : public CAtlDllModuleT< CSwapAPODllModule >
-{
-public :
- DECLARE_LIBID(LIBID_SwapAPODlllib)
- DECLARE_REGISTRY_APPID_RESOURCEID(IDR_SWAPAPODLL, "{0A21D954-674A-4C09-806E-DB4FBE8F199C}")
-public:
- HRESULT DllRegisterServer(BOOL bRegTypeLib = TRUE) throw();
- HRESULT DllUnregisterServer(BOOL bUnRegTypeLib = TRUE) throw();
-};
-
-// {secret}
-CSwapAPODllModule _AtlModule;
-
-
-HRESULT CSwapAPODllModule::DllRegisterServer(BOOL bRegTypeLib) throw()
-{
- HRESULT hResult;
- UINT32 u32APORegIndex = 0;
- UINT32 u32APOUnregIndex = 0;
-
- // Register all APOs implemented in this module.
- for (u32APORegIndex = 0; u32APORegIndex < SIZEOF_ARRAY(gCoreAPOs); u32APORegIndex++)
- {
- hResult = RegisterAPO(gCoreAPOs[u32APORegIndex]);
- if (FAILED(hResult))
- {
- goto ExitFailed;
- }
- }
-
- // Register the module.
- hResult = CAtlDllModuleT<CSwapAPODllModule>::DllRegisterServer(bRegTypeLib);
- if (FAILED(hResult))
- {
- goto ExitFailed;
- }
-
- return hResult;
-
-ExitFailed:
- // Unregister all registered APOs if something failed.
- for (u32APOUnregIndex = 0; u32APOUnregIndex < u32APORegIndex; u32APOUnregIndex++)
- {
- ATLVERIFY(SUCCEEDED(UnregisterAPO(gCoreAPOs[u32APOUnregIndex]->clsid)));
- }
-
- return hResult;
-} // DllRegisterServer
-
-HRESULT CSwapAPODllModule::DllUnregisterServer(BOOL bUnRegTypeLib) throw()
-{
- HRESULT hResult;
- UINT32 u32APOUnregIndex = 0;
-
- // Unregister the module.
- hResult = CAtlDllModuleT<CSwapAPODllModule>::UnregisterServer(bUnRegTypeLib);
- if (FAILED(hResult))
- {
- goto Exit;
- }
-
- // Unregister all the APOs that are implemented in this module.
- for (u32APOUnregIndex = 0; u32APOUnregIndex < SIZEOF_ARRAY(gCoreAPOs); u32APOUnregIndex++)
- {
- hResult = UnregisterAPO(gCoreAPOs[u32APOUnregIndex]->clsid);
- ATLASSERT(SUCCEEDED(hResult));
- }
-
-Exit:
- return hResult;
-} // DllUnregisterServer
-
-// {secret}
-extern "C" BOOL WINAPI DllMain(HINSTANCE /* hInstance */, DWORD dwReason, LPVOID lpReserved)
-{
- if (DLL_PROCESS_ATTACH == dwReason)
- {
- }
- // do necessary cleanup only if the DLL is being unloaded dynamically
- else if ((DLL_PROCESS_DETACH == dwReason) && (NULL == lpReserved))
- {
- }
-
- return _AtlModule.DllMain(dwReason, lpReserved);
-}
-
-
-// {secret}
-__control_entrypoint(DllExport)
-STDAPI DllCanUnloadNow(void)
-{
- return _AtlModule.DllCanUnloadNow();
-}
-
-
-// {secret}
-_Check_return_
-STDAPI DllGetClassObject(_In_ REFCLSID rclsid, _In_ REFIID riid, _Outptr_ LPVOID FAR* ppv)
-{
- return _AtlModule.DllGetClassObject(rclsid, riid, ppv);
-}
-
-
-// {secret}
-__control_entrypoint(DllExport)
-STDAPI DllRegisterServer(void)
-{
- // registers object, typelib and all interfaces in typelib
- HRESULT hr = _AtlModule.DllRegisterServer();
- return hr;
-}
-
-
-// {secret}
-__control_entrypoint(DllExport)
-STDAPI DllUnregisterServer(void)
-{
- HRESULT hr = _AtlModule.DllUnregisterServer();
- return hr;
-}
diff --git a/audio/sysvad/SwapAPO/DelayAPO/DelayAPODll.cpp b/audio/sysvad/SwapAPO/DelayAPO/DelayAPODll.cpp
deleted file mode 100644
index 032c3c9d..00000000
--- a/audio/sysvad/SwapAPO/DelayAPO/DelayAPODll.cpp
+++ /dev/null
@@ -1,148 +0,0 @@
-//
-// DelayAPODll.cpp -- Copyright (c) Microsoft Corporation. All rights reserved.
-//
-// Author:
-//
-// Description:
-//
-// DelayAPODll.cpp : Implementation of DLL Exports.
-
-#include <atlbase.h>
-#include <atlcom.h>
-#include <atlcoll.h>
-#include <atlsync.h>
-#include <mmreg.h>
-
-#include "resource.h"
-#include "DelayAPODll.h"
-#include <DelayAPO.h>
-
-#include <DelayAPODll_i.c>
-
-//-------------------------------------------------------------------------
-// Array of APO_REG_PROPERTIES structures implemented in this module.
-// Each new APO implementation will be added to this array.
-//
-APO_REG_PROPERTIES const *gCoreAPOs[] =
-{
- &CDelayAPOMFX::sm_RegProperties.m_Properties,
- &CDelayAPOSFX::sm_RegProperties.m_Properties
-};
-
-// {secret}
-class CDelayAPODllModule : public CAtlDllModuleT< CDelayAPODllModule >
-{
-public :
- DECLARE_LIBID(LIBID_DelayAPODlllib)
- DECLARE_REGISTRY_APPID_RESOURCEID(IDR_DELAYAPODLL, "{0A21D954-674A-4C09-806E-DB4FBE8F199C}")
-public:
- HRESULT DllRegisterServer(BOOL bRegTypeLib = TRUE) throw();
- HRESULT DllUnregisterServer(BOOL bUnRegTypeLib = TRUE) throw();
-};
-
-// {secret}
-CDelayAPODllModule _AtlModule;
-
-
-HRESULT CDelayAPODllModule::DllRegisterServer(BOOL bRegTypeLib) throw()
-{
- HRESULT hResult;
- UINT32 u32APORegIndex = 0;
- UINT32 u32APOUnregIndex = 0;
-
- // Register all APOs implemented in this module.
- for (u32APORegIndex = 0; u32APORegIndex < SIZEOF_ARRAY(gCoreAPOs); u32APORegIndex++)
- {
- hResult = RegisterAPO(gCoreAPOs[u32APORegIndex]);
- if (FAILED(hResult))
- {
- goto ExitFailed;
- }
- }
-
- // Register the module.
- hResult = CAtlDllModuleT<CDelayAPODllModule>::DllRegisterServer(bRegTypeLib);
- if (FAILED(hResult))
- {
- goto ExitFailed;
- }
-
- return hResult;
-
-ExitFailed:
- // Unregister all registered APOs if something failed.
- for (u32APOUnregIndex = 0; u32APOUnregIndex < u32APORegIndex; u32APOUnregIndex++)
- {
- ATLVERIFY(SUCCEEDED(UnregisterAPO(gCoreAPOs[u32APOUnregIndex]->clsid)));
- }
-
- return hResult;
-} // DllRegisterServer
-
-HRESULT CDelayAPODllModule::DllUnregisterServer(BOOL bUnRegTypeLib) throw()
-{
- HRESULT hResult;
- UINT32 u32APOUnregIndex = 0;
-
- // Unregister the module.
- hResult = CAtlDllModuleT<CDelayAPODllModule>::UnregisterServer(bUnRegTypeLib);
- if (FAILED(hResult))
- {
- goto Exit;
- }
-
- // Unregister all the APOs that are implemented in this module.
- for (u32APOUnregIndex = 0; u32APOUnregIndex < SIZEOF_ARRAY(gCoreAPOs); u32APOUnregIndex++)
- {
- hResult = UnregisterAPO(gCoreAPOs[u32APOUnregIndex]->clsid);
- ATLASSERT(SUCCEEDED(hResult));
- }
-
-Exit:
- return hResult;
-} // DllUnregisterServer
-
-// {secret}
-extern "C" BOOL WINAPI DllMain(HINSTANCE /* hInstance */, DWORD dwReason, LPVOID lpReserved)
-{
- if (DLL_PROCESS_ATTACH == dwReason)
- {
- }
- // do necessary cleanup only if the DLL is being unloaded dynamically
- else if ((DLL_PROCESS_DETACH == dwReason) && (NULL == lpReserved))
- {
- }
-
- return _AtlModule.DllMain(dwReason, lpReserved);
-}
-
-
-// {secret}
-STDAPI DllCanUnloadNow(void)
-{
- return _AtlModule.DllCanUnloadNow();
-}
-
-
-// {secret}
-STDAPI DllGetClassObject(_In_ REFCLSID rclsid,_In_ REFIID riid, _Outptr_ LPVOID* ppv)
-{
- return _AtlModule.DllGetClassObject(rclsid, riid, ppv);
-}
-
-
-// {secret}
-STDAPI DllRegisterServer(void)
-{
- // registers object, typelib and all interfaces in typelib
- HRESULT hr = _AtlModule.DllRegisterServer();
- return hr;
-}
-
-
-// {secret}
-STDAPI DllUnregisterServer(void)
-{
- HRESULT hr = _AtlModule.DllUnregisterServer();
- return hr;
-}
diff --git a/audio/sysvad/TabletAudioSample/ComponentizedApoSample.inf b/audio/sysvad/TabletAudioSample/ComponentizedApoSample.inx
index a60abe3f..43457d73 100644
--- a/audio/sysvad/TabletAudioSample/ComponentizedApoSample.inf
+++ b/audio/sysvad/TabletAudioSample/ComponentizedApoSample.inx
Binary files differ
diff --git a/audio/sysvad/TabletAudioSample/ComponentizedAudioSample.inf b/audio/sysvad/TabletAudioSample/ComponentizedAudioSample.inx
index 6e380029..cd77bd98 100644
--- a/audio/sysvad/TabletAudioSample/ComponentizedAudioSample.inf
+++ b/audio/sysvad/TabletAudioSample/ComponentizedAudioSample.inx
Binary files differ
diff --git a/audio/sysvad/TabletAudioSample/ComponentizedAudioSampleExtension.inf b/audio/sysvad/TabletAudioSample/ComponentizedAudioSampleExtension.inx
index d91e44ba..a13515cc 100644
--- a/audio/sysvad/TabletAudioSample/ComponentizedAudioSampleExtension.inf
+++ b/audio/sysvad/TabletAudioSample/ComponentizedAudioSampleExtension.inx
Binary files differ
diff --git a/audio/sysvad/TabletAudioSample/TabletAudioSample.rc b/audio/sysvad/TabletAudioSample/TabletAudioSample.rc
new file mode 100644
index 00000000..3ab06ea6
--- /dev/null
+++ b/audio/sysvad/TabletAudioSample/TabletAudioSample.rc
@@ -0,0 +1,30 @@
+/*++
+
+Copyright (c) Microsoft Corporation All Rights Reserved
+
+Module Name:
+
+ TabletAudioSample.rc
+
+Abstract:
+
+
+--*/
+
+#include <windows.h>
+
+#include <ntverp.h>
+
+#define VER_FILETYPE VFT_DRV
+#define VER_FILESUBTYPE VFT2_DRV_SOUND
+#define VER_FILEDESCRIPTION_STR "Microsoft Virtual Audio Tablet Sample Driver"
+#define VER_INTERNALNAME_STR "TabletAudioSample.sys"
+#define VER_ORIGINALFILENAME_STR "TabletAudioSample.sys"
+
+#define VER_LEGALCOPYRIGHT_YEARS "2013"
+#define VER_LEGALCOPYRIGHT_STR "Copyright (C) Microsoft Corp." VER_LEGALCOPYRIGHT_YEARS
+
+#include "common.ver"
+
+
+
diff --git a/audio/sysvad/TabletAudioSample/TabletAudioSample.vcxproj b/audio/sysvad/TabletAudioSample/TabletAudioSample.vcxproj
index 48c5665e..205ff309 100644
--- a/audio/sysvad/TabletAudioSample/TabletAudioSample.vcxproj
+++ b/audio/sysvad/TabletAudioSample/TabletAudioSample.vcxproj
@@ -83,19 +83,19 @@
<AdditionalDependencies>%(AdditionalDependencies);$(DDK_LIB_PATH)\portcls.lib;$(DDK_LIB_PATH)\stdunk.lib;$(DDK_LIB_PATH)\libcntpr.lib</AdditionalDependencies>
</Link>
<ResourceCompile>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..;.</AdditionalIncludeDirectories>
<PreprocessorDefinitions>%(PreprocessorDefinitions);_WIN32;UNICODE;_UNICODE;PC_IMPLEMENTATION</PreprocessorDefinitions>
<PreprocessorDefinitions>%(PreprocessorDefinitions);DEBUG_LEVEL=DEBUGLVL_TERSE</PreprocessorDefinitions>
</ResourceCompile>
<ClCompile>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..;.</AdditionalIncludeDirectories>
<TreatWarningAsError>true</TreatWarningAsError>
<WarningLevel>Level4</WarningLevel>
<PreprocessorDefinitions>%(PreprocessorDefinitions);_WIN32;UNICODE;_UNICODE;PC_IMPLEMENTATION</PreprocessorDefinitions>
<PreprocessorDefinitions>%(PreprocessorDefinitions);DEBUG_LEVEL=DEBUGLVL_TERSE</PreprocessorDefinitions>
</ClCompile>
<Midl>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..;.</AdditionalIncludeDirectories>
<PreprocessorDefinitions>%(PreprocessorDefinitions);_WIN32;UNICODE;_UNICODE;PC_IMPLEMENTATION</PreprocessorDefinitions>
<PreprocessorDefinitions>%(PreprocessorDefinitions);DEBUG_LEVEL=DEBUGLVL_TERSE</PreprocessorDefinitions>
</Midl>
@@ -105,19 +105,19 @@
<AdditionalDependencies>%(AdditionalDependencies);$(DDK_LIB_PATH)\portcls.lib;$(DDK_LIB_PATH)\stdunk.lib;$(DDK_LIB_PATH)\libcntpr.lib</AdditionalDependencies>
</Link>
<ResourceCompile>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..;.</AdditionalIncludeDirectories>
<PreprocessorDefinitions>%(PreprocessorDefinitions);_WIN32;UNICODE;_UNICODE;PC_IMPLEMENTATION</PreprocessorDefinitions>
<PreprocessorDefinitions>%(PreprocessorDefinitions);DEBUG_LEVEL=DEBUGLVL_TERSE</PreprocessorDefinitions>
</ResourceCompile>
<ClCompile>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..;.</AdditionalIncludeDirectories>
<TreatWarningAsError>true</TreatWarningAsError>
<WarningLevel>Level4</WarningLevel>
<PreprocessorDefinitions>%(PreprocessorDefinitions);_WIN32;UNICODE;_UNICODE;PC_IMPLEMENTATION</PreprocessorDefinitions>
<PreprocessorDefinitions>%(PreprocessorDefinitions);DEBUG_LEVEL=DEBUGLVL_TERSE</PreprocessorDefinitions>
</ClCompile>
<Midl>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..;.</AdditionalIncludeDirectories>
<PreprocessorDefinitions>%(PreprocessorDefinitions);_WIN32;UNICODE;_UNICODE;PC_IMPLEMENTATION</PreprocessorDefinitions>
<PreprocessorDefinitions>%(PreprocessorDefinitions);DEBUG_LEVEL=DEBUGLVL_TERSE</PreprocessorDefinitions>
</Midl>
@@ -127,19 +127,19 @@
<AdditionalDependencies>%(AdditionalDependencies);$(DDK_LIB_PATH)\portcls.lib;$(DDK_LIB_PATH)\stdunk.lib;$(DDK_LIB_PATH)\libcntpr.lib</AdditionalDependencies>
</Link>
<ResourceCompile>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..;.</AdditionalIncludeDirectories>
<PreprocessorDefinitions>%(PreprocessorDefinitions);_WIN32;UNICODE;_UNICODE;PC_IMPLEMENTATION</PreprocessorDefinitions>
<PreprocessorDefinitions>%(PreprocessorDefinitions);DEBUG_LEVEL=DEBUGLVL_TERSE</PreprocessorDefinitions>
</ResourceCompile>
<ClCompile>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..;.</AdditionalIncludeDirectories>
<TreatWarningAsError>true</TreatWarningAsError>
<WarningLevel>Level4</WarningLevel>
<PreprocessorDefinitions>%(PreprocessorDefinitions);_WIN32;UNICODE;_UNICODE;PC_IMPLEMENTATION</PreprocessorDefinitions>
<PreprocessorDefinitions>%(PreprocessorDefinitions);DEBUG_LEVEL=DEBUGLVL_TERSE</PreprocessorDefinitions>
</ClCompile>
<Midl>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..;.</AdditionalIncludeDirectories>
<PreprocessorDefinitions>%(PreprocessorDefinitions);_WIN32;UNICODE;_UNICODE;PC_IMPLEMENTATION</PreprocessorDefinitions>
<PreprocessorDefinitions>%(PreprocessorDefinitions);DEBUG_LEVEL=DEBUGLVL_TERSE</PreprocessorDefinitions>
</Midl>
@@ -149,19 +149,19 @@
<AdditionalDependencies>%(AdditionalDependencies);$(DDK_LIB_PATH)\portcls.lib;$(DDK_LIB_PATH)\stdunk.lib;$(DDK_LIB_PATH)\libcntpr.lib</AdditionalDependencies>
</Link>
<ResourceCompile>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..;.</AdditionalIncludeDirectories>
<PreprocessorDefinitions>%(PreprocessorDefinitions);_WIN32;UNICODE;_UNICODE;PC_IMPLEMENTATION</PreprocessorDefinitions>
<PreprocessorDefinitions>%(PreprocessorDefinitions);DEBUG_LEVEL=DEBUGLVL_TERSE</PreprocessorDefinitions>
</ResourceCompile>
<ClCompile>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..;.</AdditionalIncludeDirectories>
<TreatWarningAsError>true</TreatWarningAsError>
<WarningLevel>Level4</WarningLevel>
<PreprocessorDefinitions>%(PreprocessorDefinitions);_WIN32;UNICODE;_UNICODE;PC_IMPLEMENTATION</PreprocessorDefinitions>
<PreprocessorDefinitions>%(PreprocessorDefinitions);DEBUG_LEVEL=DEBUGLVL_TERSE</PreprocessorDefinitions>
</ClCompile>
<Midl>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..;.</AdditionalIncludeDirectories>
<PreprocessorDefinitions>%(PreprocessorDefinitions);_WIN32;UNICODE;_UNICODE;PC_IMPLEMENTATION</PreprocessorDefinitions>
<PreprocessorDefinitions>%(PreprocessorDefinitions);DEBUG_LEVEL=DEBUGLVL_TERSE</PreprocessorDefinitions>
</Midl>
@@ -184,8 +184,8 @@
</Link>
<ClCompile>
<PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_;SYSVAD_BTH_BYPASS</PreprocessorDefinitions>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_SingleComponentMultiFxStates</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\EndpointsCommon;.</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_SingleComponentMultiFxStates;_NEW_DELETE_OPERATORS_</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\EndpointsCommon</AdditionalIncludeDirectories>
<ExceptionHandling>
</ExceptionHandling>
<DisableSpecificWarnings>4595;%(DisableSpecificWarnings)</DisableSpecificWarnings>
@@ -193,12 +193,12 @@
<Midl>
<PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_;SYSVAD_BTH_BYPASS</PreprocessorDefinitions>
<PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_SingleComponentMultiFxStates</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\EndpointsCommon;.</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\EndpointsCommon</AdditionalIncludeDirectories>
</Midl>
<ResourceCompile>
<PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_;SYSVAD_BTH_BYPASS</PreprocessorDefinitions>
<PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_SingleComponentMultiFxStates</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\EndpointsCommon;.</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\EndpointsCommon</AdditionalIncludeDirectories>
</ResourceCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
@@ -207,8 +207,8 @@
</Link>
<ClCompile>
<PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_;SYSVAD_BTH_BYPASS</PreprocessorDefinitions>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_SingleComponentMultiFxStates</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\EndpointsCommon;.</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_SingleComponentMultiFxStates;_NEW_DELETE_OPERATORS_</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\EndpointsCommon</AdditionalIncludeDirectories>
<ExceptionHandling>
</ExceptionHandling>
<DisableSpecificWarnings>4595;%(DisableSpecificWarnings)</DisableSpecificWarnings>
@@ -216,12 +216,12 @@
<Midl>
<PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_;SYSVAD_BTH_BYPASS</PreprocessorDefinitions>
<PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_SingleComponentMultiFxStates</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\EndpointsCommon;.</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\EndpointsCommon</AdditionalIncludeDirectories>
</Midl>
<ResourceCompile>
<PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_;SYSVAD_BTH_BYPASS</PreprocessorDefinitions>
<PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_SingleComponentMultiFxStates</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\EndpointsCommon;.</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\EndpointsCommon</AdditionalIncludeDirectories>
</ResourceCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@@ -230,8 +230,8 @@
</Link>
<ClCompile>
<PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_;SYSVAD_BTH_BYPASS</PreprocessorDefinitions>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_SingleComponentMultiFxStates</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\EndpointsCommon;.</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_SingleComponentMultiFxStates;_NEW_DELETE_OPERATORS_</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\EndpointsCommon</AdditionalIncludeDirectories>
<ExceptionHandling>
</ExceptionHandling>
<DisableSpecificWarnings>4595;%(DisableSpecificWarnings)</DisableSpecificWarnings>
@@ -239,12 +239,12 @@
<Midl>
<PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_;SYSVAD_BTH_BYPASS</PreprocessorDefinitions>
<PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_SingleComponentMultiFxStates</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\EndpointsCommon;.</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\EndpointsCommon</AdditionalIncludeDirectories>
</Midl>
<ResourceCompile>
<PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_;SYSVAD_BTH_BYPASS</PreprocessorDefinitions>
<PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_SingleComponentMultiFxStates</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\EndpointsCommon;.</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\EndpointsCommon</AdditionalIncludeDirectories>
</ResourceCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
@@ -253,8 +253,8 @@
</Link>
<ClCompile>
<PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_;SYSVAD_BTH_BYPASS</PreprocessorDefinitions>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_SingleComponentMultiFxStates</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\EndpointsCommon;.</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_SingleComponentMultiFxStates;_NEW_DELETE_OPERATORS_</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\EndpointsCommon</AdditionalIncludeDirectories>
<ExceptionHandling>
</ExceptionHandling>
<DisableSpecificWarnings>4595;%(DisableSpecificWarnings)</DisableSpecificWarnings>
@@ -262,17 +262,18 @@
<Midl>
<PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_;SYSVAD_BTH_BYPASS</PreprocessorDefinitions>
<PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_SingleComponentMultiFxStates</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\EndpointsCommon;.</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\EndpointsCommon</AdditionalIncludeDirectories>
</Midl>
<ResourceCompile>
<PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_;SYSVAD_BTH_BYPASS</PreprocessorDefinitions>
<PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_SingleComponentMultiFxStates</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\EndpointsCommon;.</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\EndpointsCommon</AdditionalIncludeDirectories>
</ResourceCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\adapter.cpp" />
<ClCompile Include="..\basetopo.cpp" />
+ <ClCompile Include="..\BthhfpDevice.cpp" />
<ClCompile Include="..\common.cpp" />
<ClCompile Include="..\hw.cpp" />
<ClCompile Include="..\kshelper.cpp" />
@@ -281,10 +282,10 @@
<ClCompile Include="hdmitopo.cpp" />
<ClCompile Include="micintopo.cpp" />
<ClCompile Include="spdiftopo.cpp" />
- <ResourceCompile Include="..\sysvad.rc" />
+ <ResourceCompile Include="TabletAudioSample.rc" />
</ItemGroup>
<ItemGroup>
- <Inf Exclude="@(Inf)" Include="*.inf" />
+ <Inf Exclude="@(Inx)" Include="*.inx" />
<FilesToPackage Include="$(TargetPath)" Condition="'$(ConfigurationType)'=='Driver' or '$(ConfigurationType)'=='DynamicLibrary'" />
</ItemGroup>
<ItemGroup>
diff --git a/audio/sysvad/TabletAudioSample/TabletAudioSample.vcxproj.Filters b/audio/sysvad/TabletAudioSample/TabletAudioSample.vcxproj.Filters
index cc7dcd30..643d5929 100644
--- a/audio/sysvad/TabletAudioSample/TabletAudioSample.vcxproj.Filters
+++ b/audio/sysvad/TabletAudioSample/TabletAudioSample.vcxproj.Filters
@@ -19,40 +19,26 @@
</Filter>
</ItemGroup>
<ItemGroup>
- <ClCompile Include="..\adapter.cpp">
+ <ClCompile Include="..\*.cpp">
<Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="..\basetopo.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="..\common.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="..\hw.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="..\kshelper.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="..\savedata.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="..\tonegenerator.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="hdmitopo.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="micintopo.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="spdiftopo.cpp">
+ <ClCompile Include="*.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
- <ResourceCompile Include="..\sysvad.rc">
+ <ResourceCompile Include="TabletAudioSample.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <Inf Include="*.inx">
+ <Filter>Driver Files</Filter>
+ </Inf>
+ </ItemGroup>
</Project> \ No newline at end of file
diff --git a/audio/sysvad/TabletAudioSample/hdmitoptable.h b/audio/sysvad/TabletAudioSample/hdmitoptable.h
index 5fab7cf4..23bd8765 100644
--- a/audio/sysvad/TabletAudioSample/hdmitoptable.h
+++ b/audio/sysvad/TabletAudioSample/hdmitoptable.h
@@ -36,6 +36,51 @@ KSDATARANGE HdmiTopoPinDataRangesBridge[] =
STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
STATICGUIDOF(KSDATAFORMAT_SUBTYPE_IEC61937_DOLBY_DIGITAL),
STATICGUIDOF(KSDATAFORMAT_SPECIFIER_NONE)
+ },
+ {
+ sizeof(KSDATARANGE),
+ 0,
+ 0,
+ 0,
+ STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_IEC61937_DOLBY_MLP),
+ STATICGUIDOF(KSDATAFORMAT_SPECIFIER_NONE)
+ },
+ {
+ sizeof(KSDATARANGE),
+ 0,
+ 0,
+ 0,
+ STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_IEC61937_DTS),
+ STATICGUIDOF(KSDATAFORMAT_SPECIFIER_NONE)
+ },
+ {
+ sizeof(KSDATARANGE),
+ 0,
+ 0,
+ 0,
+ STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_IEC61937_DTS_HD),
+ STATICGUIDOF(KSDATAFORMAT_SPECIFIER_NONE)
+ },
+ {
+ sizeof(KSDATARANGE),
+ 0,
+ 0,
+ 0,
+ STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_IEC61937_DOLBY_MAT20),
+ STATICGUIDOF(KSDATAFORMAT_SPECIFIER_NONE)
+ },
+ {
+ sizeof(KSDATARANGE),
+ 0,
+ 0,
+ 0,
+ STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_IEC61937_DOLBY_MAT21),
+ STATICGUIDOF(KSDATAFORMAT_SPECIFIER_NONE)
}
};
@@ -44,7 +89,12 @@ static
PKSDATARANGE HdmiTopoPinDataRangePointersBridge[] =
{
&HdmiTopoPinDataRangesBridge[0],
- &HdmiTopoPinDataRangesBridge[1]
+ &HdmiTopoPinDataRangesBridge[1],
+ &HdmiTopoPinDataRangesBridge[2],
+ &HdmiTopoPinDataRangesBridge[3],
+ &HdmiTopoPinDataRangesBridge[4],
+ &HdmiTopoPinDataRangesBridge[5],
+ &HdmiTopoPinDataRangesBridge[6]
};
//=============================================================================
diff --git a/audio/sysvad/TabletAudioSample/hdmiwavtable.h b/audio/sysvad/TabletAudioSample/hdmiwavtable.h
index 7d786a64..ad3b26e0 100644
--- a/audio/sysvad/TabletAudioSample/hdmiwavtable.h
+++ b/audio/sysvad/TabletAudioSample/hdmiwavtable.h
@@ -44,6 +44,24 @@ Abstract:
#define HDMI_DOLBY_DIGITAL_MIN_SAMPLE_RATE 44100 // Min Sample Rate
#define HDMI_DOLBY_DIGITAL_MAX_SAMPLE_RATE 48000 // Max Sample Rate
+#define HDMI_DOLBY_MAT_MAX_CHANNELS 8 // Max Channels.
+#define HDMI_DOLBY_MAT_MIN_BITS_PER_SAMPLE 16 // Min Bits Per Sample
+#define HDMI_DOLBY_MAT_MAX_BITS_PER_SAMPLE 16 // Max Bits Per Sample
+#define HDMI_DOLBY_MAT_MIN_SAMPLE_RATE 192000 // Min Sample Rate
+#define HDMI_DOLBY_MAT_MAX_SAMPLE_RATE 192000 // Max Sample Rate
+
+#define HDMI_DTS_MAX_CHANNELS 2 // Max Channels.
+#define HDMI_DTS_MIN_BITS_PER_SAMPLE 16 // Min Bits Per Sample
+#define HDMI_DTS_MAX_BITS_PER_SAMPLE 16 // Max Bits Per Sample
+#define HDMI_DTS_MIN_SAMPLE_RATE 48000 // Min Sample Rate
+#define HDMI_DTS_MAX_SAMPLE_RATE 48000 // Max Sample Rate
+
+#define HDMI_DTS_HD_MAX_CHANNELS 8 // Max Channels.
+#define HDMI_DTS_HD_MIN_BITS_PER_SAMPLE 16 // Min Bits Per Sample
+#define HDMI_DTS_HD_MAX_BITS_PER_SAMPLE 16 // Max Bits Per Sample
+#define HDMI_DTS_HD_MIN_SAMPLE_RATE 192000 // Min Sample Rate
+#define HDMI_DTS_HD_MAX_SAMPLE_RATE 192000 // Max Sample Rate
+
//
// Max # of pin instances.
//
@@ -204,11 +222,163 @@ KSDATAFORMAT_WAVEFORMATEXTENSIBLE HdmiHostPinSupportedDeviceFormats[] =
KSAUDIO_SPEAKER_5POINT1_SURROUND,
STATICGUIDOF(KSDATAFORMAT_SUBTYPE_IEC61937_DOLBY_DIGITAL)
}
+ },
+ { // 6
+ {
+ sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE),
+ 0,
+ 0,
+ 0,
+ STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_IEC61937_DOLBY_MLP),
+ STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
+ },
+ {
+ {
+ WAVE_FORMAT_EXTENSIBLE,
+ 8,
+ 192000,
+ 3072000,
+ 16,
+ 16,
+ sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)
+ },
+ 16,
+ KSAUDIO_SPEAKER_7POINT1,
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_IEC61937_DOLBY_MLP)
+ }
+ },
+ { // 7
+ {
+ sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE),
+ 0,
+ 0,
+ 0,
+ STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_IEC61937_DOLBY_MLP),
+ STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
+ },
+ {
+ {
+ WAVE_FORMAT_EXTENSIBLE,
+ 8,
+ 192000,
+ 3072000,
+ 16,
+ 16,
+ sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)
+ },
+ 16,
+ KSAUDIO_SPEAKER_7POINT1_SURROUND,
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_IEC61937_DOLBY_MLP)
+ }
+ },
+ { // 8
+ {
+ sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE),
+ 0,
+ 0,
+ 0,
+ STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_IEC61937_DTS),
+ STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
+ },
+ {
+ {
+ WAVE_FORMAT_EXTENSIBLE,
+ 2,
+ 48000,
+ 192000,
+ 4,
+ 16,
+ sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)
+ },
+ 16,
+ KSAUDIO_SPEAKER_5POINT1_SURROUND,
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_IEC61937_DTS)
+ }
+ },
+ { // 9
+ {
+ sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE),
+ 0,
+ 0,
+ 0,
+ STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_IEC61937_DTS_HD),
+ STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
+ },
+ {
+ {
+ WAVE_FORMAT_EXTENSIBLE,
+ 8,
+ 192000,
+ 3072000,
+ 16,
+ 16,
+ sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)
+ },
+ 16,
+ KSAUDIO_SPEAKER_7POINT1,
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_IEC61937_DTS_HD)
+ }
+ },
+ { // 10
+ {
+ sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE),
+ 0,
+ 0,
+ 0,
+ STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_IEC61937_DOLBY_MAT20),
+ STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
+ },
+ {
+ {
+ WAVE_FORMAT_EXTENSIBLE,
+ 8,
+ 192000,
+ 3072000,
+ 16,
+ 16,
+ sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)
+ },
+ 16,
+ KSAUDIO_SPEAKER_7POINT1,
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_IEC61937_DOLBY_MAT20)
+ }
+ },
+ { // 11
+ {
+ sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE),
+ 0,
+ 0,
+ 0,
+ STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_IEC61937_DOLBY_MAT21),
+ STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
+ },
+ {
+ {
+ WAVE_FORMAT_EXTENSIBLE,
+ 8,
+ 192000,
+ 3072000,
+ 16,
+ 16,
+ sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)
+ },
+ 16,
+ KSAUDIO_SPEAKER_7POINT1,
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_IEC61937_DOLBY_MAT21)
+ }
}
};
//
// Supported modes (only on streaming pins).
+// Note: This pin does not support KSPROPERTY_PIN_PROPOSEDATAFORMAT2
+// since none of the modes on this endpoint have a default format.
//
static
MODE_AND_DEFAULT_FORMAT HdmiHostPinSupportedDeviceModes[] =
@@ -216,10 +386,6 @@ MODE_AND_DEFAULT_FORMAT HdmiHostPinSupportedDeviceModes[] =
{
STATIC_AUDIO_SIGNALPROCESSINGMODE_RAW,
NULL, // just an example of no default format for this endpoint/mode
- },
- {
- STATIC_AUDIO_SIGNALPROCESSINGMODE_DEFAULT,
- NULL, // just an example of no default format for this endpoint/mode
}
};
@@ -299,11 +465,91 @@ KSDATARANGE_AUDIO HdmiPinDataRangesStream[] =
STATICGUIDOF(KSDATAFORMAT_SUBTYPE_IEC61937_DOLBY_DIGITAL),
STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
},
- HDMI_DOLBY_DIGITAL_MAX_CHANNELS,
- HDMI_DOLBY_DIGITAL_MIN_BITS_PER_SAMPLE,
- HDMI_DOLBY_DIGITAL_MAX_BITS_PER_SAMPLE,
+ HDMI_DOLBY_DIGITAL_MAX_CHANNELS,
+ HDMI_DOLBY_DIGITAL_MIN_BITS_PER_SAMPLE,
+ HDMI_DOLBY_DIGITAL_MAX_BITS_PER_SAMPLE,
HDMI_DOLBY_DIGITAL_MIN_SAMPLE_RATE,
HDMI_DOLBY_DIGITAL_MAX_SAMPLE_RATE
+ },
+ { // 3 - DOLBY-MLP host
+ {
+ sizeof(KSDATARANGE_AUDIO),
+ KSDATARANGE_ATTRIBUTES, // An attributes list follows this data range
+ 0,
+ 0,
+ STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_IEC61937_DOLBY_MLP),
+ STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
+ },
+ HDMI_DOLBY_MAT_MAX_CHANNELS,
+ HDMI_DOLBY_MAT_MIN_BITS_PER_SAMPLE,
+ HDMI_DOLBY_MAT_MAX_BITS_PER_SAMPLE,
+ HDMI_DOLBY_MAT_MIN_SAMPLE_RATE,
+ HDMI_DOLBY_MAT_MAX_SAMPLE_RATE
+ },
+ { // 4 - DTS host
+ {
+ sizeof(KSDATARANGE_AUDIO),
+ KSDATARANGE_ATTRIBUTES, // An attributes list follows this data range
+ 0,
+ 0,
+ STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_IEC61937_DTS),
+ STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
+ },
+ HDMI_DTS_MAX_CHANNELS,
+ HDMI_DTS_MIN_BITS_PER_SAMPLE,
+ HDMI_DTS_MAX_BITS_PER_SAMPLE,
+ HDMI_DTS_MIN_SAMPLE_RATE,
+ HDMI_DTS_MAX_SAMPLE_RATE
+ },
+ { // 5 - DTS-HD host
+ {
+ sizeof(KSDATARANGE_AUDIO),
+ KSDATARANGE_ATTRIBUTES, // An attributes list follows this data range
+ 0,
+ 0,
+ STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_IEC61937_DTS_HD),
+ STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
+ },
+ HDMI_DTS_HD_MAX_CHANNELS,
+ HDMI_DTS_HD_MIN_BITS_PER_SAMPLE,
+ HDMI_DTS_HD_MAX_BITS_PER_SAMPLE,
+ HDMI_DTS_HD_MIN_SAMPLE_RATE,
+ HDMI_DTS_HD_MAX_SAMPLE_RATE
+ },
+ { // 6 - DOLBY-MAT20 host
+ {
+ sizeof(KSDATARANGE_AUDIO),
+ KSDATARANGE_ATTRIBUTES, // An attributes list follows this data range
+ 0,
+ 0,
+ STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_IEC61937_DOLBY_MAT20),
+ STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
+ },
+ HDMI_DOLBY_MAT_MAX_CHANNELS,
+ HDMI_DOLBY_MAT_MIN_BITS_PER_SAMPLE,
+ HDMI_DOLBY_MAT_MAX_BITS_PER_SAMPLE,
+ HDMI_DOLBY_MAT_MIN_SAMPLE_RATE,
+ HDMI_DOLBY_MAT_MAX_SAMPLE_RATE
+ },
+ { // 7 - DOLBY-MAT21 host
+ {
+ sizeof(KSDATARANGE_AUDIO),
+ KSDATARANGE_ATTRIBUTES, // An attributes list follows this data range
+ 0,
+ 0,
+ STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_IEC61937_DOLBY_MAT21),
+ STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
+ },
+ HDMI_DOLBY_MAT_MAX_CHANNELS,
+ HDMI_DOLBY_MAT_MIN_BITS_PER_SAMPLE,
+ HDMI_DOLBY_MAT_MAX_BITS_PER_SAMPLE,
+ HDMI_DOLBY_MAT_MIN_SAMPLE_RATE,
+ HDMI_DOLBY_MAT_MAX_SAMPLE_RATE
}
};
@@ -313,6 +559,16 @@ PKSDATARANGE HdmiPinDataRangePointersStream[] =
PKSDATARANGE(&HdmiPinDataRangesStream[0]),
PKSDATARANGE(&PinDataRangeAttributeList),
PKSDATARANGE(&HdmiPinDataRangesStream[2]),
+ PKSDATARANGE(&PinDataRangeAttributeList),
+ PKSDATARANGE(&HdmiPinDataRangesStream[3]),
+ PKSDATARANGE(&PinDataRangeAttributeList),
+ PKSDATARANGE(&HdmiPinDataRangesStream[4]),
+ PKSDATARANGE(&PinDataRangeAttributeList),
+ PKSDATARANGE(&HdmiPinDataRangesStream[5]),
+ PKSDATARANGE(&PinDataRangeAttributeList),
+ PKSDATARANGE(&HdmiPinDataRangesStream[6]),
+ PKSDATARANGE(&PinDataRangeAttributeList),
+ PKSDATARANGE(&HdmiPinDataRangesStream[7]),
PKSDATARANGE(&PinDataRangeAttributeList)
};
@@ -326,7 +582,7 @@ PKSDATARANGE HdmiPinDataRangePointersLoopbackStream[] =
static
KSDATARANGE HdmiPinDataRangesBridge[] =
{
- {
+ { // 0
sizeof(KSDATARANGE),
0,
0,
@@ -335,7 +591,7 @@ KSDATARANGE HdmiPinDataRangesBridge[] =
STATICGUIDOF(KSDATAFORMAT_SUBTYPE_ANALOG),
STATICGUIDOF(KSDATAFORMAT_SPECIFIER_NONE)
},
- {
+ { // 1
sizeof(KSDATARANGE),
0,
0,
@@ -343,6 +599,51 @@ KSDATARANGE HdmiPinDataRangesBridge[] =
STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
STATICGUIDOF(KSDATAFORMAT_SUBTYPE_IEC61937_DOLBY_DIGITAL),
STATICGUIDOF(KSDATAFORMAT_SPECIFIER_NONE)
+ },
+ { // 2
+ sizeof(KSDATARANGE),
+ 0,
+ 0,
+ 0,
+ STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_IEC61937_DOLBY_MLP),
+ STATICGUIDOF(KSDATAFORMAT_SPECIFIER_NONE)
+ },
+ { // 3
+ sizeof(KSDATARANGE),
+ 0,
+ 0,
+ 0,
+ STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_IEC61937_DTS),
+ STATICGUIDOF(KSDATAFORMAT_SPECIFIER_NONE)
+ },
+ { // 4
+ sizeof(KSDATARANGE),
+ 0,
+ 0,
+ 0,
+ STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_IEC61937_DTS_HD),
+ STATICGUIDOF(KSDATAFORMAT_SPECIFIER_NONE)
+ },
+ { // 5
+ sizeof(KSDATARANGE),
+ 0,
+ 0,
+ 0,
+ STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_IEC61937_DOLBY_MAT20),
+ STATICGUIDOF(KSDATAFORMAT_SPECIFIER_NONE)
+ },
+ { // 6
+ sizeof(KSDATARANGE),
+ 0,
+ 0,
+ 0,
+ STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_IEC61937_DOLBY_MAT21),
+ STATICGUIDOF(KSDATAFORMAT_SPECIFIER_NONE)
}
};
@@ -350,7 +651,12 @@ static
PKSDATARANGE HdmiPinDataRangePointersBridge[] =
{
&HdmiPinDataRangesBridge[0],
- &HdmiPinDataRangesBridge[1]
+ &HdmiPinDataRangesBridge[1],
+ &HdmiPinDataRangesBridge[2],
+ &HdmiPinDataRangesBridge[3],
+ &HdmiPinDataRangesBridge[4],
+ &HdmiPinDataRangesBridge[5],
+ &HdmiPinDataRangesBridge[6]
};
diff --git a/audio/sysvad/TabletAudioSample/micintopo.cpp b/audio/sysvad/TabletAudioSample/micintopo.cpp
index 6c1de10f..22746b95 100644
--- a/audio/sysvad/TabletAudioSample/micintopo.cpp
+++ b/audio/sysvad/TabletAudioSample/micintopo.cpp
@@ -204,7 +204,7 @@ Return Value:
// 0x00000001 - JACKDESC2_PRESENCE_DETECT_CAPABILITY
// 0x00000002 - JACKDESC2_DYNAMIC_FORMAT_CHANGE_CAPABILITY
//
- pDesc->JackCapabilities = JACKDESC2_PRESENCE_DETECT_CAPABILITY;
+ pDesc->JackCapabilities = 0;
ntStatus = STATUS_SUCCESS;
}
diff --git a/audio/sysvad/TabletAudioSample/micinwavtable.h b/audio/sysvad/TabletAudioSample/micinwavtable.h
index c22ac94c..2f923a31 100644
--- a/audio/sysvad/TabletAudioSample/micinwavtable.h
+++ b/audio/sysvad/TabletAudioSample/micinwavtable.h
@@ -414,6 +414,12 @@ PCPROPERTY_ITEM PropertiesMicInWaveFilter[] =
KSPROPERTY_PIN_PROPOSEDATAFORMAT,
KSPROPERTY_TYPE_SET | KSPROPERTY_TYPE_BASICSUPPORT,
PropertyHandler_WaveFilter
+ },
+ {
+ &KSPROPSETID_Pin,
+ KSPROPERTY_PIN_PROPOSEDATAFORMAT2,
+ KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_BASICSUPPORT,
+ PropertyHandler_WaveFilter
}
};
diff --git a/audio/sysvad/TabletAudioSample/minipairs.h b/audio/sysvad/TabletAudioSample/minipairs.h
index e955791e..0a3c82ef 100644
--- a/audio/sysvad/TabletAudioSample/minipairs.h
+++ b/audio/sysvad/TabletAudioSample/minipairs.h
@@ -163,11 +163,13 @@ static
ENDPOINT_MINIPAIR SpeakerMiniports =
{
eSpeakerDevice,
- L"TopologySpeaker", // make sure this name matches with KSNAME_TopologySpeaker in the inf's [Strings] section
+ L"TopologySpeaker", // make sure this or the template name matches with KSNAME_TopologySpeaker in the inf's [Strings] section
+ NULL, // optional template name
CreateMiniportTopologySYSVAD,
&SpeakerTopoMiniportFilterDescriptor,
0, NULL, // Interface properties
- L"WaveSpeaker", // make sure this name matches with KSNAME_WaveSpeaker in the inf's [Strings] section
+ L"WaveSpeaker", // make sure this or the template name matches with KSNAME_WaveSpeaker in the inf's [Strings] section
+ NULL, // optional template name
CreateMiniportWaveRTSYSVAD,
&SpeakerWaveMiniportFilterDescriptor,
ARRAYSIZE(SysvadWaveFilterInterfacePropertiesRender), // Interface properties
@@ -209,11 +211,13 @@ static
ENDPOINT_MINIPAIR SpeakerHpMiniports =
{
eSpeakerHpDevice,
- L"TopologySpeakerHeadphone", // make sure this name matches with KSNAME_TopologySpeakerHeadphone in the inf's [Strings] section
+ L"TopologySpeakerHeadphone", // make sure this or the template name matches with KSNAME_TopologySpeakerHeadphone in the inf's [Strings] section
+ NULL, // optional template name
CreateMiniportTopologySYSVAD,
&SpeakerHpTopoMiniportFilterDescriptor,
0, NULL, // Interface properties
- L"WaveSpeakerHeadphone", // make sure this name matches with KSNAME_WaveSpeakerHeadphone in the inf's [Strings] section
+ L"WaveSpeakerHeadphone", // make sure this or the template name matches with KSNAME_WaveSpeakerHeadphone in the inf's [Strings] section
+ NULL, // optional template name
CreateMiniportWaveRTSYSVAD,
&SpeakerHpWaveMiniportFilterDescriptor,
0, NULL, // Interface properties
@@ -254,11 +258,13 @@ static
ENDPOINT_MINIPAIR HdmiMiniports =
{
eHdmiRenderDevice,
- L"TopologyHdmi", // make sure this name matches with KSNAME_TopologyHdmi in the inf's [Strings] section
+ L"TopologyHdmi", // make sure this or the template name matches with KSNAME_TopologyHdmi in the inf's [Strings] section
+ NULL, // optional template name
CreateHdmiMiniportTopology,
&HdmiTopoMiniportFilterDescriptor,
0, NULL, // Interface properties
- L"WaveHdmi", // make sure this name matches with KSNAME_WaveHdmi in the inf's [Strings] section
+ L"WaveHdmi", // make sure this or the template name matches with KSNAME_WaveHdmi in the inf's [Strings] section
+ NULL, // optional template name
CreateMiniportWaveRTSYSVAD,
&HdmiWaveMiniportFilterDescriptor,
0, NULL, // Interface properties
@@ -267,7 +273,7 @@ ENDPOINT_MINIPAIR HdmiMiniports =
SIZEOF_ARRAY(HdmiPinDeviceFormatsAndModes),
HdmiTopologyPhysicalConnections,
SIZEOF_ARRAY(HdmiTopologyPhysicalConnections),
- ENDPOINT_NO_FLAGS,
+ ENDPOINT_LOOPBACK_SUPPORTED,
NULL, 0, NULL, // audio module settings.
};
@@ -297,11 +303,13 @@ static
ENDPOINT_MINIPAIR SpdifMiniports =
{
eSpdifRenderDevice,
- L"TopologySpdif", // make sure this name matches with KSNAME_TopologySpeaker in the inf's [Strings] section
+ L"TopologySpdif", // make sure this or the template name matches with KSNAME_TopologySpeaker in the inf's [Strings] section
+ NULL, // optional template name
CreateMiniportTopologySYSVAD,
&SpdifTopoMiniportFilterDescriptor,
0, NULL, // Interface properties
- L"WaveSpdif", // make sure this name matches with KSNAME_WaveSpeaker in the inf's [Strings] section
+ L"WaveSpdif", // make sure this or the template name matches with KSNAME_WaveSpeaker in the inf's [Strings] section
+ NULL, // optional template name
CreateMiniportWaveRTSYSVAD,
&SpdifWaveMiniportFilterDescriptor,
ARRAYSIZE(SysvadWaveFilterInterfacePropertiesRender), // Interface properties
@@ -343,11 +351,13 @@ static
ENDPOINT_MINIPAIR MicInMiniports =
{
eMicInDevice,
- L"TopologyMicIn", // make sure this name matches with KSNAME_TopologyMicIn in the inf's [Strings] section
+ L"TopologyMicIn", // make sure this or the template name matches with KSNAME_TopologyMicIn in the inf's [Strings] section
+ NULL, // optional template name
CreateMiniportTopologySYSVAD,
&MicInTopoMiniportFilterDescriptor,
0, NULL, // Interface properties
- L"WaveMicIn", // make sure this name matches with KSNAME_WaveMicIn in the inf's [Strings] section
+ L"WaveMicIn", // make sure this or the template name matches with KSNAME_WaveMicIn in the inf's [Strings] section
+ NULL, // optional template name
CreateMiniportWaveRTSYSVAD,
&MicInWaveMiniportFilterDescriptor,
0, NULL, // Interface properties
@@ -384,11 +394,13 @@ static
ENDPOINT_MINIPAIR MicArray1Miniports =
{
eMicArrayDevice1,
- L"TopologyMicArray1", // make sure this name matches with KSNAME_TopologyMicArray1 in the inf's [Strings] section
+ L"TopologyMicArray1", // make sure this or the template name matches with KSNAME_TopologyMicArray1 in the inf's [Strings] section
+ NULL, // optional template name
CreateMicArrayMiniportTopology,
&MicArray1TopoMiniportFilterDescriptor,
0, NULL, // Interface properties
- L"WaveMicArray1", // make sure this name matches with KSNAME_WaveMicArray1 in the inf's [Strings] section
+ L"WaveMicArray1", // make sure this or the template name matches with KSNAME_WaveMicArray1 in the inf's [Strings] section
+ NULL, // optional template name
CreateMiniportWaveRTSYSVAD,
&MicArrayWaveMiniportFilterDescriptor,
ARRAYSIZE(SysvadWaveFilterInterfacePropertiesCapture), // Interface properties
@@ -426,11 +438,13 @@ static
ENDPOINT_MINIPAIR MicArray2Miniports =
{
eMicArrayDevice2,
- L"TopologyMicArray2", // make sure this name matches with KSNAME_TopologyMicArray2 in the inf's [Strings] section
+ L"TopologyMicArray2", // make sure this or the template name matches with KSNAME_TopologyMicArray2 in the inf's [Strings] section
+ NULL, // optional template name
CreateMicArrayMiniportTopology,
&MicArray2TopoMiniportFilterDescriptor,
0, NULL, // Interface properties
- L"WaveMicArray2", // make sure this name matches with KSNAME_WaveMicArray2 in the inf's [Strings] section
+ L"WaveMicArray2", // make sure this or the template name matches with KSNAME_WaveMicArray2 in the inf's [Strings] section
+ NULL, // optional template name
CreateMiniportWaveRTSYSVAD,
&MicArrayWaveMiniportFilterDescriptor,
0, NULL, // Interface properties
@@ -467,11 +481,13 @@ static
ENDPOINT_MINIPAIR MicArray3Miniports =
{
eMicArrayDevice3,
- L"TopologyMicArray3", // make sure this name matches with KSNAME_TopologyMicArray3 in the inf's [Strings] section
+ L"TopologyMicArray3", // make sure this or the template name matches with KSNAME_TopologyMicArray3 in the inf's [Strings] section
+ NULL, // optional template name
CreateMicArrayMiniportTopology,
&MicArray3TopoMiniportFilterDescriptor,
0, NULL, // Interface properties
- L"WaveMicArray3", // make sure this name matches with KSNAME_WaveMicArray3 in the inf's [Strings] section
+ L"WaveMicArray3", // make sure this or the template name matches with KSNAME_WaveMicArray3 in the inf's [Strings] section
+ NULL, // optional template name
CreateMiniportWaveRTSYSVAD,
&MicArray3WaveMiniportFilterDescriptor,
0, NULL, // Interface properties
diff --git a/audio/sysvad/TabletAudioSample/sources b/audio/sysvad/TabletAudioSample/sources
index 39d0de57..91592397 100644
--- a/audio/sysvad/TabletAudioSample/sources
+++ b/audio/sysvad/TabletAudioSample/sources
@@ -34,14 +34,15 @@ KMDF_VERSION_MAJOR=1
#C_DEFINES= $(C_DEFINES) -D_USE_IPortClsRuntimePower
C_DEFINES= $(C_DEFINES) -D_USE_SingleComponentMultiFxStates
-INCLUDES= \
- $(INCLUDES); \
- ..\EndpointsCommon; \
+INCLUDES= \
+ $(INCLUDES); \
+ ..\EndpointsCommon; \
-SOURCES=$(SOURCES) \
- hdmitopo.cpp \
- spdiftopo.cpp \
- micintopo.cpp \
+SOURCES=$(SOURCES) \
+ hdmitopo.cpp \
+ spdiftopo.cpp \
+ micintopo.cpp \
+ TabletAudioSample.rc \
# Indicate that this module must be included in the driver package
@@ -49,5 +50,4 @@ DDK_NO_PACKAGE_PROJECT=0
DDK_INCLUDE_PACKAGE_PROJECT=1
-MUI_VERIFY_NO_LOC_RESOURCE=1
-
+MUI_VERIFY_NO_LOC_RESOURCE=1
diff --git a/audio/sysvad/TabletAudioSample/spdifwavtable.h b/audio/sysvad/TabletAudioSample/spdifwavtable.h
index 36b0e903..fd23799c 100644
--- a/audio/sysvad/TabletAudioSample/spdifwavtable.h
+++ b/audio/sysvad/TabletAudioSample/spdifwavtable.h
@@ -423,6 +423,8 @@ KSDATAFORMAT_WAVEFORMATEXTENSIBLE SpdifOffloadPinSupportedDeviceFormats[] =
//
// Supported modes (only on streaming pins).
+// Note: This pin does not support KSPROPERTY_PIN_PROPOSEDATAFORMAT2
+// since none of the modes on this endpoint have a default format.
//
static
MODE_AND_DEFAULT_FORMAT SpdifHostPinSupportedDeviceModes[] =
@@ -443,10 +445,6 @@ MODE_AND_DEFAULT_FORMAT SpdifOffloadPinSupportedDeviceModes[] =
{
STATIC_AUDIO_SIGNALPROCESSINGMODE_RAW,
NULL, // just an example of no default format for this endpoint/mode
- },
- {
- STATIC_AUDIO_SIGNALPROCESSINGMODE_DEFAULT,
- NULL, // just an example of no default format for this endpoint/mode
}
};
diff --git a/audio/sysvad/TabletAudioSample/tabletaudiosample.inf b/audio/sysvad/TabletAudioSample/tabletaudiosample.inx
index 8a0eb788..e1c0512f 100644
--- a/audio/sysvad/TabletAudioSample/tabletaudiosample.inf
+++ b/audio/sysvad/TabletAudioSample/tabletaudiosample.inx
Binary files differ
diff --git a/audio/sysvad/ToneGenerator.cpp b/audio/sysvad/ToneGenerator.cpp
index 2a01e49a..6ef2a39a 100644
--- a/audio/sysvad/ToneGenerator.cpp
+++ b/audio/sysvad/ToneGenerator.cpp
@@ -15,7 +15,6 @@ Abstract:
#include <sysvad.h>
#include "ToneGenerator.h"
-const double TONE_AMPLITUDE = 0.5; // Scalar value, should be between 0.0 - 1.0
const double TWO_PI = M_PI * 2;
extern DWORD g_DisableToneGenerator;
@@ -89,7 +88,7 @@ VOID ToneGenerator::InitNewFrame
_In_ DWORD FrameSize
)
{
- double sinValue = TONE_AMPLITUDE * sin( m_Theta );
+ double sinValue = m_ToneDCOffset + m_ToneAmplitude * sin( m_Theta );
if (FrameSize != (DWORD)m_ChannelCount * m_BitsPerSample/8)
{
@@ -222,6 +221,9 @@ ZeroBuffer:
NTSTATUS ToneGenerator::Init
(
_In_ DWORD ToneFrequency,
+ _In_ double ToneAmplitude,
+ _In_ double ToneDCOffset,
+ _In_ double ToneInitialPhase,
_In_ PWAVEFORMATEXTENSIBLE WfExt
)
{
@@ -248,8 +250,11 @@ NTSTATUS ToneGenerator::Init
//
// Basic init.
//
- RtlZeroMemory(&m_Theta, sizeof(m_Theta));
+ m_Theta = ToneInitialPhase;
m_Frequency = ToneFrequency;
+ m_ToneAmplitude = ToneAmplitude;
+ m_ToneDCOffset = ToneDCOffset;
+
m_ChannelCount = WfExt->Format.nChannels; // # channels.
m_BitsPerSample = WfExt->Format.wBitsPerSample; // bits per sample.
m_SamplesPerSecond = WfExt->Format.nSamplesPerSec; // samples per sec.
diff --git a/audio/sysvad/ToneGenerator.h b/audio/sysvad/ToneGenerator.h
index af4cb310..e364ccd4 100644
--- a/audio/sysvad/ToneGenerator.h
+++ b/audio/sysvad/ToneGenerator.h
@@ -32,6 +32,8 @@ public:
BYTE* m_PartialFrame;
DWORD m_PartialFrameBytes;
DWORD m_FrameSize;
+ double m_ToneAmplitude;
+ double m_ToneDCOffset;
public:
ToneGenerator();
@@ -41,6 +43,9 @@ public:
Init
(
_In_ DWORD ToneFrequency,
+ _In_ double ToneAmplitude,
+ _In_ double ToneDCOffset,
+ _In_ double ToneInitialPhase,
_In_ PWAVEFORMATEXTENSIBLE WfExt
);
diff --git a/audio/sysvad/adapter.cpp b/audio/sysvad/adapter.cpp
index 83c72f9b..ab91a448 100644
--- a/audio/sysvad/adapter.cpp
+++ b/audio/sysvad/adapter.cpp
@@ -245,6 +245,7 @@ DRIVER_DISPATCH PnpHandler;
//
DWORD g_DoNotCreateDataFiles = 0; // default is off.
DWORD g_DisableToneGenerator = 0; // default is to generate tones.
+UNICODE_STRING g_RegistryPath; // This is used to store the registry settings path for the driver
#ifdef SYSVAD_BTH_BYPASS
@@ -260,6 +261,18 @@ DWORD g_DisableBthScoBypass = 0; // default is SCO bypass enabled.
// Functions
//-----------------------------------------------------------------------------
+#pragma code_seg("PAGE")
+void ReleaseRegistryStringBuffer()
+{
+ if (g_RegistryPath.Buffer != NULL)
+ {
+ ExFreePool(g_RegistryPath.Buffer);
+ g_RegistryPath.Buffer = NULL;
+ g_RegistryPath.Length = 0;
+ g_RegistryPath.MaximumLength = 0;
+ }
+}
+
//=============================================================================
#pragma code_seg("PAGE")
extern "C"
@@ -287,6 +300,8 @@ Environment:
DPF(D_TERSE, ("[DriverUnload]"));
+ ReleaseRegistryStringBuffer();
+
if (DriverObject == NULL)
{
goto Done;
@@ -317,6 +332,51 @@ Done:
#pragma code_seg("INIT")
__drv_requiresIRQL(PASSIVE_LEVEL)
NTSTATUS
+CopyRegistrySettingsPath(
+ _In_ PUNICODE_STRING RegistryPath
+)
+/*++
+
+Routine Description:
+
+Copies the following registry path to a global variable.
+
+\REGISTRY\MACHINE\SYSTEM\ControlSetxxx\Services\<driver>\Parameters
+
+Arguments:
+
+RegistryPath - Registry path passed to DriverEntry
+
+Returns:
+
+NTSTATUS - SUCCESS if able to configure the framework
+
+--*/
+
+{
+ // Initializing the unicode string, so that if it is not allocated it will not be deallocated too.
+ RtlInitUnicodeString(&g_RegistryPath, NULL);
+
+ g_RegistryPath.MaximumLength = RegistryPath->Length + sizeof(WCHAR);
+
+ g_RegistryPath.Buffer = (PWCH)ExAllocatePoolWithTag(PagedPool, g_RegistryPath.MaximumLength, MINADAPTER_POOLTAG);
+
+ if (g_RegistryPath.Buffer == NULL)
+ {
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ RtlZeroMemory(g_RegistryPath.Buffer, g_RegistryPath.MaximumLength);
+
+ RtlAppendUnicodeToString(&g_RegistryPath, RegistryPath->Buffer);
+
+ return STATUS_SUCCESS;
+}
+
+//=============================================================================
+#pragma code_seg("INIT")
+__drv_requiresIRQL(PASSIVE_LEVEL)
+NTSTATUS
GetRegistrySettings(
_In_ PUNICODE_STRING RegistryPath
)
@@ -348,7 +408,7 @@ Returns:
{ NULL, RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_TYPECHECK, L"DisableToneGenerator", &g_DisableToneGenerator, (REG_DWORD << RTL_QUERY_REGISTRY_TYPECHECK_SHIFT) | REG_DWORD, &g_DisableToneGenerator, sizeof(ULONG)},
#ifdef SYSVAD_BTH_BYPASS
{ NULL, RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_TYPECHECK, L"DisableBthScoBypass", &g_DisableBthScoBypass, (REG_DWORD << RTL_QUERY_REGISTRY_TYPECHECK_SHIFT) | REG_DWORD, &g_DisableBthScoBypass, sizeof(ULONG)},
-#endif
+#endif // SYSVAD_BTH_BYPASS
{ NULL, 0, NULL, NULL, 0, NULL, 0}
};
@@ -440,6 +500,16 @@ Return Value:
WDF_DRIVER_CONFIG config;
DPF(D_TERSE, ("[DriverEntry]"));
+
+ // Copy registry Path name in a global variable to be used by modules inside driver.
+ // !! NOTE !! Inside this function we are initializing the registrypath, so we MUST NOT add any failing calls
+ // before the following call.
+ ntStatus = CopyRegistrySettingsPath(RegistryPathName);
+ IF_FAILED_ACTION_JUMP(
+ ntStatus,
+ DPF(D_ERROR, ("Registry path copy error 0x%x", ntStatus)),
+ Done);
+
//
// Get registry configuration.
//
@@ -505,6 +575,8 @@ Done:
{
WdfDriverMiniportUnload(WdfGetDriver());
}
+
+ ReleaseRegistryStringBuffer();
}
return ntStatus;
@@ -556,14 +628,15 @@ Return Value:
DPF(D_TERSE, ("[AddDevice]"));
maxObjects = g_MaxMiniports;
-
+
#ifdef SYSVAD_BTH_BYPASS
//
// Allow three (3) Bluetooth hands-free profile devices.
//
- maxObjects += g_MaxBthHfpMiniports * 3;
+ maxObjects += g_MaxBthHfpMiniports;
#endif // SYSVAD_BTH_BYPASS
+
// Tell the class driver to add the device.
//
ntStatus =
@@ -1097,3 +1170,4 @@ Return Value:
#pragma code_seg()
+
diff --git a/audio/sysvad/common.cpp b/audio/sysvad/common.cpp
index a4c8f5e2..a0e148ca 100644
--- a/audio/sysvad/common.cpp
+++ b/audio/sysvad/common.cpp
@@ -8,7 +8,7 @@ Module Name:
Abstract:
- Implementation of the AdapterCommon class.
+ Implementation of the AdapterCommon class.
--*/
@@ -27,11 +27,7 @@ Abstract:
#include <wdmguid.h> // guild-arrival/removal
#include <devpkey.h>
#include "bthhfpminipairs.h"
-
-// # of sec before sync request is cancelled.
-#define BTH_HFP_SYNC_REQ_TIMEOUT_IN_SEC 60
-#define BTH_HFP_NOTIFICATION_MAX_ERROR_COUNT 5
-
+#include "BthhfpDevice.h"
#endif // SYSVAD_BTH_BYPASS
//-----------------------------------------------------------------------------
@@ -40,7 +36,6 @@ Abstract:
PSAVEWORKER_PARAM CSaveData::m_pWorkItems = NULL;
PDEVICE_OBJECT CSaveData::m_pDeviceObject = NULL;
-
//=============================================================================
// Classes
//=============================================================================
@@ -50,18 +45,18 @@ class BthHfpDevice; // Forward declaration.
///////////////////////////////////////////////////////////////////////////////
// CAdapterCommon
-//
-class CAdapterCommon :
+//
+class CAdapterCommon :
public IAdapterCommon,
public IAdapterPowerManagement,
- public CUnknown
+ public CUnknown
{
private:
PSERVICEGROUP m_pServiceGroupWave;
PDEVICE_OBJECT m_pDeviceObject;
PDEVICE_OBJECT m_pPhysicalDeviceObject;
- WDFDEVICE m_WdfDevice; // Wdf device.
- DEVICE_POWER_STATE m_PowerState;
+ WDFDEVICE m_WdfDevice; // Wdf device.
+ DEVICE_POWER_STATE m_PowerState;
PCSYSVADHW m_pHW; // Virtual SYSVAD HW object
PPORTCLSETWHELPER m_pPortClsEtwHelper;
@@ -82,21 +77,21 @@ class CAdapterCommon :
IMP_IAdapterPowerManagement;
//=====================================================================
- // IAdapterCommon methods
+ // IAdapterCommon methods
STDMETHODIMP_(NTSTATUS) Init
- (
+ (
_In_ PDEVICE_OBJECT DeviceObject
);
STDMETHODIMP_(PDEVICE_OBJECT) GetDeviceObject(void);
-
+
STDMETHODIMP_(PDEVICE_OBJECT) GetPhysicalDeviceObject(void);
-
+
STDMETHODIMP_(WDFDEVICE) GetWdfDevice(void);
STDMETHODIMP_(void) SetWaveServiceGroup
- (
+ (
_In_ PSERVICEGROUP ServiceGroup
);
@@ -142,26 +137,26 @@ class CAdapterCommon :
STDMETHODIMP_(void) MixerReset(void);
STDMETHODIMP_(LONG) MixerVolumeRead
- (
+ (
_In_ ULONG Index,
_In_ ULONG Channel
);
STDMETHODIMP_(void) MixerVolumeWrite
- (
+ (
_In_ ULONG Index,
_In_ ULONG Channel,
- _In_ LONG Value
+ _In_ LONG Value
);
STDMETHODIMP_(LONG) MixerPeakMeterRead
- (
+ (
_In_ ULONG Index,
_In_ ULONG Channel
);
- STDMETHODIMP_(NTSTATUS) WriteEtwEvent
- (
+ STDMETHODIMP_(NTSTATUS) WriteEtwEvent
+ (
_In_ EPcMiniportEngineEvent miniportEventType,
_In_ ULONGLONG ullData1,
_In_ ULONGLONG ullData2,
@@ -169,15 +164,16 @@ class CAdapterCommon :
_In_ ULONGLONG ullData4
);
- STDMETHODIMP_(VOID) SetEtwHelper
- (
+ STDMETHODIMP_(VOID) SetEtwHelper
+ (
PPORTCLSETWHELPER _pPortClsEtwHelper
);
-
+
STDMETHODIMP_(NTSTATUS) InstallSubdevice
- (
+ (
_In_opt_ PIRP Irp,
_In_ PWSTR Name,
+ _In_opt_ PWSTR TemplateName,
_In_ REFGUID PortClassId,
_In_ REFGUID MiniportClassId,
_In_opt_ PFNCREATEMINIPORT MiniportCreate,
@@ -191,12 +187,12 @@ class CAdapterCommon :
_Out_opt_ PUNKNOWN * OutPortUnknown,
_Out_opt_ PUNKNOWN * OutMiniportUnknown
);
-
+
STDMETHODIMP_(NTSTATUS) UnregisterSubdevice
(
_In_opt_ PUNKNOWN UnknownPort
);
-
+
STDMETHODIMP_(NTSTATUS) ConnectTopologies
(
_In_ PUNKNOWN UnknownTopology,
@@ -204,7 +200,7 @@ class CAdapterCommon :
_In_ PHYSICALCONNECTIONTABLE* PhysicalConnections,
_In_ ULONG PhysicalConnectionCount
);
-
+
STDMETHODIMP_(NTSTATUS) DisconnectTopologies
(
_In_ PUNKNOWN UnknownTopology,
@@ -212,10 +208,10 @@ class CAdapterCommon :
_In_ PHYSICALCONNECTIONTABLE* PhysicalConnections,
_In_ ULONG PhysicalConnectionCount
);
-
+
STDMETHODIMP_(NTSTATUS) InstallEndpointFilters
(
- _In_opt_ PIRP Irp,
+ _In_opt_ PIRP Irp,
_In_ PENDPOINT_MINIPAIR MiniportPair,
_In_opt_ PVOID DeviceContext,
_Out_opt_ PUNKNOWN * UnknownTopology,
@@ -223,7 +219,7 @@ class CAdapterCommon :
_Out_opt_ PUNKNOWN * UnknownMiniportTopology,
_Out_opt_ PUNKNOWN * UnknownMiniportWave
);
-
+
STDMETHODIMP_(NTSTATUS) RemoveEndpointFilters
(
_In_ PENDPOINT_MINIPAIR MiniportPair,
@@ -246,25 +242,35 @@ class CAdapterCommon :
_In_ BOOL bEnabled
);
+ STDMETHODIMP_(NTSTATUS) NotifyEndpointPair
+ (
+ _In_ WCHAR *RenderEndpointTopoName,
+ _In_ ULONG RenderEndpointNameLen,
+ _In_ ULONG RenderPinId,
+ _In_ WCHAR *CaptureEndpointTopoName,
+ _In_ ULONG CaptureEndpointNameLen,
+ _In_ ULONG CapturePinId
+ );
+
#ifdef SYSVAD_BTH_BYPASS
STDMETHODIMP_(NTSTATUS) InitBthScoBypass();
-
+
STDMETHODIMP_(VOID) CleanupBthScoBypass();
#endif // SYSVAD_BTH_BYPASS
STDMETHODIMP_(VOID) Cleanup();
-
+
//=====================================================================
// friends
friend NTSTATUS NewAdapterCommon
- (
+ (
_Out_ PUNKNOWN * Unknown,
_In_ REFCLSID,
_In_opt_ PUNKNOWN UnknownOuter,
_When_((PoolType & NonPagedPoolMustSucceed) != 0,
__drv_reportError("Must succeed pool allocations are forbidden. "
"Allocation failures cause a system crash"))
- _In_ POOL_TYPE PoolType
+ _In_ POOL_TYPE PoolType
);
#ifdef SYSVAD_BTH_BYPASS
@@ -277,17 +283,17 @@ class CAdapterCommon :
WDFWORKITEM m_BthHfpWorkItem; // Async work-item.
LIST_ENTRY m_BthHfpWorkTasks; // Work-item's tasks.
LIST_ENTRY m_BthHfpDevices; // Bth HFP devices.
- NPAGED_LOOKASIDE_LIST m_BhtHfpWorkTaskPool; // LookasideList
- size_t m_BhtHfpWorkTaskPoolElementSize;
+ NPAGED_LOOKASIDE_LIST m_BthHfpWorkTaskPool; // LookasideList
+ size_t m_BthHfpWorkTaskPoolElementSize;
BOOL m_BthHfpEnableCleanup; // Do cleanup if true.
private:
- static
+ static
DRIVER_NOTIFICATION_CALLBACK_ROUTINE EvtBthHfpScoBypassInterfaceChange;
-
- static
+
+ static
EVT_WDF_WORKITEM EvtBthHfpScoBypassInterfaceWorkItem;
-
+
protected:
BthHfpDevice * BthHfpDeviceFind
(
@@ -305,7 +311,6 @@ class CAdapterCommon :
);
#endif // SYSVAD_BTH_BYPASS
-
private:
LIST_ENTRY m_SubdeviceCache;
@@ -323,7 +328,7 @@ class CAdapterCommon :
_In_ PUNKNOWN UnknownPort,
_In_ PUNKNOWN UnknownMiniport
);
-
+
NTSTATUS RemoveCachedSubdevice
(
_In_ PWSTR Name
@@ -334,10 +339,17 @@ class CAdapterCommon :
NTSTATUS CreateAudioInterfaceWithProperties
(
_In_ PCWSTR ReferenceString,
+ _In_opt_ PCWSTR TemplateReferenceString,
_In_ ULONG cPropertyCount,
_In_reads_opt_(cPropertyCount) const SYSVAD_DEVPROPERTY *pProperties,
_Out_ _At_(AudioSymbolicLinkName->Buffer, __drv_allocatesMem(Mem)) PUNICODE_STRING AudioSymbolicLinkName
);
+
+ NTSTATUS MigrateDeviceInterfaceTemplateParameters
+ (
+ _In_ PUNICODE_STRING SymbolicLinkName,
+ _In_opt_ PCWSTR TemplateReferenceString
+ );
};
typedef struct _MINIPAIR_UNKNOWN
@@ -347,419 +359,17 @@ typedef struct _MINIPAIR_UNKNOWN
PUNKNOWN PortInterface;
PUNKNOWN MiniportInterface;
PADAPTERPOWERMANAGEMENT PowerInterface;
+ PMINIPORTCHANGE MiniportChange;
} MINIPAIR_UNKNOWN;
+#define MAX_DEVICE_REG_KEY_LENGTH 0x100
+
//
// Used to implement the singleton pattern.
//
LONG CAdapterCommon::m_AdapterInstances = 0;
-#ifdef SYSVAD_BTH_BYPASS
-
-//=====================================================================
-//
-// CAdapterCommon: Bluetooth Hands-Free Profile SCO Bypass definitions.
-//
-
-struct BthHfpWorkItemContext
-{
- CAdapterCommon * Adapter;
-};
-
-WDF_DECLARE_CONTEXT_TYPE_WITH_NAME
-(
- BthHfpWorkItemContext,
- GetBthHfpWorkItemContext
-)
-
-// start/stop the device
-enum eBthHfpTaskAction
-{
- eBthHfpTaskStart = 1,
- eBthHfpTaskStop = 2,
-};
-
-struct BthHfpWorkTask
-{
- LIST_ENTRY ListEntry;
- BthHfpDevice * Device;
- eBthHfpTaskAction Action;
-};
-
-
-//=====================================================================
-//
-// Device: Bluetooth Hands-Free Profile SCO Bypass definitions.
-//
-
-// BTH HFP device's notification work-item context.
-struct BthHfpDeviceNotificationWorkItemContext
-{
- BthHfpDevice * BthHfpDevice;
-};
-
-WDF_DECLARE_CONTEXT_TYPE_WITH_NAME
-(
- BthHfpDeviceNotificationWorkItemContext,
- GetBthHfpDeviceNotificationWorkItemContext
-)
-
-// BTH HFP device's notification request context.
-union BthHfpDeviceNotificationBuffer
-{
- BOOL bImmediate;
- LONG Volume;
- BOOL BoolStatus;
- NTSTATUS NtStatus;
-};
-
-struct BthHfpDeviceNotificationReqContext
-{
- BthHfpDevice * BthHfpDevice;
- LONG Errors;
- BthHfpDeviceNotificationBuffer Buffer;
- WDFMEMORY MemIn;
- WDFMEMORY MemOut;
-};
-
-WDF_DECLARE_CONTEXT_TYPE_WITH_NAME
-(
- BthHfpDeviceNotificationReqContext,
- GetBthHfpDeviceNotificationReqContext
-)
-
-enum eBthHfpState
-{
- eBthHfpStateInvalid = 0,
- eBthHfpStateInitializing = 1,
- eBthHfpStateRunning = 2,
- eBthHfpStateStopping = 3,
- eBthHfpStateStopped = 4,
- eBthHfpStateFailed = 5,
-};
-
-// To support event notification.
-struct BthHfpEventCallback
-{
- PFNEVENTNOTIFICATION Handler;
- PVOID Context;
-};
-
-//
-// This class represents a the Bluetooth Hands-Free Profile SCO Bypass device.
-// There is one class for each interface (id = symbolic-link-name).
-//
-class BthHfpDevice :
- IBthHfpDeviceCommon,
- public CUnknown
-{
- private:
- eBthHfpState m_State;
-
- CAdapterCommon * m_Adapter;
- WDFIOTARGET m_WdfIoTarget;
-
- LIST_ENTRY m_ListEntry;
- UNICODE_STRING m_SymbolicLinkName;
-
- //
- // The Topo Filter Desc and Topo Pins structures referenced from
- // the Miniports structure are deep copies: they start as copies of the
- // static structures and are modified to allow per-SCO-Device pin
- // categories based on the info obtained from
- // IOCTL_BTHHFP_DEVICE_GET_DESCRIPTOR2
- //
- PENDPOINT_MINIPAIR m_SpeakerMiniports;
- PENDPOINT_MINIPAIR m_MicMiniports;
-
- PUNKNOWN m_UnknownSpeakerTopology;
- PUNKNOWN m_UnknownSpeakerWave;
- PUNKNOWN m_UnknownMicTopology;
- PUNKNOWN m_UnknownMicWave;
-
- PBTHHFP_DESCRIPTOR2 m_Descriptor;
- PKSPROPERTY_VALUES m_VolumePropValues;
- LONG m_SpeakerVolumeLevel;
- LONG m_MicVolumeLevel;
- union{
- BOOL m_ConnectionStatus;
- LONG m_ConnectionStatusLong;
- }; // unnamed.
-
- union{
- NTSTATUS m_StreamStatus;
- LONG m_StreamStatusLong;
- }; // unnamed.
-
- KEVENT m_StreamStatusEvent;
-
- //
- // Set to TRUE when the HF (remote device) wants to disable the
- // NR + EC of the AG (local system).
- //
- LONG m_NRECDisableStatusLong;
-
- WDFREQUEST m_StreamReq;
- WDFREQUEST m_SpeakerVolumeReq;
- WDFREQUEST m_MicVolumeReq;
- WDFREQUEST m_ConnectionReq;
- WDFREQUEST m_NRECDisableStatusReq;
- WDFWORKITEM m_WorkItem;
- WDFCOLLECTION m_ReqCollection;
- KSPIN_LOCK m_Lock;
-
- LONG m_nStreams; // # of open streams.
-
- BthHfpEventCallback m_SpeakerVolumeCallback;
- BthHfpEventCallback m_SpeakerConnectionStatusCallback;
- BthHfpEventCallback m_MicVolumeCallback;
- BthHfpEventCallback m_MicConnectionStatusCallback;
-
- public:
- //=====================================================================
- // Default CUnknown
- DECLARE_STD_UNKNOWN();
- DEFINE_STD_CONSTRUCTOR(BthHfpDevice);
- ~BthHfpDevice();
-
- NTSTATUS Init
- (
- _In_ CAdapterCommon * Adapter,
- _In_ PUNICODE_STRING SymbolicLinkName
- );
-
- public:
- //=====================================================================
- //
- // Public functions used by CAdapterCommon object.
- //
- VOID Start();
- VOID Stop();
-
- PLIST_ENTRY GetListEntry()
- {
- return &m_ListEntry;
- }
-
- PUNICODE_STRING GetSymbolicLinkName()
- {
- return &m_SymbolicLinkName;
- }
-
- static
- BthHfpDevice *
- GetBthHfpDevice
- (
- _In_ PLIST_ENTRY le
- )
- {
- return CONTAINING_RECORD(le, BthHfpDevice, m_ListEntry);
- }
-
- public:
- //=====================================================================
- //
- // IBthHfpDeviceCommon functions.
- //
- STDMETHODIMP_(BOOL) IsVolumeSupported();
-
- STDMETHODIMP_(PKSPROPERTY_VALUES) GetVolumeSettings
- (
- _Out_ PULONG Size
- );
-
- STDMETHODIMP_(LONG) GetSpeakerVolume();
-
- STDMETHODIMP_(NTSTATUS) SetSpeakerVolume
- (
- _In_ ULONG Volume
- );
-
- STDMETHODIMP_(LONG) GetMicVolume();
-
- STDMETHODIMP_(NTSTATUS) SetMicVolume
- (
- _In_ ULONG Volume
- );
-
- STDMETHODIMP_(BOOL) GetConnectionStatus();
-
- STDMETHODIMP_(NTSTATUS) Connect();
-
- STDMETHODIMP_(NTSTATUS) Disconnect();
-
- STDMETHODIMP_(BOOL) GetStreamStatus();
-
- STDMETHODIMP_(NTSTATUS) StreamOpen();
-
- STDMETHODIMP_(NTSTATUS) StreamClose();
-
- STDMETHODIMP_(GUID) GetContainerId();
-
- STDMETHODIMP_(VOID) SetSpeakerVolumeHandler
- (
- _In_opt_ PFNEVENTNOTIFICATION EventHandler,
- _In_opt_ PVOID EventHandlerContext
- );
-
- STDMETHODIMP_(VOID) SetSpeakerConnectionStatusHandler
- (
- _In_opt_ PFNEVENTNOTIFICATION EventHandler,
- _In_opt_ PVOID EventHandlerContext
- );
-
- STDMETHODIMP_(VOID) SetMicVolumeHandler
- (
- _In_opt_ PFNEVENTNOTIFICATION EventHandler,
- _In_opt_ PVOID EventHandlerContext
- );
-
- STDMETHODIMP_(VOID) SetMicConnectionStatusHandler
- (
- _In_opt_ PFNEVENTNOTIFICATION EventHandler,
- _In_opt_ PVOID EventHandlerContext
- );
-
- STDMETHODIMP_(BOOL) IsNRECSupported();
-
- STDMETHODIMP_(BOOL) GetNRECDisableStatus();
-
- private:
- //=====================================================================
- //
- // Helper functions.
- //
- NTSTATUS SendIoCtrlSynchronously
- (
- _In_opt_ WDFREQUEST Request,
- _In_ ULONG IoControlCode,
- _In_ ULONG InLength,
- _In_ ULONG OutLength,
- _When_(InLength > 0 || OutLength > 0, _In_)
- _When_(InLength == 0 && OutLength == 0, _In_opt_)
- PVOID Buffer
- );
-
- NTSTATUS SendIoCtrlAsynchronously
- (
- _In_ WDFREQUEST Request,
- _In_ ULONG IoControlCode,
- _In_opt_ WDFMEMORY MemIn,
- _In_opt_ WDFMEMORY MemOut,
- _In_ PFN_WDF_REQUEST_COMPLETION_ROUTINE CompletionRoutine,
- _In_ WDFCONTEXT Context
- );
-
- NTSTATUS GetBthHfpDescriptor
- (
- _Out_ PBTHHFP_DESCRIPTOR2 * Descriptor
- );
-
- NTSTATUS EnableBthHfpNrecDisableStatusNotification();
-
- NTSTATUS GetBthHfpVolumePropertyValues
- (
- _In_ ULONG Length,
- _Out_ PKSPROPERTY_VALUES * PropValues
- );
-
- NTSTATUS SetBthHfpSpeakerVolume
- (
- _In_ LONG Volume
- );
-
- NTSTATUS GetBthHfpSpeakerVolume
- (
- _Out_ LONG * Volume
- );
-
- NTSTATUS EnableBthHfpSpeakerVolumeStatusNotification();
-
- NTSTATUS SetBthHfpMicVolume
- (
- _In_ LONG Volume
- );
-
- NTSTATUS GetBthHfpMicVolume
- (
- _Out_ LONG * Volume
- );
-
- NTSTATUS EnableBthHfpMicVolumeStatusNotification();
-
- NTSTATUS GetBthHfpConnectionStatus
- (
- _Out_ BOOL * ConnectionStatus
- );
-
- NTSTATUS EnableBthHfpConnectionStatusNotification();
-
- static
- NTSTATUS CreateCustomEndpointMinipair
- (
- _In_ PENDPOINT_MINIPAIR pBaseMinipair,
- _In_ PUNICODE_STRING FriendlyName,
- _In_ PGUID pCategory,
- _Outptr_ PENDPOINT_MINIPAIR *ppCustomMinipair
- );
-
- static
- NTSTATUS UpdateCustomEndpointCategory
- (
- _In_ PPCFILTER_DESCRIPTOR pCustomMinipairTopoFilter,
- _In_ PPCPIN_DESCRIPTOR pCustomMinipairTopoPins,
- _In_ PGUID pCategory
- );
-
- static
- VOID DeleteCustomEndpointMinipair
- (
- _In_ PENDPOINT_MINIPAIR CustomMinipair
- );
-
- NTSTATUS GetBthHfpCodecId
- (
- _Out_ UCHAR * CodecId
- );
-
- NTSTATUS SetBthHfpConnect();
-
- NTSTATUS SetBthHfpDisconnect();
-
- NTSTATUS SetBthHfpStreamOpen();
-
- NTSTATUS SetBthHfpStreamClose();
-
- NTSTATUS EnableBthHfpStreamStatusNotification();
-
- NTSTATUS StopBthHfpStreamStatusNotification();
-
- //
- // WDF I/O Target callback.
- //
- static
- EVT_WDF_IO_TARGET_QUERY_REMOVE EvtBthHfpTargetQueryRemove;
-
- static
- EVT_WDF_IO_TARGET_REMOVE_CANCELED EvtBthHfpTargetRemoveCanceled;
-
- static
- EVT_WDF_IO_TARGET_REMOVE_COMPLETE EvtBthHfpTargetRemoveComplete;
-
- //
- // Status notifications callbacks.
- //
- static
- EVT_WDF_REQUEST_COMPLETION_ROUTINE EvtBthHfpDeviceStreamStatusCompletion;
-
- static
- EVT_WDF_REQUEST_COMPLETION_ROUTINE EvtBthHfpDeviceNotificationStatusCompletion;
-
- static
- EVT_WDF_WORKITEM EvtBthHfpDeviceNotificationStatusWorkItem;
-};
-#endif // SYSVAD_BTH_BYPASS
//-----------------------------------------------------------------------------
// Functions
@@ -805,14 +415,14 @@ NTSTATUS SysvadIoSetDeviceInterfacePropertyDataMultiple
#pragma code_seg("PAGE")
NTSTATUS
NewAdapterCommon
-(
+(
_Out_ PUNKNOWN * Unknown,
_In_ REFCLSID,
_In_opt_ PUNKNOWN UnknownOuter,
_When_((PoolType & NonPagedPoolMustSucceed) != 0,
__drv_reportError("Must succeed pool allocations are forbidden. "
- "Allocation failures cause a system crash"))
- _In_ POOL_TYPE PoolType
+ "Allocation failures cause a system crash"))
+ _In_ POOL_TYPE PoolType
)
/*++
@@ -822,7 +432,7 @@ Routine Description:
Arguments:
- Unknown -
+ Unknown -
UnknownOuter -
@@ -842,7 +452,7 @@ Return Value:
//
// This sample supports only one instance of this object.
- // (b/c of CSaveData's static members and Bluetooth HFP logic).
+ // (b/c of CSaveData's static members and Bluetooth HFP logic).
//
if (InterlockedCompareExchange(&CAdapterCommon::m_AdapterInstances, 1, 0) != 0)
{
@@ -850,7 +460,7 @@ Return Value:
DPF(D_ERROR, ("NewAdapterCommon failed, only one instance is allowed"));
goto Done;
}
-
+
//
// Allocate an adapter object.
//
@@ -862,22 +472,22 @@ Return Value:
goto Done;
}
- //
+ //
// Success.
//
*Unknown = PUNKNOWN((PADAPTERCOMMON)(p));
- (*Unknown)->AddRef();
- ntStatus = STATUS_SUCCESS;
+ (*Unknown)->AddRef();
+ ntStatus = STATUS_SUCCESS;
-Done:
+Done:
return ntStatus;
} // NewAdapterCommon
//=============================================================================
#pragma code_seg("PAGE")
CAdapterCommon::~CAdapterCommon
-(
- void
+(
+ void
)
/*++
@@ -901,12 +511,11 @@ Return Value:
delete m_pHW;
m_pHW = NULL;
}
-
+
CSaveData::DestroyWorkItems();
-
SAFE_RELEASE(m_pPortClsEtwHelper);
SAFE_RELEASE(m_pServiceGroupWave);
-
+
if (m_WdfDevice)
{
WdfObjectDelete(m_WdfDevice);
@@ -915,11 +524,11 @@ Return Value:
InterlockedDecrement(&CAdapterCommon::m_AdapterInstances);
ASSERT(CAdapterCommon::m_AdapterInstances == 0);
-} // ~CAdapterCommon
+} // ~CAdapterCommon
//=============================================================================
#pragma code_seg("PAGE")
-STDMETHODIMP_(PDEVICE_OBJECT)
+STDMETHODIMP_(PDEVICE_OBJECT)
CAdapterCommon::GetDeviceObject
(
void
@@ -939,13 +548,13 @@ Return Value:
--*/
{
PAGED_CODE();
-
+
return m_pDeviceObject;
} // GetDeviceObject
//=============================================================================
#pragma code_seg("PAGE")
-STDMETHODIMP_(PDEVICE_OBJECT)
+STDMETHODIMP_(PDEVICE_OBJECT)
CAdapterCommon::GetPhysicalDeviceObject
(
void
@@ -965,13 +574,13 @@ Return Value:
--*/
{
PAGED_CODE();
-
+
return m_pPhysicalDeviceObject;
} // GetPhysicalDeviceObject
//=============================================================================
#pragma code_seg("PAGE")
-STDMETHODIMP_(WDFDEVICE)
+STDMETHODIMP_(WDFDEVICE)
CAdapterCommon::GetWdfDevice
(
void
@@ -993,7 +602,7 @@ Return Value:
--*/
{
PAGED_CODE();
-
+
return m_WdfDevice;
} // GetWdfDevice
@@ -1001,8 +610,8 @@ Return Value:
#pragma code_seg("PAGE")
NTSTATUS
CAdapterCommon::Init
-(
- _In_ PDEVICE_OBJECT DeviceObject
+(
+ _In_ PDEVICE_OBJECT DeviceObject
)
/*++
@@ -1031,8 +640,6 @@ Return Value:
m_BthHfpEnableCleanup = FALSE;
#endif // SYSVAD_BTH_BYPASS
-
-
m_pServiceGroupWave = NULL;
m_pDeviceObject = DeviceObject;
m_pPhysicalDeviceObject = NULL;
@@ -1053,7 +660,7 @@ Return Value:
Done);
//
- // Create a WDF miniport to represent the adapter. Note that WDF miniports
+ // Create a WDF miniport to represent the adapter. Note that WDF miniports
// are NOT audio miniports. An audio adapter is associated with a single WDF
// miniport. This driver uses WDF to simplify the handling of the Bluetooth
// SCO HFP Bypass interface.
@@ -1070,7 +677,7 @@ Return Value:
Done);
// Initialize HW.
- //
+ //
m_pHW = new (NonPagedPoolNx, SYSVAD_POOLTAG) CSYSVADHW;
if (!m_pHW)
{
@@ -1078,7 +685,7 @@ Return Value:
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
}
IF_FAILED_JUMP(ntStatus, Done);
-
+
m_pHW->MixerReset();
//
@@ -1087,7 +694,6 @@ Return Value:
CSaveData::SetDeviceObject(DeviceObject); //device object is needed by CSaveData
ntStatus = CSaveData::InitializeWorkItems(DeviceObject);
IF_FAILED_JUMP(ntStatus, Done);
-
Done:
return ntStatus;
@@ -1097,8 +703,8 @@ Done:
#pragma code_seg("PAGE")
STDMETHODIMP_(void)
CAdapterCommon::MixerReset
-(
- void
+(
+ void
)
/*++
@@ -1115,7 +721,7 @@ Return Value:
--*/
{
PAGED_CODE();
-
+
if (m_pHW)
{
m_pHW->MixerReset();
@@ -1125,60 +731,60 @@ Return Value:
//=============================================================================
/* Here are the definitions of the standard miniport events.
-Event type : eMINIPORT_IHV_DEFINED
-Parameter 1 : Defined and used by IHVs
-Parameter 2 : Defined and used by IHVs
-Parameter 3 :Defined and used by IHVs
+Event type : eMINIPORT_IHV_DEFINED
+Parameter 1 : Defined and used by IHVs
+Parameter 2 : Defined and used by IHVs
+Parameter 3 : Defined and used by IHVs
Parameter 4 :Defined and used by IHVs
Event type: eMINIPORT_BUFFER_COMPLETE
-Parameter 1: Current linear buffer position
-Parameter 2: the previous WaveRtBufferWritePosition that the drive received
+Parameter 1: Current linear buffer position
+Parameter 2: the previous WaveRtBufferWritePosition that the drive received
Parameter 3: Data length completed
Parameter 4:0
Event type: eMINIPORT_PIN_STATE
-Parameter 1: Current linear buffer position
-Parameter 2: the previous WaveRtBufferWritePosition that the drive received
-Parameter 3: Pin State 0->KS_STOP, 1->KS_ACQUIRE, 2->KS_PAUSE, 3->KS_RUN
+Parameter 1: Current linear buffer position
+Parameter 2: the previous WaveRtBufferWritePosition that the drive received
+Parameter 3: Pin State 0->KS_STOP, 1->KS_ACQUIRE, 2->KS_PAUSE, 3->KS_RUN
Parameter 4:0
Event type: eMINIPORT_GET_STREAM_POS
-Parameter 1: Current linear buffer position
-Parameter 2: the previous WaveRtBufferWritePosition that the drive received
+Parameter 1: Current linear buffer position
+Parameter 2: the previous WaveRtBufferWritePosition that the drive received
Parameter 3: 0
Parameter 4:0
Event type: eMINIPORT_SET_WAVERT_BUFFER_WRITE_POS
-Parameter 1: Current linear buffer position
-Parameter 2: the previous WaveRtBufferWritePosition that the drive received
+Parameter 1: Current linear buffer position
+Parameter 2: the previous WaveRtBufferWritePosition that the drive received
Parameter 3: the arget WaveRtBufferWritePosition received from portcls
Parameter 4:0
Event type: eMINIPORT_GET_PRESENTATION_POS
-Parameter 1: Current linear buffer position
-Parameter 2: the previous WaveRtBufferWritePosition that the drive received
+Parameter 1: Current linear buffer position
+Parameter 2: the previous WaveRtBufferWritePosition that the drive received
Parameter 3: Presentation position
Parameter 4:0
-Event type: eMINIPORT_PROGRAM_DMA
-Parameter 1: Current linear buffer position
-Parameter 2: the previous WaveRtBufferWritePosition that the drive received
+Event type: eMINIPORT_PROGRAM_DMA
+Parameter 1: Current linear buffer position
+Parameter 2: the previous WaveRtBufferWritePosition that the drive received
Parameter 3: Starting WaveRt buffer offset
Parameter 4: Data length
Event type: eMINIPORT_GLITCH_REPORT
-Parameter 1: Current linear buffer position
-Parameter 2: the previous WaveRtBufferWritePosition that the drive received
-Parameter 3: major glitch code: 1:WaveRT buffer is underrun,
- 2:decoder errors,
+Parameter 1: Current linear buffer position
+Parameter 2: the previous WaveRtBufferWritePosition that the drive received
+Parameter 3: major glitch code: 1:WaveRT buffer is underrun,
+ 2:decoder errors,
3:receive the same wavert buffer two in a row in event driven mode
Parameter 4: minor code for the glitch cause
Event type: eMINIPORT_LAST_BUFFER_RENDERED
-Parameter 1: Current linear buffer position
-Parameter 2: the very last WaveRtBufferWritePosition that the driver received
+Parameter 1: Current linear buffer position
+Parameter 2: the very last WaveRtBufferWritePosition that the driver received
Parameter 3: 0
Parameter 4: 0
@@ -1186,7 +792,7 @@ Parameter 4: 0
#pragma code_seg()
STDMETHODIMP
CAdapterCommon::WriteEtwEvent
-(
+(
_In_ EPcMiniportEngineEvent miniportEventType,
_In_ ULONGLONG ullData1,
_In_ ULONGLONG ullData2,
@@ -1207,12 +813,12 @@ CAdapterCommon::WriteEtwEvent
#pragma code_seg("PAGE")
STDMETHODIMP_(void)
CAdapterCommon::SetEtwHelper
-(
+(
PPORTCLSETWHELPER _pPortClsEtwHelper
)
{
PAGED_CODE();
-
+
SAFE_RELEASE(m_pPortClsEtwHelper);
m_pPortClsEtwHelper = _pPortClsEtwHelper;
@@ -1227,9 +833,9 @@ CAdapterCommon::SetEtwHelper
#pragma code_seg("PAGE")
STDMETHODIMP
CAdapterCommon::NonDelegatingQueryInterface
-(
+(
_In_ REFIID Interface,
- _COM_Outptr_ PVOID * Object
+ _COM_Outptr_ PVOID * Object
)
/*++
@@ -1239,7 +845,7 @@ Routine Description:
Arguments:
- Interface -
+ Interface -
Object -
@@ -1283,8 +889,8 @@ Return Value:
#pragma code_seg("PAGE")
STDMETHODIMP_(void)
CAdapterCommon::SetWaveServiceGroup
-(
- _In_ PSERVICEGROUP ServiceGroup
+(
+ _In_ PSERVICEGROUP ServiceGroup
)
/*++
@@ -1301,7 +907,7 @@ Return Value:
{
PAGED_CODE();
DPF_ENTER(("[CAdapterCommon::SetWaveServiceGroup]"));
-
+
SAFE_RELEASE(m_pServiceGroupWave);
m_pServiceGroupWave = ServiceGroup;
@@ -1551,7 +1157,7 @@ Return Value:
//=============================================================================
#pragma code_seg()
STDMETHODIMP_(ULONG)
-CAdapterCommon::MixerMuxRead()
+CAdapterCommon::MixerMuxRead()
/*++
Routine Description:
@@ -1613,7 +1219,7 @@ Return Value:
#pragma code_seg()
STDMETHODIMP_(LONG)
CAdapterCommon::MixerVolumeRead
-(
+(
_In_ ULONG Index,
_In_ ULONG Channel
)
@@ -1647,7 +1253,7 @@ Return Value:
#pragma code_seg()
STDMETHODIMP_(void)
CAdapterCommon::MixerVolumeWrite
-(
+(
_In_ ULONG Index,
_In_ ULONG Channel,
_In_ LONG Value
@@ -1682,7 +1288,7 @@ Return Value:
#pragma code_seg()
STDMETHODIMP_(LONG)
CAdapterCommon::MixerPeakMeterRead
-(
+(
_In_ ULONG Index,
_In_ ULONG Channel
)
@@ -1716,8 +1322,8 @@ Return Value:
#pragma code_seg()
STDMETHODIMP_(void)
CAdapterCommon::PowerChangeState
-(
- _In_ POWER_STATE NewState
+(
+ _In_ POWER_STATE NewState
)
/*++
@@ -1726,7 +1332,7 @@ Routine Description:
Arguments:
- NewState - The requested, new power state for the device.
+ NewState - The requested, new power state for the device.
Return Value:
@@ -1737,29 +1343,29 @@ Note:
To assist the driver, PortCls will pause any active audio streams prior to calling
this method to place the device in a sleep state. After calling this method, PortCls
- will unpause active audio streams, to wake the device up. Miniports can opt for
+ will unpause active audio streams, to wake the device up. Miniports can opt for
additional notification by utilizing the IPowerNotify interface.
- The miniport driver must perform the requested change to the device's power state
- before it returns from the PowerChangeState call. If the miniport driver needs to
- save or restore any device state before a power-state change, the miniport driver
+ The miniport driver must perform the requested change to the device's power state
+ before it returns from the PowerChangeState call. If the miniport driver needs to
+ save or restore any device state before a power-state change, the miniport driver
should support the IPowerNotify interface, which allows it to receive advance warning
- of any such change. Before returning from a successful PowerChangeState call, the
+ of any such change. Before returning from a successful PowerChangeState call, the
miniport driver should cache the new power state.
- While the miniport driver is in one of the sleep states (any state other than
+ While the miniport driver is in one of the sleep states (any state other than
PowerDeviceD0), it must avoid writing to the hardware. The miniport driver must cache
any hardware accesses that need to be deferred until the device powers up again. If
- the power state is changing from one of the sleep states to PowerDeviceD0, the
+ the power state is changing from one of the sleep states to PowerDeviceD0, the
miniport driver should perform any deferred hardware accesses after it has powered up
- the device. If the power state is changing from PowerDeviceD0 to a sleep state, the
+ the device. If the power state is changing from PowerDeviceD0 to a sleep state, the
miniport driver can perform any necessary hardware accesses during the PowerChangeState
call before it powers down the device.
While powered down, a miniport driver is never asked to create a miniport driver object
or stream object. PortCls always places the device in the PowerDeviceD0 state before
calling the miniport driver's NewStream method.
-
+
--*/
{
DPF_ENTER(("[CAdapterCommon::PowerChangeState]"));
@@ -1791,15 +1397,15 @@ Note:
m_PowerState = NewState.DeviceState;
DPF
- (
- D_VERBOSE,
- ("Entering D%u", ULONG(m_PowerState) - ULONG(PowerDeviceD0))
+ (
+ D_VERBOSE,
+ ("Entering D%u", ULONG(m_PowerState) - ULONG(PowerDeviceD0))
);
break;
-
+
default:
-
+
DPF(D_VERBOSE, ("Unknown Device Power State"));
break;
}
@@ -1810,20 +1416,20 @@ Note:
#pragma code_seg()
STDMETHODIMP_(NTSTATUS)
CAdapterCommon::QueryDeviceCapabilities
-(
- _Inout_updates_bytes_(sizeof(DEVICE_CAPABILITIES)) PDEVICE_CAPABILITIES PowerDeviceCaps
+(
+ _Inout_updates_bytes_(sizeof(DEVICE_CAPABILITIES)) PDEVICE_CAPABILITIES PowerDeviceCaps
)
/*++
Routine Description:
- Called at startup to get the caps for the device. This structure provides
- the system with the mappings between system power state and device power
- state. This typically will not need modification by the driver.
+ Called at startup to get the caps for the device. This structure provides
+ the system with the mappings between system power state and device power
+ state. This typically will not need modification by the driver.
Arguments:
- PowerDeviceCaps - The device's capabilities.
+ PowerDeviceCaps - The device's capabilities.
Return Value:
@@ -1842,14 +1448,14 @@ Return Value:
#pragma code_seg()
STDMETHODIMP_(NTSTATUS)
CAdapterCommon::QueryPowerChangeState
-(
- _In_ POWER_STATE NewStateQuery
+(
+ _In_ POWER_STATE NewStateQuery
)
/*++
Routine Description:
- Query to see if the device can change to this power state
+ Query to see if the device can change to this power state
Arguments:
@@ -1887,6 +1493,7 @@ NTSTATUS
CAdapterCommon::CreateAudioInterfaceWithProperties
(
_In_ PCWSTR ReferenceString,
+ _In_opt_ PCWSTR TemplateReferenceString,
_In_ ULONG cPropertyCount,
_In_reads_opt_(cPropertyCount) const SYSVAD_DEVPROPERTY *pProperties,
_Out_ _At_(AudioSymbolicLinkName->Buffer, __drv_allocatesMem(Mem)) PUNICODE_STRING AudioSymbolicLinkName
@@ -1927,6 +1534,20 @@ Create the audio interface (in disabled mode).
Done);
//
+ // Migrate optional device interface parameters from the template if it exists
+ // This is done first, so that any additional parameters in pProperties will override the defaults.
+ //
+ if (NULL != TemplateReferenceString)
+ {
+ ntStatus = MigrateDeviceInterfaceTemplateParameters(AudioSymbolicLinkName, TemplateReferenceString);
+
+ IF_FAILED_ACTION_JUMP(
+ ntStatus,
+ DPF(D_ERROR, ("MigrateDeviceInterfaceTempalteParameters: MigrateDeviceInterfaceTemplateParameters(...): failed, 0x%x", ntStatus)),
+ Done);
+ }
+
+ //
// Set properties on the interface
//
ntStatus = SysvadIoSetDeviceInterfacePropertyDataMultiple(AudioSymbolicLinkName, cPropertyCount, pProperties);
@@ -1954,9 +1575,10 @@ Done:
#pragma code_seg("PAGE")
STDMETHODIMP_(NTSTATUS)
CAdapterCommon::InstallSubdevice
-(
+(
_In_opt_ PIRP Irp,
_In_ PWSTR Name,
+ _In_opt_ PWSTR TemplateName,
_In_ REFGUID PortClassId,
_In_ REFGUID MiniportClassId,
_In_opt_ PFNCREATEMINIPORT MiniportCreate,
@@ -1975,34 +1597,34 @@ CAdapterCommon::InstallSubdevice
Routine Description:
- This function creates and registers a subdevice consisting of a port
- driver, a minport driver and a set of resources bound together. It will
- also optionally place a pointer to an interface on the port driver in a
- specified location before initializing the port driver. This is done so
- that a common ISR can have access to the port driver during
- initialization, when the ISR might fire.
+ This function creates and registers a subdevice consisting of a port
+ driver, a minport driver and a set of resources bound together. It will
+ also optionally place a pointer to an interface on the port driver in a
+ specified location before initializing the port driver. This is done so
+ that a common ISR can have access to the port driver during
+ initialization, when the ISR might fire.
Arguments:
Irp - pointer to the irp object.
Name - name of the miniport. Passes to PcRegisterSubDevice
-
+
PortClassId - port class id. Passed to PcNewPort.
MiniportClassId - miniport class id. Passed to PcNewMiniport.
- MiniportCreate - pointer to a miniport creation function. If NULL,
+ MiniportCreate - pointer to a miniport creation function. If NULL,
PcNewMiniport is used.
-
+
DeviceContext - deviceType specific.
- MiniportPair - endpoint configuration info.
+ MiniportPair - endpoint configuration info.
ResourceList - pointer to the resource list.
PortInterfaceId - GUID that represents the port interface.
-
+
OutPortInterface - pointer to store the port interface
OutPortUnknown - pointer to store the unknown port interface.
@@ -2028,7 +1650,7 @@ Return Value:
adapterCommon = PADAPTERCOMMON(this);
- ntStatus = CreateAudioInterfaceWithProperties(Name, cPropertyCount, pProperties, &symbolicLink);
+ ntStatus = CreateAudioInterfaceWithProperties(Name, TemplateName, cPropertyCount, pProperties, &symbolicLink);
if (NT_SUCCESS(ntStatus))
{
// Currently have no use for the symbolic link
@@ -2045,9 +1667,9 @@ Return Value:
{
if (MiniportCreate)
{
- ntStatus =
+ ntStatus =
MiniportCreate
- (
+ (
&miniport,
MiniportClassId,
NULL,
@@ -2059,10 +1681,10 @@ Return Value:
}
else
{
- ntStatus =
+ ntStatus =
PcNewMiniport
(
- (PMINIPORT *) &miniport,
+ (PMINIPORT *) &miniport,
MiniportClassId
);
}
@@ -2078,14 +1700,14 @@ Return Value:
// still succeed.
//
#pragma warning(disable:6387)
- ntStatus =
+ ntStatus =
port->Init
- (
+ (
m_pDeviceObject,
Irp,
miniport,
adapterCommon,
- ResourceList
+ ResourceList
);
#pragma warning (pop)
@@ -2093,12 +1715,12 @@ Return Value:
{
// Register the subdevice (port/miniport combination).
//
- ntStatus =
+ ntStatus =
PcRegisterSubdevice
- (
+ (
m_pDeviceObject,
Name,
- port
+ port
);
}
}
@@ -2109,31 +1731,31 @@ Return Value:
{
if (OutPortUnknown)
{
- ntStatus =
+ ntStatus =
port->QueryInterface
- (
+ (
IID_IUnknown,
- (PVOID *)OutPortUnknown
+ (PVOID *)OutPortUnknown
);
}
if (OutPortInterface)
{
- ntStatus =
+ ntStatus =
port->QueryInterface
- (
+ (
PortInterfaceId,
- (PVOID *) OutPortInterface
+ (PVOID *) OutPortInterface
);
}
if (OutMiniportUnknown)
{
- ntStatus =
+ ntStatus =
miniport->QueryInterface
- (
+ (
IID_IUnknown,
- (PVOID *)OutMiniportUnknown
+ (PVOID *)OutMiniportUnknown
);
}
@@ -2179,10 +1801,10 @@ Return Value:
DPF_ENTER(("[CAdapterCommon::UnregisterSubdevice]"));
ASSERT(m_pDeviceObject != NULL);
-
+
NTSTATUS ntStatus = STATUS_SUCCESS;
PUNREGISTERSUBDEVICE unregisterSubdevice = NULL;
-
+
if (NULL == UnknownPort)
{
return ntStatus;
@@ -2191,7 +1813,7 @@ Return Value:
//
// Get the IUnregisterSubdevice interface.
//
- ntStatus = UnknownPort->QueryInterface(
+ ntStatus = UnknownPort->QueryInterface(
IID_IUnregisterSubdevice,
(PVOID *)&unregisterSubdevice);
@@ -2209,7 +1831,7 @@ Return Value:
//
unregisterSubdevice->Release();
}
-
+
return ntStatus;
}
@@ -2239,9 +1861,9 @@ Return Value:
{
PAGED_CODE();
DPF_ENTER(("[CAdapterCommon::ConnectTopologies]"));
-
+
ASSERT(m_pDeviceObject != NULL);
-
+
NTSTATUS ntStatus = STATUS_SUCCESS;
//
@@ -2251,13 +1873,13 @@ Return Value:
//
for (ULONG i = 0; i < PhysicalConnectionCount && NT_SUCCESS(ntStatus); i++)
{
-
+
switch(PhysicalConnections[i].eType)
{
case CONNECTIONTYPE_TOPOLOGY_OUTPUT:
ntStatus =
PcRegisterPhysicalConnection
- (
+ (
m_pDeviceObject,
UnknownTopology,
PhysicalConnections[i].ulTopology,
@@ -2272,7 +1894,7 @@ Return Value:
case CONNECTIONTYPE_WAVE_OUTPUT:
ntStatus =
PcRegisterPhysicalConnection
- (
+ (
m_pDeviceObject,
UnknownWave,
PhysicalConnections[i].ulWave,
@@ -2285,7 +1907,7 @@ Return Value:
}
break;
}
- }
+ }
//
// Cleanup in case of error.
@@ -2326,9 +1948,9 @@ Return Value:
{
PAGED_CODE();
DPF_ENTER(("[CAdapterCommon::DisconnectTopologies]"));
-
+
ASSERT(m_pDeviceObject != NULL);
-
+
NTSTATUS ntStatus = STATUS_SUCCESS;
NTSTATUS ntStatus2 = STATUS_SUCCESS;
PUNREGISTERPHYSICALCONNECTION unregisterPhysicalConnection = NULL;
@@ -2336,12 +1958,12 @@ Return Value:
//
// Get the IUnregisterPhysicalConnection interface
//
- ntStatus = UnknownTopology->QueryInterface(
+ ntStatus = UnknownTopology->QueryInterface(
IID_IUnregisterPhysicalConnection,
(PVOID *)&unregisterPhysicalConnection);
-
+
if (NT_SUCCESS(ntStatus))
- {
+ {
for (ULONG i = 0; i < PhysicalConnectionCount; i++)
{
switch(PhysicalConnections[i].eType)
@@ -2382,9 +2004,9 @@ Return Value:
{
ntStatus = ntStatus2;
}
- }
+ }
}
-
+
//
// Release the IUnregisterPhysicalConnection interface.
//
@@ -2481,6 +2103,7 @@ CAdapterCommon::CacheSubdevice
// like FM and cellular, have their own power requirements that we must track. If this fails,
// it just means this filter doesn't do power management.
UnknownMiniport->QueryInterface(IID_IAdapterPowerManagement, (PVOID *)&(pNewSubdevice->PowerInterface));
+ UnknownMiniport->QueryInterface(IID_IMiniportChange, (PVOID *)&(pNewSubdevice->MiniportChange));
InsertTailList(&m_SubdeviceCache, &pNewSubdevice->ListEntry);
}
@@ -2521,6 +2144,7 @@ CAdapterCommon::RemoveCachedSubdevice
SAFE_RELEASE(pRecord->PortInterface);
SAFE_RELEASE(pRecord->MiniportInterface);
SAFE_RELEASE(pRecord->PowerInterface);
+ SAFE_RELEASE(pRecord->MiniportChange);
memset(pRecord->Name, 0, sizeof(pRecord->Name));
RemoveEntryList(le);
bRemoved = TRUE;
@@ -2546,6 +2170,7 @@ CAdapterCommon::EmptySubdeviceCache()
SAFE_RELEASE(pRecord->PortInterface);
SAFE_RELEASE(pRecord->MiniportInterface);
+ SAFE_RELEASE(pRecord->MiniportChange);
SAFE_RELEASE(pRecord->PowerInterface);
memset(pRecord->Name, 0, sizeof(pRecord->Name));
@@ -2576,7 +2201,7 @@ CAdapterCommon::Cleanup()
STDMETHODIMP_(NTSTATUS)
CAdapterCommon::InstallEndpointFilters
(
- _In_opt_ PIRP Irp,
+ _In_opt_ PIRP Irp,
_In_ PENDPOINT_MINIPAIR MiniportPair,
_In_opt_ PVOID DeviceContext,
_Out_opt_ PUNKNOWN * UnknownTopology,
@@ -2587,7 +2212,7 @@ CAdapterCommon::InstallEndpointFilters
{
PAGED_CODE();
DPF_ENTER(("[CAdapterCommon::InstallEndpointFilters]"));
-
+
NTSTATUS ntStatus = STATUS_SUCCESS;
PUNKNOWN unknownTopology = NULL;
PUNKNOWN unknownWave = NULL;
@@ -2606,7 +2231,7 @@ CAdapterCommon::InstallEndpointFilters
{
*UnknownWave = NULL;
}
-
+
if (UnknownMiniportTopology)
{
*UnknownMiniportTopology = NULL;
@@ -2626,8 +2251,9 @@ CAdapterCommon::InstallEndpointFilters
//
ntStatus = InstallSubdevice(Irp,
MiniportPair->TopoName, // make sure this name matches with SYSVAD.<TopoName>.szPname in the inf's [Strings] section
+ MiniportPair->TemplateTopoName,
CLSID_PortTopology,
- CLSID_PortTopology,
+ CLSID_PortTopology,
MiniportPair->TopoCreateCallback,
MiniportPair->TopoInterfacePropertyCount,
MiniportPair->TopoInterfaceProperties,
@@ -2654,8 +2280,9 @@ CAdapterCommon::InstallEndpointFilters
//
ntStatus = InstallSubdevice(Irp,
MiniportPair->WaveName, // make sure this name matches with SYSVAD.<WaveName>.szPname in the inf's [Strings] section
+ MiniportPair->TemplateWaveName,
CLSID_PortWaveRT,
- CLSID_PortWaveRT,
+ CLSID_PortWaveRT,
MiniportPair->WaveCreateCallback,
MiniportPair->WaveInterfacePropertyCount,
MiniportPair->WaveInterfaceProperties,
@@ -2663,7 +2290,7 @@ CAdapterCommon::InstallEndpointFilters
MiniportPair,
NULL,
IID_IPortWaveRT,
- NULL,
+ NULL,
&unknownWave,
&unknownMiniWave
);
@@ -2698,7 +2325,7 @@ CAdapterCommon::InstallEndpointFilters
unknownTopology->AddRef();
*UnknownTopology = unknownTopology;
}
-
+
if (UnknownWave != NULL && unknownWave != NULL)
{
unknownWave->AddRef();
@@ -2724,14 +2351,14 @@ CAdapterCommon::InstallEndpointFilters
UnregisterSubdevice(unknownTopology);
RemoveCachedSubdevice(MiniportPair->TopoName);
}
-
+
if (bWaveCreated && unknownWave != NULL)
{
UnregisterSubdevice(unknownWave);
RemoveCachedSubdevice(MiniportPair->WaveName);
}
}
-
+
SAFE_RELEASE(unknownMiniTopo);
SAFE_RELEASE(unknownTopology);
SAFE_RELEASE(unknownMiniWave);
@@ -2752,9 +2379,9 @@ CAdapterCommon::RemoveEndpointFilters
{
PAGED_CODE();
DPF_ENTER(("[CAdapterCommon::RemoveEndpointFilters]"));
-
+
NTSTATUS ntStatus = STATUS_SUCCESS;
-
+
if (UnknownTopology != NULL && UnknownWave != NULL)
{
ntStatus = DisconnectTopologies(
@@ -2769,7 +2396,7 @@ CAdapterCommon::RemoveEndpointFilters
}
}
-
+
RemoveCachedSubdevice(MiniportPair->WaveName);
ntStatus = UnregisterSubdevice(UnknownWave);
@@ -2790,7 +2417,7 @@ CAdapterCommon::RemoveEndpointFilters
// All Done.
//
ntStatus = STATUS_SUCCESS;
-
+
return ntStatus;
}
@@ -2808,8 +2435,8 @@ CAdapterCommon::GetFilters
{
PAGED_CODE();
DPF_ENTER(("[CAdapterCommon::GetFilters]"));
-
- NTSTATUS ntStatus = STATUS_SUCCESS;
+
+ NTSTATUS ntStatus = STATUS_SUCCESS;
PUNKNOWN unknownTopologyPort = NULL;
PUNKNOWN unknownTopologyMiniport = NULL;
PUNKNOWN unknownWavePort = NULL;
@@ -2866,7 +2493,7 @@ CAdapterCommon::SetIdlePowerManagement
PAGED_CODE();
DPF_ENTER(("[CAdapterCommon::SetIdlePowerManagement]"));
- NTSTATUS ntStatus = STATUS_SUCCESS;
+ NTSTATUS ntStatus = STATUS_SUCCESS;
IUnknown *pUnknown = NULL;
PPORTCLSPOWER pPortClsPower = NULL;
// refcounting disable requests. Each miniport is responsible for calling this in pairs,
@@ -2878,7 +2505,7 @@ CAdapterCommon::SetIdlePowerManagement
ntStatus = GetFilters(MiniportPair, NULL, NULL, &pUnknown, NULL);
if (NT_SUCCESS(ntStatus))
{
- ntStatus =
+ ntStatus =
pUnknown->QueryInterface
(
IID_IPortClsPower,
@@ -2935,15 +2562,15 @@ Routine Description:
Arguments:
WorkItem - WDF work-item object.
-
+
--*/
{
PAGED_CODE();
DPF_ENTER(("[EvtBthHfpScoBypassInterfaceWorkItem]"));
CAdapterCommon * This;
-
- if (WorkItem == NULL)
+
+ if (WorkItem == NULL)
{
return;
}
@@ -2955,7 +2582,7 @@ Arguments:
{
PLIST_ENTRY le = NULL;
BthHfpWorkTask * task = NULL;
-
+
//
// Retrieve a taask.
//
@@ -2967,7 +2594,7 @@ Arguments:
InitializeListHead(le);
}
ExReleaseFastMutex(&This->m_BthHfpFastMutex);
-
+
if (task == NULL)
{
break;
@@ -2975,7 +2602,7 @@ Arguments:
ASSERT(task->Device != NULL);
_Analysis_assume_(task->Device != NULL);
-
+
//
// Process the task.
//
@@ -3003,7 +2630,7 @@ Arguments:
//
// Free the task.
//
- ExFreeToNPagedLookasideList(&This->m_BhtHfpWorkTaskPool, task);
+ ExFreeToNPagedLookasideList(&This->m_BthHfpWorkTaskPool, task);
}
}
@@ -3023,7 +2650,7 @@ Routine Description:
Arguments:
SymbolicLinkName - interface's symbolic link.
-
+
Return Value:
BthHfpDevice pointer or NULL.
@@ -3032,17 +2659,17 @@ Return Value:
{
PAGED_CODE();
DPF_ENTER(("[CAdapterCommon::BthHfpDeviceFind]"));
-
+
PLIST_ENTRY le = NULL;
BthHfpDevice * bthDevice = NULL;
ExAcquireFastMutex(&m_BthHfpFastMutex);
-
+
for (le = m_BthHfpDevices.Flink; le != &m_BthHfpDevices; le = le->Flink)
{
BthHfpDevice * tmpBthDevice = BthHfpDevice::GetBthHfpDevice(le);
ASSERT(tmpBthDevice != NULL);
-
+
PUNICODE_STRING unicodeStr = tmpBthDevice->GetSymbolicLinkName();
ASSERT(unicodeStr != NULL);
@@ -3055,7 +2682,7 @@ Return Value:
break;
}
}
-
+
ExReleaseFastMutex(&m_BthHfpFastMutex);
return bthDevice;
@@ -3077,7 +2704,7 @@ Routine Description:
Arguments:
SymbolicLinkName - new interface's symbolic link.
-
+
Return Value:
NT status code.
@@ -3090,7 +2717,7 @@ Return Value:
NTSTATUS ntStatus = STATUS_SUCCESS;
BthHfpDevice * bthDevice = NULL;
BthHfpWorkTask * bthWorkTask = NULL;
-
+
DPF(D_VERBOSE, ("BthHfpScoInterfaceArrival: SymbolicLinkName %wZ", SymbolicLinkName));
//
@@ -3106,7 +2733,7 @@ Return Value:
ntStatus = STATUS_SUCCESS;
goto Done;
}
-
+
//
// Alloc a new structure for this Bluetooth hands-free device.
//
@@ -3117,9 +2744,9 @@ Return Value:
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
goto Done;
}
-
+
DPF(D_VERBOSE, ("BthHfpScoInterfaceArrival: created BthHfpDevice 0x%p ", bthDevice));
-
+
//
// Basic initialization of the Bluetooth Hands-Free Profile interface.
// The audio miniport creation is done later by the BthHfpDevice.Start()
@@ -3132,14 +2759,14 @@ Return Value:
//
// Get and init a work task.
//
- bthWorkTask = (BthHfpWorkTask*)ExAllocateFromNPagedLookasideList(&m_BhtHfpWorkTaskPool);
+ bthWorkTask = (BthHfpWorkTask*)ExAllocateFromNPagedLookasideList(&m_BthHfpWorkTaskPool);
if (NULL == bthWorkTask)
{
DPF(D_ERROR, ("BthHfpScoInterfaceArrival: unable to allocate BthHfpWorkTask, out of memory"));
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
goto Done;
}
-
+
// bthWorkTask->L.Size is set to sizeof(BthHfpWorkTask) in the Look Aside List configuration
#pragma warning(suppress: 6386)
RtlZeroMemory(bthWorkTask, sizeof(*bthWorkTask));
@@ -3147,9 +2774,9 @@ Return Value:
InitializeListHead(&bthWorkTask->ListEntry);
// Note that bthDevice has one reference at this point.
bthWorkTask->Device = bthDevice;
-
+
ExAcquireFastMutex(&m_BthHfpFastMutex);
-
+
//
// Insert this new Bluetooth HFP device in our list.
//
@@ -3165,22 +2792,22 @@ Return Value:
// Schedule a work-item if not already running.
//
WdfWorkItemEnqueue(m_BthHfpWorkItem);
-
+
ExReleaseFastMutex(&m_BthHfpFastMutex);
Done:
if (!NT_SUCCESS(ntStatus))
{
- // Release the last ref, this will delete the BthHfpDevice
+ // Release the last ref, this will delete the BthHfpDevice
SAFE_RELEASE(bthDevice);
if (bthWorkTask != NULL)
{
- ExFreeToNPagedLookasideList(&m_BhtHfpWorkTaskPool, bthWorkTask);
+ ExFreeToNPagedLookasideList(&m_BthHfpWorkTaskPool, bthWorkTask);
bthWorkTask = NULL;
}
}
-
+
return ntStatus;
}
@@ -3200,7 +2827,7 @@ Routine Description:
Arguments:
SymbolicLinkName - interface's symbolic link to remove.
-
+
Return Value:
NT status code.
@@ -3213,7 +2840,7 @@ Return Value:
NTSTATUS ntStatus = STATUS_SUCCESS;
BthHfpDevice * bthDevice = NULL;
BthHfpWorkTask * bthWorkTask = NULL;
-
+
DPF(D_VERBOSE, ("BthHfpScoInterfaceRemoval: SymbolicLinkName %wZ", SymbolicLinkName));
//
@@ -3227,18 +2854,18 @@ Return Value:
ntStatus = STATUS_SUCCESS;
goto Done;
}
-
+
//
// Init a work task.
//
- bthWorkTask = (BthHfpWorkTask*)ExAllocateFromNPagedLookasideList(&m_BhtHfpWorkTaskPool);
+ bthWorkTask = (BthHfpWorkTask*)ExAllocateFromNPagedLookasideList(&m_BthHfpWorkTaskPool);
if (NULL == bthWorkTask)
{
DPF(D_ERROR, ("BthHfpScoInterfaceRemoval: unable to allocate BthHfpWorkTask, out of memory"));
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
goto Done;
}
-
+
// bthWorkTask->L.Size is set to sizeof(BthHfpWorkTask) in the Look Aside List configuration
#pragma warning(suppress: 6386)
RtlZeroMemory(bthWorkTask, sizeof(*bthWorkTask));
@@ -3248,7 +2875,7 @@ Return Value:
bthWorkTask->Device = bthDevice;
ExAcquireFastMutex(&m_BthHfpFastMutex);
-
+
//
// Remove this Bluetooth device from our list and release the associated reference.
//
@@ -3265,7 +2892,7 @@ Return Value:
// Schedule a work-item if not already running.
//
WdfWorkItemEnqueue(m_BthHfpWorkItem);
-
+
ExReleaseFastMutex(&m_BthHfpFastMutex);
//
@@ -3280,7 +2907,7 @@ Done:
// Release the ref we got in find.
SAFE_RELEASE(bthDevice);
}
-
+
return ntStatus;
}
@@ -3298,9 +2925,9 @@ Routine Description:
This callback is invoked when a new HFP SCO Bypass interface is added or removed.
Arguments:
- NotificationPointer - Interface change notification
+ NotificationPointer - Interface change notification
Context - CAdapterCommon ptr.
-
+
Return Value:
NT status code.
@@ -3309,32 +2936,32 @@ Return Value:
{
PAGED_CODE();
DPF_ENTER(("[EvtBthHfpScoBypassInterfaceChange]"));
-
+
NTSTATUS ntStatus = STATUS_SUCCESS;
CAdapterCommon * This = NULL;
PDEVICE_INTERFACE_CHANGE_NOTIFICATION Notification = (PDEVICE_INTERFACE_CHANGE_NOTIFICATION) NotificationPointer;
-
+
//
// Make sure this is the interface class we extect. Any other class guid
// is an error, but let it go since it is not fatal to the machine.
//
- if (!IsEqualGUID(Notification->InterfaceClassGuid, GUID_DEVINTERFACE_BLUETOOTH_HFP_SCO_HCIBYPASS))
+ if (!IsEqualGUID(Notification->InterfaceClassGuid, GUID_DEVINTERFACE_BLUETOOTH_HFP_SCO_HCIBYPASS))
{
DPF(D_VERBOSE, ("EvtBthHfpScoBypassInterfaceChange: bad interface ClassGuid"));
ASSERTMSG("EvtBthHfpScoBypassInterfaceChange: bad interface ClassGuid ", FALSE);
-
+
goto Done;
}
This = (CAdapterCommon *)Context;
ASSERT(This != NULL);
_Analysis_assume_(This != NULL);
-
+
//
- // Take action based on the event. Any other event type is an error,
+ // Take action based on the event. Any other event type is an error,
// but let it go since it is not fatal to the machine.
//
- if (IsEqualGUID(Notification->Event, GUID_DEVICE_INTERFACE_ARRIVAL))
+ if (IsEqualGUID(Notification->Event, GUID_DEVICE_INTERFACE_ARRIVAL))
{
ntStatus = This->BthHfpScoInterfaceArrival(Notification->SymbolicLinkName);
}
@@ -3342,13 +2969,13 @@ Return Value:
{
ntStatus = This->BthHfpScoInterfaceRemoval(Notification->SymbolicLinkName);
}
- else
+ else
{
DPF(D_VERBOSE, ("EvtBthHfpScoBypassInterfaceChange: bad "
"GUID_DEVINTERFACE_BLUETOOTH_HFP_SCO_HCIBYPASS event"));
ASSERTMSG("EvtBthHfpScoBypassInterfaceChange: bad "
"GUID_DEVINTERFACE_BLUETOOTH_HFP_SCO_HCIBYPASS event ", FALSE);
-
+
goto Done;
}
@@ -3379,7 +3006,7 @@ Return Value:
WDF_WORKITEM_CONFIG wiConfig;
WDF_OBJECT_ATTRIBUTES attributes;
BthHfpWorkItemContext * wiContext;
-
+
//
// Init spin-lock, linked lists, work-item, event, etc.
// Init all members to default values. This basic init should not fail.
@@ -3389,14 +3016,14 @@ Return Value:
ExInitializeFastMutex(&m_BthHfpFastMutex);
InitializeListHead(&m_BthHfpWorkTasks);
InitializeListHead(&m_BthHfpDevices);
- m_BhtHfpWorkTaskPoolElementSize = sizeof(BthHfpWorkTask);
- ExInitializeNPagedLookasideList(&m_BhtHfpWorkTaskPool,
+ m_BthHfpWorkTaskPoolElementSize = sizeof(BthHfpWorkTask);
+ ExInitializeNPagedLookasideList(&m_BthHfpWorkTaskPool,
NULL,
NULL,
POOL_NX_ALLOCATION,
- m_BhtHfpWorkTaskPoolElementSize,
+ m_BthHfpWorkTaskPoolElementSize,
MINADAPTER_POOLTAG,
- 0);
+ 0);
//
// Enable Bluetooth HFP SCO-Bypass Cleanup.
// Do any allocation/initialization that can fail after this point.
@@ -3421,7 +3048,7 @@ Return Value:
wiContext = GetBthHfpWorkItemContext(m_BthHfpWorkItem);
wiContext->Adapter = this; // weak ref.
-
+
//
// Register for bluetooth heandsfree profile interface changes.
//
@@ -3470,7 +3097,7 @@ Routine Description:
{
return;
}
-
+
//
// Unregister for bluetooth heandsfree profile interface changes.
//
@@ -3489,20 +3116,20 @@ Routine Description:
WdfObjectDelete(m_BthHfpWorkItem);
m_BthHfpWorkItem = NULL;
}
-
+
ASSERT(IsListEmpty(&m_BthHfpWorkTasks));
-
+
//
- // Stop and delete all BthHfpDevices. We are the only thread accessing this list,
+ // Stop and delete all BthHfpDevices. We are the only thread accessing this list,
// so there is no need to acquire the mutex.
//
while (!IsListEmpty(&m_BthHfpDevices))
{
BthHfpDevice * bthDevice = NULL;
PLIST_ENTRY le = NULL;
-
+
le = RemoveHeadList(&m_BthHfpDevices);
-
+
bthDevice = BthHfpDevice::GetBthHfpDevice(le);
InitializeListHead(le);
@@ -3512,3033 +3139,374 @@ Routine Description:
// This should be the last reference.
bthDevice->Release();
}
-
+
ASSERT(IsListEmpty(&m_BthHfpDevices));
-
+
//
// General cleanup.
//
- ExDeleteNPagedLookasideList(&m_BhtHfpWorkTaskPool);
+ ExDeleteNPagedLookasideList(&m_BthHfpWorkTaskPool);
}
#endif // SYSVAD_BTH_BYPASS
-#ifdef SYSVAD_BTH_BYPASS
-//
-// BthHfpDevice implementation.
-//
-
-//=============================================================================
-#pragma code_seg("PAGE")
-STDMETHODIMP
-BthHfpDevice::NonDelegatingQueryInterface
-(
- _In_ REFIID Interface,
- _COM_Outptr_ PVOID * Object
-)
-/*++
-
-Routine Description:
-
- QueryInterface routine for BthHfpDevice
-
-Arguments:
-
- Interface -
-
- Object -
-
-Return Value:
-
- NT status code.
-
---*/
-{
- PAGED_CODE();
-
- ASSERT(Object);
-
- if (IsEqualGUIDAligned(Interface, IID_IUnknown))
- {
- *Object = PVOID(PUNKNOWN(PBTHHFPDEVICECOMMON(this)));
- }
- else if (IsEqualGUIDAligned(Interface, IID_IBthHfpDeviceCommon))
- {
- *Object = PVOID(PBTHHFPDEVICECOMMON(this));
- }
- else
- {
- *Object = NULL;
- }
-
- if (*Object)
- {
- PUNKNOWN(*Object)->AddRef();
- return STATUS_SUCCESS;
- }
-
- return STATUS_INVALID_PARAMETER;
-} // NonDelegatingQueryInterface
-
-//=============================================================================
-// Dummy stubs to override the default WDF behavior of closing the target
-// on query remove. This driver closes and deletes the supporting objects
-// when the target removes the BTH HFP SCO Bypass interface.
-//
-
#pragma code_seg("PAGE")
NTSTATUS
-BthHfpDevice::EvtBthHfpTargetQueryRemove
-(
- _In_ WDFIOTARGET IoTarget
-)
-{
- PAGED_CODE();
- DPF_ENTER(("[BthHfpDevice::EvtBthHfpTargetQueryRemove]"));
-
- UNREFERENCED_PARAMETER(IoTarget);
- return STATUS_SUCCESS;
-}
-
-#pragma code_seg("PAGE")
-VOID
-BthHfpDevice::EvtBthHfpTargetRemoveCanceled
-(
- _In_ WDFIOTARGET IoTarget
-)
-{
- PAGED_CODE();
- DPF_ENTER(("[BthHfpDevice::EvtBthHfpTargetRemoveCanceled]"));
-
- UNREFERENCED_PARAMETER(IoTarget);
-}
-#pragma code_seg("PAGE")
-VOID
-BthHfpDevice::EvtBthHfpTargetRemoveComplete
-(
- _In_ WDFIOTARGET IoTarget
-)
-{
- PAGED_CODE();
- DPF_ENTER(("[BthHfpDevice::EvtBthHfpTargetRemoveComplete]"));
-
- UNREFERENCED_PARAMETER(IoTarget);
-}
-
-//=============================================================================
-#pragma code_seg("PAGE")
-NTSTATUS
-BthHfpDevice::Init
-(
- _In_ CAdapterCommon * Adapter,
- _In_ PUNICODE_STRING SymbolicLinkName
-)
-{
- PAGED_CODE();
- DPF_ENTER(("[BthHfpDevice::Init]"));
-
- NTSTATUS ntStatus = STATUS_SUCCESS;
- BthHfpDeviceNotificationWorkItemContext *wiCtx = NULL;
- BthHfpDeviceNotificationReqContext *reqCtx = NULL;
- WDF_OBJECT_ATTRIBUTES attributes;
- WDF_IO_TARGET_OPEN_PARAMS openParams;
- WDF_WORKITEM_CONFIG wiConfig;
-
- AddRef(); // first ref.
-
- //
- // Basic init of all the class' members.
- //
- m_State = eBthHfpStateInitializing;
- m_Adapter = Adapter;
-
- // Static config.
- m_WdfIoTarget = NULL;
- m_SpeakerMiniports = NULL;
- m_MicMiniports = NULL;
- m_UnknownSpeakerTopology = NULL;
- m_UnknownSpeakerWave = NULL;
- m_UnknownMicTopology = NULL;
- m_UnknownMicWave = NULL;
- m_Descriptor = NULL;
- m_VolumePropValues = NULL;
-
- // Notification updates.
- m_SpeakerVolumeLevel = 0;
- m_MicVolumeLevel = 0;
- m_ConnectionStatusLong = FALSE;
- m_StreamStatusLong = STATUS_INVALID_DEVICE_STATE; // Sco stream is not open.
- m_NRECDisableStatusLong = FALSE;
-
- m_StreamReq = NULL;
- m_SpeakerVolumeReq = NULL;
- m_MicVolumeReq = NULL;
- m_ConnectionReq = NULL;
- m_NRECDisableStatusReq = NULL;
-
- m_WorkItem = NULL;
- m_ReqCollection = NULL;
-
- m_nStreams = 0;
-
- KeInitializeEvent(&m_StreamStatusEvent, NotificationEvent, TRUE);
-
- InitializeListHead(&m_ListEntry);
- KeInitializeSpinLock(&m_Lock);
-
- RtlZeroMemory(&m_SymbolicLinkName, sizeof(m_SymbolicLinkName));
-
- RtlZeroMemory(&m_SpeakerVolumeCallback, sizeof(m_SpeakerVolumeCallback));
- RtlZeroMemory(&m_SpeakerConnectionStatusCallback, sizeof(m_SpeakerConnectionStatusCallback));
- RtlZeroMemory(&m_MicVolumeCallback, sizeof(m_MicVolumeCallback));
- RtlZeroMemory(&m_MicConnectionStatusCallback, sizeof(m_MicConnectionStatusCallback));
-
- //
- // Allocate a notification WDF work-item.
- //
- WDF_WORKITEM_CONFIG_INIT(&wiConfig, EvtBthHfpDeviceNotificationStatusWorkItem);
- wiConfig.AutomaticSerialization = FALSE;
-
- WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, BthHfpDeviceNotificationWorkItemContext);
- attributes.ParentObject = Adapter->GetWdfDevice();
- ntStatus = WdfWorkItemCreate( &wiConfig,
- &attributes,
- &m_WorkItem);
- IF_FAILED_ACTION_JUMP(
- ntStatus,
- DPF(D_ERROR, ("Init: WdfWorkItemCreate failed: 0x%x", ntStatus)),
- Done);
-
- wiCtx = GetBthHfpDeviceNotificationWorkItemContext(m_WorkItem);
- wiCtx->BthHfpDevice = this; // weak ref.
-
- //
- // Allocate a collection to hold notification requests for the notification work-item.
- //
- WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
- attributes.ParentObject = m_Adapter->GetWdfDevice();
- ntStatus = WdfCollectionCreate(
- &attributes,
- &m_ReqCollection);
-
- IF_FAILED_ACTION_JUMP(
- ntStatus,
- DPF(D_ERROR, ("Init: WdfCollectionCreate failed: 0x%x", ntStatus)),
- Done);
-
- //
- // Open the target interface.
- //
- WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
- attributes.ParentObject = m_Adapter->GetWdfDevice();
- ntStatus = WdfIoTargetCreate(m_Adapter->GetWdfDevice(),
- &attributes,
- &m_WdfIoTarget);
- IF_FAILED_ACTION_JUMP(
- ntStatus,
- DPF(D_ERROR, ("Init: WdfIoTargetCreate failed: 0x%x", ntStatus)),
- Done);
-
- WDF_IO_TARGET_OPEN_PARAMS_INIT_OPEN_BY_NAME(
- &openParams,
- SymbolicLinkName,
- STANDARD_RIGHTS_ALL);
-
- openParams.EvtIoTargetQueryRemove = EvtBthHfpTargetQueryRemove;
- openParams.EvtIoTargetRemoveCanceled = EvtBthHfpTargetRemoveCanceled;
- openParams.EvtIoTargetRemoveComplete = EvtBthHfpTargetRemoveComplete;
-
- ntStatus = WdfIoTargetOpen(m_WdfIoTarget, &openParams);
- IF_FAILED_ACTION_JUMP(
- ntStatus,
- DPF(D_ERROR, ("Init: WdfIoTargetOpen(%wZ) failed: 0x%x", SymbolicLinkName, ntStatus)),
- Done);
-
- //
- // Make a copy of the symbolic link name.
- //
- m_SymbolicLinkName.MaximumLength = SymbolicLinkName->MaximumLength;
- m_SymbolicLinkName.Length = SymbolicLinkName->Length;
- m_SymbolicLinkName.Buffer = (PWSTR) ExAllocatePoolWithTag(NonPagedPoolNx,
- SymbolicLinkName->MaximumLength,
- MINADAPTER_POOLTAG);
- if (m_SymbolicLinkName.Buffer == NULL)
- {
- ntStatus = STATUS_INSUFFICIENT_RESOURCES;
- }
-
- IF_FAILED_ACTION_JUMP(
- ntStatus,
- DPF(D_ERROR, ("Init: ExAllocatePoolWithTag failed, out of memory")),
- Done);
-
- RtlCopyUnicodeString(&m_SymbolicLinkName, SymbolicLinkName);
-
- //
- // Allocate the WDF requests for status notifications.
- //
-
- //
- // IOCTL_BTHHFP_DEVICE_GET_NRECDISABLE_STATUS_UPDATE
- //
- WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, BthHfpDeviceNotificationReqContext);
- attributes.ParentObject = m_Adapter->GetWdfDevice();
- ntStatus = WdfRequestCreate(
- &attributes,
- m_WdfIoTarget,
- &m_NRECDisableStatusReq);
- IF_FAILED_ACTION_JUMP(
- ntStatus,
- DPF(D_ERROR, ("Init: WdfRequestCreate(Nrec-disable status) failed, 0x%x", ntStatus)),
- Done);
-
- // Init context.
- reqCtx = GetBthHfpDeviceNotificationReqContext(m_NRECDisableStatusReq);
- reqCtx->BthHfpDevice = this; // weak ref.
-
- ntStatus = WdfMemoryCreatePreallocated(
- WDF_NO_OBJECT_ATTRIBUTES,
- &reqCtx->Buffer,
- sizeof(reqCtx->Buffer.bImmediate),
- &reqCtx->MemIn);
- IF_FAILED_ACTION_JUMP(
- ntStatus,
- DPF(D_ERROR, ("Init: WdfMemoryCreatePreallocated failed, 0x%x", ntStatus)),
- Done);
-
- ntStatus = WdfMemoryCreatePreallocated(
- WDF_NO_OBJECT_ATTRIBUTES,
- &reqCtx->Buffer,
- sizeof(reqCtx->Buffer.BoolStatus),
- &reqCtx->MemOut);
- IF_FAILED_ACTION_JUMP(
- ntStatus,
- DPF(D_ERROR, ("Init: WdfMemoryCreatePreallocated failed, 0x%x", ntStatus)),
- Done);
-
- //
- // IOCTL_BTHHFP_SPEAKER_GET_VOLUME_STATUS_UPDATE
- //
- WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, BthHfpDeviceNotificationReqContext);
- attributes.ParentObject = m_Adapter->GetWdfDevice();
- ntStatus = WdfRequestCreate(
- &attributes,
- m_WdfIoTarget,
- &m_SpeakerVolumeReq);
- IF_FAILED_ACTION_JUMP(
- ntStatus,
- DPF(D_ERROR, ("Init: WdfRequestCreate(Speaker-Volume) failed, 0x%x", ntStatus)),
- Done);
-
- // Init context.
- reqCtx = GetBthHfpDeviceNotificationReqContext(m_SpeakerVolumeReq);
- reqCtx->BthHfpDevice = this; // weak ref.
-
- ntStatus = WdfMemoryCreatePreallocated(
- WDF_NO_OBJECT_ATTRIBUTES,
- &reqCtx->Buffer,
- sizeof(reqCtx->Buffer.bImmediate),
- &reqCtx->MemIn);
- IF_FAILED_ACTION_JUMP(
- ntStatus,
- DPF(D_ERROR, ("Init: WdfMemoryCreatePreallocated failed, 0x%x", ntStatus)),
- Done);
-
- ntStatus = WdfMemoryCreatePreallocated(
- WDF_NO_OBJECT_ATTRIBUTES,
- &reqCtx->Buffer,
- sizeof(reqCtx->Buffer.Volume),
- &reqCtx->MemOut);
- IF_FAILED_ACTION_JUMP(
- ntStatus,
- DPF(D_ERROR, ("Init: WdfMemoryCreatePreallocated failed, 0x%x", ntStatus)),
- Done);
-
- //
- // IOCTL_BTHHFP_MIC_GET_VOLUME_STATUS_UPDATE
- //
- WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, BthHfpDeviceNotificationReqContext);
- attributes.ParentObject = m_Adapter->GetWdfDevice();
- ntStatus = WdfRequestCreate(
- &attributes,
- m_WdfIoTarget,
- &m_MicVolumeReq);
- IF_FAILED_ACTION_JUMP(
- ntStatus,
- DPF(D_ERROR, ("Init: WdfRequestCreate(Mic-Volume) failed, 0x%x", ntStatus)),
- Done);
-
- // Init context.
- reqCtx = GetBthHfpDeviceNotificationReqContext(m_MicVolumeReq);
- reqCtx->BthHfpDevice = this; // weak ref.
-
- ntStatus = WdfMemoryCreatePreallocated(
- WDF_NO_OBJECT_ATTRIBUTES,
- &reqCtx->Buffer,
- sizeof(reqCtx->Buffer.bImmediate),
- &reqCtx->MemIn);
- IF_FAILED_ACTION_JUMP(
- ntStatus,
- DPF(D_ERROR, ("Init: WdfMemoryCreatePreallocated failed, 0x%x", ntStatus)),
- Done);
-
- ntStatus = WdfMemoryCreatePreallocated(
- WDF_NO_OBJECT_ATTRIBUTES,
- &reqCtx->Buffer,
- sizeof(reqCtx->Buffer.Volume),
- &reqCtx->MemOut);
- IF_FAILED_ACTION_JUMP(
- ntStatus,
- DPF(D_ERROR, ("Init: WdfMemoryCreatePreallocated failed, 0x%x", ntStatus)),
- Done);
-
- //
- // IOCTL_BTHHFP_DEVICE_GET_CONNECTION_STATUS_UPDATE
- //
- WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, BthHfpDeviceNotificationReqContext);
- attributes.ParentObject = m_Adapter->GetWdfDevice();
- ntStatus = WdfRequestCreate(
- &attributes,
- m_WdfIoTarget,
- &m_ConnectionReq);
- IF_FAILED_ACTION_JUMP(
- ntStatus,
- DPF(D_ERROR, ("Init: WdfRequestCreate(Connection-Status) failed, 0x%x", ntStatus)),
- Done);
-
- // Init context.
- reqCtx = GetBthHfpDeviceNotificationReqContext(m_ConnectionReq);
- reqCtx->BthHfpDevice = this; // weak ref.
-
- ntStatus = WdfMemoryCreatePreallocated(
- WDF_NO_OBJECT_ATTRIBUTES,
- &reqCtx->Buffer,
- sizeof(reqCtx->Buffer.bImmediate),
- &reqCtx->MemIn);
- IF_FAILED_ACTION_JUMP(
- ntStatus,
- DPF(D_ERROR, ("Init: WdfMemoryCreatePreallocated failed, 0x%x", ntStatus)),
- Done);
-
- ntStatus = WdfMemoryCreatePreallocated(
- WDF_NO_OBJECT_ATTRIBUTES,
- &reqCtx->Buffer,
- sizeof(reqCtx->Buffer.BoolStatus),
- &reqCtx->MemOut);
- IF_FAILED_ACTION_JUMP(
- ntStatus,
- DPF(D_ERROR, ("Init: WdfMemoryCreatePreallocated failed, 0x%x", ntStatus)),
- Done);
-
- //
- // IOCTL_BTHHFP_STREAM_GET_STATUS_UPDATE
- //
- WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, BthHfpDeviceNotificationReqContext);
- attributes.ParentObject = m_Adapter->GetWdfDevice();
- ntStatus = WdfRequestCreate(
- &attributes,
- m_WdfIoTarget,
- &m_StreamReq);
- IF_FAILED_ACTION_JUMP(
- ntStatus,
- DPF(D_ERROR, ("Init: WdfRequestCreate(Stream-Status) failed, 0x%x", ntStatus)),
- Done);
-
- // Init context.
- reqCtx = GetBthHfpDeviceNotificationReqContext(m_StreamReq);
- reqCtx->BthHfpDevice = this; // weak ref.
-
- ntStatus = WdfMemoryCreatePreallocated(
- WDF_NO_OBJECT_ATTRIBUTES,
- &reqCtx->Buffer,
- sizeof(reqCtx->Buffer.bImmediate),
- &reqCtx->MemIn);
- IF_FAILED_ACTION_JUMP(
- ntStatus,
- DPF(D_ERROR, ("Init: WdfMemoryCreatePreallocated failed, 0x%x", ntStatus)),
- Done);
-
- ntStatus = WdfMemoryCreatePreallocated(
- WDF_NO_OBJECT_ATTRIBUTES,
- &reqCtx->Buffer,
- sizeof(reqCtx->Buffer.NtStatus),
- &reqCtx->MemOut);
- IF_FAILED_ACTION_JUMP(
- ntStatus,
- DPF(D_ERROR, ("Init: WdfMemoryCreatePreallocated failed, 0x%x", ntStatus)),
- Done);
-
- //
- // This remote device is now in running state. No need to use interlock operations
- // b/c at this time this is the only thread accessing this info.
- //
- m_State = eBthHfpStateRunning;
-
- //
- // Init successful.
- //
- ntStatus = STATUS_SUCCESS;
-
-Done:
- return ntStatus;
-}
-
-//=============================================================================
-#pragma code_seg("PAGE")
-BthHfpDevice::~BthHfpDevice
-(
- void
-)
+CopyRegistryValues(HANDLE _hSourceKey, HANDLE _hDestinationKey)
/*++
Routine Description:
- Destructor for BthHfpDevice.
-
-Arguments:
+ This method copies the registry values in _hSourceKey to _hDestinationKey.
Return Value:
- void
+ NT status code.
--*/
{
+ NTSTATUS ntStatus = STATUS_SUCCESS;
+ PKEY_VALUE_FULL_INFORMATION kvFullInfo = NULL;
+ ULONG ulFullInfoLength = 0;
+ ULONG ulFullInfoResultLength = 0;
+ PWSTR pwstrKeyValueName = NULL;
+ UNICODE_STRING strKeyValueName;
PAGED_CODE();
- DPF_ENTER(("[BthHfpDevice::~BthHfpDevice]"));
-
- ASSERT(m_State != eBthHfpStateRunning);
- ASSERT(IsListEmpty(&m_ListEntry));
-
- //
- // Release ref to remote stack.
- //
- if (m_WdfIoTarget != NULL)
- {
- WdfObjectDelete(m_WdfIoTarget);
- m_WdfIoTarget = NULL;
- }
+ // Allocate the KEY_VALUE_FULL_INFORMATION structure
+ ulFullInfoLength = sizeof(KEY_VALUE_FULL_INFORMATION) + MAX_DEVICE_REG_KEY_LENGTH;
+ kvFullInfo = (PKEY_VALUE_FULL_INFORMATION)ExAllocatePoolWithTag(NonPagedPoolNx, ulFullInfoLength, MINADAPTER_POOLTAG);
+ IF_TRUE_ACTION_JUMP(kvFullInfo == NULL, ntStatus = STATUS_INSUFFICIENT_RESOURCES, Exit);
- //
- // Free symbolic links.
- //
- if (m_SymbolicLinkName.Buffer != NULL)
+ // Iterate over each value and copy it to the destination
+ for (UINT i = 0; NT_SUCCESS(ntStatus); i++)
{
- ExFreePoolWithTag(m_SymbolicLinkName.Buffer, MINADAPTER_POOLTAG);
- RtlZeroMemory(&m_SymbolicLinkName, sizeof(m_SymbolicLinkName));
- }
-
- DeleteCustomEndpointMinipair(m_SpeakerMiniports);
- m_SpeakerMiniports = NULL;
+ // Enumerate the next value
+ ntStatus = ZwEnumerateValueKey(_hSourceKey, i, KeyValueFullInformation, kvFullInfo, ulFullInfoLength, &ulFullInfoResultLength);
- DeleteCustomEndpointMinipair(m_MicMiniports);
- m_MicMiniports = NULL;
+ // Jump out of this loop if there are no more values
+ IF_TRUE_ACTION_JUMP(ntStatus == STATUS_NO_MORE_ENTRIES, ntStatus = STATUS_SUCCESS, Exit);
- if (m_Descriptor != NULL)
- {
- ExFreePoolWithTag(m_Descriptor, MINADAPTER_POOLTAG);
- m_Descriptor = NULL;
- }
-
- if (m_VolumePropValues != NULL)
- {
- ExFreePoolWithTag(m_VolumePropValues, MINADAPTER_POOLTAG);
- m_VolumePropValues = NULL;
- }
-
- //
- // Free Irps.
- //
- if (m_SpeakerVolumeReq != NULL)
- {
- BthHfpDeviceNotificationReqContext * ctx;
-
- // Delete the associated memory objects.
- ctx = GetBthHfpDeviceNotificationReqContext(m_SpeakerVolumeReq);
- if (ctx->MemIn != NULL)
+ // Handle incorrect buffer size
+ if (ntStatus == STATUS_BUFFER_TOO_SMALL || ntStatus == STATUS_BUFFER_OVERFLOW)
{
- WdfObjectDelete(ctx->MemIn);
- ctx->MemIn = NULL;
- }
+ // Free and re-allocate the KEY_VALUE_FULL_INFORMATION structure with the correct size
+ ExFreePoolWithTag(kvFullInfo, MINADAPTER_POOLTAG);
- if (ctx->MemOut != NULL)
- {
- WdfObjectDelete(ctx->MemOut);
- ctx->MemOut = NULL;
- }
-
- // Delete the request.
- WdfObjectDelete(m_SpeakerVolumeReq);
- m_SpeakerVolumeReq = NULL;
- }
-
- if (m_MicVolumeReq != NULL)
- {
- BthHfpDeviceNotificationReqContext * ctx;
-
- // Delete the associated memory objects.
- ctx = GetBthHfpDeviceNotificationReqContext(m_MicVolumeReq);
- if (ctx->MemIn != NULL)
- {
- WdfObjectDelete(ctx->MemIn);
- ctx->MemIn = NULL;
- }
-
- if (ctx->MemOut != NULL)
- {
- WdfObjectDelete(ctx->MemOut);
- ctx->MemOut = NULL;
- }
-
- // Delete the request.
- WdfObjectDelete(m_MicVolumeReq);
- m_MicVolumeReq = NULL;
- }
-
- if (m_ConnectionReq != NULL)
- {
- BthHfpDeviceNotificationReqContext * ctx;
-
- // Delete the associated memory objects.
- ctx = GetBthHfpDeviceNotificationReqContext(m_ConnectionReq);
- if (ctx->MemIn != NULL)
- {
- WdfObjectDelete(ctx->MemIn);
- ctx->MemIn = NULL;
- }
+ ulFullInfoLength = ulFullInfoResultLength;
- if (ctx->MemOut != NULL)
- {
- WdfObjectDelete(ctx->MemOut);
- ctx->MemOut = NULL;
- }
+ kvFullInfo = (PKEY_VALUE_FULL_INFORMATION)ExAllocatePoolWithTag(NonPagedPoolNx, ulFullInfoLength, MINADAPTER_POOLTAG);
+ IF_TRUE_ACTION_JUMP(kvFullInfo == NULL, ntStatus = STATUS_INSUFFICIENT_RESOURCES, loop_exit);
- // Delete the request.
- WdfObjectDelete(m_ConnectionReq);
- m_ConnectionReq = NULL;
- }
+ // Try to enumerate the current value again
+ ntStatus = ZwEnumerateValueKey(_hSourceKey, i, KeyValueFullInformation, kvFullInfo, ulFullInfoLength, &ulFullInfoResultLength);
- if (m_StreamReq != NULL)
- {
- BthHfpDeviceNotificationReqContext * ctx;
-
- // Delete the associated memory objects.
- ctx = GetBthHfpDeviceNotificationReqContext(m_StreamReq);
- if (ctx->MemIn != NULL)
- {
- WdfObjectDelete(ctx->MemIn);
- ctx->MemIn = NULL;
+ // Jump out of this loop if there are no more values
+ IF_TRUE_ACTION_JUMP(ntStatus == STATUS_NO_MORE_ENTRIES, ntStatus = STATUS_SUCCESS, Exit);
+ IF_FAILED_JUMP(ntStatus, loop_exit);
}
-
- if (ctx->MemOut != NULL)
+ else
{
- WdfObjectDelete(ctx->MemOut);
- ctx->MemOut = NULL;
+ IF_FAILED_JUMP(ntStatus, loop_exit);
}
- // Delete the request.
- WdfObjectDelete(m_StreamReq);
- m_StreamReq = NULL;
- }
-
- //
- // Notification work-item.
- //
- if (m_WorkItem != NULL)
- {
- WdfObjectDelete(m_WorkItem);
- m_WorkItem = NULL;
- }
-
- //
- // Notification req. collection.
- //
- if (m_ReqCollection != NULL)
- {
- WdfObjectDelete(m_ReqCollection);
- m_ReqCollection = NULL;
- }
-
- ASSERT(m_UnknownSpeakerTopology == NULL);
- SAFE_RELEASE(m_UnknownSpeakerTopology);
-
- ASSERT(m_UnknownSpeakerWave == NULL);
- SAFE_RELEASE(m_UnknownSpeakerWave);
-
- ASSERT(m_UnknownMicTopology == NULL);
- SAFE_RELEASE(m_UnknownMicTopology);
-
- ASSERT(m_UnknownMicWave == NULL);
- SAFE_RELEASE(m_UnknownMicWave);
-
- ASSERT(m_nStreams == 0);
-
- ASSERT(m_SpeakerVolumeCallback.Handler == NULL);
- ASSERT(m_SpeakerConnectionStatusCallback.Handler == NULL);
- ASSERT(m_MicVolumeCallback.Handler == NULL);
- ASSERT(m_MicConnectionStatusCallback.Handler == NULL);
-} // ~CAdapterCommon
-
-//
-// IBthHfpDeviceCommon implementation.
-//
-
-//=============================================================================
-#pragma code_seg("PAGE")
-BOOL
-BthHfpDevice::IsVolumeSupported()
-{
- PAGED_CODE();
- DPF_ENTER(("[BthHfpDevice::IsVolumeSupported]"));
-
- return m_Descriptor->SupportsVolume;
-}
-
-//=============================================================================
-#pragma code_seg("PAGE")
-PKSPROPERTY_VALUES
-BthHfpDevice::GetVolumeSettings
-(
- _Out_ PULONG Size
-)
-{
- PAGED_CODE();
- DPF_ENTER(("[BthHfpDevice::GetVolumeSettings]"));
-
- ASSERT(Size != NULL);
-
- *Size = m_Descriptor->VolumePropertyValuesSize;
-
- return m_VolumePropValues;
-}
-
-//=============================================================================
-#pragma code_seg("PAGE")
-LONG
-BthHfpDevice::GetSpeakerVolume()
-{
- PAGED_CODE();
- DPF_ENTER(("[BthHfpDevice::GetSpeakerVolume]"));
-
- return InterlockedCompareExchange(&m_SpeakerVolumeLevel, 0, 0);
-}
-
-//=============================================================================
-#pragma code_seg("PAGE")
-NTSTATUS
-BthHfpDevice::SetSpeakerVolume
-(
- _In_ ULONG Volume
-)
-{
- PAGED_CODE();
- DPF_ENTER(("[BthHfpDevice::SetSpeakerVolume]"));
-
- return SetBthHfpSpeakerVolume(Volume);
-}
-
-//=============================================================================
-#pragma code_seg("PAGE")
-LONG
-BthHfpDevice::GetMicVolume()
-{
- PAGED_CODE();
- DPF_ENTER(("[BthHfpDevice::GetMicVolume]"));
-
- return InterlockedCompareExchange(&m_MicVolumeLevel, 0, 0);
-}
-
-//=============================================================================
-#pragma code_seg("PAGE")
-NTSTATUS
-BthHfpDevice::SetMicVolume
-(
- _In_ ULONG Volume
-)
-{
- PAGED_CODE();
- DPF_ENTER(("[BthHfpDevice::SetMicVolume]"));
-
- return SetBthHfpMicVolume(Volume);
-}
-
-//=============================================================================
-#pragma code_seg("PAGE")
-BOOL
-BthHfpDevice::GetConnectionStatus()
-{
- PAGED_CODE();
- DPF_ENTER(("[BthHfpDevice::GetConnectionStatus]"));
-
- return (BOOL)InterlockedCompareExchange(&m_ConnectionStatusLong, 0, 0);
-}
-
-//=============================================================================
-#pragma code_seg("PAGE")
-NTSTATUS
-BthHfpDevice::GetBthHfpCodecId(_Out_ UCHAR * CodecId)
-{
- PAGED_CODE();
- DPF_ENTER(("[BthHfpDevice::GetBthHfpCodecId]"));
-
- ASSERT(CodecId != NULL);
-
-#if !defined(NTDDI_WIN10_RS3)
- typedef enum _HFP_BYPASS_CODEC_ID_VERSION {
- REQ_HFP_BYPASS_CODEC_ID_V1 = 1,
- } HFP_BYPASS_CODEC_ID_VERSION, *PHFP_BYPASS_CODEC_ID_VERSION;
-
- typedef struct _HFP_BYPASS_CODEC_ID_V1 {
- UCHAR CodecId;
- } HFP_BYPASS_CODEC_ID_V1, *PHFP_BYPASS_CODEC_ID_V1;
-#endif
-
- NTSTATUS ntStatus = STATUS_SUCCESS;
-
- union {
- HFP_BYPASS_CODEC_ID_V1 CodecIdV1;
- HFP_BYPASS_CODEC_ID_VERSION Version;
- } value;
-
- *CodecId = 0;
+ // Allocate the key value name string
+ pwstrKeyValueName = (PWSTR)ExAllocatePoolWithTag(NonPagedPoolNx, kvFullInfo->NameLength + sizeof(WCHAR)*2, MINADAPTER_POOLTAG);
+ IF_TRUE_ACTION_JUMP(kvFullInfo == NULL, ntStatus = STATUS_INSUFFICIENT_RESOURCES, loop_exit);
- value.Version = REQ_HFP_BYPASS_CODEC_ID_V1;
+ // Copy the key value name from the full information struct
+ RtlStringCbCopyNW(pwstrKeyValueName, kvFullInfo->NameLength + sizeof(WCHAR)*2, kvFullInfo->Name, kvFullInfo->NameLength);
- //
- // Get the Bth HFP SCO Codec ID.
- //
- ntStatus = SendIoCtrlSynchronously(
- NULL,
- IOCTL_BTHHFP_DEVICE_GET_CODEC_ID,
- sizeof(value.Version),
- sizeof(value.CodecIdV1),
- &value);
-
- IF_FAILED_ACTION_JUMP(
- ntStatus,
- DPF(D_ERROR, ("GetBthHfpCodecId: SendIoCtrlSynchronously(IOCTL_BTHHFP_DEVICE_GET_CODEC_ID) failed, 0x%x", ntStatus)),
- Done);
-
- //
- // All done.
- //
- *CodecId = value.CodecIdV1.CodecId;
- ntStatus = STATUS_SUCCESS;
-
-Done:
-
- return ntStatus;
-}
-
-//=============================================================================
-#pragma code_seg("PAGE")
-NTSTATUS
-BthHfpDevice::Connect()
-{
- PAGED_CODE();
- DPF_ENTER(("[BthHfpDevice::Connect]"));
-
- return SetBthHfpConnect();
-}
-
-//=============================================================================
-#pragma code_seg("PAGE")
-NTSTATUS
-BthHfpDevice::Disconnect()
-{
- PAGED_CODE();
- DPF_ENTER(("[BthHfpDevice::Disconnect]"));
+ // Make sure the string is null terminated
+ pwstrKeyValueName[(kvFullInfo->NameLength) / sizeof(WCHAR)] = 0;
- return SetBthHfpDisconnect();
-}
-
-//=============================================================================
-#pragma code_seg()
-BOOL
-BthHfpDevice::GetStreamStatus()
-{
- DPF_ENTER(("[BthHfpDevice::GetStreamStatus]"));
-
- NTSTATUS ntStatus;
-
- ntStatus = (NTSTATUS)InterlockedCompareExchange(&m_StreamStatusLong, 0, 0);
-
- return NT_SUCCESS(ntStatus) ? TRUE : FALSE;
-}
-
-//=============================================================================
-#pragma code_seg("PAGE")
-NTSTATUS
-BthHfpDevice::StreamOpen()
-{
- PAGED_CODE();
- DPF_ENTER(("[BthHfpDevice::StreamOpen]"));
-
- NTSTATUS ntStatus = STATUS_SUCCESS;
- LONG nStreams = 0;
+ // Copy the key value name string to a UNICODE string
+ RtlInitUnicodeString(&strKeyValueName, pwstrKeyValueName);
- ASSERT(m_nStreams >= 0);
-
- nStreams = InterlockedIncrement(&m_nStreams);
- if (nStreams == 1)
- {
- BOOLEAN streamOpen = FALSE;
+ // Write the key value from the source into the destination
+ ntStatus = ZwSetValueKey(_hDestinationKey, &strKeyValueName, 0, kvFullInfo->Type, (PVOID)((PUCHAR)kvFullInfo + kvFullInfo->DataOffset), kvFullInfo->DataLength);
+ IF_FAILED_JUMP(ntStatus, loop_exit);
- ntStatus = SetBthHfpStreamOpen();
- if (NT_SUCCESS(ntStatus))
+ loop_exit:
+ // Free the key value name string
+ if (pwstrKeyValueName)
{
- streamOpen = TRUE;
- m_StreamStatus = STATUS_SUCCESS;
- ntStatus = EnableBthHfpStreamStatusNotification();
+ ExFreePoolWithTag(pwstrKeyValueName, MINADAPTER_POOLTAG);
}
- //
- // Cleanup if any error.
- //
- if (!NT_SUCCESS(ntStatus))
- {
- nStreams = InterlockedDecrement(&m_nStreams);
- ASSERT(nStreams == 0);
- UNREFERENCED_VAR(nStreams);
-
- if (streamOpen)
- {
- SetBthHfpStreamClose();
- }
-
- m_StreamStatus = STATUS_INVALID_DEVICE_STATE;
- }
+ // Bail if anything failed
+ IF_FAILED_JUMP(ntStatus, Exit);
}
- return ntStatus;
-}
-
-//=============================================================================
-#pragma code_seg("PAGE")
-NTSTATUS
-BthHfpDevice::StreamClose()
-{
- PAGED_CODE();
- DPF_ENTER(("[BthHfpDevice::StreamClose]"));
-
- NTSTATUS ntStatus = STATUS_SUCCESS;
- LONG nStreams = 0;
-
- ASSERT(m_nStreams > 0);
-
- nStreams = InterlockedDecrement(&m_nStreams);
- if (nStreams == 0)
+Exit:
+ // Free the KEY_VALUE_FULL_INFORMATION structure
+ if (kvFullInfo)
{
- ntStatus = SetBthHfpStreamClose();
-
- StopBthHfpStreamStatusNotification();
-
- m_StreamStatus = STATUS_INVALID_DEVICE_STATE;
+ ExFreePoolWithTag(kvFullInfo, MINADAPTER_POOLTAG);
}
return ntStatus;
}
-//=============================================================================
-#pragma code_seg("PAGE")
-GUID
-BthHfpDevice::GetContainerId()
-{
- PAGED_CODE();
- DPF_ENTER(("[BthHfpDevice::GetContainerId]"));
-
- return m_Descriptor->ContainerId;
-}
-
-//=============================================================================
-#pragma code_seg("PAGE")
-VOID
-BthHfpDevice::SetSpeakerVolumeHandler
-(
- _In_opt_ PFNEVENTNOTIFICATION EventHandler,
- _In_opt_ PVOID EventHandlerContext
-)
- {
- PAGED_CODE();
- DPF_ENTER(("[BthHfpDevice::SetSpeakerVolumeHandler]"));
-
- ASSERT(EventHandler == NULL || m_SpeakerVolumeCallback.Handler == NULL);
-
- m_SpeakerVolumeCallback.Handler = EventHandler; // weak ref.
- m_SpeakerVolumeCallback.Context = EventHandlerContext;
- }
-
-//=============================================================================
-#pragma code_seg("PAGE")
-VOID
-BthHfpDevice::SetSpeakerConnectionStatusHandler
-(
- _In_opt_ PFNEVENTNOTIFICATION EventHandler,
- _In_opt_ PVOID EventHandlerContext
-)
-{
- PAGED_CODE();
- DPF_ENTER(("[BthHfpDevice::SetSpeakerConnectionStatusHandler]"));
-
- ASSERT(EventHandler == NULL || m_SpeakerConnectionStatusCallback.Handler == NULL);
-
- m_SpeakerConnectionStatusCallback.Handler = EventHandler; // weak ref.
- m_SpeakerConnectionStatusCallback.Context = EventHandlerContext;
-}
-
-//=============================================================================
-#pragma code_seg("PAGE")
-VOID
-BthHfpDevice::SetMicVolumeHandler
-(
- _In_opt_ PFNEVENTNOTIFICATION EventHandler,
- _In_opt_ PVOID EventHandlerContext
-)
-{
- PAGED_CODE();
- DPF_ENTER(("[BthHfpDevice::SetMicVolumeHandler]"));
-
- ASSERT(EventHandler == NULL || m_MicVolumeCallback.Handler == NULL);
-
- m_MicVolumeCallback.Handler = EventHandler; // weak ref.
- m_MicVolumeCallback.Context = EventHandlerContext;
-}
-
-//=============================================================================
-#pragma code_seg("PAGE")
-VOID
-BthHfpDevice::SetMicConnectionStatusHandler
-(
- _In_opt_ PFNEVENTNOTIFICATION EventHandler,
- _In_opt_ PVOID EventHandlerContext
-)
-{
- PAGED_CODE();
- DPF_ENTER(("[BthHfpDevice::SetMicConnectionStatusHandler]"));
-
- ASSERT(EventHandler == NULL || m_MicConnectionStatusCallback.Handler == NULL);
-
- m_MicConnectionStatusCallback.Handler = EventHandler; // weak ref.
- m_MicConnectionStatusCallback.Context = EventHandlerContext;
-}
-
-//=============================================================================
-#pragma code_seg("PAGE")
-BOOL
-BthHfpDevice::IsNRECSupported()
-{
- PAGED_CODE();
- DPF_ENTER(("[BthHfpDevice::IsNRECSupported]"));
-
- return m_Descriptor->SupportsNREC;
-}
-
-//=============================================================================
-#pragma code_seg("PAGE")
-BOOL
-BthHfpDevice::GetNRECDisableStatus()
-{
- PAGED_CODE();
- DPF_ENTER(("[BthHfpDevice::GetNRECDisableStatus]"));
-
- // Return TRUE if HF wants to disable the NREC on the AG.
- return (BOOL)InterlockedCompareExchange(&m_NRECDisableStatusLong, 0, 0);
-}
-
-//
-// Helper functions.
-//
-
-//=============================================================================
-#pragma code_seg()
NTSTATUS
-BthHfpDevice::SendIoCtrlAsynchronously
-(
- _In_ WDFREQUEST Request,
- _In_ ULONG IoControlCode,
- _In_opt_ WDFMEMORY MemIn,
- _In_opt_ WDFMEMORY MemOut,
- _In_ PFN_WDF_REQUEST_COMPLETION_ROUTINE CompletionRoutine,
- _In_ WDFCONTEXT Context
-)
+CopyRegistryKey(HANDLE _hSourceKey, HANDLE _hDestinationKey, BOOL _bOverwrite = FALSE)
/*++
Routine Description:
- This function aynchronously sends an I/O Ctrl request to the BTH HFP
- SCO Bypass device.
-
---*/
-{
- DPF_ENTER(("[BthHfpDevice::SendIoCtrlAsynchronously]"));
-
- NTSTATUS ntStatus = STATUS_SUCCESS;
- BOOLEAN fSent = FALSE;
-
- //
- // Format and send the request.
- //
- ntStatus = WdfIoTargetFormatRequestForIoctl(
- m_WdfIoTarget,
- Request,
- IoControlCode,
- MemIn,
- NULL,
- MemOut,
- NULL);
-
- IF_FAILED_ACTION_JUMP(
- ntStatus,
- DPF(D_ERROR, ("SendIoCtrlAsynchronously: WdfIoTargetFormatRequestForIoctl(0x%x) failed, 0x%x", IoControlCode, ntStatus)),
- Done);
-
- WdfRequestSetCompletionRoutine(
- Request,
- CompletionRoutine,
- Context);
-
- fSent = WdfRequestSend(Request, m_WdfIoTarget, NULL); // no options.
- if (fSent == FALSE)
- {
- ntStatus = WdfRequestGetStatus(Request);
- if (NT_SUCCESS(ntStatus))
- {
- ntStatus = STATUS_INVALID_DEVICE_STATE;
- }
-
- DPF(D_ERROR, ("SendIoCtrlAsynchronously: WdfRequestSend(0x%x) failed, 0x%x", IoControlCode, ntStatus));
- goto Done;
- }
-
- //
- // All Done.
- //
- ntStatus = STATUS_SUCCESS;
-
-Done:
-
- return ntStatus;
-}
-
-//=============================================================================
-#pragma code_seg("PAGE")
-NTSTATUS
-BthHfpDevice::SendIoCtrlSynchronously
-(
- _In_opt_ WDFREQUEST Request,
- _In_ ULONG IoControlCode,
- _In_ ULONG InLength,
- _In_ ULONG OutLength,
- _When_(InLength > 0 || OutLength > 0, _In_)
- _When_(InLength == 0 && OutLength == 0, _In_opt_)
- PVOID Buffer
-)
-/*++
+ This method recursively copies the registry values in _hSourceKey to _hDestinationKey.
+ Set _bOverwrite to indicate whether the first level values are copied or not.
+ Normal use is to set false for the initial call, and then all sub paths will be copied.
-Routine Description:
+Return Value:
- This function inits and synchronously sends an I/O Ctrl request to the BTH HFP
- SCO Bypass device.
+ NT status code.
--*/
{
+ NTSTATUS ntStatus = STATUS_UNSUCCESSFUL;
+ PKEY_BASIC_INFORMATION kBasicInfo = NULL;
+ ULONG ulBasicInfoLength = 0;
+ ULONG ulBasicInfoResultLength = 0;
+ ULONG ulDisposition = 0;
+ PWSTR pwstrKeyName = NULL;
+ UNICODE_STRING strKeyName;
+ OBJECT_ATTRIBUTES hCurrentSourceKeyAttributes;
+ OBJECT_ATTRIBUTES hNewDestinationKeyAttributes;
+ HANDLE hCurrentSourceKey = NULL;
+ HANDLE hNewDestinationKey = NULL;
PAGED_CODE();
- DPF_ENTER(("[BthHfpDevice::SendIoCtrlSynchronously]"));
-
- NTSTATUS ntStatus = STATUS_SUCCESS;
- PWDF_MEMORY_DESCRIPTOR memInPtr = NULL;
- PWDF_MEMORY_DESCRIPTOR memOutPtr = NULL;
- WDF_MEMORY_DESCRIPTOR memIn;
- WDF_MEMORY_DESCRIPTOR memOut;
- WDF_REQUEST_SEND_OPTIONS reqOpts;
-
- //
- // Format and send the request.
- //
- if (InLength)
- {
- WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&memIn, Buffer, InLength);
- memInPtr = &memIn;
- }
-
- if (OutLength)
- {
- WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&memOut, Buffer, OutLength);
- memOutPtr = &memOut;
- }
-
- WDF_REQUEST_SEND_OPTIONS_INIT(
- &reqOpts,
- WDF_REQUEST_SEND_OPTION_TIMEOUT |
- WDF_REQUEST_SEND_OPTION_SYNCHRONOUS);
-
- reqOpts.Timeout = WDF_REL_TIMEOUT_IN_SEC(BTH_HFP_SYNC_REQ_TIMEOUT_IN_SEC);
-
- ntStatus = WdfIoTargetSendIoctlSynchronously(
- m_WdfIoTarget,
- Request,
- IoControlCode,
- memInPtr,
- memOutPtr,
- &reqOpts,
- NULL); // bytes returned.
+ // Validate parameters
+ IF_TRUE_ACTION_JUMP(_hSourceKey == nullptr, ntStatus = STATUS_INVALID_PARAMETER, Exit);
+ IF_TRUE_ACTION_JUMP(_hDestinationKey == nullptr, ntStatus = STATUS_INVALID_PARAMETER, Exit);
- IF_FAILED_ACTION_JUMP(
- ntStatus,
- DPF(D_VERBOSE, ("SendIoCtrlSynchronously: WdfIoTargetSendIoctlSynchronously(0x%x) failed, 0x%x", IoControlCode, ntStatus)),
- Done);
-
-Done:
-
- return ntStatus;
-}
+ // Allocate the KEY_BASIC_INFORMATION structure
+ ulBasicInfoLength = sizeof(KEY_BASIC_INFORMATION) + MAX_DEVICE_REG_KEY_LENGTH;
+ kBasicInfo = (PKEY_BASIC_INFORMATION)ExAllocatePoolWithTag(NonPagedPoolNx, ulBasicInfoLength, MINADAPTER_POOLTAG);
+ IF_TRUE_ACTION_JUMP(kBasicInfo == NULL, ntStatus = STATUS_INSUFFICIENT_RESOURCES, Exit);
-//=============================================================================
-#pragma code_seg()
-VOID
-BthHfpDevice::EvtBthHfpDeviceNotificationStatusWorkItem
-(
- _In_ WDFWORKITEM WorkItem
-)
-/*++
-
-Routine Description:
-
- The function processes status notification updates.
-
-Arguments:
-
- WorkItem - WDF work-item object.
-
---*/
-{
- DPF_ENTER(("[BthHfpDevice::EvtBthHfpDeviceNotificationStatusWorkItem]"));
-
- NTSTATUS ntStatus = STATUS_SUCCESS;
- BthHfpDevice * This;
- KIRQL oldIrql;
-
- if (WorkItem == NULL)
- {
- return;
- }
-
- This = GetBthHfpDeviceNotificationWorkItemContext(WorkItem)->BthHfpDevice;
- ASSERT(This != NULL);
-
- for (;;)
+ ntStatus = STATUS_SUCCESS;
+ // Iterate over each key and copy it
+ for (UINT i = 0; NT_SUCCESS(ntStatus); i++)
{
- BOOL resend = TRUE;
- WDFREQUEST req = NULL;
- BthHfpDeviceNotificationReqContext * reqCtx;
- WDF_REQUEST_COMPLETION_PARAMS params;
+ // Enumerate the next key
+ ntStatus = ZwEnumerateKey(_hSourceKey, i, KeyBasicInformation, kBasicInfo, ulBasicInfoLength, &ulBasicInfoResultLength);
- //
- // Retrieve a task.
- //
- KeAcquireSpinLock(&This->m_Lock, &oldIrql);
- req = (WDFREQUEST) WdfCollectionGetFirstItem(This->m_ReqCollection);
- if (req != NULL)
- {
- WdfCollectionRemove(This->m_ReqCollection, req);
- }
- KeReleaseSpinLock(&This->m_Lock, oldIrql);
+ // Jump out of this loop if there are no more keys
+ IF_TRUE_ACTION_JUMP(ntStatus == STATUS_NO_MORE_ENTRIES, ntStatus = STATUS_SUCCESS, copy_values);
- if (req == NULL)
+ // Handle incorrect buffer size
+ if (ntStatus == STATUS_BUFFER_TOO_SMALL || ntStatus == STATUS_BUFFER_OVERFLOW)
{
- break;
- }
-
- //
- // Get request parameters and context.
- //
- WDF_REQUEST_COMPLETION_PARAMS_INIT(&params);
- WdfRequestGetCompletionParams(req, &params);
+ // Free and re-allocate the KEY_BASIC_INFORMATION structure with the correct size.
+ ExFreePoolWithTag(kBasicInfo, MINADAPTER_POOLTAG);
+ ulBasicInfoLength = ulBasicInfoResultLength;
+ kBasicInfo = (PKEY_BASIC_INFORMATION)ExAllocatePoolWithTag(NonPagedPoolNx, ulBasicInfoLength, MINADAPTER_POOLTAG);
+ IF_TRUE_ACTION_JUMP(kBasicInfo == NULL, ntStatus = STATUS_INSUFFICIENT_RESOURCES, loop_exit);
- reqCtx = GetBthHfpDeviceNotificationReqContext(req);
- ASSERT(reqCtx != NULL);
+ // Try to enumerate the current key again.
+ ntStatus = ZwEnumerateKey(_hSourceKey, i, KeyBasicInformation, kBasicInfo, ulBasicInfoLength, &ulBasicInfoResultLength);
- //
- // Handle this notification.
- //
- if (NT_SUCCESS(params.IoStatus.Status))
- {
- switch(params.Parameters.Ioctl.IoControlCode)
- {
- case IOCTL_BTHHFP_DEVICE_GET_NRECDISABLE_STATUS_UPDATE:
- {
- InterlockedExchange(&This->m_NRECDisableStatusLong, (LONG)reqCtx->Buffer.BoolStatus);
- }
- break;
-
- case IOCTL_BTHHFP_SPEAKER_GET_VOLUME_STATUS_UPDATE:
- {
- LONG oldVolume;
-
- oldVolume = InterlockedExchange(&This->m_SpeakerVolumeLevel, reqCtx->Buffer.Volume);
- if (reqCtx->Buffer.Volume != oldVolume)
- {
- // Notify audio miniport about this change.
- if (This->m_SpeakerVolumeCallback.Handler != NULL)
- {
- This->m_SpeakerVolumeCallback.Handler(
- This->m_SpeakerVolumeCallback.Context);
- }
- }
- }
- break;
-
- case IOCTL_BTHHFP_MIC_GET_VOLUME_STATUS_UPDATE:
- {
- LONG oldVolume;
-
- oldVolume = InterlockedExchange(&This->m_MicVolumeLevel, reqCtx->Buffer.Volume);
- if (reqCtx->Buffer.Volume != oldVolume)
- {
- // Notify audio miniport about this change.
- if (This->m_MicVolumeCallback.Handler != NULL)
- {
- This->m_MicVolumeCallback.Handler(
- This->m_MicVolumeCallback.Context);
- }
- }
- }
- break;
-
- case IOCTL_BTHHFP_DEVICE_GET_CONNECTION_STATUS_UPDATE:
- {
- BOOL oldStatus;
-
- oldStatus = (BOOL)InterlockedExchange(&This->m_ConnectionStatusLong, (LONG)reqCtx->Buffer.BoolStatus);
- if (reqCtx->Buffer.BoolStatus != oldStatus)
- {
- // Notify audio miniport about this change.
- if (This->m_SpeakerConnectionStatusCallback.Handler != NULL)
- {
- This->m_SpeakerConnectionStatusCallback.Handler(
- This->m_SpeakerConnectionStatusCallback.Context);
- }
-
- if (This->m_MicConnectionStatusCallback.Handler != NULL)
- {
- This->m_MicConnectionStatusCallback.Handler(
- This->m_MicConnectionStatusCallback.Context);
- }
- }
- }
- break;
-
- default:
- // This should never happen.
- resend = FALSE;
- DPF(D_ERROR, ("EvtBthHfpDeviceNotificationStatusWorkItem: invalid request ctrl 0x%x",
- params.Parameters.Ioctl.IoControlCode));
- break;
- }
+ // Jump out of this loop if there are no more keys
+ IF_TRUE_ACTION_JUMP(ntStatus == STATUS_NO_MORE_ENTRIES, ntStatus = STATUS_SUCCESS, copy_values);
+ IF_FAILED_JUMP(ntStatus, loop_exit);
}
-
- if (resend)
+ else
{
- WDF_REQUEST_REUSE_PARAMS reuseParams;
+ IF_FAILED_JUMP(ntStatus, loop_exit);
+ }
- WDF_REQUEST_REUSE_PARAMS_INIT(
- &reuseParams,
- WDF_REQUEST_REUSE_NO_FLAGS,
- STATUS_SUCCESS);
+ // Allocate the key name string
+ pwstrKeyName = (PWSTR)ExAllocatePoolWithTag(NonPagedPoolNx, kBasicInfo->NameLength + sizeof(WCHAR), MINADAPTER_POOLTAG);
+ IF_TRUE_ACTION_JUMP(kBasicInfo == NULL, ntStatus = STATUS_INSUFFICIENT_RESOURCES, loop_exit);
- ntStatus = WdfRequestReuse(req, &reuseParams);
- if (!NT_SUCCESS(ntStatus))
- {
- DPF(D_ERROR, ("EvtBthHfpDeviceNotificationStatusWorkItem: WdfRequestReuse failed, 0x%x", ntStatus));
- break;
- }
+ // Copy the key name from the basic information struct
+ RtlStringCbCopyNW(pwstrKeyName, kBasicInfo->NameLength + sizeof(WCHAR), kBasicInfo->Name, kBasicInfo->NameLength);
- // Resend status notification request.
- reqCtx->Buffer.bImmediate = FALSE;
+ // Make sure the string is null terminated
+ pwstrKeyName[(kBasicInfo->NameLength) / sizeof(WCHAR)] = 0;
- ntStatus = This->SendIoCtrlAsynchronously(
- req,
- params.Parameters.Ioctl.IoControlCode,
- reqCtx->MemIn,
- reqCtx->MemOut,
- EvtBthHfpDeviceNotificationStatusCompletion,
- This);
-
- if (!NT_SUCCESS(ntStatus))
- {
- DPF(D_ERROR, ("EvtBthHfpDeviceNotificationStatusWorkItem: SendIoCtrlAsynchronously"
- "(0x%x) failed, 0x%x",
- params.Parameters.Ioctl.IoControlCode, ntStatus));
- break;
- }
- }
- }
-}
+ // Copy the key name string to a UNICODE string
+ RtlInitUnicodeString(&strKeyName, pwstrKeyName);
-//=============================================================================
-#pragma code_seg()
-void
-BthHfpDevice::EvtBthHfpDeviceNotificationStatusCompletion
-(
- _In_ WDFREQUEST Request,
- _In_ WDFIOTARGET Target,
- _In_ PWDF_REQUEST_COMPLETION_PARAMS Params,
- _In_ WDFCONTEXT Context
-)
-{
- DPF_ENTER(("[BthHfpDevice::EvtBthHfpDeviceNotificationStatusCompletion]"));
+ // Initialize attributes to open the currently enumerated source key
+ InitializeObjectAttributes(&hCurrentSourceKeyAttributes, &strKeyName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, _hSourceKey, NULL);
- NTSTATUS ntStatus = STATUS_SUCCESS;
- BthHfpDeviceNotificationReqContext * ctx = NULL;
- BthHfpDevice * This = NULL;
- KIRQL oldIrql;
+ // Open the currently enumerated source key
+ ntStatus = ZwOpenKey(&hCurrentSourceKey, KEY_READ, &hCurrentSourceKeyAttributes);
+ IF_FAILED_ACTION_JUMP(ntStatus, ZwClose(hCurrentSourceKey), loop_exit);
- UNREFERENCED_PARAMETER(Target);
- UNREFERENCED_PARAMETER(Context);
+ // Initialize attributes to create the new destination key
+ InitializeObjectAttributes(&hNewDestinationKeyAttributes, &strKeyName, OBJ_KERNEL_HANDLE, _hDestinationKey, NULL);
- ctx = GetBthHfpDeviceNotificationReqContext(Request);
- This = ctx->BthHfpDevice;
- ASSERT(This != NULL);
+ // Create the key at the destination
+ ntStatus = ZwCreateKey(&hNewDestinationKey, KEY_WRITE, &hNewDestinationKeyAttributes, 0, NULL, REG_OPTION_NON_VOLATILE, &ulDisposition);
+ IF_FAILED_ACTION_JUMP(ntStatus, ZwClose(hCurrentSourceKey), loop_exit);
- ntStatus = Params->IoStatus.Status;
- if (ntStatus == STATUS_CANCELLED)
- {
- // BTH HFP device is shutting down. Do not re-send this request.
- goto Done;
- }
+ // Now copy the contents of the currently enumerated key to the destination
+ ntStatus = CopyRegistryKey(hCurrentSourceKey, hNewDestinationKey, TRUE);
+ IF_FAILED_JUMP(ntStatus, loop_exit);
- //
- // If something is wrong with the HFP interface, do not loop forever.
- //
- if (!NT_SUCCESS(ntStatus))
- {
- if (++ctx->Errors > BTH_HFP_NOTIFICATION_MAX_ERROR_COUNT)
+ loop_exit:
+ // Free the key name string
+ if (pwstrKeyName)
{
- // Too many errors. Do not re-send this request.
- goto Done;
+ ExFreePoolWithTag(pwstrKeyName, MINADAPTER_POOLTAG);
}
- }
- else
- {
- // reset the # of errors.
- ctx->Errors = 0;
- }
-
- //
- // Let the work-item thread process this request.
- //
- KeAcquireSpinLock(&This->m_Lock, &oldIrql);
-
- ntStatus = WdfCollectionAdd(This->m_ReqCollection, Request);
- if (NT_SUCCESS(ntStatus))
- {
- WdfWorkItemEnqueue(This->m_WorkItem);
- }
-
- KeReleaseSpinLock(&This->m_Lock, oldIrql);
-
-Done:;
-}
-
-//=============================================================================
-#pragma code_seg("PAGE")
-NTSTATUS
-BthHfpDevice::GetBthHfpDescriptor
-(
- _Out_ PBTHHFP_DESCRIPTOR2 * Descriptor
-)
-/*++
-
-Routine Description:
-
- This function synchronously gets the remote Bluetooth Hands-Free Profile SCO
- Bypass descriptor.
-
---*/
-{
- PAGED_CODE();
- DPF_ENTER(("[BthHfpDevice::GetBthHfpDescriptor]"));
-
- NTSTATUS ntStatus = STATUS_SUCCESS;
- WDFREQUEST req = NULL;
- PBTHHFP_DESCRIPTOR2 descriptor = NULL;
- ULONG length = 0;
- ULONG_PTR information = 0;
- WDF_REQUEST_REUSE_PARAMS reuseParams;
- WDF_OBJECT_ATTRIBUTES attributes;
- *Descriptor = NULL;
-
- //
- // Allocate and format a WDF request.
- //
- WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
- attributes.ParentObject = m_Adapter->GetWdfDevice();
- ntStatus = WdfRequestCreate(
- &attributes,
- m_WdfIoTarget,
- &req);
- IF_FAILED_ACTION_JUMP(
- ntStatus,
- DPF(D_ERROR, ("GetBthHfpDescriptor: WdfRequestCreate failed, 0x%x", ntStatus)),
- Done);
-
- //
- // Get the size of the buffer.
- //
- ntStatus = SendIoCtrlSynchronously(
- req,
- IOCTL_BTHHFP_DEVICE_GET_DESCRIPTOR2,
- NULL,
- NULL,
- NULL);
-
- if (ntStatus != STATUS_BUFFER_TOO_SMALL)
- {
- if (NT_SUCCESS(ntStatus))
+ // Close the current source key
+ if (hCurrentSourceKey)
{
- ntStatus = STATUS_INVALID_DEVICE_STATE;
+ ZwClose(hCurrentSourceKey);
}
- DPF(D_ERROR, ("GetBthHfpDescriptor: SendIoCtrlSynchronously(IOCTL_BTHHFP_DEVICE_GET_DESCRIPTOR2): failed, 0x%x", ntStatus));
- goto Done;
- }
-
- ntStatus = STATUS_SUCCESS;
-
- information = WdfRequestGetInformation(req);
- if (information == 0 || information > ULONG_MAX)
- {
- ntStatus = STATUS_INVALID_DEVICE_STATE;
- DPF(D_ERROR, ("GetBthHfpDescriptor: IOCTL_BTHHFP_DEVICE_GET_DESCRIPTOR2 buffer too big (%Id): 0x%x", information, ntStatus));
- goto Done;
- }
-
- length = (ULONG)information;
-
- //
- // Allocate memory needed to hold the info.
- //
- descriptor = (PBTHHFP_DESCRIPTOR2) ExAllocatePoolWithTag(NonPagedPoolNx, length, MINADAPTER_POOLTAG);
- if (descriptor == NULL)
- {
- ntStatus = STATUS_INSUFFICIENT_RESOURCES;
- }
- IF_FAILED_ACTION_JUMP(
- ntStatus,
- DPF(D_ERROR, ("GetBthHfpDescriptor: ExAllocatePoolWithTag failed, out of memory")),
- Done);
-
- //
- // Get the Bth HFP SCO Bypass descriptor.
- //
- WDF_REQUEST_REUSE_PARAMS_INIT(
- &reuseParams,
- WDF_REQUEST_REUSE_NO_FLAGS,
- STATUS_SUCCESS);
-
- ntStatus = WdfRequestReuse(req, &reuseParams);
- IF_FAILED_ACTION_JUMP(
- ntStatus,
- DPF(D_ERROR, ("GetBthHfpDescriptor: WdfRequestReuse failed, 0x%x", ntStatus)),
- Done);
-
- ntStatus = SendIoCtrlSynchronously(
- req,
- IOCTL_BTHHFP_DEVICE_GET_DESCRIPTOR2,
- NULL,
- length,
- descriptor);
- IF_FAILED_ACTION_JUMP(
- ntStatus,
- DPF(D_ERROR, ("GetBthHfpDescriptor: SendIoCtrlSynchronously(IOCTL_BTHHFP_DEVICE_GET_DESCRIPTOR2) failed, 0x%x", ntStatus)),
- Done);
-
- //
- // All done.
- //
- *Descriptor = descriptor;
- ntStatus = STATUS_SUCCESS;
-
-Done:
- if (!NT_SUCCESS(ntStatus))
- {
- if (descriptor != NULL)
+ // Close the new destination key
+ if (hNewDestinationKey)
{
- ExFreePoolWithTag(descriptor, MINADAPTER_POOLTAG);
+ ZwClose(hNewDestinationKey);
}
- }
- if (req != NULL)
- {
- WdfObjectDelete(req);
- req = NULL;
+ // Bail if anything failed
+ IF_FAILED_JUMP(ntStatus, Exit);
}
- return ntStatus;
-}
-
-//=============================================================================
-#pragma code_seg()
-NTSTATUS
-BthHfpDevice::EnableBthHfpNrecDisableStatusNotification()
-/*++
-
-Routine Description:
-
- This function registers for Bluetooth Hands-Free Profile SCO Bypass NREC-Disable
- status change notification.
-
---*/
-{
- DPF_ENTER(("[BthHfpDevice::EnableBthHfpNrecDisableStatusNotification]"));
-
- NTSTATUS ntStatus = STATUS_SUCCESS;
- BthHfpDeviceNotificationReqContext * ctx = NULL;
-
- ctx = GetBthHfpDeviceNotificationReqContext(m_NRECDisableStatusReq);
-
- //
- // This is a notification request.
- //
- ctx->Buffer.bImmediate = FALSE;
-
- //
- // Get the Bth HFP SCO Bypass NREC-Disable status (async).
- //
- ntStatus = SendIoCtrlAsynchronously(
- m_NRECDisableStatusReq,
- IOCTL_BTHHFP_DEVICE_GET_NRECDISABLE_STATUS_UPDATE,
- ctx->MemIn,
- ctx->MemOut,
- EvtBthHfpDeviceNotificationStatusCompletion,
- this);
-
- IF_FAILED_ACTION_JUMP(
- ntStatus,
- DPF(D_ERROR, ("EnableBthHfpNrecDisableStatusNotification: SendIoCtrlAsynchronously(IOCTL_BTHHFP_DEVICE_GET_NRECDISABLE_STATUS_UPDATE) failed, 0x%x", ntStatus)),
- Done);
-
- //
- // All done.
- //
- ntStatus = STATUS_SUCCESS;
-
-Done:
-
- return ntStatus;
-}
-
-//=============================================================================
-#pragma code_seg("PAGE")
-NTSTATUS
-BthHfpDevice::GetBthHfpVolumePropertyValues
-(
- _In_ ULONG Length,
- _Out_ PKSPROPERTY_VALUES * PropValues
-)
-/*++
-
-Routine Description:
-
- This function synchronously gets the remote Bluetooth Hands-Free Profile SCO
- Bypass volume values.
-
---*/
-{
- PAGED_CODE();
- DPF_ENTER(("[BthHfpDevice::GetBthHfpVolumePropertyValues]"));
-
- NTSTATUS ntStatus = STATUS_SUCCESS;
- PKSPROPERTY_VALUES propValues = NULL;
-
- *PropValues = NULL;
-
- //
- // Allocate memory.
- //
- propValues = (PKSPROPERTY_VALUES) ExAllocatePoolWithTag(NonPagedPoolNx, Length, MINADAPTER_POOLTAG);
- if (propValues == NULL)
+copy_values:
+ // Copy the values
+ if (_bOverwrite)
{
- ntStatus = STATUS_INSUFFICIENT_RESOURCES;
+ ntStatus = CopyRegistryValues(_hSourceKey, _hDestinationKey);
+ IF_FAILED_JUMP(ntStatus, Exit);
}
- IF_FAILED_ACTION_JUMP(
- ntStatus,
- DPF(D_ERROR, ("GetBthHfpVolumePropertyValues: ExAllocatePoolWithTag failed, out of memory")),
- Done);
-
- //
- // Get the Bth HFP SCO Bypass descriptor.
- //
- ntStatus = SendIoCtrlSynchronously(
- NULL,
- IOCTL_BTHHFP_DEVICE_GET_VOLUMEPROPERTYVALUES,
- 0,
- Length,
- propValues);
- IF_FAILED_ACTION_JUMP(
- ntStatus,
- DPF(D_ERROR, ("GetBthHfpVolumePropertyValues: SendIoCtrlSynchronously(IOCTL_BTHHFP_DEVICE_GET_VOLUMEPROPERTYVALUES) failed, 0x%x", ntStatus)),
- Done);
-
- //
- // All done.
- //
- *PropValues = propValues;
- ntStatus = STATUS_SUCCESS;
-
-Done:
- if (!NT_SUCCESS(ntStatus))
+Exit:
+ // Free the basic information structure
+ if (kBasicInfo)
{
- if (propValues != NULL)
- {
- ExFreePoolWithTag(propValues, MINADAPTER_POOLTAG);
- }
+ ExFreePoolWithTag(kBasicInfo, MINADAPTER_POOLTAG);
}
-
- return ntStatus;
-}
-
-//=============================================================================
-#pragma code_seg("PAGE")
-NTSTATUS
-BthHfpDevice::SetBthHfpSpeakerVolume
-(
- _In_ LONG Volume
-)
-/*++
-
-Routine Description:
-
- This function synchronously sets the remote Bluetooth Hands-Free Profile SCO
- Bypass speaker volume.
-
---*/
-{
- PAGED_CODE();
- DPF_ENTER(("[BthHfpDevice::SetBthHfpSpeakerVolume]"));
-
- NTSTATUS ntStatus = STATUS_SUCCESS;
-
- //
- // Get the Bth HFP SCO Bypass speaker volume.
- //
- ntStatus = SendIoCtrlSynchronously(
- NULL,
- IOCTL_BTHHFP_SPEAKER_SET_VOLUME,
- sizeof(Volume),
- 0,
- &Volume);
-
- IF_FAILED_ACTION_JUMP(
- ntStatus,
- DPF(D_ERROR, ("SetBthHfpSpeakerVolume: SendIoCtrlSynchronously(IOCTL_BTHHFP_SPEAKER_SET_VOLUME) failed, 0x%x", ntStatus)),
- Done);
-
- //
- // All done.
- //
- ntStatus = STATUS_SUCCESS;
-
-Done:
-
- return ntStatus;
-}
-
-//=============================================================================
-#pragma code_seg("PAGE")
-NTSTATUS
-BthHfpDevice::GetBthHfpSpeakerVolume
-(
- _Out_ LONG * Volume
-)
-/*++
-
-Routine Description:
-
- This function synchronously gets the remote Bluetooth Hands-Free Profile SCO
- Bypass speaker volume.
-
---*/
-{
- PAGED_CODE();
- DPF_ENTER(("[BthHfpDevice::GetBthHfpSpeakerVolume]"));
-
- NTSTATUS ntStatus = STATUS_SUCCESS;
- BthHfpDeviceNotificationBuffer buffer = {0};
-
- *Volume = 0;
-
- buffer.bImmediate = TRUE;
-
- //
- // Get the Bth HFP SCO Bypass speaker volume.
- //
- ntStatus = SendIoCtrlSynchronously(
- NULL,
- IOCTL_BTHHFP_SPEAKER_GET_VOLUME_STATUS_UPDATE,
- sizeof(buffer.bImmediate),
- sizeof(buffer.Volume),
- &buffer);
-
- IF_FAILED_ACTION_JUMP(
- ntStatus,
- DPF(D_ERROR, ("GetBthHfpSpeakerVolume: SendIoCtrlSynchronously(IOCTL_BTHHFP_SPEAKER_GET_VOLUME_STATUS_UPDATE) failed, 0x%x", ntStatus)),
- Done);
-
- //
- // All done.
- //
- *Volume = buffer.Volume;
- ntStatus = STATUS_SUCCESS;
-
-Done:
-
- return ntStatus;
-}
-
-//=============================================================================
-#pragma code_seg()
-NTSTATUS
-BthHfpDevice::EnableBthHfpSpeakerVolumeStatusNotification()
-/*++
-
-Routine Description:
-
- This function registers for Bluetooth Hands-Free Profile SCO Bypass speaker
- volume change notification.
-
---*/
-{
- DPF_ENTER(("[BthHfpDevice::EnableBthHfpSpeakerVolumeStatusNotification]"));
-
- NTSTATUS ntStatus = STATUS_SUCCESS;
- BthHfpDeviceNotificationReqContext * ctx = NULL;
-
- ctx = GetBthHfpDeviceNotificationReqContext(m_SpeakerVolumeReq);
-
- //
- // This is a notification request.
- //
- ctx->Buffer.bImmediate = FALSE;
-
- //
- // Register for speaker volume updates.
- //
- ntStatus = SendIoCtrlAsynchronously(
- m_SpeakerVolumeReq,
- IOCTL_BTHHFP_SPEAKER_GET_VOLUME_STATUS_UPDATE,
- ctx->MemIn,
- ctx->MemOut,
- EvtBthHfpDeviceNotificationStatusCompletion,
- this);
-
- IF_FAILED_ACTION_JUMP(
- ntStatus,
- DPF(D_ERROR, ("EnableBthHfpSpeakerVolumeStatusNotification: SendIoCtrlAsynchronously(IOCTL_BTHHFP_SPEAKER_GET_VOLUME_STATUS_UPDATE) failed, 0x%x", ntStatus)),
- Done);
-
- //
- // All done.
- //
- ntStatus = STATUS_SUCCESS;
-
-Done:
-
return ntStatus;
}
-//=============================================================================
-#pragma code_seg("PAGE")
-NTSTATUS
-BthHfpDevice::SetBthHfpMicVolume
-(
- _In_ LONG Volume
-)
-/*++
-
-Routine Description:
-
- This function synchronously sets the remote Bluetooth Hands-Free Profile SCO
- Bypass mic volume.
-
---*/
-{
- PAGED_CODE();
- DPF_ENTER(("[BthHfpDevice::SetBthHfpMicVolume]"));
-
- NTSTATUS ntStatus = STATUS_SUCCESS;
-
- //
- // Get the Bth HFP SCO Bypass mic volume.
- //
- ntStatus = SendIoCtrlSynchronously(
- NULL,
- IOCTL_BTHHFP_MIC_SET_VOLUME,
- sizeof(Volume),
- 0,
- &Volume);
-
- IF_FAILED_ACTION_JUMP(
- ntStatus,
- DPF(D_ERROR, ("SetBthHfpMicVolume: SendIoCtrlSynchronously(IOCTL_BTHHFP_MIC_SET_VOLUME) failed, 0x%x", ntStatus)),
- Done);
-
- //
- // All done.
- //
- ntStatus = STATUS_SUCCESS;
-
-Done:
-
- return ntStatus;
-}
-//=============================================================================
-#pragma code_seg("PAGE")
-NTSTATUS
-BthHfpDevice::GetBthHfpMicVolume
+NTSTATUS CAdapterCommon::MigrateDeviceInterfaceTemplateParameters
(
- _Out_ LONG * Volume
+ _In_ PUNICODE_STRING SymbolicLinkName,
+ _In_opt_ PCWSTR TemplateReferenceString
)
/*++
Routine Description:
- This function synchronously gets the remote Bluetooth Hands-Free Profile SCO
- Bypass mic volume.
-
---*/
-{
- PAGED_CODE();
- DPF_ENTER(("[BthHfpDevice::GetBthHfpMicVolume]"));
-
- NTSTATUS ntStatus = STATUS_SUCCESS;
- BthHfpDeviceNotificationBuffer buffer = {0};
-
- *Volume = 0;
-
- buffer.bImmediate = TRUE;
-
- //
- // Get the Bth HFP SCO Bypass mic volume.
- //
- ntStatus = SendIoCtrlSynchronously(
- NULL,
- IOCTL_BTHHFP_MIC_GET_VOLUME_STATUS_UPDATE,
- sizeof(buffer.bImmediate),
- sizeof(buffer.Volume),
- &buffer);
-
- IF_FAILED_ACTION_JUMP(
- ntStatus,
- DPF(D_ERROR, ("GetBthHfpMicVolume: SendIoCtrlSynchronously(IOCTL_BTHHFP_MIC_GET_VOLUME_STATUS_UPDATE) failed, 0x%x", ntStatus)),
- Done);
-
- //
- // All done.
- //
- *Volume = buffer.Volume;
- ntStatus = STATUS_SUCCESS;
-
-Done:
-
- return ntStatus;
-}
-
-//=============================================================================
-#pragma code_seg()
-NTSTATUS
-BthHfpDevice::EnableBthHfpMicVolumeStatusNotification()
-/*++
-
-Routine Description:
-
- This function registers for Bluetooth Hands-Free Profile SCO Bypass mic
- volume change notification.
-
---*/
-{
- DPF_ENTER(("[BthHfpDevice::EnableBthHfpMicVolumeStatusNotification]"));
-
- NTSTATUS ntStatus = STATUS_SUCCESS;
- BthHfpDeviceNotificationReqContext * ctx = NULL;
-
- ctx = GetBthHfpDeviceNotificationReqContext(m_MicVolumeReq);
-
- //
- // This is a notification request.
- //
- ctx->Buffer.bImmediate = FALSE;
-
- //
- // Register for mic volume updates.
- //
- ntStatus = SendIoCtrlAsynchronously(
- m_MicVolumeReq,
- IOCTL_BTHHFP_MIC_GET_VOLUME_STATUS_UPDATE,
- ctx->MemIn,
- ctx->MemOut,
- EvtBthHfpDeviceNotificationStatusCompletion,
- this);
-
- IF_FAILED_ACTION_JUMP(
- ntStatus,
- DPF(D_ERROR, ("EnableBthHfpMicVolumeStatusNotification: SendIoCtrlAsynchronously(IOCTL_BTHHFP_MIC_GET_VOLUME_STATUS_UPDATE) failed, 0x%x", ntStatus)),
- Done);
-
- //
- // All done.
- //
- ntStatus = STATUS_SUCCESS;
-
-Done:
-
- return ntStatus;
-}
-
-//=============================================================================
-#pragma code_seg("PAGE")
-NTSTATUS
-BthHfpDevice::GetBthHfpConnectionStatus
-(
- _Out_ BOOL * ConnectionStatus
-)
-/*++
-
-Routine Description:
-
- This function synchronously gets the remote Bluetooth Hands-Free Profile SCO
- Bypass connection status.
-
---*/
-{
- PAGED_CODE();
- DPF_ENTER(("[BthHfpDevice::GetBthHfpConnectionStatus]"));
-
- NTSTATUS ntStatus = STATUS_SUCCESS;
- BOOL bValue = TRUE; // In: bImmediate, Out: value.
-
- *ConnectionStatus = 0;
-
- //
- // Get the Bth HFP SCO Bypass connection status.
- //
- ntStatus = SendIoCtrlSynchronously(
- NULL,
- IOCTL_BTHHFP_DEVICE_GET_CONNECTION_STATUS_UPDATE,
- sizeof(bValue),
- sizeof(bValue),
- &bValue);
-
- IF_FAILED_ACTION_JUMP(
- ntStatus,
- DPF(D_ERROR, ("GetBthHfpConnectionStatus: SendIoCtrlSynchronously(IOCTL_BTHHFP_DEVICE_GET_CONNECTION_STATUS_UPDATE) failed, 0x%x", ntStatus)),
- Done);
-
- //
- // All done.
- //
- *ConnectionStatus = bValue;
- ntStatus = STATUS_SUCCESS;
-
-Done:
-
- return ntStatus;
-}
-
-//=============================================================================
-#pragma code_seg()
-NTSTATUS
-BthHfpDevice::EnableBthHfpConnectionStatusNotification()
-/*++
-
-Routine Description:
-
- This function registers for Bluetooth Hands-Free Profile SCO Bypass
- connection status notification.
-
---*/
-{
- DPF_ENTER(("[BthHfpDevice::EnableBthHfpConnectionStatusNotification]"));
-
- NTSTATUS ntStatus = STATUS_SUCCESS;
- BthHfpDeviceNotificationReqContext * ctx = NULL;
-
- ctx = GetBthHfpDeviceNotificationReqContext(m_ConnectionReq);
-
- //
- // Make sure this obj is alive while the IRP is active.
- //
- ctx->Buffer.bImmediate = FALSE;
-
- //
- // Get the Bth HFP SCO Bypass connection status.
- //
- ntStatus = SendIoCtrlAsynchronously(
- m_ConnectionReq,
- IOCTL_BTHHFP_DEVICE_GET_CONNECTION_STATUS_UPDATE,
- ctx->MemIn,
- ctx->MemOut,
- EvtBthHfpDeviceNotificationStatusCompletion,
- this);
-
- IF_FAILED_ACTION_JUMP(
- ntStatus,
- DPF(D_ERROR, ("EnableBthHfpConnectionStatusNotification: SendIoCtrlAsynchronously(IOCTL_BTHHFP_DEVICE_GET_CONNECTION_STATUS_UPDATE) failed, 0x%x", ntStatus)),
- Done);
-
- //
- // All done.
- //
- ntStatus = STATUS_SUCCESS;
-
-Done:
-
- return ntStatus;
-}
-
-//=============================================================================
-#pragma code_seg("PAGE")
-NTSTATUS
-BthHfpDevice::SetBthHfpConnect()
-/*++
-
-Routine Description:
-
- This function synchronously requests a Bluetooth Hands-Free Profile level
- connection to the paired Bluetooth device.
-
- This request initiates the Service Level Connection establishment procedure
- and completes without waiting for the connection procedure to complete.
- Connection status can be determined using IOCTL_BTHHFP_GET_CONNECTION_STATUS_UPDATE.
-
---*/
-{
- PAGED_CODE();
- DPF_ENTER(("[BthHfpDevice::SetBthHfpConnect]"));
-
- NTSTATUS ntStatus = STATUS_SUCCESS;
-
- ntStatus = SendIoCtrlSynchronously(
- NULL,
- IOCTL_BTHHFP_DEVICE_REQUEST_CONNECT,
- 0,
- 0,
- NULL);
-
- IF_FAILED_ACTION_JUMP(
- ntStatus,
- DPF(D_ERROR, ("SetBthHfpConnect: SendIoCtrlSynchronously(IOCTL_BTHHFP_DEVICE_REQUEST_CONNECT) failed, 0x%x", ntStatus)),
- Done);
-
- //
- // All done.
- //
- ntStatus = STATUS_SUCCESS;
-
-Done:
-
- return ntStatus;
-}
-
-//=============================================================================
-#pragma code_seg("PAGE")
-NTSTATUS
-BthHfpDevice::SetBthHfpDisconnect()
-/*++
-
-Routine Description:
-
- This function synchronously requests a Bluetooth Hands-Free Profile level
- connection to the paired Bluetooth device.
-
- This request initiates disconnection of the Service Level Connection and
- completes without waiting for the disconnection to complete. Connection
- status can be determined using IOCTL_BTHHFP_GET_CONNECTION_STATUS_UPDATE.
-
---*/
-{
- PAGED_CODE();
- DPF_ENTER(("[BthHfpDevice::SetBthHfpDisconnect]"));
-
- NTSTATUS ntStatus = STATUS_SUCCESS;
-
- ntStatus = SendIoCtrlSynchronously(
- NULL,
- IOCTL_BTHHFP_DEVICE_REQUEST_DISCONNECT,
- 0,
- 0,
- NULL);
-
- IF_FAILED_ACTION_JUMP(
- ntStatus,
- DPF(D_ERROR, ("SetBthHfpDisconnect: SendIoCtrlSynchronously(IOCTL_BTHHFP_DEVICE_REQUEST_DISCONNECT) failed, 0x%x", ntStatus)),
- Done);
-
- //
- // All done.
- //
- ntStatus = STATUS_SUCCESS;
+ This method copies all of the properties from the template interface,
+ which is specified in the inf, to the actual interface being used which
+ may be dynamically generated at run time. This allows for a driver
+ to reuse a single inf entry for multiple audio endpoints. The primary
+ purpose for this is to allow for sideband audio endpoints to dynamically
+ generate the reference string at run time, tied to the peripheral connected,
+ while still having a simple static inf entry for setting up apo's or other
+ parameters.
-Done:
-
- return ntStatus;
-}
-
-//=============================================================================
-#pragma code_seg()
-void
-BthHfpDevice::EvtBthHfpDeviceStreamStatusCompletion
-(
- _In_ WDFREQUEST Request,
- _In_ WDFIOTARGET Target,
- _In_ PWDF_REQUEST_COMPLETION_PARAMS Params,
- _In_ WDFCONTEXT Context
-)
-/*++
+ For example, if you have an interface in your inf defined with reference string
+ "SpeakerWave". At runtime you could generate "SpeakerWave-1234ABCDE", and specify
+ "SpeakerWave" as the template name. When "SpeakerWave-1234ABCDE" is installed
+ we will copy all of the parameters that were specified in the inf for "SpeakerWave"
+ over to "SpeakerWave-1234ABCDE". You simply need to specify "SpeakerWave" as the
+ "TemplateName" in the ENDPOINT_MINIPAIRS.
-Routine Description:
+ By default, the first level of registry keys are not copied. Only the 2nd level and
+ deeper are copied. This way the friendly name and other PNP properties will not
+ be modified, but the EP and FX properties will be copied.
+
+Return Value:
- Completion callback for the Bluetooth Hands-Free Profile SCO Bypass
- stream status notification.
+ NT status code.
--*/
-{
- DPF_ENTER(("[BthHfpDevice::EvtBthHfpDeviceStreamStatusCompletion]"));
-
- NTSTATUS ntStatus = STATUS_SUCCESS;
- BthHfpDeviceNotificationReqContext * reqCtx = NULL;
- BthHfpDevice * This = NULL;
- NTSTATUS ntResult = STATUS_SUCCESS;
-
- UNREFERENCED_PARAMETER(Target);
- UNREFERENCED_PARAMETER(Context);
-
- //
- // Get the SCO stream status.
- //
- reqCtx = GetBthHfpDeviceNotificationReqContext(Request);
- This = reqCtx->BthHfpDevice;
- ASSERT(This != NULL);
-
- ntStatus = Params->IoStatus.Status;
- if (!NT_SUCCESS(ntStatus))
- {
- ntResult = STATUS_INVALID_DEVICE_STATE;
- }
- else
- {
- ntResult = reqCtx->Buffer.NtStatus;
- }
-
- InterlockedExchange(&This->m_StreamStatusLong, (LONG)ntResult);
-
- //
- // Let the stop routine know we are done. Stop routine will
- // re-init the request.
- //
- KeSetEvent(&This->m_StreamStatusEvent, IO_NO_INCREMENT, FALSE);
-}
-
-//=============================================================================
-#pragma code_seg()
-NTSTATUS
-BthHfpDevice::EnableBthHfpStreamStatusNotification()
-/*++
-
-Routine Description:
-
- This function registers for Bluetooth Hands-Free Profile SCO Bypass
- stream status notification.
---*/
{
- DPF_ENTER(("[BthHfpDevice::EnableBthHfpStreamStatusNotification]"));
-
- NTSTATUS ntStatus = STATUS_SUCCESS;
- BthHfpDeviceNotificationReqContext * ctx = NULL;
-
- ASSERT(m_nStreams > 0);
-
- ctx = GetBthHfpDeviceNotificationReqContext(m_StreamReq);
- ctx->Buffer.bImmediate = FALSE;
-
- KeClearEvent(&m_StreamStatusEvent);
-
- //
- // Get the Bth HFP SCO Bypass connection status.
- //
- ntStatus = SendIoCtrlAsynchronously(
- m_StreamReq,
- IOCTL_BTHHFP_STREAM_GET_STATUS_UPDATE,
- ctx->MemIn,
- ctx->MemOut,
- EvtBthHfpDeviceStreamStatusCompletion,
- this);
+ NTSTATUS ntStatus = STATUS_SUCCESS;
+ HANDLE hDeviceInterfaceParametersKey(NULL);
+ HANDLE hTemplateDeviceInterfaceParametersKey(NULL);
+ UNICODE_STRING TemplateSymbolicLinkName;
+ UNICODE_STRING referenceString;
- if (!NT_SUCCESS(ntStatus))
- {
- KeSetEvent(&m_StreamStatusEvent, IO_NO_INCREMENT, FALSE);
- DPF(D_ERROR, ("EnableBthHfpStreamStatusNotification: SendIoCtrlAsynchronously(IOCTL_BTHHFP_STREAM_GET_STATUS_UPDATE) failed, 0x%x", ntStatus));
- goto Done;
- }
+ RtlInitUnicodeString(&TemplateSymbolicLinkName, NULL);
+ RtlInitUnicodeString(&referenceString, TemplateReferenceString);
//
- // All done.
+ // Register an audio interface if not already present for the template interface, so we can access
+ // the registry path. If it's already registered, this simply returns the symbolic link name.
+ // No need to unregister it (there is no mechanism to), and we'll never make it active.
//
- ntStatus = STATUS_SUCCESS;
-
-Done:
-
- return ntStatus;
-}
-
-//=============================================================================
-#pragma code_seg("PAGE")
-NTSTATUS
-BthHfpDevice::StopBthHfpStreamStatusNotification()
-/*++
-
-Routine Description:
-
- This function stops the Bluetooth Hands-Free Profile SCO Bypass
- connection status notification.
- The function waits for the request to be done before returning.
+ ntStatus = IoRegisterDeviceInterface(
+ GetPhysicalDeviceObject(),
+ &KSCATEGORY_AUDIO,
+ &referenceString,
+ &TemplateSymbolicLinkName);
---*/
-{
- PAGED_CODE();
- DPF_ENTER(("[BthHfpDevice::StopBthHfpStreamStatusNotification]"));
+ // Open the template device interface's registry key path
+ ntStatus = IoOpenDeviceInterfaceRegistryKey(&TemplateSymbolicLinkName, GENERIC_READ, &hTemplateDeviceInterfaceParametersKey);
+ IF_FAILED_JUMP(ntStatus, Exit);
- NTSTATUS ntStatus = STATUS_SUCCESS;
- BthHfpDeviceNotificationReqContext * reqCtx = NULL;
- WDF_REQUEST_REUSE_PARAMS reuseParams;
+ // Open the new device interface's registry key path that we plan to activate
+ ntStatus = IoOpenDeviceInterfaceRegistryKey(SymbolicLinkName, GENERIC_WRITE, &hDeviceInterfaceParametersKey);
+ IF_FAILED_JUMP(ntStatus, Exit);
- WdfRequestCancelSentRequest(m_StreamReq);
- KeWaitForSingleObject(&m_StreamStatusEvent, Executive, KernelMode, FALSE, NULL);
+ // Copy the template device parameters key to the device interface key
+ ntStatus = CopyRegistryKey(hTemplateDeviceInterfaceParametersKey, hDeviceInterfaceParametersKey);
+ IF_FAILED_JUMP(ntStatus, Exit);
- reqCtx = GetBthHfpDeviceNotificationReqContext(m_StreamReq);
- ASSERT(reqCtx != NULL);
- UNREFERENCED_VAR(reqCtx);
+Exit:
+ RtlFreeUnicodeString(&TemplateSymbolicLinkName);
- //
- // Re-init the request for later.
- //
- WDF_REQUEST_REUSE_PARAMS_INIT(
- &reuseParams,
- WDF_REQUEST_REUSE_NO_FLAGS,
- STATUS_SUCCESS);
-
- ntStatus = WdfRequestReuse(m_StreamReq, &reuseParams);
- if (!NT_SUCCESS(ntStatus))
+ if (hTemplateDeviceInterfaceParametersKey)
{
- DPF(D_ERROR, ("StopBthHfpStreamStatusNotification: WdfRequestReuse failed, 0x%x", ntStatus));
+ ZwClose(hTemplateDeviceInterfaceParametersKey);
}
- return STATUS_SUCCESS;
-}
-
-//=============================================================================
-#pragma code_seg("PAGE")
-NTSTATUS
-BthHfpDevice::SetBthHfpStreamOpen()
-/*++
-
-Routine Description:
-
- This function synchronously requests an open SCO channel to transmit audio
- data over the air.
-
---*/
-{
- PAGED_CODE();
- DPF_ENTER(("[BthHfpDevice::SetBthHfpStreamOpen]"));
-
- NTSTATUS ntStatus = STATUS_SUCCESS;
-
- ntStatus = SendIoCtrlSynchronously(
- NULL,
- IOCTL_BTHHFP_STREAM_OPEN,
- 0,
- 0,
- NULL);
-
- if (ntStatus == STATUS_DEVICE_BUSY)
+ if (hDeviceInterfaceParametersKey)
{
- // The stream channel is already open.
- DPF(D_VERBOSE, ("SetBthHfpStreamOpen: the stream channel is already open"));
- ntStatus = STATUS_SUCCESS;
+ ZwClose(hDeviceInterfaceParametersKey);
}
- IF_FAILED_ACTION_JUMP(
- ntStatus,
- DPF(D_ERROR, ("SetBthHfpStreamOpen: SendIoCtrlSynchronously(IOCTL_BTHHFP_STREAM_OPEN) failed, 0x%x", ntStatus)),
- Done);
-
- //
- // All done.
- //
- ntStatus = STATUS_SUCCESS;
-
-Done:
-
return ntStatus;
}
-//=============================================================================
-#pragma code_seg("PAGE")
-NTSTATUS
-BthHfpDevice::SetBthHfpStreamClose()
-/*++
-
-Routine Description:
-
- This function synchronously requests to close the SCO channel.
-
---*/
-{
- PAGED_CODE();
- DPF_ENTER(("[BthHfpDevice::SetBthHfpStreamClose]"));
-
- NTSTATUS ntStatus = STATUS_SUCCESS;
-
- ntStatus = SendIoCtrlSynchronously(
- NULL,
- IOCTL_BTHHFP_STREAM_CLOSE,
- 0,
- 0,
- NULL);
-
- IF_FAILED_ACTION_JUMP(
- ntStatus,
- DPF(D_ERROR, ("SetBthHfpStreamClose: SendIoCtrlSynchronously(IOCTL_BTHHFP_STREAM_CLOSE) failed, 0x%x", ntStatus)),
- Done);
-
- //
- // All done.
- //
- ntStatus = STATUS_SUCCESS;
-
-Done:
-
- return ntStatus;
-}
-
-//=============================================================================
-#pragma code_seg("PAGE")
-VOID
-BthHfpDevice::Start()
-/*++
-
-Routine Description:
-
- Asynchronously called to start the audio device.
-
---*/
-{
- PAGED_CODE();
- DPF_ENTER(("[BthHfpDevice::Start]"));
-
- NTSTATUS ntStatus = STATUS_SUCCESS;
- BOOL connStatus = FALSE;
- UCHAR codecId = 0;
- UINT bthMiniportsIndex = 0;
-
- // CVSD is the narrow band codec for SCO. Wideband codec IDs are any number higher than 1.
- // mSBC is the only required wideband codec, though the controller+headset combination may
- // support other wideband codecs.
- const UCHAR CODEC_CVSD = 1;
-
- //
- // Get bth hfp descriptor
- //
- ntStatus = GetBthHfpDescriptor(&m_Descriptor);
- IF_FAILED_ACTION_JUMP(
- ntStatus,
- DPF(D_ERROR, ("Start: GetBthHfpDescriptor: failed to retrieve BTHHFP_DESCRIPTOR2, 0x%x", ntStatus)),
- Done);
-
- //
- // Get valume settings.
- //
- if (m_Descriptor->SupportsVolume)
- {
- PKSPROPERTY_VALUES volumePropValues = NULL;
- LONG volume = 0;
-
- // Volume settings.
- ntStatus = GetBthHfpVolumePropertyValues(
- m_Descriptor->VolumePropertyValuesSize,
- &volumePropValues);
-
- IF_FAILED_ACTION_JUMP(
- ntStatus,
- DPF(D_ERROR, ("Start: GetBthHfpVolumePropertyValues: failed to retrieve KSPROPERTY_VALUES, 0x%x", ntStatus)),
- Done);
-
- m_VolumePropValues = volumePropValues;
-
- // Speaker volume.
- ntStatus = GetBthHfpSpeakerVolume(&volume);
- IF_FAILED_ACTION_JUMP(
- ntStatus,
- DPF(D_ERROR, ("Start: GetBthHfpSpeakerVolume: failed, 0x%x", ntStatus)),
- Done);
-
- m_SpeakerVolumeLevel = volume;
-
- // Mic volume.
- ntStatus = GetBthHfpMicVolume(&volume);
- IF_FAILED_ACTION_JUMP(
- ntStatus,
- DPF(D_ERROR, ("Start: GetBthHfpMicVolume: failed, 0x%x", ntStatus)),
- Done);
-
- m_MicVolumeLevel = volume;
- }
-
- //
- // Get connection status.
- //
- ntStatus = GetBthHfpConnectionStatus(&connStatus);
- IF_FAILED_ACTION_JUMP(
- ntStatus,
- DPF(D_ERROR, ("Start: GetBthHfpConnectionStatus: failed, 0x%x", ntStatus)),
- Done);
-
- m_ConnectionStatus = connStatus;
-
- //
- // Get codec id (if non-zero, connection supports Wideband Speech)
- //
- ntStatus = GetBthHfpCodecId(&codecId);
- if (ntStatus == STATUS_INVALID_DEVICE_REQUEST)
- {
- // GetBthHfpCodecId fails with STATUS_INVALID_DEVICE_REQUEST if the system doesn't
- // support Wideband Speech (currently only Mobile supports this call)
- ntStatus = STATUS_SUCCESS;
- }
- IF_FAILED_ACTION_JUMP(
- ntStatus,
- DPF(D_ERROR, ("Start: GetBthHfpCodecId: failed, 0x%x", ntStatus)),
- Done);
-
- if (codecId > CODEC_CVSD)
- {
- // Use the miniport tables that support 16kHz
- bthMiniportsIndex = 1;
- }
-
- //
- // Customize the topology/wave descriptors for this instance
- //
- ntStatus = CreateCustomEndpointMinipair(
- g_BthHfpRenderEndpoints[bthMiniportsIndex],
- &m_Descriptor->FriendlyName,
- &m_Descriptor->OutputPinCategory,
- &m_SpeakerMiniports);
- IF_FAILED_ACTION_JUMP(
- ntStatus,
- DPF(D_ERROR, ("Start: CreateCustomEndpointMinipair for Render: failed, 0x%x", ntStatus)),
- Done);
-
- ntStatus = CreateCustomEndpointMinipair(
- g_BthHfpCaptureEndpoints[bthMiniportsIndex],
- &m_Descriptor->FriendlyName,
- &m_Descriptor->InputPinCategory,
- &m_MicMiniports);
- IF_FAILED_ACTION_JUMP(
- ntStatus,
- DPF(D_ERROR, ("Start: CreateCustomEndpointMinipair for Capture: failed, 0x%x", ntStatus)),
- Done);
-
- ASSERT(m_SpeakerMiniports != NULL);
- ASSERT(m_MicMiniports != NULL);
- _Analysis_assume_(m_SpeakerMiniports != NULL);
- _Analysis_assume_(m_MicMiniports != NULL);
-
- //
- // Register topology and wave filters.
- //
- ntStatus = m_Adapter->InstallEndpointFilters(
- NULL,
- m_SpeakerMiniports,
- PBTHHFPDEVICECOMMON(this),
- &m_UnknownSpeakerTopology,
- &m_UnknownSpeakerWave, NULL, NULL
- );
-
- IF_FAILED_ACTION_JUMP(
- ntStatus,
- DPF(D_ERROR, ("Start: InstallEndpointRenderFilters (Bth HFP SCO-Bypass): failed, 0x%x", ntStatus)),
- Done);
-
- ntStatus = m_Adapter->InstallEndpointFilters(
- NULL,
- m_MicMiniports,
- PBTHHFPDEVICECOMMON(this),
- &m_UnknownMicTopology,
- &m_UnknownMicWave, NULL, NULL
- );
-
- IF_FAILED_ACTION_JUMP(
- ntStatus,
- DPF(D_ERROR, ("Start: InstallEndpointCaptureFilters (Bth HFP SCO-Bypass): failed, 0x%x", ntStatus)),
- Done);
-
- //
- // Pend status notifications.
- //
-
- // NREC disable AudioGateway (AG) status.
- ntStatus = EnableBthHfpNrecDisableStatusNotification();
- IF_FAILED_ACTION_JUMP(
- ntStatus,
- DPF(D_ERROR, ("Start: EnableBthHfpNrecDisableStatusNotification: failed, 0x%x", ntStatus)),
- Done);
-
- // Volume speaker status.
- ntStatus = EnableBthHfpSpeakerVolumeStatusNotification();
- IF_FAILED_ACTION_JUMP(
- ntStatus,
- DPF(D_ERROR, ("Start: EnableBthHfpSpeakerVolumeStatusNotification: failed, 0x%x", ntStatus)),
- Done);
-
- // Volume mic status.
- ntStatus = EnableBthHfpMicVolumeStatusNotification();
- IF_FAILED_ACTION_JUMP(
- ntStatus,
- DPF(D_ERROR, ("Start: EnableBthHfpMicVolumeStatusNotification: failed, 0x%x", ntStatus)),
- Done);
-
- // Connection status.
- ntStatus = EnableBthHfpConnectionStatusNotification();
- IF_FAILED_ACTION_JUMP(
- ntStatus,
- DPF(D_ERROR, ("Start: EnableBthHfpConnectionStatusNotification: failed, 0x%x", ntStatus)),
- Done);
-
- //
- // All done.
- //
- ntStatus = STATUS_SUCCESS;
-
-Done:;
- if (!NT_SUCCESS(ntStatus))
- {
- InterlockedExchange((PLONG)&m_State, eBthHfpStateFailed);
- }
-}
-
-//=============================================================================
-#pragma code_seg("PAGE")
-NTSTATUS
-BthHfpDevice::CreateCustomEndpointMinipair
-(
- _In_ PENDPOINT_MINIPAIR pBaseMinipair,
- _In_ PUNICODE_STRING FriendlyName,
- _In_ PGUID pCategory,
- _Outptr_ PENDPOINT_MINIPAIR *ppCustomMinipair
-)
-{
- NTSTATUS ntStatus;
- PENDPOINT_MINIPAIR pNewMinipair = NULL;
- SYSVAD_DEVPROPERTY* pProperties = NULL;
- PPCFILTER_DESCRIPTOR pNewTopoFilterDesc = NULL;
- PPCPIN_DESCRIPTOR pNewTopoPins = NULL;
- ULONG cProperties;
- ULONG cTopoPins;
-
- PAGED_CODE();
-
- //
- // This routine will add one more property to whatever the base minipair describes for the topo filter interface properties
- // It will also allocate and set up custom filter and pin descriptors to allow changing the KSNODETYPE for the hfp device
- //
- cTopoPins = pBaseMinipair->TopoDescriptor->PinCount;
- cProperties = pBaseMinipair->TopoInterfacePropertyCount + 1;
- pProperties = (SYSVAD_DEVPROPERTY*)ExAllocatePoolWithTag(NonPagedPoolNx, cProperties * sizeof(SYSVAD_DEVPROPERTY), SYSVAD_POOLTAG);
- pNewMinipair = (ENDPOINT_MINIPAIR*)ExAllocatePoolWithTag(NonPagedPoolNx, sizeof(ENDPOINT_MINIPAIR), SYSVAD_POOLTAG);
- pNewTopoFilterDesc = (PCFILTER_DESCRIPTOR*)ExAllocatePoolWithTag(NonPagedPoolNx, sizeof(PCFILTER_DESCRIPTOR), SYSVAD_POOLTAG);
- pNewTopoPins = (PCPIN_DESCRIPTOR*)ExAllocatePoolWithTag(NonPagedPoolNx, cTopoPins * sizeof(PCPIN_DESCRIPTOR), SYSVAD_POOLTAG);
-
- if ((pProperties != NULL) && (pNewMinipair != NULL) && (pNewTopoFilterDesc != NULL) && (pNewTopoPins != NULL))
- {
- SYSVAD_DEVPROPERTY *pLastProperty;
-
- // Copy base minipair properties to new property list
- if (pBaseMinipair->TopoInterfacePropertyCount > 0)
- {
- RtlCopyMemory(pProperties, pBaseMinipair->TopoInterfaceProperties, (cProperties - 1) * sizeof(SYSVAD_DEVPROPERTY));
- }
-
- // Add friendly name property to the list
- NT_ASSERT(FriendlyName->Length + sizeof(UNICODE_NULL) <= FriendlyName->MaximumLength); // Assuming NULL terminated string
- pLastProperty = &pProperties[cProperties - 1];
- pLastProperty->PropertyKey = &DEVPKEY_DeviceInterface_FriendlyName;
- pLastProperty->Type = DEVPROP_TYPE_STRING_INDIRECT;
- pLastProperty->BufferSize = FriendlyName->Length + sizeof(UNICODE_NULL);
- pLastProperty->Buffer = FriendlyName->Buffer;
-
- // Copy base minipair structure
- RtlCopyMemory(pNewMinipair, pBaseMinipair, sizeof(ENDPOINT_MINIPAIR));
-
- RtlCopyMemory(pNewTopoFilterDesc, pBaseMinipair->TopoDescriptor, sizeof(PCFILTER_DESCRIPTOR));
- RtlCopyMemory(pNewTopoPins, pBaseMinipair->TopoDescriptor->Pins, cTopoPins * sizeof(PCPIN_DESCRIPTOR));
-
- pNewTopoFilterDesc->Pins = pNewTopoPins;
- pNewMinipair->TopoDescriptor = pNewTopoFilterDesc;
-
- // Update it to point to new property list
- pNewMinipair->TopoInterfacePropertyCount = cProperties;
- pNewMinipair->TopoInterfaceProperties = pProperties;
-
- ntStatus = UpdateCustomEndpointCategory(pNewTopoFilterDesc, pNewTopoPins, pCategory);
- if (!NT_SUCCESS(ntStatus))
- {
- DPF(D_ERROR, ("UpdateCustomEndpointCategory: failed, 0x%x", ntStatus));
- }
- else
- {
- *ppCustomMinipair = pNewMinipair;
-
- pProperties = NULL;
- pNewMinipair = NULL;
- pNewTopoFilterDesc = NULL;
- pNewTopoPins = NULL;
-
- ntStatus = STATUS_SUCCESS;
- }
- }
- else
- {
- ntStatus = STATUS_INSUFFICIENT_RESOURCES;
- }
-
- if (pProperties != NULL)
- {
- ExFreePoolWithTag(pProperties, SYSVAD_POOLTAG);
- }
- if (pNewMinipair != NULL)
- {
- ExFreePoolWithTag(pNewMinipair, SYSVAD_POOLTAG);
- }
- if (pNewTopoFilterDesc != NULL)
- {
- ExFreePoolWithTag(pNewTopoFilterDesc, SYSVAD_POOLTAG);
- }
- if (pNewTopoPins != NULL)
- {
- ExFreePoolWithTag(pNewTopoPins, SYSVAD_POOLTAG);
- }
-
- return ntStatus;
-}
-//=============================================================================
#pragma code_seg("PAGE")
-NTSTATUS
-BthHfpDevice::UpdateCustomEndpointCategory
-(
- _In_ PPCFILTER_DESCRIPTOR pCustomMinipairTopoFilter,
- _In_ PPCPIN_DESCRIPTOR pCustomMinipairTopoPins,
- _In_ PGUID pCategory
+STDMETHODIMP_(NTSTATUS)
+CAdapterCommon::NotifyEndpointPair
+(
+ _In_ WCHAR *RenderEndpointTopoName,
+ _In_ ULONG RenderEndpointNameLen,
+ _In_ ULONG RenderPinId,
+ _In_ WCHAR *CaptureEndpointTopoName,
+ _In_ ULONG CaptureEndpointNameLen,
+ _In_ ULONG CapturePinId
)
{
- NTSTATUS ntStatus = STATUS_NOT_FOUND;
- ULONG cPinCount = 0;
- BOOL FoundCategoryAudio = FALSE;
- BOOL FoundNodeType = FALSE;
+ NTSTATUS ntStatus = STATUS_SUCCESS;
- PAGED_CODE();
+ PAGED_CODE ();
- cPinCount = pCustomMinipairTopoFilter->PinCount;
+ PLIST_ENTRY le = NULL;
+ BOOL bRemoved = FALSE;
- // Find the right pin: There should be two pins, one with Category KSCATEGORY_AUDIO,
- // and one with a KSNODETYPE_* Category. We need to modify the KSNODETYPE category.
- for (ULONG i = 0; i < cPinCount; ++i)
+ // notify each subdevice which implements IMiniportChange
+ for (le = m_SubdeviceCache.Flink; le != &m_SubdeviceCache && !bRemoved; le = le->Flink)
{
- if (IsEqualGUID(*pCustomMinipairTopoPins[i].KsPinDescriptor.Category, KSCATEGORY_AUDIO))
- {
- ASSERT(FoundCategoryAudio == FALSE);
- if (FoundCategoryAudio)
- {
- ntStatus = STATUS_INVALID_DEVICE_STATE;
- DPF(D_ERROR, ("UpdateCustomEndpointCategory: KSCATEGORY_AUDIO found more than once, 0x%x", ntStatus));
- break;
- }
-
- FoundCategoryAudio = TRUE;
- continue;
- }
+ MINIPAIR_UNKNOWN *pRecord = CONTAINING_RECORD(le, MINIPAIR_UNKNOWN, ListEntry);
- ASSERT(FoundNodeType == FALSE);
- if (FoundNodeType)
+ if(pRecord->MiniportChange)
{
- ntStatus = STATUS_INVALID_DEVICE_STATE;
- DPF(D_ERROR, ("UpdateCustomEndpointCategory: Found more than one applicable Pin, 0x%x", ntStatus));
- break;
+ pRecord->MiniportChange->NotifyEndpointPair(
+ RenderEndpointTopoName,
+ RenderEndpointNameLen,
+ RenderPinId,
+ CaptureEndpointTopoName,
+ CaptureEndpointNameLen,
+ CapturePinId
+ );
}
-
- pCustomMinipairTopoPins[i].KsPinDescriptor.Category = pCategory;
- FoundNodeType = TRUE;
- ntStatus = STATUS_SUCCESS;
}
return ntStatus;
}
-//=============================================================================
-#pragma code_seg("PAGE")
-VOID
-BthHfpDevice::DeleteCustomEndpointMinipair
-(
- _In_ PENDPOINT_MINIPAIR pCustomMinipair
-)
-{
- PAGED_CODE();
-
- if (pCustomMinipair != NULL)
- {
- if (pCustomMinipair->TopoInterfaceProperties != NULL)
- {
- ExFreePoolWithTag(const_cast<SYSVAD_DEVPROPERTY*>(pCustomMinipair->TopoInterfaceProperties), SYSVAD_POOLTAG);
- pCustomMinipair->TopoInterfaceProperties = NULL;
- }
- if (pCustomMinipair->TopoDescriptor != NULL)
- {
- if (pCustomMinipair->TopoDescriptor->Pins != NULL)
- {
- ExFreePoolWithTag((PVOID)pCustomMinipair->TopoDescriptor->Pins, SYSVAD_POOLTAG);
- pCustomMinipair->TopoDescriptor->Pins = NULL;
- }
- ExFreePoolWithTag(pCustomMinipair->TopoDescriptor, SYSVAD_POOLTAG);
- pCustomMinipair->TopoDescriptor = NULL;
- }
- ExFreePoolWithTag(pCustomMinipair, SYSVAD_POOLTAG);
- }
-}
-
-//=============================================================================
-#pragma code_seg("PAGE")
-VOID
-BthHfpDevice::Stop()
-/*++
-
-Routine Description:
-
- Asynchronously called to stop the audio device.
- After returning from this function, there are no more async notifications
- pending (volume, connection, etc.).
-
---*/
-{
- PAGED_CODE();
- DPF_ENTER(("[BthHfpDevice::Stop]"));
-
- NTSTATUS ntStatus = STATUS_SUCCESS;
- eBthHfpState state = eBthHfpStateInvalid;
-
- state = (eBthHfpState) InterlockedExchange((PLONG)&m_State, eBthHfpStateStopping);
- ASSERT(state == eBthHfpStateRunning || state == eBthHfpStateFailed);
- UNREFERENCED_VAR(state);
-
- //
- // Stop async notifications.
- //
- WdfIoTargetPurge(m_WdfIoTarget, WdfIoTargetPurgeIoAndWait);
-
- //
- // Wait for work-item.
- //
- WdfWorkItemFlush(m_WorkItem);
-
- //
- // Remove the topology and wave render filters.
- //
- if (m_UnknownSpeakerTopology || m_UnknownSpeakerWave)
- {
- ntStatus = m_Adapter->RemoveEndpointFilters(
- m_SpeakerMiniports,
- m_UnknownSpeakerTopology,
- m_UnknownSpeakerWave);
-
- if (!NT_SUCCESS(ntStatus))
- {
- DPF(D_ERROR, ("RemoveEndpointFilters (Bth HFP SCO-Bypass Speaker): failed, 0x%x", ntStatus));
- }
- }
-
- //
- // Remove the topology and wave capture filters.
- //
- if (m_UnknownMicTopology || m_UnknownMicWave)
- {
- ntStatus = m_Adapter->RemoveEndpointFilters(
- m_MicMiniports,
- m_UnknownMicTopology,
- m_UnknownMicWave);
-
- if (!NT_SUCCESS(ntStatus))
- {
- DPF(D_ERROR, ("RemoveEndpointFilters (Bth HFP SCO-Bypass Capture): failed, 0x%x", ntStatus));
- }
- }
-
- //
- // Release port/miniport pointers.
- //
- SAFE_RELEASE(m_UnknownSpeakerTopology);
- SAFE_RELEASE(m_UnknownSpeakerWave);
- SAFE_RELEASE(m_UnknownMicTopology);
- SAFE_RELEASE(m_UnknownMicWave);
-
- //
- // The device is in the stopped state.
- //
- InterlockedExchange((PLONG)&m_State, eBthHfpStateStopped);
-
- DeleteCustomEndpointMinipair(m_SpeakerMiniports);
- m_SpeakerMiniports = NULL;
-
- DeleteCustomEndpointMinipair(m_MicMiniports);
- m_MicMiniports = NULL;
-
-}
-
-#endif // SYSVAD_BTH_BYPASS
-
-//
-// The following are copied from:
-// \Program Files\Windows Kits\10\Include\10.0.15063.0\km\stdunk.h
-//
-
-#ifdef _NEW_DELETE_OPERATORS_
-
-// Note: Since VS2015 Update 2 overloaded operator new and operator delete may not
-// be declared inline (Level 1 (/W1) on-by-default, warning C4595).
-// See https://msdn.microsoft.com/en-us/library/mt656697.aspx
-//
-// To mitigate this issue, add "#define _NEW_DELETE_OPERATORS_" before "#include <stdunk.h>"
-// and implement non-inline operator new and operator delete locally.
-
-/*****************************************************************************
- * ::new()
- *****************************************************************************
- * New function for creating objects with a specified allocation tag.
- */
-// PVOID operator new
-// (
-// size_t iSize,
-// _When_((poolType & NonPagedPoolMustSucceed) != 0,
-// __drv_reportError("Must succeed pool allocations are forbidden. "
-// "Allocation failures cause a system crash"))
-// POOL_TYPE poolType
-// )
-// {
-// PVOID result = ExAllocatePoolWithTag(poolType,iSize,'wNcP');
-//
-// if (result)
-// {
-// RtlZeroMemory(result,iSize);
-// }
-//
-// return result;
-// }
-
-/*****************************************************************************
- * ::new()
- *****************************************************************************
- * New function for creating objects with a specified allocation tag.
- */
-PVOID operator new
-(
- size_t iSize,
- _When_((poolType & NonPagedPoolMustSucceed) != 0,
- __drv_reportError("Must succeed pool allocations are forbidden. "
- "Allocation failures cause a system crash"))
- POOL_TYPE poolType,
- ULONG tag
-)
-{
- PVOID result = ExAllocatePoolWithTag(poolType,iSize,tag);
-
- if (result)
- {
- RtlZeroMemory(result,iSize);
- }
-
- return result;
-}
-
-/*****************************************************************************
- * ::delete()
- *****************************************************************************
- * Delete function.
- */
-// void __cdecl operator delete
-// (
-// PVOID pVoid
-// )
-// {
-// if (pVoid)
-// {
-// ExFreePool(pVoid);
-// }
-// }
-
-/*****************************************************************************
- * ::delete()
- *****************************************************************************
- * Delete function.
- */
-// void __cdecl operator delete
-// (
-// PVOID pVoid,
-// ULONG tag
-// )
-// {
-// if (pVoid)
-// {
-// ExFreePoolWithTag(pVoid,tag);
-// }
-// }
-
-void __cdecl operator delete
-(
- _Pre_maybenull_ __drv_freesMem(Mem) PVOID pVoid,
- _In_ size_t cbSize
-)
-{
- UNREFERENCED_PARAMETER(cbSize);
-
- if (pVoid)
- {
- ExFreePool(pVoid);
- }
-}
-
-void __cdecl operator delete[]
-(
- _Pre_maybenull_ __drv_freesMem(Mem) PVOID pVoid
-)
-{
- if (pVoid)
- {
- ExFreePool(pVoid);
- }
-}
-
-// void __cdecl operator delete[]
-// (
-// _Pre_maybenull_ __drv_freesMem(Mem) PVOID pVoid,
-// _In_ size_t cbSize
-// )
-// {
-// UNREFERENCED_PARAMETER(cbSize);
-
-// if (pVoid)
-// {
-// ExFreePool(pVoid);
-// }
-// }
-#endif //!_NEW_DELETE_OPERATORS_
diff --git a/audio/sysvad/common.h b/audio/sysvad/common.h
index d46a9090..f138c1fb 100644
--- a/audio/sysvad/common.h
+++ b/audio/sysvad/common.h
@@ -107,6 +107,7 @@ Abstract:
}
#define SAFE_RELEASE(p) {if (p) { (p)->Release(); (p) = nullptr; } }
+#define SAFE_DELETE_PTR_WITH_TAG(ptr, tag) if(ptr) { ExFreePoolWithTag((ptr), tag); (ptr) = NULL; }
// JACKDESC_RGB(r, g, b)
#define JACKDESC_RGB(r, g, b) \
@@ -116,9 +117,9 @@ Abstract:
#define MIN(x, y) ((x) < (y) ? (x) : (y))
#define MAX(x, y) ((x) > (y) ? (x) : (y))
-#define MINWAVERT_POOLTAG 'RWNM'
-#define MINTOPORT_POOLTAG 'RTNM'
-#define MINADAPTER_POOLTAG 'uAyS'
+#define MINWAVERT_POOLTAG 'RWNM'
+#define MINTOPORT_POOLTAG 'RTNM'
+#define MINADAPTER_POOLTAG 'uAyS'
typedef enum
{
@@ -138,6 +139,9 @@ typedef enum
eMicHsDevice,
eFmRxDevice,
eSpdifRenderDevice,
+ eUsbHsSpeakerDevice,
+ eUsbHsMicDevice,
+ eA2dpHpSpeakerDevice,
eMaxDeviceType
} eDeviceType;
@@ -318,7 +322,7 @@ typedef HRESULT (*PFNCREATEMINIPORT)(
_In_opt_ PUNKNOWN UnknownOuter,
_When_((PoolType & NonPagedPoolMustSucceed) != 0,
__drv_reportError("Must succeed pool allocations are forbidden. "
- "Allocation failures cause a system crash"))
+ "Allocation failures cause a system crash"))
_In_ POOL_TYPE PoolType,
_In_ PUNKNOWN UnknownAdapter,
_In_opt_ PVOID DeviceContext,
@@ -335,11 +339,12 @@ typedef struct _SYSVAD_DEVPROPERTY {
__field_bcount_opt(BufferSize) PVOID Buffer;
} SYSVAD_DEVPROPERTY, PSYSVAD_DEVPROPERTY;
-#define ENDPOINT_NO_FLAGS 0x00000000
-#define ENDPOINT_OFFLOAD_SUPPORTED 0x00000001
-#define ENDPOINT_SOUNDDETECTOR_SUPPORTED 0x00000002
-#define ENDPOINT_CELLULAR_PROVIDER1 0x00000010
-#define ENDPOINT_CELLULAR_PROVIDER2 0x00000020
+#define ENDPOINT_NO_FLAGS 0x00000000
+#define ENDPOINT_OFFLOAD_SUPPORTED 0x00000001
+#define ENDPOINT_LOOPBACK_SUPPORTED 0x00000002
+#define ENDPOINT_SOUNDDETECTOR_SUPPORTED 0x00000004
+#define ENDPOINT_CELLULAR_PROVIDER1 0x00000008
+#define ENDPOINT_CELLULAR_PROVIDER2 0x00000010
//
// Endpoint miniport pair (wave/topology) descriptor.
@@ -349,14 +354,16 @@ typedef struct _ENDPOINT_MINIPAIR
eDeviceType DeviceType;
// Topology miniport.
- PWSTR TopoName; // make sure this name matches with SYSVAD.<TopoName>.szPname in the inf's [Strings] section
+ PWSTR TopoName; // make sure this or the template name matches with SYSVAD.<TopoName>.szPname in the inf's [Strings] section
+ PWSTR TemplateTopoName; // optional template name
PFNCREATEMINIPORT TopoCreateCallback;
PCFILTER_DESCRIPTOR* TopoDescriptor;
ULONG TopoInterfacePropertyCount;
const SYSVAD_DEVPROPERTY* TopoInterfaceProperties;
// Wave RT miniport.
- PWSTR WaveName; // make sure this name matches with SYSVAD.<WaveName>.szPname in the inf's [Strings] section
+ PWSTR WaveName; // make sure this or the template name matches with SYSVAD.<WaveName>.szPname in the inf's [Strings] section
+ PWSTR TemplateWaveName; // optional template name
PFNCREATEMINIPORT WaveCreateCallback;
PCFILTER_DESCRIPTOR* WaveDescriptor;
ULONG WaveInterfacePropertyCount;
@@ -386,11 +393,32 @@ typedef struct _ENDPOINT_MINIPAIR
DEFINE_GUID(IID_IAdapterCommon,
0x7eda2950, 0xbf9f, 0x11d0, 0x87, 0x1f, 0x0, 0xa0, 0xc9, 0x11, 0xb5, 0x44);
+// {4E1E5697-4D04-4438-A913-B0EEE03732BA}
+DEFINE_GUID(IID_IMiniportChange,
+0x4e1e5697, 0x4d04, 0x4438, 0xa9, 0x13, 0xb0, 0xee, 0xe0, 0x37, 0x32, 0xba);
+
//=============================================================================
// Interfaces
//=============================================================================
///////////////////////////////////////////////////////////////////////////////
+// IID_IMiniportChange
+//
+DECLARE_INTERFACE_(IMiniportChange, IUnknown)
+{
+ STDMETHOD_(NTSTATUS, NotifyEndpointPair)
+ (
+ THIS_
+ _In_ WCHAR *RenderEndpointTopoName,
+ _In_ ULONG RenderEndpointNameLen,
+ _In_ ULONG RenderPinId,
+ _In_ WCHAR *CaptureEndpointTopoName,
+ _In_ ULONG CaptureEndpointNameLen,
+ _In_ ULONG CapturePinId
+ ) PURE;
+};
+
+///////////////////////////////////////////////////////////////////////////////
// IAdapterCommon
//
DECLARE_INTERFACE_(IAdapterCommon, IUnknown)
@@ -528,6 +556,7 @@ DECLARE_INTERFACE_(IAdapterCommon, IUnknown)
(
_In_opt_ PIRP Irp,
_In_ PWSTR Name,
+ _In_opt_ PWSTR TemplateName,
_In_ REFGUID PortClassId,
_In_ REFGUID MiniportClassId,
_In_opt_ PFNCREATEMINIPORT MiniportCreate,
@@ -609,9 +638,21 @@ DECLARE_INTERFACE_(IAdapterCommon, IUnknown)
#endif // SYSVAD_BTH_BYPASS
STDMETHOD_(VOID, Cleanup)();
+
+ STDMETHOD_(NTSTATUS, NotifyEndpointPair)
+ (
+ THIS_
+ _In_ WCHAR *RenderEndpointTopoName,
+ _In_ ULONG RenderEndpointNameLen,
+ _In_ ULONG RenderPinId,
+ _In_ WCHAR *CaptureEndpointTopoName,
+ _In_ ULONG CaptureEndpointNameLen,
+ _In_ ULONG CapturePinId
+ ) PURE;
};
typedef IAdapterCommon *PADAPTERCOMMON;
+typedef IMiniportChange *PMINIPORTCHANGE;
//=============================================================================
// Function Prototypes
@@ -624,12 +665,12 @@ NewAdapterCommon
_In_opt_ PUNKNOWN UnknownOuter,
_When_((PoolType & NonPagedPoolMustSucceed) != 0,
__drv_reportError("Must succeed pool allocations are forbidden. "
- "Allocation failures cause a system crash"))
+ "Allocation failures cause a system crash"))
_In_ POOL_TYPE PoolType
);
-#ifdef SYSVAD_BTH_BYPASS
+#if defined(SYSVAD_BTH_BYPASS)
// Event callback definition.
typedef VOID (*PFNEVENTNOTIFICATION)(
@@ -637,48 +678,80 @@ typedef VOID (*PFNEVENTNOTIFICATION)(
);
DEFINE_GUID(IID_IBthHfpDeviceCommon,
-0x576b824a, 0x5248, 0x47b1, 0x82, 0xc5, 0xe4, 0x7b, 0xa7, 0xe2, 0xaf, 0x2b);
+ 0x576b824a, 0x5248, 0x47b1, 0x82, 0xc5, 0xe4, 0x7b, 0xa7, 0xe2, 0xaf, 0x2b);
+
+DEFINE_GUID(IID_IUsbHsDeviceCommon,
+ 0xb57b5547, 0x63f, 0x4a58, 0xb3, 0x7, 0x90, 0xb2, 0xfc, 0x6c, 0x32, 0xdb);
+
+DEFINE_GUID(IID_IA2dpHpDeviceCommon,
+ 0xe1a6f128, 0x905, 0x4c18, 0xb4, 0x84, 0xc2, 0xca, 0x45, 0xb1, 0x57, 0x6d);
+
+
//=============================================================================
// Interfaces
//=============================================================================
///////////////////////////////////////////////////////////////////////////////
-// IAdapterCommon
+// ISidebandDeviceCommon
//
-DECLARE_INTERFACE_(IBthHfpDeviceCommon, IUnknown)
+DECLARE_INTERFACE_(ISidebandDeviceCommon, IUnknown)
{
STDMETHOD_(BOOL, IsVolumeSupported)
(
THIS_
+ _In_ eDeviceType deviceType
) PURE;
- STDMETHOD_(PKSPROPERTY_VALUES, GetVolumeSettings)
+ STDMETHOD_(PVOID, GetVolumeSettings)
+ (
+ THIS_
+ _In_ eDeviceType deviceType,
+ _Out_ PULONG Size
+ ) PURE;
+
+ STDMETHOD_(NTSTATUS, GetVolume)
(
THIS_
- _Out_ PULONG Size
+ _In_ eDeviceType deviceType,
+ _In_ LONG Channel,
+ _Out_ LONG *pVolume
) PURE;
- STDMETHOD_(LONG, GetSpeakerVolume)
+ STDMETHOD_(NTSTATUS, SetVolume)
(
THIS_
+ _In_ eDeviceType deviceType,
+ _In_ LONG Channel,
+ _In_ LONG Volume
) PURE;
- STDMETHOD_(NTSTATUS, SetSpeakerVolume)
+ STDMETHOD_(BOOL, IsMuteSupported)
(
THIS_
- _In_ ULONG Volume
+ _In_ eDeviceType deviceType
) PURE;
- STDMETHOD_(LONG, GetMicVolume)
+ STDMETHOD_(PVOID, GetMuteSettings)
+ (
+ THIS_
+ _In_ eDeviceType deviceType,
+ _Out_ PULONG Size
+ ) PURE;
+
+ STDMETHOD_(LONG, GetMute)
(
THIS_
+ _In_ eDeviceType deviceType,
+ _In_ LONG Channel
) PURE;
- STDMETHOD_(NTSTATUS, SetMicVolume)
+ STDMETHOD_(NTSTATUS, SetMute)
(
THIS_
- _In_ ULONG Volume
+ _In_ eDeviceType deviceType,
+ _In_ LONG Channel,
+ _In_ LONG Mute
) PURE;
STDMETHOD_(BOOL, GetConnectionStatus)
@@ -699,51 +772,77 @@ DECLARE_INTERFACE_(IBthHfpDeviceCommon, IUnknown)
STDMETHOD_(BOOL, GetStreamStatus)
(
THIS_
+ _In_ eDeviceType deviceType
) PURE;
STDMETHOD_(NTSTATUS, StreamOpen)
(
THIS_
+ _In_ eDeviceType deviceType
+ ) PURE;
+
+ STDMETHOD_(NTSTATUS, StreamStart)
+ (
+ THIS_
+ _In_ eDeviceType deviceType
+ ) PURE;
+
+ STDMETHOD_(NTSTATUS, StreamSuspend)
+ (
+ THIS_
+ _In_ eDeviceType deviceType
) PURE;
STDMETHOD_(NTSTATUS, StreamClose)
(
THIS_
+ _In_ eDeviceType deviceType
) PURE;
STDMETHOD_(GUID, GetContainerId)
(
THIS_
+ _In_ eDeviceType deviceType
) PURE;
- STDMETHOD_(VOID, SetSpeakerVolumeHandler)
+ STDMETHOD_(VOID, SetVolumeHandler)
(
THIS_
+ _In_ eDeviceType deviceType,
_In_opt_ PFNEVENTNOTIFICATION EventHandler,
_In_opt_ PVOID EventHandlerContext
) PURE;
-
- STDMETHOD_(VOID, SetSpeakerConnectionStatusHandler)
+
+ STDMETHOD_(VOID, SetMuteHandler)
(
THIS_
+ _In_ eDeviceType deviceType,
_In_opt_ PFNEVENTNOTIFICATION EventHandler,
_In_opt_ PVOID EventHandlerContext
) PURE;
- STDMETHOD_(VOID, SetMicVolumeHandler)
+ STDMETHOD_(VOID, SetConnectionStatusHandler)
(
THIS_
+ _In_ eDeviceType deviceType,
_In_opt_ PFNEVENTNOTIFICATION EventHandler,
_In_opt_ PVOID EventHandlerContext
) PURE;
-
- STDMETHOD_(VOID, SetMicConnectionStatusHandler)
+
+ STDMETHOD_(VOID, SetFormatChangeHandler)
(
THIS_
+ _In_ eDeviceType deviceType,
_In_opt_ PFNEVENTNOTIFICATION EventHandler,
_In_opt_ PVOID EventHandlerContext
) PURE;
+ STDMETHOD_(PPIN_DEVICE_FORMATS_AND_MODES, GetFormatsAndModes)
+ (
+ THIS_
+ _In_ eDeviceType deviceType
+ ) PURE;
+
STDMETHOD_(BOOL, IsNRECSupported)
(
THIS_
@@ -754,9 +853,10 @@ DECLARE_INTERFACE_(IBthHfpDeviceCommon, IUnknown)
THIS_
) PURE;
};
-typedef IBthHfpDeviceCommon *PBTHHFPDEVICECOMMON;
+typedef ISidebandDeviceCommon *PSIDEBANDDEVICECOMMON;
#endif // SYSVAD_BTH_BYPASS
#endif //_SYSVAD_COMMON_H_
+
diff --git a/audio/sysvad/hw.cpp b/audio/sysvad/hw.cpp
index 2ba0d514..1666e146 100644
--- a/audio/sysvad/hw.cpp
+++ b/audio/sysvad/hw.cpp
@@ -337,7 +337,8 @@ Return Value:
PAGED_CODE();
RtlFillMemory(m_VolumeControls, sizeof(LONG) * MAX_TOPOLOGY_NODES, 0xFF);
- RtlFillMemory(m_MuteControls, sizeof(BOOL) * MAX_TOPOLOGY_NODES, TRUE);
+ // Endpoints are not muted by default.
+ RtlZeroMemory(m_MuteControls, sizeof(BOOL) * MAX_TOPOLOGY_NODES);
for (ULONG i=0; i<MAX_TOPOLOGY_NODES; ++i)
{
diff --git a/audio/sysvad/savedata.cpp b/audio/sysvad/savedata.cpp
index 573e491f..7e60cf4d 100644
--- a/audio/sysvad/savedata.cpp
+++ b/audio/sysvad/savedata.cpp
@@ -48,6 +48,7 @@ Abstract:
#define DEFAULT_BUFFER_SIZE DEFAULT_FRAME_SIZE * DEFAULT_FRAME_COUNT
#define DEFAULT_FILE_NAME L"\\DosDevices\\C:\\STREAM"
+#define OSDATA_FILE_NAME L"\\DosDevices\\O:\\STREAM"
#define OFFLOAD_FILE_NAME L"OFFLOAD"
#define HOST_FILE_NAME L"HOST"
@@ -451,6 +452,10 @@ CSaveData::Initialize
NTSTATUS ntStatus = STATUS_SUCCESS;
WCHAR szTemp[MAX_PATH];
size_t cLen;
+ OBJECT_ATTRIBUTES objectAttributes;
+ UNICODE_STRING osDataVolumeString;
+ HANDLE osDataFileHandle = NULL;
+ IO_STATUS_BLOCK ioStatusBlock;
DPF_ENTER(("[CSaveData::Initialize]"));
@@ -463,9 +468,42 @@ CSaveData::Initialize
m_ulStreamId++;
}
+ // Probe if OSData volume exists.
+ //
+ RtlStringCchPrintfW(szTemp, MAX_PATH, L"%s_probe.txt", OSDATA_FILE_NAME);
+ RtlInitUnicodeString(&osDataVolumeString, szTemp);
+ InitializeObjectAttributes
+ (
+ &objectAttributes,
+ &osDataVolumeString,
+ OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+ NULL,
+ NULL
+ );
+
+ ntStatus =
+ ZwCreateFile
+ (
+ &osDataFileHandle,
+ GENERIC_WRITE | SYNCHRONIZE,
+ &objectAttributes,
+ &ioStatusBlock,
+ NULL,
+ FILE_ATTRIBUTE_NORMAL,
+ 0,
+ FILE_OVERWRITE_IF,
+ FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
+ NULL,
+ 0
+ );
+ if (NT_SUCCESS(ntStatus))
+ {
+ ZwClose(osDataFileHandle);
+ }
+
// Allocate data file name.
//
- RtlStringCchPrintfW(szTemp, MAX_PATH, L"%s_%s_%d.wav", DEFAULT_FILE_NAME, _bOffloaded ? OFFLOAD_FILE_NAME : HOST_FILE_NAME, _bOffloaded ? m_ulOffloadStreamId : m_ulStreamId);
+ RtlStringCchPrintfW(szTemp, MAX_PATH, L"%s_%s_%d.wav", NT_SUCCESS(ntStatus) ? OSDATA_FILE_NAME : DEFAULT_FILE_NAME, _bOffloaded ? OFFLOAD_FILE_NAME : HOST_FILE_NAME, _bOffloaded ? m_ulOffloadStreamId : m_ulStreamId);
m_FileName.Length = 0;
ntStatus = RtlStringCchLengthW (szTemp, sizeof(szTemp)/sizeof(szTemp[0]), &cLen);
if (NT_SUCCESS(ntStatus))
diff --git a/audio/sysvad/sources.inc b/audio/sysvad/sources.inc
index 7396cf46..369014a0 100644
--- a/audio/sysvad/sources.inc
+++ b/audio/sysvad/sources.inc
@@ -25,10 +25,11 @@ C_DEFINES= $(C_DEFINES) -DDEBUG_LEVEL=DEBUGLVL_TERSE
SOURCES=\
..\adapter.cpp \
..\basetopo.cpp \
+ ..\BthhfpDevice.cpp \
..\common.cpp \
..\hw.cpp \
..\kshelper.cpp \
..\savedata.cpp \
..\tonegenerator.cpp \
- ..\sysvad.rc
+ ..\wavereader.cpp \
diff --git a/audio/sysvad/sysvad.h b/audio/sysvad/sysvad.h
index e99a54b2..a3cc555c 100644
--- a/audio/sysvad/sysvad.h
+++ b/audio/sysvad/sysvad.h
@@ -16,33 +16,14 @@ Abstract:
#define _SYSVAD_H_
#include <portcls.h>
-
-// Note: Since VS2015 Update 2 overloaded operator new and operator delete may not
-// be declared inline (Level 1 (/W1) on-by-default, warning C4595).
-// See https://msdn.microsoft.com/en-us/library/mt656697.aspx
-//
-// To mitigate this issue, add "#define _NEW_DELETE_OPERATORS_" before "#include <stdunk.h>"
-// and implement non-inline operator new and operator delete locally.
-//
-#define _NEW_DELETE_OPERATORS_
#include <stdunk.h>
-// non-inline operator new and operator delete are implemented in common.cpp
-PVOID operator new
-(
- size_t iSize,
- _When_((poolType & NonPagedPoolMustSucceed) != 0,
- __drv_reportError("Must succeed pool allocations are forbidden. "
- "Allocation failures cause a system crash"))
- POOL_TYPE poolType,
- ULONG tag
-);
-
#include <ksdebug.h>
#include <ntintsafe.h>
#include <wdf.h>
#include <wdfminiport.h>
#include <MsApoFxProxy.h>
#include <Ntstrsafe.h>
+#include "NewDelete.h"
//=============================================================================
// Defines
@@ -62,7 +43,7 @@ DEFINE_GUIDSTRUCT("5B722BF8-F0AB-47ee-B9C8-8D61D31375A1", PID_SYSVAD);
#define PID_SYSVAD DEFINE_GUIDNAMED(PID_SYSVAD)
// Pool tag used for SYSVAD allocations
-#define SYSVAD_POOLTAG 'DVSM'
+#define SYSVAD_POOLTAG 'DVSM'
// Debug module name
#define STR_MODULENAME "SYSVAD: "
@@ -70,9 +51,9 @@ DEFINE_GUIDSTRUCT("5B722BF8-F0AB-47ee-B9C8-8D61D31375A1", PID_SYSVAD);
// Debug utility macros
#define D_FUNC 4
#define D_BLAB DEBUGLVL_BLAB
-#define D_VERBOSE DEBUGLVL_VERBOSE
-#define D_TERSE DEBUGLVL_TERSE
-#define D_ERROR DEBUGLVL_ERROR
+#define D_VERBOSE DEBUGLVL_VERBOSE
+#define D_TERSE DEBUGLVL_TERSE
+#define D_ERROR DEBUGLVL_ERROR
#define DPF _DbgPrintF
#define DPF_ENTER(x) DPF(D_FUNC, x)
@@ -126,80 +107,15 @@ DEFINE_GUIDSTRUCT("5B722BF8-F0AB-47ee-B9C8-8D61D31375A1", PID_SYSVAD);
#define ALL_CHANNELS_ID UINT32_MAX
-// Flags to identify stream processing mode
-typedef enum {
- SIGNALPROCESSINGMODE_NONE = 0x00,
- SIGNALPROCESSINGMODE_DEFAULT = 0x01,
- SIGNALPROCESSINGMODE_RAW = 0x02,
- SIGNALPROCESSINGMODE_COMMUNICATIONS = 0x04,
- SIGNALPROCESSINGMODE_SPEECH = 0x08,
- SIGNALPROCESSINGMODE_NOTIFICATION = 0x10,
- SIGNALPROCESSINGMODE_MEDIA = 0x20,
- SIGNALPROCESSINGMODE_MOVIE = 0x40
-} SIGNALPROCESSINGMODE;
-
-#define MAP_GUID_TO_MODE(guid, mode) \
- if (IsEqualGUID(guid, AUDIO_SIGNALPROCESSINGMODE_DEFAULT)) \
- { \
- mode = SIGNALPROCESSINGMODE_DEFAULT; \
- } \
- else if (IsEqualGUID(guid, AUDIO_SIGNALPROCESSINGMODE_RAW)) \
- { \
- mode = SIGNALPROCESSINGMODE_RAW; \
- } \
- else if (IsEqualGUID(guid, AUDIO_SIGNALPROCESSINGMODE_COMMUNICATIONS)) \
- { \
- mode = SIGNALPROCESSINGMODE_COMMUNICATIONS; \
- } \
- else if (IsEqualGUID(guid, AUDIO_SIGNALPROCESSINGMODE_SPEECH)) \
- { \
- mode = SIGNALPROCESSINGMODE_SPEECH; \
- } \
- else if (IsEqualGUID(guid, AUDIO_SIGNALPROCESSINGMODE_NOTIFICATION)) \
- { \
- mode = SIGNALPROCESSINGMODE_NOTIFICATION; \
- } \
- else if (IsEqualGUID(guid, AUDIO_SIGNALPROCESSINGMODE_MEDIA)) \
- { \
- mode = SIGNALPROCESSINGMODE_MEDIA; \
- } \
- else if (IsEqualGUID(guid, AUDIO_SIGNALPROCESSINGMODE_MOVIE)) \
- { \
- mode = SIGNALPROCESSINGMODE_MOVIE; \
- } \
- else \
- { \
- ASSERT(FALSE && "Unknown Signal Processing Mode"); \
- mode = SIGNALPROCESSINGMODE_NONE; \
- }
-
-#define VERIFY_MODE_RESOURCES_AVAILABLE(modes, guid, status) \
- { \
- SIGNALPROCESSINGMODE mode = SIGNALPROCESSINGMODE_NONE; \
- MAP_GUID_TO_MODE(guid, mode); \
- if (SIGNALPROCESSINGMODE_NONE != mode) \
- { \
- status = (modes & mode) ? STATUS_INSUFFICIENT_RESOURCES : STATUS_SUCCESS; \
- } \
- else \
- { \
- status = STATUS_INVALID_PARAMETER; \
- } \
- }
+// Macros to assist with pin instance counting
+#define VERIFY_PIN_INSTANCE_RESOURCES_AVAILABLE(status, allocated, max) \
+ status = (allocated < max) ? STATUS_SUCCESS : STATUS_INSUFFICIENT_RESOURCES
-#define ALLOCATE_MODE_RESOURCES(modes, guid) \
- { \
- SIGNALPROCESSINGMODE mode = SIGNALPROCESSINGMODE_NONE; \
- MAP_GUID_TO_MODE(guid, mode); \
- modes |= mode; \
- }
+#define ALLOCATE_PIN_INSTANCE_RESOURCES(allocated) \
+ allocated++
-#define FREE_MODE_RESOURCES(modes, guid) \
- { \
- SIGNALPROCESSINGMODE mode = SIGNALPROCESSINGMODE_NONE; \
- MAP_GUID_TO_MODE(guid, mode); \
- modes &= (~mode); \
- }
+#define FREE_PIN_INSTANCE_RESOURCES(allocated) \
+ allocated--
// Define the value data type for supported sound detector patterns. Only
// one pattern type is supported in this sample.
@@ -236,7 +152,7 @@ typedef struct _PortClassDeviceContext // 32 64 Byte off
ULONG_PTR m_pulReserved1[2]; // 0-7 0-15 First two pointers are reserved.
PDEVICE_OBJECT m_DoNotUsePhysicalDeviceObject; // 8-11 16-23 Reserved pointer to our Physical Device Object (PDO).
PVOID m_pvReserved2; // 12-15 24-31 Reserved pointer to our Start Device function.
- PVOID m_pvReserved3; // 16-19 32-39 "Out Memory" according to DDK.
+ PVOID m_pvReserved3; // 16-19 32-39 "Out Memory" according to DDK.
IAdapterCommon* m_pCommon; // 20-23 40-47 Pointer to our adapter common object.
#ifdef _USE_SingleComponentMultiFxStates
POHANDLE m_poHandle; // 24-27 48-55 PoFxDevice handle.
@@ -254,7 +170,7 @@ typedef struct _PortClassDeviceContext // 32 64 Byte off
//
#define MajorTarget_to_Obj(ptr) \
reinterpret_cast<CMiniportWaveRT*>(ptr)
-
+
#define MinorTarget_to_Obj(ptr) \
static_cast<CMiniportWaveRTStream*>(reinterpret_cast<PMINIPORTWAVERTSTREAM>(ptr))
@@ -263,6 +179,7 @@ typedef struct _PortClassDeviceContext // 32 64 Byte off
//
extern DWORD g_DoNotCreateDataFiles;
extern DWORD g_DisableBthScoBypass;
+extern UNICODE_STRING g_RegistryPath;
//=============================================================================
// Function prototypes
@@ -270,8 +187,8 @@ extern DWORD g_DisableBthScoBypass;
// Generic topology handler
NTSTATUS PropertyHandler_Topology
-(
- _In_ PPCPROPERTY_REQUEST PropertyRequest
+(
+ _In_ PPCPROPERTY_REQUEST PropertyRequest
);
// Default WaveFilter automation table.
@@ -287,8 +204,8 @@ NTSTATUS PropertyHandler_OffloadPin
);
NTSTATUS PropertyHandler_GenericPin
-(
- _In_ PPCPROPERTY_REQUEST PropertyRequest
+(
+ _In_ PPCPROPERTY_REQUEST PropertyRequest
);
// common.h uses some of the above definitions.
diff --git a/audio/sysvad/sysvad.sln b/audio/sysvad/sysvad.sln
index 4aef7d1f..6fa08722 100644
--- a/audio/sysvad/sysvad.sln
+++ b/audio/sysvad/sysvad.sln
@@ -1,16 +1,12 @@

Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 14
-VisualStudioVersion = 14.0.25431.01
+# Visual Studio 15
+VisualStudioVersion = 15.0.27703.2042
MinimumVisualStudioVersion = 12.0
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Package", "Package", "{FA56D96B-290B-4C73-A5E1-02C1861D3224}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "KeywordDetectorAdapter", "KeywordDetectorAdapter", "{DBD14E7B-7F95-4743-86E3-4E16FA43F990}"
EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SwapAPO", "SwapAPO", "{684FF1CF-64CC-430E-81F7-9D603EF56D59}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "APO", "APO", "{367FF255-7280-48C4-90AC-767124A8D5F7}"
-EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "EndpointsCommon", "EndpointsCommon", "{0B4B8E51-20A8-43A4-A8DA-42FF90D628AC}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "PhoneAudioSample", "PhoneAudioSample", "{D0DBEBE9-0DCC-4EA7-966B-C029C1334D9E}"
@@ -21,10 +17,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "package", "package\package.
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KeywordDetectorContosoAdapter", "KeywordDetectorAdapter\KeywordDetectorContosoAdapter.vcxproj", "{E0F02048-78A4-4FE8-B863-66E6CB6A2C37}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SwapAPO", "SwapAPO\APO\SwapAPO.vcxproj", "{691F1D0F-CA50-46CD-8BBA-A59E9E8EB601}"
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DelayAPO", "SwapAPO\DelayAPO\DelayAPO.vcxproj", "{8851AB85-70B3-4798-A149-BA366DF9EC25}"
-EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "EndpointsCommon", "EndpointsCommon\EndpointsCommon.vcxproj", "{33E61864-6F2C-4F9F-BE70-8F8985A4F283}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PhoneAudioSample", "PhoneAudioSample\PhoneAudioSample.vcxproj", "{FABA4668-DB5E-4F6C-9D25-A0B25AD084EE}"
@@ -37,70 +29,76 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TabletAudioSample", "Tablet
{33E61864-6F2C-4F9F-BE70-8F8985A4F283} = {33E61864-6F2C-4F9F-BE70-8F8985A4F283}
EndProjectSection
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "APO", "APO", "{D86F9A10-C48D-4048-A03C-DD7BCA6E165F}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DelayAPO", "APO\DelayAPO\DelayAPO.vcxproj", "{8851AB85-70B3-4798-A149-BA366DF9EC25}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SwapAPO", "APO\SwapAPO\SwapAPO.vcxproj", "{691F1D0F-CA50-46CD-8BBA-A59E9E8EB601}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
- Release|Win32 = Release|Win32
Debug|x64 = Debug|x64
+ Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{830B14D5-0E32-4F9E-AEFA-4C9F6FC13C2A}.Debug|Win32.ActiveCfg = Debug|Win32
{830B14D5-0E32-4F9E-AEFA-4C9F6FC13C2A}.Debug|Win32.Build.0 = Debug|Win32
- {830B14D5-0E32-4F9E-AEFA-4C9F6FC13C2A}.Release|Win32.ActiveCfg = Release|Win32
- {830B14D5-0E32-4F9E-AEFA-4C9F6FC13C2A}.Release|Win32.Build.0 = Release|Win32
{830B14D5-0E32-4F9E-AEFA-4C9F6FC13C2A}.Debug|x64.ActiveCfg = Debug|x64
{830B14D5-0E32-4F9E-AEFA-4C9F6FC13C2A}.Debug|x64.Build.0 = Debug|x64
+ {830B14D5-0E32-4F9E-AEFA-4C9F6FC13C2A}.Release|Win32.ActiveCfg = Release|Win32
+ {830B14D5-0E32-4F9E-AEFA-4C9F6FC13C2A}.Release|Win32.Build.0 = Release|Win32
{830B14D5-0E32-4F9E-AEFA-4C9F6FC13C2A}.Release|x64.ActiveCfg = Release|x64
{830B14D5-0E32-4F9E-AEFA-4C9F6FC13C2A}.Release|x64.Build.0 = Release|x64
{E0F02048-78A4-4FE8-B863-66E6CB6A2C37}.Debug|Win32.ActiveCfg = Debug|Win32
{E0F02048-78A4-4FE8-B863-66E6CB6A2C37}.Debug|Win32.Build.0 = Debug|Win32
- {E0F02048-78A4-4FE8-B863-66E6CB6A2C37}.Release|Win32.ActiveCfg = Release|Win32
- {E0F02048-78A4-4FE8-B863-66E6CB6A2C37}.Release|Win32.Build.0 = Release|Win32
{E0F02048-78A4-4FE8-B863-66E6CB6A2C37}.Debug|x64.ActiveCfg = Debug|x64
{E0F02048-78A4-4FE8-B863-66E6CB6A2C37}.Debug|x64.Build.0 = Debug|x64
+ {E0F02048-78A4-4FE8-B863-66E6CB6A2C37}.Release|Win32.ActiveCfg = Release|Win32
+ {E0F02048-78A4-4FE8-B863-66E6CB6A2C37}.Release|Win32.Build.0 = Release|Win32
{E0F02048-78A4-4FE8-B863-66E6CB6A2C37}.Release|x64.ActiveCfg = Release|x64
{E0F02048-78A4-4FE8-B863-66E6CB6A2C37}.Release|x64.Build.0 = Release|x64
- {691F1D0F-CA50-46CD-8BBA-A59E9E8EB601}.Debug|Win32.ActiveCfg = Debug|Win32
- {691F1D0F-CA50-46CD-8BBA-A59E9E8EB601}.Debug|Win32.Build.0 = Debug|Win32
- {691F1D0F-CA50-46CD-8BBA-A59E9E8EB601}.Release|Win32.ActiveCfg = Release|Win32
- {691F1D0F-CA50-46CD-8BBA-A59E9E8EB601}.Release|Win32.Build.0 = Release|Win32
- {691F1D0F-CA50-46CD-8BBA-A59E9E8EB601}.Debug|x64.ActiveCfg = Debug|x64
- {691F1D0F-CA50-46CD-8BBA-A59E9E8EB601}.Debug|x64.Build.0 = Debug|x64
- {691F1D0F-CA50-46CD-8BBA-A59E9E8EB601}.Release|x64.ActiveCfg = Release|x64
- {691F1D0F-CA50-46CD-8BBA-A59E9E8EB601}.Release|x64.Build.0 = Release|x64
- {8851AB85-70B3-4798-A149-BA366DF9EC25}.Debug|Win32.ActiveCfg = Debug|Win32
- {8851AB85-70B3-4798-A149-BA366DF9EC25}.Debug|Win32.Build.0 = Debug|Win32
- {8851AB85-70B3-4798-A149-BA366DF9EC25}.Release|Win32.ActiveCfg = Release|Win32
- {8851AB85-70B3-4798-A149-BA366DF9EC25}.Release|Win32.Build.0 = Release|Win32
- {8851AB85-70B3-4798-A149-BA366DF9EC25}.Debug|x64.ActiveCfg = Debug|x64
- {8851AB85-70B3-4798-A149-BA366DF9EC25}.Debug|x64.Build.0 = Debug|x64
- {8851AB85-70B3-4798-A149-BA366DF9EC25}.Release|x64.ActiveCfg = Release|x64
- {8851AB85-70B3-4798-A149-BA366DF9EC25}.Release|x64.Build.0 = Release|x64
{33E61864-6F2C-4F9F-BE70-8F8985A4F283}.Debug|Win32.ActiveCfg = Debug|Win32
{33E61864-6F2C-4F9F-BE70-8F8985A4F283}.Debug|Win32.Build.0 = Debug|Win32
- {33E61864-6F2C-4F9F-BE70-8F8985A4F283}.Release|Win32.ActiveCfg = Release|Win32
- {33E61864-6F2C-4F9F-BE70-8F8985A4F283}.Release|Win32.Build.0 = Release|Win32
{33E61864-6F2C-4F9F-BE70-8F8985A4F283}.Debug|x64.ActiveCfg = Debug|x64
{33E61864-6F2C-4F9F-BE70-8F8985A4F283}.Debug|x64.Build.0 = Debug|x64
+ {33E61864-6F2C-4F9F-BE70-8F8985A4F283}.Release|Win32.ActiveCfg = Release|Win32
+ {33E61864-6F2C-4F9F-BE70-8F8985A4F283}.Release|Win32.Build.0 = Release|Win32
{33E61864-6F2C-4F9F-BE70-8F8985A4F283}.Release|x64.ActiveCfg = Release|x64
{33E61864-6F2C-4F9F-BE70-8F8985A4F283}.Release|x64.Build.0 = Release|x64
{FABA4668-DB5E-4F6C-9D25-A0B25AD084EE}.Debug|Win32.ActiveCfg = Debug|Win32
{FABA4668-DB5E-4F6C-9D25-A0B25AD084EE}.Debug|Win32.Build.0 = Debug|Win32
- {FABA4668-DB5E-4F6C-9D25-A0B25AD084EE}.Release|Win32.ActiveCfg = Release|Win32
- {FABA4668-DB5E-4F6C-9D25-A0B25AD084EE}.Release|Win32.Build.0 = Release|Win32
{FABA4668-DB5E-4F6C-9D25-A0B25AD084EE}.Debug|x64.ActiveCfg = Debug|x64
{FABA4668-DB5E-4F6C-9D25-A0B25AD084EE}.Debug|x64.Build.0 = Debug|x64
+ {FABA4668-DB5E-4F6C-9D25-A0B25AD084EE}.Release|Win32.ActiveCfg = Release|Win32
+ {FABA4668-DB5E-4F6C-9D25-A0B25AD084EE}.Release|Win32.Build.0 = Release|Win32
{FABA4668-DB5E-4F6C-9D25-A0B25AD084EE}.Release|x64.ActiveCfg = Release|x64
{FABA4668-DB5E-4F6C-9D25-A0B25AD084EE}.Release|x64.Build.0 = Release|x64
{E4DF0EEE-D35B-47F2-A9B1-41EA97C465FF}.Debug|Win32.ActiveCfg = Debug|Win32
{E4DF0EEE-D35B-47F2-A9B1-41EA97C465FF}.Debug|Win32.Build.0 = Debug|Win32
- {E4DF0EEE-D35B-47F2-A9B1-41EA97C465FF}.Release|Win32.ActiveCfg = Release|Win32
- {E4DF0EEE-D35B-47F2-A9B1-41EA97C465FF}.Release|Win32.Build.0 = Release|Win32
{E4DF0EEE-D35B-47F2-A9B1-41EA97C465FF}.Debug|x64.ActiveCfg = Debug|x64
{E4DF0EEE-D35B-47F2-A9B1-41EA97C465FF}.Debug|x64.Build.0 = Debug|x64
+ {E4DF0EEE-D35B-47F2-A9B1-41EA97C465FF}.Release|Win32.ActiveCfg = Release|Win32
+ {E4DF0EEE-D35B-47F2-A9B1-41EA97C465FF}.Release|Win32.Build.0 = Release|Win32
{E4DF0EEE-D35B-47F2-A9B1-41EA97C465FF}.Release|x64.ActiveCfg = Release|x64
{E4DF0EEE-D35B-47F2-A9B1-41EA97C465FF}.Release|x64.Build.0 = Release|x64
+ {8851AB85-70B3-4798-A149-BA366DF9EC25}.Debug|Win32.ActiveCfg = Debug|Win32
+ {8851AB85-70B3-4798-A149-BA366DF9EC25}.Debug|Win32.Build.0 = Debug|Win32
+ {8851AB85-70B3-4798-A149-BA366DF9EC25}.Debug|x64.ActiveCfg = Debug|x64
+ {8851AB85-70B3-4798-A149-BA366DF9EC25}.Debug|x64.Build.0 = Debug|x64
+ {8851AB85-70B3-4798-A149-BA366DF9EC25}.Release|Win32.ActiveCfg = Release|Win32
+ {8851AB85-70B3-4798-A149-BA366DF9EC25}.Release|Win32.Build.0 = Release|Win32
+ {8851AB85-70B3-4798-A149-BA366DF9EC25}.Release|x64.ActiveCfg = Release|x64
+ {8851AB85-70B3-4798-A149-BA366DF9EC25}.Release|x64.Build.0 = Release|x64
+ {691F1D0F-CA50-46CD-8BBA-A59E9E8EB601}.Debug|Win32.ActiveCfg = Debug|Win32
+ {691F1D0F-CA50-46CD-8BBA-A59E9E8EB601}.Debug|Win32.Build.0 = Debug|Win32
+ {691F1D0F-CA50-46CD-8BBA-A59E9E8EB601}.Debug|x64.ActiveCfg = Debug|x64
+ {691F1D0F-CA50-46CD-8BBA-A59E9E8EB601}.Debug|x64.Build.0 = Debug|x64
+ {691F1D0F-CA50-46CD-8BBA-A59E9E8EB601}.Release|Win32.ActiveCfg = Release|Win32
+ {691F1D0F-CA50-46CD-8BBA-A59E9E8EB601}.Release|Win32.Build.0 = Release|Win32
+ {691F1D0F-CA50-46CD-8BBA-A59E9E8EB601}.Release|x64.ActiveCfg = Release|x64
+ {691F1D0F-CA50-46CD-8BBA-A59E9E8EB601}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -108,11 +106,13 @@ Global
GlobalSection(NestedProjects) = preSolution
{830B14D5-0E32-4F9E-AEFA-4C9F6FC13C2A} = {FA56D96B-290B-4C73-A5E1-02C1861D3224}
{E0F02048-78A4-4FE8-B863-66E6CB6A2C37} = {DBD14E7B-7F95-4743-86E3-4E16FA43F990}
- {691F1D0F-CA50-46CD-8BBA-A59E9E8EB601} = {367FF255-7280-48C4-90AC-767124A8D5F7}
- {8851AB85-70B3-4798-A149-BA366DF9EC25} = {367FF255-7280-48C4-90AC-767124A8D5F7}
{33E61864-6F2C-4F9F-BE70-8F8985A4F283} = {0B4B8E51-20A8-43A4-A8DA-42FF90D628AC}
{FABA4668-DB5E-4F6C-9D25-A0B25AD084EE} = {D0DBEBE9-0DCC-4EA7-966B-C029C1334D9E}
{E4DF0EEE-D35B-47F2-A9B1-41EA97C465FF} = {C06F6070-75EE-4F57-8D35-4AC2AB08D029}
- {367FF255-7280-48C4-90AC-767124A8D5F7} = {684FF1CF-64CC-430E-81F7-9D603EF56D59}
+ {8851AB85-70B3-4798-A149-BA366DF9EC25} = {D86F9A10-C48D-4048-A03C-DD7BCA6E165F}
+ {691F1D0F-CA50-46CD-8BBA-A59E9E8EB601} = {D86F9A10-C48D-4048-A03C-DD7BCA6E165F}
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {6DB4FE19-4FE0-4DC4-B898-C46E01E6BDF4}
EndGlobalSection
EndGlobal