From 8aff658a0affaaf9b049c945eaf2490564723d33 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Mon, 3 May 2021 09:29:51 +0530 Subject: [PATCH] Windows WPD driver: Fix an error reading the filesystem on some MTP based devices At least I hope retaining a reference to the bulk properties callback while processing events fixes it. Also add a better error message when waiting fails. Fixes #1926900 [send to device winerror6](https://bugs.launchpad.net/calibre/+bug/1926900) --- src/calibre/devices/mtp/windows/content_enumeration.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/calibre/devices/mtp/windows/content_enumeration.cpp b/src/calibre/devices/mtp/windows/content_enumeration.cpp index 4046abcbd5..7e1cc09731 100644 --- a/src/calibre/devices/mtp/windows/content_enumeration.cpp +++ b/src/calibre/devices/mtp/windows/content_enumeration.cpp @@ -202,6 +202,7 @@ public: if (complete != INVALID_HANDLE_VALUE) CloseHandle(complete); items = NULL; subfolders = NULL; level = 0; complete = INVALID_HANDLE_VALUE; callback = NULL; } + bool handle_is_valid() const { return complete != INVALID_HANDLE_VALUE; } HRESULT __stdcall OnStart(REFGUID Context) { return S_OK; } HRESULT __stdcall OnEnd(REFGUID Context, HRESULT hrStatus) { if (complete != INVALID_HANDLE_VALUE) SetEvent(complete); return S_OK; } @@ -232,6 +233,7 @@ public: DWORD wait_for_messages(int seconds=60) { DWORD wait_result; + if (complete == INVALID_HANDLE_VALUE) return WAIT_OBJECT_0; Py_BEGIN_ALLOW_THREADS; wait_result = MsgWaitForMultipleObjects(1, &complete, FALSE, seconds * 1000, QS_ALLEVENTS); Py_END_ALLOW_THREADS; @@ -276,6 +278,7 @@ bulk_get_filesystem( return false; } + bulk_properties_callback->AddRef(); while (!PyErr_Occurred()) { DWORD wait_result = bulk_properties_callback->wait_for_messages(); if (wait_result == WAIT_OBJECT_0) { @@ -291,7 +294,9 @@ bulk_get_filesystem( PyErr_SetString(WPDError, "An unknown error occurred (mutex abandoned)"); } else { // The wait failed for some reason - PyErr_SetFromWindowsErr(0); + const char buf[256] = {0}; + _snprintf_s((char *const)buf, sizeof(buf) - 1, _TRUNCATE, "handle wait failed in bulk filesystem get at file: %s line: %d", __FILE__, __LINE__); + PyErr_SetExcFromWindowsErrWithFilename(WPDError, 0, buf); } } bulk_properties_callback->end_processing(); @@ -299,6 +304,7 @@ bulk_get_filesystem( bulk_properties->Cancel(guid_context); pump_waiting_messages(); } + bulk_properties_callback->Release(); return PyErr_Occurred() ? false : true; }