none
Custom Audio Endpoint rdpendp.dll for 2008 R2

    Question

  • Hi,

    I am trying to replace the native rdpendp.dll with my custom dll.

    While I have the basic functionality working, there are a few things need to be clarified.

    I couldn’t find any reasonable documentation on how to “Implement a Custom Audio Endpoint Enumerator”.

    Some few words mentioned in http://technet.microsoft.com/en-us/query/ee958171 and other similar sites

    Does anyone know where to get more info?


    wind15
    Thursday, January 19, 2012 4:30 PM

All replies

  • The reference documentation for how to implement and register audio endpoints is here:

    http://msdn.microsoft.com/en-us/library/windows/desktop/dd379706(v=vs.85).aspx


    Matthew van Eerde
    Thursday, January 19, 2012 4:38 PM
  • Maurits,

    Thanks for the quick reply! I think the information you pointed out is for something on the client side of the RDP connection.

    In addition it looks like this doesn’t support Win 2008 server. For example the IAudioDeviceEndpoint Requirements say:

    Minimum supported client            Windows 7

    Minimum supported server           None supported

      

     I am looking for the service side of RDP: rdpendp.DLL with the entry point:  GetTSAudioEndpointEnumeratorForSession() returned IMMDeviceEnumerator

    Once the IMMDeviceEnumerator object obtained the rest of the objects will be initialized and use (IMMDevice, IMMDeviceCollection, IMMDeviceEnumerator, IMMEndpoint, IAudioSessionManager, IPropertyStore e.t.c)

    The APIs provided describe the application side of it. It is not clear how the objects interconnect and their functionality.

    For example: IAudioSessionManager is obtained from ImmDevice::Activate.

    If I call Activate on two different devices do I get the same IAudioSessionManager? Is the IAudioSessionManager per ImmDevice or per Application or WTS session?

    IAudioSessionManager also can be obtained from  CIAudioSessionManager::QueryInterface – is that the same IAudioSessionManager or a new instance of it?

    Is there any information on how the objects interconnect? Any sample source code on the implementation of the custom rdpendp.dll?

    I have checked both SDK and DDK and didn’t find any sample code.

     


    wind15
    Thursday, January 19, 2012 5:48 PM
  • As I understand it...

    Clients don't need to do anything special to be able to use your audio endpoints.  They won't know (or care) whether the audio endpoints they're playing to are physical audio devices, or Windows remote audio, or your remote audio.  They act at an IAudioClient level (or above.)

    If you're implementing audio endpoints then you will need to implement an object which exposes the IMMDeviceEnumerator interface, and return it from yourdll!GetTSAudioEndpointEnumeratorForSession.

    This should enumerate all of your audio endpoints (possibly only one.)

    You shouldn't need to worry about IAudioSessionManager at all.  This is not a session in the sense of a Windows session; it's a session in the sense of a slider in the Volume Mixer (usually, an app.).  All of these sessions will get mixed together into a single stream by the Windows audio engine before they hit your audio endpoint.


    Matthew van Eerde
    Thursday, January 19, 2012 6:35 PM
  • >> “Clients don't need to do anything special to be able to use your audio endpoints.”

    Ok, I think there may be some terminology confusion here. When you say “Clients” do you mean an RDP client or an application that uses an audio driver?

    >> “If you're implementing audio endpoints…”

    I guess I do implement audio endpoints - I am trying to redirect audio from terminal session on W2008 to elsewhere (using protocols other than RDP).

    In order to achieve it I replaced rdpendp.dll with Custom.dll in

    System\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp :  AudioEnumeratorDll

    I did it in hope that any application that uses audio will eventually end up calling IAudioClient/ IAudioCaptureClient/ IAudioRenderClient

    I implemented the minimum required by MSDN:

    http://msdn.microsoft.com/en-us/library/windows/desktop/ee958171(v=vs.85).aspx

    It sort of works and I am able to hear the sound on my client PC while playing it on the server. However, there are a lot of unknowns and issues with my driver Custom.dll and so I am looking for additional information on how the components should work together.

    >> “You shouldn't need to worry about IAudioSessionManager at all…”

    I understand it is not a windows session, rather for the Volume Mixer.

    Before the IAudioClient is created the system calls for IMMDevice and other things including IAudioSessionManager - it is huge complex thing that needs to be fully implemented

    It is got called during the audio initialization and operation. So I do have to worry about it and provide the correct implementation. Each IAudioClient::Initialize is assigned a LPCGUID AudioSessionGuid that is some how should end up recognized by the Volume Mixer and be displayed.

    Where can I get info on how it all works?

    Thank you for your help.

     


    wind15
    Thursday, January 19, 2012 8:49 PM
  • Here's a diagram that shows how WASAPI works.

    http://technet.microsoft.com/en-us/query/dd316780

    Your endpoint would plug in immediately after the audio engine.


    Matthew van Eerde
    Thursday, January 19, 2012 11:20 PM
  • And slo another question:

    My drivers receives this call form the SndVol.exe:

    CIAudioSessionControl::QueryInterface with IID == {604E2AE7-C4C5-4032-93FF-88B26CDD75B8}

    I checked SDKs, DirectX SDK, DDKs - can't find what this IID value means. There are more of those unknown IIDs but at the momnet this one is the show stopper.

    Where can I find the list of IID values? They seem to be scatered all over the place.


    wind15
    Thursday, January 19, 2012 11:28 PM
  • I see... you're implementing IMMDeviceEnumerator, so you're implementing IMMDevice, and you are therefore getting IMMDevice::Activate calls for all kinds of stuff.  Let me ask internally how much of the IMMDevice::Activate stuff you're expected to acknowledge.


    Matthew van Eerde
    Thursday, January 19, 2012 11:43 PM
  • Your endpoint would plug in immediately after the audio engine.

    The rdpendp.DLL runs in the Application process. I was under the impression this is where the audio can get redirected – similar to rdpsnd.dll in W2003.

    So, if I am right after the audio engine, it means (according to the diagram) my driver should be in the service process (not in the kernel and not in the application process)?

    What service do I need to replace to achieve my goal?

    What interface the service has to export to the layers above?


    wind15
    Thursday, January 19, 2012 11:47 PM
  • W2008's audio architecture is very different than W2003's; all of "user mode audio" was new for W2008.

    The IMMDeviceEnumerator stuff should get loaded in the client process as well as the audio service and audiodg.exe (the audio device graph).

    The IAudioEndpoint stuff would be loaded only in audiodg.exe (not in the client process.)


    Matthew van Eerde
    Friday, January 20, 2012 12:10 AM
  • I can give you a partial answer now while I wait to hear back from people...

    The docs for IMMDevice::Activate give a whole list of interfaces:

    IID_IAudioClient
    IID_IAudioEndpointVolume
    IID_IAudioMeterInformation
    IID_IAudioSessionManager
    IID_IAudioSessionManager2
    IID_IBaseFilter
    IID_IDeviceTopology
    IID_IDirectSound
    IID_IDirectSound8
    IID_IDirectSoundCapture
    IID_IDirectSoundCapture8
    IID_IMFTrustedOutput

    You are not on the hook to implement all of these (in fact, you likely don't need to implement any of them.)  If you don't implement one, you have to return the specific HRESULT E_NOINTERFACE from the ::Activate implementation, and then Windows will fall back to its own implementation.  Don't return any other failing HRESULT or Windows will give up and bad things will happen.

    I'm attempting to get a definitive answer on whether you are on the hook to implement any specific interfaces.


    Matthew van Eerde
    Friday, January 20, 2012 12:26 AM
  • Yes, I did implement only some of them:

    IID_IAudioClient
    IID_IAudioEndpointVolume
    IID_IAudioMeterInformation
    IID_IAudioSessionManager
    IID_IAudioSessionManager2
    IID_IBaseFilter
    IID_IDeviceTopology

    Those I couldn't get away with E_NOINTERFACE – the sndVol.exe and mmsys.cpl  would crash. Others don't get called at all - so I don't know how they affect an application.

     


    wind15
    Friday, January 20, 2012 1:22 AM
  • I can confirm that none of them are required - it is safe to return E_NOINTERFACE for all of them.  The crash is worrying though.  Where's it crashing?

    EDIT: In particular, all of these have default implementations which will be used if you return E_NOINTERFACE from you IMMDevice::Activate implementation.  You are free to provide implementations if you like, though - for example, you might bubble IAudioEndpointVolume down to the TS client.

     


    Matthew van Eerde
    Friday, January 20, 2012 1:25 AM
  • Ok, I guess I understand: If I didn’t implement IID_IAudioSessionManager and IID_IAudioSessionManager2 then I wouldn’t see sessions in the SndVol.exe

    However, in order to redirect the audio stream and have access to the stream buffers I do have to implement the chain: IID_IAudioClient -> IAudioClient::GetService() -> IID_IAudioCaptureClient/ IID_IAudioRenderClient.

    Is that a correct assumption?

     

    I will disable all the rest of IIDs in the IMMDevice::Activate and see which one causes the crash.

    Thank you for your help!


    wind15
    Friday, January 20, 2012 4:35 PM
  • If you don't implement IAudioSessionManager, then Windows will fall back to its own implementation.  You will still see sessions in sndvol.exe.

    If you don't implement IAudioClient, Windows will fall back to its own implementation.

    You should only need to implement:

    IMMDeviceEnumerator -> IMMDevice -> ??? -> IAudioEndpoint and friends.

    I'm not quite sure yet how Windows gets from an IMMDevice to an IAudioEndpoint.  Looking.

     


    Matthew van Eerde
    Friday, January 20, 2012 5:49 PM
  • OK, I believe that:

    When the number of playing audio streams goes from 0 to 1 you will see an IMMDevice::Activate(IAudioOutputEndpointRT).  You should implement this interface.  You will also see some QIs off of the IAudioOutputEndpointRT to other interfaces in the AudioEndpoint API family.

    As the number of playing audio streams (in that TS session) goes up to n, Windows will take care of mixing the streams for you; you only need to worry about handling the already-mixed buffers that Windows gives you.

    When the number of streams drops to 0 then the audio endpoint will be released and your .dll will be unloaded.


    Matthew van Eerde
    Friday, January 20, 2012 6:28 PM
  • That sounds great!

    Except I am in doubt - IMMDevice::Activate doesn’t have the IID_IAudioOutputEndpointRT listed as a possible parameter. Where is this IID defined? Can’t find it.

     


    wind15
    Friday, January 20, 2012 6:42 PM
  • It's in sdk/inc/audioengineendpoint.h

    The IMMDevice::Activate documentation is primarily geared to WASAPI audio clients (apps) which should not be messing with IAudioOutputEndpointRT.  I will ask that the TS audio docs be updated to indicate that the link between "how to write a custom audio enumerator" and "how to implement a custom audio endpoint" is IMMDevice::Activate(IAudioOutputEndpointRT).


    Matthew van Eerde
    Friday, January 20, 2012 6:46 PM
  • According to http://msdn.microsoft.com/en-us/library/windows/desktop/dd920052(v=vs.85).aspx you shouldn't be modifying settings under Rdp-Tcp; instead you should define your own protocol listener and register it alongside Rdp-Tcp.
    Matthew van Eerde
    Friday, January 20, 2012 6:59 PM
  • >> "According to http://msdn.microsoft.com/en-us/library/windows/desktop/dd920052(v=vs.85).aspx you shouldn't be modifying settings under Rdp-Tcp; instead you should define your own protocol listener and register it alongside Rdp-Tcp."

    I am aware of this, it didn't work for me so I used Rdp-Tcp - it is whole new subject. I will revisit it later on when the driver works. BTW will need more info.

    I've also added all of these: IID_IAudioEndpoint, IID_IAudioEndpointRT, IID_IAudioOutputEndpointRT, IID_IAudioInputEndpointRT in to IMMDevice::Activate(IID) - it never get called with those IID.

    In fact, I didn't find any info on how to obtain any of the mentioned IIDs by any other means.

     

     

     

     

     



    wind15
    Friday, January 20, 2012 9:05 PM
  • Hmmm...

    Could you start a thread in the Remote Desktop Services forum? http://social.technet.microsoft.com/Forums/en-us/winserverTS/threads


    Matthew van Eerde
    Friday, January 20, 2012 9:24 PM
  • I sure will try.

    Please let me know if you find any other relative info.

    I appreciate your help!


    wind15
    Friday, January 20, 2012 10:41 PM
  • Just to follow up on the open issues:

    1.    IMMDevice::Activate() and optional IIDs. I tried to remove some of them. Here is what I‘ve got:

    A must implement:

    IID_IAudioClient
    IID_IAudioEndpointVolume
    IID_IAudioMeterInformation

    Optional - you don’t see session in SndVol.exe, but audio APPs above are ok:

    IID_IAudioSessionManager
    IID_IAudioSessionManager2

    IID_IDeviceTopology

    IID_IBaseFilter

    IIDs never got called:

    IID_IDirectSound
    IID_IDirectSound8
    IID_IDirectSoundCapture
    IID_IDirectSoundCapture8
    IID_IMFTrustedOutput

    2.    Tried to do installation according to  http://msdn.microsoft.com/en-us/library/windows/desktop/dd920052(v=vs.85).aspx

    It doesn’t work – my driver never got called.

    In my CustomRdp-Tcp I only implemented two values:

    AudioEnumeratorDll = MyCustom.Dll

    LoadableProtocol_Object = {18b726bb-6fe6-4fb9-9276-ed57ce7c7cb2}

     

    What would be the value of LoadableProtocol_Object for my driver? Is it the same as for the Rdp-Tcp ({18b726bb-6fe6-4fb9-9276-ed57ce7c7cb2})?

     

    I wonder how much of the registry set I need to implement? The Rdp-Tcp has a lot of entries there what do they all mean?

     

    Thank you for your help.

     

     


    wind15
    Tuesday, January 24, 2012 4:56 PM
  • IAudioEndpointVolume and IAudioMeterInformation should also be optional.  If the endpoint doesn't provide a volume control or a meter, then an APO will be injected in the device pipe which fulfills that function.

    If you're having to implement IAudioClient, something is very wrong.

    Are you able to confirm that your .dll is getting loaded by the audio service and/or audiodg.exe, and not just by the audio-playing-app?


    Matthew van Eerde
    Tuesday, January 24, 2012 8:58 PM
  • The only way for me to gain access to the Capture/Render buffers is to implement IAudioCaptureClient/IAudioRenderClient. The IAudioRenderClient can be obtained only from the IAudioClient.

     

    The way you suggested (IID_IAudioEndpoint->IID_IAudioEndpointRT->IID_IAudioOutputEndpointRT) is not documented. It is not clear how to create the create objects for those IIDs.

     

    The http://social.technet.microsoft.com/Forums/en-us/winserverTS/threads is not responding so far.

    The only choice I have left is: IAudioClient.

    Do you think I can find out more info if I open my msdn subscription incident or do you have the same sources of information? Can I talk directly to the developers?

     

    Thank you.


    wind15
    Tuesday, January 24, 2012 9:59 PM
  • Opening a support request is a good idea.

    Are you seeing IMMDevice::Activate requests for any of the audio endpoint API interfaces?

    Is your IPropertyStore interface being queried? If so, what properties are you being asked for and what values are you providing?  In particular I'm interested in a "do you support event-driven mode" property.


    Matthew van Eerde
    Tuesday, January 24, 2012 10:17 PM
  • “Are you seeing IMMDevice::Activate requests for any of the audio endpoint API interfaces?”

    No, nothing on endpoint API(IID_IAudioEndpointXXX). Only for IID_IAudioClientXXX

    Is your IPropertyStore interface being queried? If so, what properties are you being asked for and what values are you providing?

    IPropertyStore::GetValue is coming for:

              PKEY_DeviceInterface_FriendlyName

              PKEY_Device_DeviceDesc

              PKEY_Device_FriendlyName

              PKEY_AudioEndpoint_FormFactor

              PKEY_AudioEndpoint_GUID

              PKEY_DeviceClass_IconPath

              PKEY_Device_EnumeratorName

     

    I support them as per minimal support according to http://msdn.microsoft.com/en-us/library/windows/desktop/ee958171(v=vs.85).aspx

     

    Some others coming but I couldn’t find what they are. For example:

    {B3F8FA53-0004-438E-9003-51A46E139BFC}-1

     

    “"Do you support event-driven mode" property?”

    I am not sure what this property is. Do you mean IAudioClient::Initialize(AUDCLNT_STREAMFLAGS_EVENTCALLBACK)?


    wind15
    Wednesday, January 25, 2012 4:35 PM
  • PKEY_AudioEndpoint_Supports_EventDriven_Mode (in mmdeviceapi.idl).

     

    What values are you returning?


    Matthew van Eerde
    Wednesday, January 25, 2012 4:53 PM
  • Here are the samples of requests I am getting in IPropertyStore::GetValue();

     PKEY_Device_FriendlyName == My Audio In Device

    PKEY_DeviceInterface_FriendlyName == My Audio In Iface

    PKEY_Device_FriendlyName == My Audio Out Device

    PKEY_DeviceInterface_FriendlyName == My Audio Out Iface

    PKEY_Device_DeviceDesc == My Audio RDP Capture Device

    PKEY_Device_DeviceDesc == My Audio RDP Capture Device

    PKEY_Device_DeviceDesc == My Audio RDP Render Device

    PKEY_DeviceInterface_FriendlyName == My Audio Out Iface

     

    These two I don’t support and return S_OK along with pv->vt = VT_EMPTY;

    PKEY_AudioEndpoint_Disable_SysFx

    {B3F8FA53-0004-438E-9003-51A46E139BFC} – 1 – don’t know what it is

    Never received PKEY_AudioEndpoint_Supports_EventDriven_Mode

    I think it is really depend on the APP which PKEY_XXX it requests.

    The sample I gave you is from Communicator.exe.

    Please, let me know if you want to see the results from different processes.


    wind15
    Wednesday, January 25, 2012 6:17 PM
  • @wind15
    I think your DLL is not correctly signed and is blocked by window server 2008.

    @Maurits:
    a. I got IMMDevice::Activate(IAudioOutputEndpointRT) called by svchost.exe/Audiodg.exe.
    b. I got following APIs called:
         IAudioDeviceEndpoint::GetEventDrivenCapable  return TRUE
         IAudioEndpoint::SetStreamFlags                         return S_OK
         IAudioDeviceEndpoint::SetBuffer                         return S_OK
         IAudioEndpoint::GetFrameFormat                        return S_OK with my  mix format
         IAudioEndpoint::GetLatency                                return 0   
         IAudioEndpoint::SetEventHandle                        return S_OK

       But tried with audio client app from SDK sample "multimedia\audio\RenderSharedTimerDriven".
       IAudioClient::GetMixFormat return my DLL's mixer format.  but IAudioClient::Initialize always return 0x88890008  (AUDCLINT_E_UNSUPPORTED_FORMAT).

       I returned mixer format in IAudioEndpoint::GetFrameFormat and IPropertyStore::GetValue(PKEY_AudioEngine_DeviceFormat).
    pwaf->Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
    pwaf->Format.nChannels = 2;
    pwaf->Format.nSamplesPerSec = 44100;
    pwaf->Format.nAvgBytesPerSec = 44100 * 4;
    pwaf->Format.nBlockAlign = 4;
    pwaf->Format.wBitsPerSample = 16;
    pwaf->Format.cbSize = 22;
    pwaf->Samples.wValidBitsPerSample = 16;
    pwaf->dwChannelMask = 3;
    pwaf->SubFormat = KSDATAFORMAT_SUBTYPE_PCM;

       I am wordering the behavior is related with audio device's properties.
       I got following unkonw property in IPropertyStore::GetValue.

       {9855c4cd-df8c-449c-a181-8191b68bd06c}, 0
       {9855c4cd-df8c-449c-a181-8191b68bd06c}, 1
       {b3f8fa53-0004-438e-9003-51a46e139bfc}, 1
       {b3f8fa53-0004-438e-9003-51a46e139bfc}, 2
       {b3f8fa53-0004-438e-9003-51a46e139bfc}, 4
       {b3f8fa53-0004-438e-9003-51a46e139bfc}, 8
       {b3f8fa53-0004-438e-9003-51a46e139bfc}, 9
       {b3f8fa53-0004-438e-9003-51a46e139bfc}, 14
       {e4870e26-3cc5-4cd2-ba46-ca0a9a70ed04}, 1
       {f3e80bef-1723-4ff2-bcc4-7f83dc5e46d4}, 3
       {b3f8fa53-0004-438e-9003-51a46e139bfc}, 8
       {b3f8fa53-0004-438e-9003-51a46e139bfc}, 9

       Can I know what properties are the mininum set for us to implement and the meanings for those IDs.

    thanks

      
    Wednesday, March 14, 2012 8:49 AM
  • @Herb Wang,

    I am not sure why you think my “DLL is not correctly signed and is blocked by window server 2008”. You don’t need to sign it. It works fine with the SndVol.exe, mmsys.cpl, the Office communicator 2007, Lync and Skype. I didn’t test it with the others as I don’t need to.

    I was looking for more information on how the things supposed to work and where to find those GUID values – welcome to my world…

    As for the IAudioClient::Initialize(), you have full control of how to implement it and what value to return.


    wind15

    Wednesday, March 14, 2012 2:37 PM
  • @wind15

    From MSDN http://msdn.microsoft.com/en-us/library/windows/desktop/ee958171(v=vs.85).aspx 

    "The DLL must be signed so that secure processes can load it."

    You can follow MSDN's "Kernel-Mode code signing" to verify it, will find error in system log, "code integrity" section.

    I want audio-engine combine all audio sessions for me, e.g. two audio apps are playing sound at same time.

    Using IAudioOutputEndpointRT interface can get audio data after audio-engine.

    However, this approach is poor documented, and lots of details are missing.

    -Herb

    Thursday, March 15, 2012 2:27 AM
  •  Herb,

    The subject of signing is irrelevant to this thread, it may fail to load with “secure processes”, I don’t care. My DLL get loaded and runs just fine with normal process.

    My initial question was about the source of information, in particular: Who implements and exports the IAudioEndpoint object and how can I implement my own.

    If you look at the entire conversation Maurits wrote: “IMMDeviceEnumerator -> IMMDevice -> ??? -> IAudioEndpoint and friends.”

    The “???” was never clarified.

    It was suggested that IAudioOutputEndpointRT  is obtained by IMMDevice::Activate(IID_IAudioOutputEndpointRT). I don’t see this particular IID – in the meantime all others IMMDevice::Activate() got called just fine.


    wind15

    Thursday, March 15, 2012 2:41 PM
  • Hi Wind15:

    just try to sign your dll, then IMMDevice::Activate(IID_IAudioOutputEndpointRT) will be called by audiodg.exe.

    Don't need to implement IAudioClient, IAudioEndpointVolume and IAudioMeterInformation.

    Although Window will query them, it's ok not to implement them.

    -Herb 

    Friday, March 16, 2012 3:03 AM
  •  

    Herb,

    I signed my debug version of the driver (both 32 and 64 bit) – the behavior didn’t change.  IMMDevice::Activate(IID_IAudioOutputEndpointRT) doesn’t get executed.
    1. What is the audiodg.exe and why do I need it? It doesn’t run on my 2008 R2 and even if it does sometime I can kill it with no problem for audio. My driver is loaded for each application and sound goes over my RDP and doesn’t involve any other audio components. The audiodg.exe seems to be irrelevant and not active. I couldn’t find any reasonable info on this audio graph isolation thing…

    2. Where does it say that IAudioOutputEndpointRT is obtained via IMMDevice::Activate?

    The documentation for the IMMDevice::Activate method doesn’t list IAudioOutputEndpointRT:

    http://msdn.microsoft.com/en-us/library/windows/desktop/dd371405(v=vs.85).aspx

    The documentation for IAudioOutputEndpointRT doesn’t say how to obtain it:

    http://msdn.microsoft.com/en-us/library/windows/desktop/dd379571(v=vs.85).aspx

    3. You said: “Don't need to implement IAudioClient, IAudioEndpointVolume and IAudioMeterInformation.”

    Do you know it for fact or you think so?

    Did you try it?

    What if I implemented those, will it prevent me from getting the IAudioOutputEndpointRT?

    Again, I am in doubt that IAudioOutputEndpointRT comes from the IMMDevice::Activate…


    wind15

    Friday, March 16, 2012 4:23 PM
  • Hi Wind15:

    Yes, my dll and IMMDevice::Activate(IID_IAudioOutputEndpointRT) get called by audiodg.exe.

    I only implemented IID_IAudioOutputEndpointRT interface in IMMDevice::Activate.

    Tried rdpendp.dll, kill audiodg.exe on server will stop audio playing on remote machine.

    Herb 

    Monday, March 19, 2012 9:18 AM
  •  

    I removed all implementations and left only the IMMDevice::Activate(IID_IAudioOutputEndpointRT) – never got called, In addition I lost all audio. Audiodg.exe doesn’t even start with my driver.

    Did you use some kind of sample code?

    I have noticed that audiodg.exe runs in the WTS SessionId == 0;

    How do you know your driver is loaded?

    Did you attach debugger to session 0?

    Unfortunately it takes too much time and effort… Unless I can find the detailed info on what and how it has to be done, I will have to drop this approach and go with whatever I have so far.


    wind15

    Monday, March 19, 2012 9:52 PM
  • Hi wind:

    I printed process name from DllMain.

    The document for this approach is too simple for me to dev a stable version.

    I drop this approach too.

    -Herb

    Tuesday, March 20, 2012 2:01 AM
  •  

    Herb,

    I agree! It is too risky to use poor documented driver to support multiple users and multiple applications at the same time – as it all goes through the audiodg.exe of the session 0.

    In the meantime, my driver got loaded per application in TS session – I’ll stick with it and wait if MSFT provides more info in the future. Thanks for your help.


    wind15


    • Edited by wind15 Tuesday, March 20, 2012 4:20 PM
    Tuesday, March 20, 2012 4:19 PM
  • Hi Herb Wang,

    I would like to know more about your approach to load custom endpoint dll.

    • Have you implemented your own Remote Desktop Protocol where your are trying re-direct the audio?
    • Or, did you replace the rdpendp.dll with your custorm endpoint dll?
    • If you have replaced rdpendp.dll, then how did you achieve?

    For my testing,

    • I did a self code signing.
    • Enabled the TestSigning in my test machine.
    • Signed the DLL using SignTool and self signed certificate.
    • Installed the certificate.
    • Replaced the rdpendp.dll with my custom dll.

    When I tested using SDK samples like WinAudio or CaptureSharedEventDrivern, I get E_ACCESSDENIED error on IAudioClient::Initialize function.

    Please help me.

    Thanks in advance

    Vish

    Friday, January 04, 2013 9:51 AM
  • So, my custom.dll is working fine on Win7 and Serv2008R2.<o:p></o:p>

    It fails on Win8 and Server2012.<o:p></o:p>

    On Win8 and Server2012 plays ok from:<o:p></o:p>

    Control Panel->Sound->Playback->MyDevice->Test<o:p></o:p>

    However it fails:<o:p></o:p>

    Control Panel->Sound->Sounds->Asterisk->Test<o:p></o:p>

    I have noticed the new query coming to IAudioClient::QueryInterface()
    with IID ==
    A81E6A89-2EA3-4B30-AF44-88690E165FF6<o:p></o:p>

    Since I don’t know what this query means, I return E_NOITERFACE. The control panel then fails to play
    the sound.<o:p></o:p>

    Does anybody know the difference between W2012 and W2008 is?

    Do I need to rebuild my custom.dll with some other SDKs (SDK 8)?<o:p></o:p>

    What is that IID: A81E6A89-2EA3-4B30-AF44-88690E165FF6 ?

    Is there a place to get any information?<o:p></o:p>



    wind15

    Wednesday, January 09, 2013 9:10 PM
  • You should not be implementing IAudioClient; please limit yourself to the documented and supported ways of implementing custom endpoints.

    http://msdn.microsoft.com/en-us/library/windows/desktop/dd379706(v=vs.85).aspx


    Matthew van Eerde

    Thursday, January 10, 2013 3:35 AM
  • Maurits,

    You keep making reference to the “Remote Desktop Services -> Remote Desktop Services references -> Remote Desktop Services AudioEndpoint API reference” chapter of your documentation.

    http://msdn.microsoft.com/en-us/library/windows/desktop/dd379706(v=vs.85).aspx

    This chapter has no word about how to come to the point of this APIs (IAudioEndpointRT) being called. It doesn’t say anything how to create, install and run the driver.

    The previous chapter “Remote Desktop Services -> Using Remote Desktop Services -> Implementing a Custom Audio Endpoint Enumerator” - somehow explain how to create the driver.

    http://msdn.microsoft.com/en-us/library/windows/desktop/ee958171(v=vs.85).aspx

    So, I followed the instruction and created the driver.

    As I stated before, I have implemented the IAudioEndpoint and IAudioEndpointRT, but they never get called! Instead IAudioClient get called. If I remove IAudioClient the driver doesn‘t work and the system doesn’t have sound working.

    Questions:

    1. Tell me if I followed the wrong instructions and implemented the wrong driver.
    2. What is the supported ways of implementing custom endpoints”?
    3. Do you know for fact that I “should not be implementing IAudioClient”?
    4. How do I make that IAudioEndpointRT get called?
    5. Do you have a sample code that shows how to make that driver that uses the IAudioEndpointRT?


    wind15

    Thursday, January 10, 2013 3:30 PM
  • That's a good question, but unfortunately I don't know how to register a custom enumerator; please ask on the Remote Desktop services forum.

    I do know that implementing IAudioClient is definitely the wrong approach.


    Matthew van Eerde

    Thursday, January 10, 2013 4:31 PM
  • Which question (number) you call as a "good question"?

    Do you know of a way to create a driver that will be called through IAudioEndpointRT?


    wind15

    Thursday, January 10, 2013 5:10 PM
  • > Tell me if I followed the wrong instructions and implemented the wrong driver.

    See below.

    > What is the “supported ways of implementing custom endpoints”?

    There are two supported ways to implement an audio endpoint.

    One is to write a virtual Kernel Streaming driver (see MSVad in the Windows Driver Kit.)
    The other is to register with Remote Desktop services.

    There are also third-party audio stacks like ASIO.

    > Do you know for fact that I “should not be implementing IAudioClient”?

    Yes.

    > How do I make that IAudioEndpointRT get called?

    I don't know.

    > Do you have a sample code that shows how to make that driver that uses the IAudioEndpointRT?

    I don't, but maybe the Remote Desktop folks do.

     


    Matthew van Eerde

    Thursday, January 10, 2013 5:19 PM
  • >There are two supported ways to implement an audio endpoint

    >One is to write a virtual Kernel Streaming driver (see MSVad in the Windows Driver Kit.)

    MSVad is not supported in RDP environment. Kernel Audio devices are disabled during the RDP sessions and are not accessible. This was the change MSFT made since Server 2003. Searching the Internet I have found no evidence that anyone successfully used MSVad in RDP environment

    Do you know of anybody who actually succeeded in using MSVad in Term Services environment?

    >The other is to register with Remote Desktop services

    That is exactly what I am doing! That is exactly why I am asking all these questions. It doesn’t work as described.

    http://msdn.microsoft.com/en-us/library/windows/desktop/ee958171(v=vs.85).aspx
    Do you know of anybody who implemented a driver with IAudioEndpointRT?

    >There are also third-party audio stacks like ASIO

    Those are for the physical adapters only! They are not available for TS environment.


    wind15

    Thursday, January 10, 2013 5:58 PM
  • There's an option in mstsc.exe to leave audio at the server, which allows kernel streaming audio devices to work.

    It sounds from your description like you're having trouble getting the remote desktop services audio plugin mechanism to work.

    I don't know how to get that working.  I encourage you to ask to in the Remote Desktop Services forum, or to open a support case; if the issue is identified to a be Microsoft bug then the support fee will be waived.


    Matthew van Eerde

    Thursday, January 10, 2013 7:59 PM
  • >There's an option in mstsc.exe to leave audio at the server, which allows kernel streaming audio devices to work.<o:p></o:p>

    If multiple terminal sessions will "leave at audio at server" then multiple audio streams will go through the same Kernel/Hardware drivers.<o:p></o:p>

    Because it is not practical, MSFT disabled Kernel Audio capability in the TS mode and on the server at all. The last time I had it working was Windows XP. Because of this MSFT made RdpEndp.dll available for custom audio redirection. It is my understanding the Kernel
    redirection out of question.<o:p></o:p>

    >It sounds from your description like you're having trouble getting the remote desktop services audio plugin mechanism to work.<o:p></o:p>

    Hmmm, I was under the impression you are aware of it as you kept making reference to the “Remote Desktop Services references"<o:p></o:p>



    wind15

    Thursday, January 10, 2013 9:00 PM
  • Sure, I understand what you're saying, and I have a good idea of what the problem you're trying to solve is.

    I just don't know the solution.  I suspect that the easiest way for you to find someone that knows the solution is to ask on a board that is specific to Remote Desktop services, or failing that, to open a support case; the Windows Desktop Pro Audio Application Development Forum is not likely to be much help to you.


    Matthew van Eerde

    Thursday, January 10, 2013 9:32 PM
  • audiodg.exe is a protected process and I don't think it can load any non-MS dll, which does not have the "special MS signature"; and because of that, IAudioClient is the only way left. This special signature seems to be a totally different thing from the digital signature signed by a certificate, since if you right-click on rdpendp.dll, it does not get one as well. I was wondering how Mr. Herb Wang managed to do this, but I have the impression that it's not possible to create a component that can be loaded by protected process, unless the creator works for Microsoft.
    Friday, May 10, 2013 7:01 AM
  • The way to get a .dll loaded into the protected environment is to add a signature attribute PETrust=true. See for example wdmaudio.inf:

    [SignatureAttributes]
    drmk.sys=SignatureAttributes.DRM
    portcls.sys=SignatureAttributes.DRM
    wmalfxgfxdsp.dll=SignatureAttributes.PETrust

    [SignatureAttributes.DRM]
    DRMLevel=1300

    [SignatureAttributes.PETrust]
    PETrust=true


    Matthew van Eerde

    Friday, May 10, 2013 3:21 PM
  • I have read this document "Code Signing for Protected Media Components

    http://msdn.microsoft.com/en-us/windows/hardware/gg487338.aspx

    In section "User-Mode Code-Signing Requirements", it states that the component must be either "Signed by WHQL" or "by using a PMP-PE certificate obtained from Microsoft". Doesn't that mean neither a test certificate nor even a verisign trusted certificate could be used to sign a dll so that it can be loaded into PE? In this case, it looks like one must request for a PMP-PE certificate from Microsoft, or if that's not possible, must then bypass audiodg.exe and go with the IAudioClient approach.


    • Edited by llyzs Monday, May 13, 2013 4:06 AM
    Monday, May 13, 2013 4:04 AM
  • Do not attempt to replace the inbox .dll; that's not a supported mechanism.

    Do not attempt to implement IAudioClient; that's not a supported mechanism.

    The two supported mechanisms for writing a custom endpoint are:

    1. Use the Remote Desktop Services plug-in model to implement your own device enumerator, and the IAudioEndpoint family of interfaces
    2. Write a Kernel Streaming audio driver

    Yes, you are correct that the only way to get loaded into the protected environment is to get your driver logo'd by Microsoft.


    Matthew van Eerde

    Monday, May 13, 2013 10:14 AM
  • What values are we supposed to return for the following properties when we are trying to implement a custom audioendpoint for RDS?

    PKEY_AudioEndpoint_FormFactor

    PKEY_AudioEngine_DeviceFormat


    reverie21

    Thursday, June 20, 2013 10:38 PM