From 7005d6ecd0d81157024f7daf581e359b97716306 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Thu, 22 Apr 2021 22:01:26 +0530 Subject: [PATCH] Use RAII for PROPVARIANT --- .../mtp/windows/content_enumeration.cpp | 28 +++++++------------ .../mtp/windows/device_enumeration.cpp | 4 +-- src/calibre/utils/windows/common.h | 8 ++++++ 3 files changed, 19 insertions(+), 21 deletions(-) diff --git a/src/calibre/devices/mtp/windows/content_enumeration.cpp b/src/calibre/devices/mtp/windows/content_enumeration.cpp index db2013925d..60252d8e9c 100644 --- a/src/calibre/devices/mtp/windows/content_enumeration.cpp +++ b/src/calibre/devices/mtp/windows/content_enumeration.cpp @@ -326,44 +326,36 @@ find_objects_in(CComPtr &content, CComPtr children; HRESULT hr = S_OK, hr2 = S_OK; PWSTR child_ids[10]; - DWORD fetched, i; - PROPVARIANT pv; - bool ok = true; - - PropVariantInit(&pv); - pv.vt = VT_LPWSTR; + prop_variant pv(VT_LPWSTR); Py_BEGIN_ALLOW_THREADS; hr = content->EnumObjects(0, parent_id, NULL, &children); Py_END_ALLOW_THREADS; - if (FAILED(hr)) {hresult_set_exc("Failed to get children from device", hr); ok = false; goto end;} + if (FAILED(hr)) {hresult_set_exc("Failed to get children from device", hr); return false;} hr = S_OK; while (hr == S_OK) { + DWORD fetched; Py_BEGIN_ALLOW_THREADS; - hr = children->Next(10, child_ids, &fetched); + hr = children->Next(arraysz(child_ids), child_ids, &fetched); Py_END_ALLOW_THREADS; if (SUCCEEDED(hr)) { - for(i = 0; i < fetched; i++) { + com_wchar_raii cleanup[arraysz(child_ids)]; + for(DWORD i = 0; i < fetched; i++) { cleanup[i].attach(child_ids[i]); } + for(DWORD i = 0; i < fetched; i++) { pv.pwszVal = child_ids[i]; hr2 = object_ids->Add(&pv); pv.pwszVal = NULL; - if (FAILED(hr2)) { hresult_set_exc("Failed to add child ids to propvariantcollection", hr2); break; } + if (FAILED(hr2)) { hresult_set_exc("Failed to add child ids to propvariantcollection", hr2); return false; } } - for (i = 0; i < fetched; i++) { CoTaskMemFree(child_ids[i]); child_ids[i] = NULL; } - if (FAILED(hr2) || !ok) { ok = false; goto end; } } } - -end: - if (children != NULL) children->Release(); - PropVariantClear(&pv); - return ok; + return true; } // }}} // Single get filesystem {{{ diff --git a/src/calibre/devices/mtp/windows/device_enumeration.cpp b/src/calibre/devices/mtp/windows/device_enumeration.cpp index e734ab4e25..98319a4fc4 100644 --- a/src/calibre/devices/mtp/windows/device_enumeration.cpp +++ b/src/calibre/devices/mtp/windows/device_enumeration.cpp @@ -256,12 +256,10 @@ get_device_information(CComPtr &device, CComPtrGetAt(i, &pv)) && pv.puuid != NULL) { if (IsEqualGUID(WPD_FUNCTIONAL_CATEGORY_STORAGE, *pv.puuid)) has_storage = true; } - PropVariantClear(&pv); } PyDict_SetItemString(ans, "has_storage", has_storage ? Py_True : Py_False); diff --git a/src/calibre/utils/windows/common.h b/src/calibre/utils/windows/common.h index 91b90f6fef..eccfd6e255 100644 --- a/src/calibre/utils/windows/common.h +++ b/src/calibre/utils/windows/common.h @@ -27,3 +27,11 @@ set_error_from_hresult(PyObject *exc_type, const char *file, const int line, con typedef generic_raii com_wchar_raii; static inline void handle_destructor(HANDLE p) { CloseHandle(p); } typedef generic_raii handle_raii; + +struct prop_variant : PROPVARIANT { + prop_variant(VARTYPE vt=VT_EMPTY) noexcept : PROPVARIANT{} { PropVariantInit(this); this->vt = vt; } + + ~prop_variant() noexcept { clear(); } + + void clear() noexcept { PropVariantClear(this); } +};