@@ -35,32 +35,49 @@ DEFINE_PROPERTYKEY(PKEY_SynchronousAudioRouter_EndpointId,
35
35
0xf4b15b6f , 0x8c3f , 0x48b6 , 0xa1 , 0x15 , 0x42 , 0xfd , 0xe1 , 0x9e , 0xf0 , 0x5b ,
36
36
0 );
37
37
38
- SarMMDeviceEnumerator::SarMMDeviceEnumerator ():
39
- _lib (nullptr )
38
+ SarMMDeviceEnumerator::SarMMDeviceEnumerator ()
40
39
{
41
40
char buf[256 ] = {};
42
41
DllGetClassObjectFn *fn_DllGetClassObject;
43
42
CComPtr<IClassFactory> cf;
43
+ HMODULE lib, dummy;
44
44
45
45
_config = DriverConfig::fromFile (ConfigurationPath (" default.json" ));
46
46
47
47
if (!ExpandEnvironmentStringsA (MMDEVAPI_PATH, buf, sizeof (buf))) {
48
48
return ;
49
49
}
50
50
51
- _lib = LoadLibraryA (buf);
51
+ lib = LoadLibraryA (buf);
52
52
53
- if (!_lib ) {
53
+ if (!lib ) {
54
54
return ;
55
55
}
56
56
57
57
fn_DllGetClassObject =
58
- (DllGetClassObjectFn *)GetProcAddress (_lib , " DllGetClassObject" );
58
+ (DllGetClassObjectFn *)GetProcAddress (lib , " DllGetClassObject" );
59
59
60
60
if (!fn_DllGetClassObject) {
61
+ FreeLibrary (lib);
61
62
return ;
62
63
}
63
64
65
+ // Because of the nasty way we're loading the underlying COM object outside
66
+ // of CoCreateInstance, we need to make sure that both our dll and the
67
+ // MMDevAPI dll never unload for the lifetime of the process, so we pin them
68
+ // here.
69
+ GetModuleHandleEx (
70
+ GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_PIN,
71
+ (LPCTSTR)fn_DllGetClassObject, &dummy);
72
+
73
+ GetModuleHandleEx (
74
+ GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_PIN,
75
+ (LPCTSTR)DllGetClassObject, &dummy);
76
+
77
+ // It probably doesn't matter since we've pinned the library anyway, but
78
+ // balance the LoadLibraryA call above.
79
+ FreeLibrary (lib);
80
+
64
81
if (!SUCCEEDED (fn_DllGetClassObject (
65
82
__uuidof (MMDeviceEnumerator), IID_IClassFactory, (LPVOID *)&cf))) {
66
83
@@ -74,10 +91,6 @@ SarMMDeviceEnumerator::SarMMDeviceEnumerator():
74
91
SarMMDeviceEnumerator::~SarMMDeviceEnumerator ()
75
92
{
76
93
_innerEnumerator = nullptr ;
77
-
78
- if (_lib) {
79
- FreeLibrary (_lib);
80
- }
81
94
}
82
95
83
96
HRESULT STDMETHODCALLTYPE SarMMDeviceEnumerator::EnumAudioEndpoints (
0 commit comments