summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
author Brad Hughes <bradhugh@outlook.com>2016-04-05 09:58:29 -0400
committer Brad Hughes <bradhugh@outlook.com>2016-04-05 09:58:29 -0400
commit31d425e866d8ac0bed2a819686e3809242f6af0c (patch)
tree41376a5eef1a5bc78bf4941b79a279d901e99ef5 /src
parentca142e877119c4941adf53dddeb1f53ff200dec7 (diff)
Release WMI COM objects correctly in XInput device discovery.
Diffstat (limited to 'src')
-rw-r--r--src/osd/modules/input/input_winhybrid.cpp63
1 files changed, 52 insertions, 11 deletions
diff --git a/src/osd/modules/input/input_winhybrid.cpp b/src/osd/modules/input/input_winhybrid.cpp
index 753a806859a..538abe38da4 100644
--- a/src/osd/modules/input/input_winhybrid.cpp
+++ b/src/osd/modules/input/input_winhybrid.cpp
@@ -13,6 +13,7 @@
#include <wbemcli.h>
#include <list>
+#include <vector>
// standard windows headers
#define WIN32_LEAN_AND_MEAN
@@ -41,7 +42,53 @@
using namespace Microsoft::WRL;
-#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=nullptr; } }
+template<class TCom>
+class ComArray
+{
+private:
+ std::vector<TCom*> m_entries;
+
+public:
+ ComArray(size_t capacity)
+ : m_entries(capacity, nullptr)
+ {
+ }
+
+ ~ComArray()
+ {
+ Release();
+ }
+
+ TCom** ReleaseAndGetAddressOf()
+ {
+ Release();
+
+ // This works b/c vector elements are guaranteed to be contiguous.
+ return &m_entries[0];
+ }
+
+ TCom* operator [] (int i)
+ {
+ return m_entries[i];
+ }
+
+ size_t Size()
+ {
+ return m_entries.size();
+ }
+
+ void Release()
+ {
+ for (int i = 0; i < m_entries.size(); i++)
+ {
+ if (m_entries[i] != nullptr)
+ {
+ m_entries[i]->Release();
+ m_entries[i] = nullptr;
+ }
+ }
+ }
+};
struct bstr_deleter
{
@@ -239,7 +286,7 @@ private:
ComPtr<IWbemServices> pIWbemServices;
ComPtr<IEnumWbemClassObject> pEnumDevices;
ComPtr<IWbemLocator> pIWbemLocator;
- IWbemClassObject* pDevices[20];
+ ComArray<IWbemClassObject> pDevices(20);
bstr_ptr bstrDeviceID;
bstr_ptr bstrClassName;
bstr_ptr bstrNamespace;
@@ -309,12 +356,12 @@ private:
// Loop over all devices
for (; ; )
{
- // Get 20 at a time
- hr = pEnumDevices->Next(10000, 20, pDevices, &uReturned);
+ // Get a few at a time
+ hr = pEnumDevices->Next(10000, pDevices.Size(), pDevices.ReleaseAndGetAddressOf(), &uReturned);
if (FAILED(hr))
{
osd_printf_error("Enumerating WMI classes failed. Error: 0x%X\n", static_cast<unsigned int>(hr));
- goto cleanup;;
+ return hr;
}
if (uReturned == 0)
@@ -352,12 +399,6 @@ private:
}
}
- cleanup:
- for (iDevice = 0; iDevice < 20; iDevice++)
- {
- SAFE_RELEASE(pDevices[iDevice]);
- }
-
if (SUCCEEDED(hr))
hr = S_OK;