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, x64nun 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