Skip to content

Commit 1bad5bf

Browse files
committed
Add symbolic names for various known MTP error codes
1 parent 452058a commit 1bad5bf

1 file changed

Lines changed: 43 additions & 1 deletion

File tree

src/calibre/devices/mtp/windows/global.h

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,49 @@ typedef struct {
3939
} Device;
4040
extern PyTypeObject DeviceType;
4141

42-
#define hresult_set_exc(msg, hr, ...) set_error_from_hresult(wpd::WPDError, __FILE__, __LINE__, hr, msg, __VA_ARGS__)
42+
static inline PyObject*
43+
set_error_from_hresult_mtp(PyObject *exc_type, const char *file, const int line, const HRESULT hr, const char *prefix="", PyObject *name=NULL) {
44+
_com_error err(hr);
45+
PyObject *pmsg = PyUnicode_FromWideChar(err.ErrorMessage(), -1);
46+
// See https://learn.microsoft.com/en-us/windows/win32/wpd_sdk/error-constants
47+
const char *err_name = "unknown";
48+
#define C(x) case x: err_name = #x; break
49+
#define D(code, x) case code: err_name = #x; break
50+
switch((unsigned long)hr) {
51+
C(E_WPD_DEVICE_ALREADY_OPENED); C(E_WPD_DEVICE_IS_HUNG); C(E_WPD_DEVICE_NOT_OPEN); C(E_WPD_OBJECT_ALREADY_ATTACHED_TO_DEVICE);
52+
C(E_WPD_OBJECT_ALREADY_ATTACHED_TO_SERVICE); C(E_WPD_OBJECT_NOT_ATTACHED_TO_DEVICE); C(E_WPD_OBJECT_NOT_ATTACHED_TO_SERVICE);
53+
C(E_WPD_OBJECT_NOT_COMMITED); C(E_WPD_SERVICE_ALREADY_OPENED); C(E_WPD_SERVICE_BAD_PARAMETER_ORDER); C(E_WPD_SERVICE_NOT_OPEN);
54+
C(E_WPD_SMS_INVALID_RECIPIENT); C(E_WPD_SMS_INVALID_MESSAGE_BODY); C(E_WPD_SMS_SERVICE_UNAVAILABLE);
55+
56+
C(ERROR_ACCESS_DENIED); C(ERROR_ARITHMETIC_OVERFLOW); C(ERROR_BUSY); C(ERROR_CANCELLED); C(ERROR_DATATYPE_MISMATCH);
57+
C(ERROR_DEVICE_IN_USE); C(ERROR_DEVICE_NOT_CONNECTED); C(ERROR_DIR_NOT_EMPTY); C(ERROR_EMPTY); C(ERROR_FILE_NOT_FOUND);
58+
C(ERROR_GEN_FAILURE); C(ERROR_INVALID_DATA); C(ERROR_INVALID_DATATYPE); C(ERROR_INVALID_FUNCTION); C(ERROR_INVALID_OPERATION);
59+
C(ERROR_INVALID_PARAMETER); C(ERROR_INVALID_TIME); C(ERROR_IO_DEVICE); C(ERROR_NOT_FOUND); C(ERROR_NOT_READY);
60+
C(ERROR_NOT_SUPPORTED); C(ERROR_OPERATION_ABORTED); C(ERROR_READ_FAULT); C(ERROR_RESOURCE_NOT_AVAILABLE);
61+
C(ERROR_SEM_TIMEOUT); C(ERROR_TIMEOUT); C(ERROR_UNSUPPORTED_TYPE); C(ERROR_WRITE_FAULT); C(WSAETIMEDOUT);
62+
63+
D(0xC00D2767, NS_E_DRM_DEBUGGING_NOT_ALLOWED); D(0xC00D00CD, NS_E_NOT_LICENSED);
64+
65+
D(0x80042003, SESSION_NOT_OPEN); D(0x80042004, INVALID_TRANSACTION_ID); D(0x80042005, OPERATION_NOT_SUPPORTED);
66+
D(0x80042006, PARAMETER_NOT_SUPPORTED); D(0x80042007, INCOMPLETE_TRANSFER); D(0x80042008, INVALID_STORAGE_ID);
67+
D(0x80042009, INVALID_OBJECT_HANDLE); D(0x8004200A, DEVICE_PROP_NOT_SUPPORTED); D(0x8004200B, INVALID_OBJECT_FORMAT_CODE);
68+
D(0x80042012, PARTIAL_DELETION); D(0x80042013, STORE_NOT_AVAILABLE); D(0x80042014, SPECIFICATION_BY_FORMAT_UNSUPPORTED);
69+
D(0x80042015, NO_VALID_OBJECTINFO); D(0x80042016, INVALID_CODE_FORMAT); D(0x80042017, UNKNOWN_VENDOR_CODE);
70+
D(0x8004201A, INVALID_PARENT_OBJECT); D(0x8004201B, INVALID_DEVICE_PROP_FORMAT); D(0x8004201C, INVALID_DEVICE_PROP_VALUE);
71+
D(0x8004201E, SESSION_ALREADY_OPEN); D(0x8004201F, TRANSACTION_CANCELED); D(0x80042020, SPECIFICATION_OF_DESTINATION_UNSUPPORTED);
72+
D(0x8004A801, INVALID_OBJECTPROP_CODE); D(0x8004A802, INVALID_OBJECT_FORMAT); D(0x8004A803, INVALID_OBJECTPROP_VALUE);
73+
D(0x8004A804, INVALID_OBJECT_REFERENCE); D(0x8004A806, INVALID_DATASET); D(0x8004A807, OBJECT_TOO_LARGE);
74+
D(0x8004A301, INVALID_SERVICE_ID); D(0x8004A302, INVALID_SERVICE_PROP_CODE);
75+
}
76+
#undef C
77+
#undef D
78+
if (name) PyErr_Format(exc_type, "%s:%d:%s:[hr=0x%x wCode=%d name=%s] %V: %S", file, line, prefix, hr, err.WCode(), err_name, pmsg, "Out of memory", name);
79+
else PyErr_Format(exc_type, "%s:%d:%s:[hr=0x%x wCode=%d name=%s] %V", file, line, prefix, hr, err.WCode(), err_name, pmsg, "Out of memory");
80+
Py_CLEAR(pmsg);
81+
return NULL;
82+
}
83+
84+
#define hresult_set_exc(msg, hr, ...) set_error_from_hresult_mtp(wpd::WPDError, __FILE__, __LINE__, hr, msg, __VA_ARGS__)
4385

4486
extern IPortableDeviceValues* get_client_information();
4587
extern IPortableDevice* open_device(const wchar_t *pnp_id, CComPtr<IPortableDeviceValues> &client_information);

0 commit comments

Comments
 (0)