Use RAII for PROPVARIANT

This commit is contained in:
Kovid Goyal 2021-04-22 22:01:26 +05:30
parent ad3f147c56
commit 7005d6ecd0
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
3 changed files with 19 additions and 21 deletions

View File

@ -326,44 +326,36 @@ find_objects_in(CComPtr<IPortableDeviceContent> &content, CComPtr<IPortableDevic
* The child ids are put into object_ids. Returns False if any errors
* occurred (also sets the python exception).
*/
IEnumPortableDeviceObjectIDs *children;
CComPtr<IEnumPortableDeviceObjectIDs> 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 {{{

View File

@ -256,12 +256,10 @@ get_device_information(CComPtr<IPortableDevice> &device, CComPtr<IPortableDevice
bool has_storage = false;
for (i = 0; i < num_of_categories && !has_storage; i++) {
PROPVARIANT pv;
PropVariantInit(&pv);
prop_variant pv;
if (SUCCEEDED(categories->GetAt(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);

View File

@ -27,3 +27,11 @@ set_error_from_hresult(PyObject *exc_type, const char *file, const int line, con
typedef generic_raii<wchar_t*, CoTaskMemFree, NULL> com_wchar_raii;
static inline void handle_destructor(HANDLE p) { CloseHandle(p); }
typedef generic_raii<HANDLE, handle_destructor, INVALID_HANDLE_VALUE> 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); }
};