SetDefaultEndpoint [gelöst]



  • Hi.

    Zu erst mal: es geht um ein undokumentiertes Interface (der WinAPI).
    zu finden hier:
    https://code.google.com/p/soundprison/source/browse/trunk/ipolicyconfig.h?r=4
    ich nutze win7, x64

    nun weiß ich aber nicht, ob ich mich zu doof anstelle oder es geändert wurde:

    #include <endpointvolume.h>
    #include <mmdeviceapi.h>
    
    #if 1 //>=win7
      interface DECLSPEC_UUID( "f8679f50-850a-41cf-9c72-430f290290c8" ) set_default_endpoint_i;
      class     DECLSPEC_UUID( "870af99c-171d-4f9e-af0d-e63df40c2bc9" ) set_default_endpoint_c;
    //GetLastError(): ERROR_ENVVAR_NOT_FOUND / 203 / The system could not find the environment option that was entered.
    //hr = E_POINTER
    #else //>=win vista
      interface DECLSPEC_UUID( "568b9108-44bf-40b4-9006-86afe5b5a620" ) set_default_endpoint_i;
      class     DECLSPEC_UUID( "294935CE-F637-4E7C-A41B-AB255460B862" ) set_default_endpoint_c;
    //GetLastError(): ERROR_ENVVAR_NOT_FOUND / 203 / The system could not find the environment option that was entered.
    //hr = ERROR_NOT_SUPPORTED
    #endif
    
    interface set_default_endpoint_interface : public IUnknown
    {
    public:
      virtual HRESULT STDMETHODCALLTYPE SetDefaultEndpoint( __in PCWSTR wszDeviceId, __in ERole eRole );
    };
    
    #include <iostream>
    #include <cstdlib>
    
    int main()
    {
    	CoInitialize( NULL );
    
    	set_default_endpoint_interface* interface_handle;
    	HRESULT hr = CoCreateInstance( __uuidof( set_default_endpoint_c ), NULL, CLSCTX_ALL, __uuidof( set_default_endpoint_i ), (LPVOID*)&interface_handle );
    
    	if( hr != S_OK )
    	{
    		std::cout << "ups1: " << GetLastError() << std::endl;
    	}
    	else
    	{
    		hr = interface_handle->SetDefaultEndpoint( L"", eConsole );
    		if( hr != S_OK )
    			std::cout << "ups2: " << GetLastError() << std::endl;
    
    		interface_handle->Release(); //edit - vergessen, der vollständigkeit halber^^
    	}
    
    	CoUninitialize();
    	system( "PAUSE" );
    }
    

    Das es mit L"" nicht funktionieren kann ist schon klar, aber auch wenn ich eine (gültige) bezeichnung nehme (bei mir z.Bsp. L"{0.0.0.00000000}.{0372ba27-74ec-4057-9702-cf13e82e460c}" ), kommt der gleiche fehler...

    irgend jemand eine idee?

    danke im voraus

    bb



  • Ich habe doch noch ein wenig rum porbiert...

    zeile 38 in:

    //eMultimedia, korrekte id -> Zugriffsverletzung beim Schreiben an Pos 0x01 in AudioSes.dll
    		PCWSTR id = L"{0.0.0.00000000}.{f152da52-e3e2-4620-afea-a73b9284195d}";
    		hr = interface_handle->SetDefaultEndpoint( id, eMultimedia );
    
    //eConsole, korrekte id -> hr = E_POINTER
    		PCWSTR id = L"{0.0.0.00000000}.{f152da52-e3e2-4620-afea-a73b9284195d}";
    		hr = interface_handle->SetDefaultEndpoint( id, eConsole );
    
    //eConsole, falsche id -> hr = E_POINTER
    		PCWSTR id = L"{0.0.0.00000000}.{f152da52-e3e2-4620-afea-a73b9284195d_}";
    		hr = interface_handle->SetDefaultEndpoint( id, eConsole );
    
    //eMultimedia, falsche id -> hr = ERROR_NOT_FOUND -> richtiges verhalten
    		PCWSTR id = L"{0.0.0.00000000}.{f152da52-e3e2-4620-afea-a73b9284195d_}";
    		hr = interface_handle->SetDefaultEndpoint( id, eMultimedia );
    

    bb



  • ok, wenn ich das komplette interface kopiere, geht alles so, wie es soll...

    kann das pls jemand erklären?



  • Du kannst nicht einfach das Interface verändern und erwarten dass immernoch das selbe rauskommt wenn du es verwendest.
    Letztlich liegen die Methoden in einer "virtual method table" (vtable) vor, in diesem Fall so:

    void** vTable = //XXX
    
    //IUnknown Methoden, implizit (fast) immer dabei
    vTable[0] = &QueryInterface
    vTable[1] = &AddRef
    vTable[2] = &Release
    
    //IPolicyConfig  Methoden
    vTable[3] = &GetMixFormat
    vTable[4] = &GetDeviceFormat
    vTable[5] = &ResetDeviceFormat
    vTable[6] = &SetDeviceFormat
    vTable[7] = &GetProcessingPeriod
    vTable[8] = &SetProcessingPeriod
    vTable[9] = &GetShareMode
    vTable[10] = &SetShareMode
    vTable[11] = &GetPropertyValue
    vTable[12] = &SetPropertyValue
    vTable[13] = &SetDefaultEndpoint
    vTable[14] = &SetEndpointVisibility
    

    Durch die Definition des Interfaces definierst du wie der Compiler diese Methoden behandeln sol.
    In deinem Beispiel:

    interface set_default_endpoint_interface : public IUnknown
    {
    public:
      virtual HRESULT STDMETHODCALLTYPE SetDefaultEndpoint( __in PCWSTR wszDeviceId, __in ERole eRole ); //Die erste Methode in der vtable (mal abgesehen von den impliziten Methoden) heißt SetDefaultEndpoint und nimmt einen PCWSTR und eine ERole als Parameter
    };
    

    Wie du allerdings in der original Definition des Interfaces siehst, ist die erste Methode in Wirklichkeit

    virtual HRESULT GetMixFormat(PCWSTR, WAVEFORMATEX **);
    

    Du kannst dir vorstellen was passiert wenn du die Addresse von "GetMixFormat" wie die von "SetDefaultEndpoint" behandelst? 😉

    So würde es wieder gehen:

    interface set_default_endpoint_interface : public IUnknown
    {
    public:
    	virtual HRESULT STDMETHODCALLTYPE Dummy1(); //GetMixFormat
    	virtual HRESULT STDMETHODCALLTYPE Dummy2(); //GetDeviceFormat
    	virtual HRESULT STDMETHODCALLTYPE Dummy3(); //ResetDeviceFormat
    	virtual HRESULT STDMETHODCALLTYPE Dummy4(); //SetDeviceFormat
    	virtual HRESULT STDMETHODCALLTYPE Dummy5(); //GetProcessingPeriod
    	virtual HRESULT STDMETHODCALLTYPE Dummy6(); //SetProcessingPeriod
    	virtual HRESULT STDMETHODCALLTYPE Dummy7(); //GetShareMode
    	virtual HRESULT STDMETHODCALLTYPE Dummy8(); //SetShareMode
    	virtual HRESULT STDMETHODCALLTYPE Dummy9(); //GetPropertyValue
    	virtual HRESULT STDMETHODCALLTYPE Dummy10(); //SetPropertyValue
    	virtual HRESULT STDMETHODCALLTYPE SetDefaultEndpoint( __in PCWSTR wszDeviceId, __in ERole eRole );
    };
    


  • ty


Anmelden zum Antworten