mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Niceties for getting the last error on windows
This commit is contained in:
parent
795c4c6061
commit
467af44edb
@ -5,12 +5,15 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#include <string>
|
||||||
#define PY_SSIZE_T_CLEAN
|
#define PY_SSIZE_T_CLEAN
|
||||||
#define UNICODE
|
#define UNICODE
|
||||||
#define _UNICODE
|
#define _UNICODE
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <Python.h>
|
#include <Python.h>
|
||||||
|
#include <memory>
|
||||||
#include <comdef.h>
|
#include <comdef.h>
|
||||||
|
#include <system_error>
|
||||||
#include "../cpp_binding.h"
|
#include "../cpp_binding.h"
|
||||||
|
|
||||||
static inline PyObject*
|
static inline PyObject*
|
||||||
@ -24,6 +27,46 @@ set_error_from_hresult(PyObject *exc_type, const char *file, const int line, con
|
|||||||
}
|
}
|
||||||
#define error_from_hresult(hr, ...) set_error_from_hresult(PyExc_OSError, __FILE__, __LINE__, hr, __VA_ARGS__)
|
#define error_from_hresult(hr, ...) set_error_from_hresult(PyExc_OSError, __FILE__, __LINE__, hr, __VA_ARGS__)
|
||||||
|
|
||||||
|
// trim from end (in place)
|
||||||
|
template<typename T>
|
||||||
|
static inline void
|
||||||
|
rtrim(std::basic_string<T> &s) {
|
||||||
|
s.erase(std::find_if(s.rbegin(), s.rend(), [](T ch) {
|
||||||
|
switch (ch) { case ' ': case '\t': case '\n': case '\r': case '\v': case '\f': return false; }
|
||||||
|
return true;
|
||||||
|
}).base(), s.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline std::wstring
|
||||||
|
get_last_error(std::wstring const & prefix = L"") {
|
||||||
|
auto ec = GetLastError();
|
||||||
|
LPWSTR buf;
|
||||||
|
DWORD n;
|
||||||
|
|
||||||
|
if ((n = FormatMessageW(
|
||||||
|
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||||
|
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||||
|
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||||
|
NULL,
|
||||||
|
ec,
|
||||||
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||||
|
reinterpret_cast<LPWSTR>(&buf),
|
||||||
|
0, NULL)) == 0) {
|
||||||
|
auto error_code{ ::GetLastError() };
|
||||||
|
throw std::system_error(error_code, std::system_category(), "Failed to retrieve error message string.");
|
||||||
|
}
|
||||||
|
auto deleter = [](void* p) { ::LocalFree(p); };
|
||||||
|
std::unique_ptr<WCHAR, decltype(deleter)> ptrBuffer(buf, deleter);
|
||||||
|
auto msg = std::wstring(buf, n);
|
||||||
|
std::wstring ans = prefix;
|
||||||
|
if (prefix.size() > 0) {
|
||||||
|
ans += L": ";
|
||||||
|
}
|
||||||
|
rtrim(msg);
|
||||||
|
ans += L"Code: " + std::to_wstring(ec) + L" Message: " + msg;
|
||||||
|
return ans;
|
||||||
|
}
|
||||||
|
|
||||||
class scoped_com_initializer { // {{{
|
class scoped_com_initializer { // {{{
|
||||||
public:
|
public:
|
||||||
scoped_com_initializer() : m_succeded(false), hr(0) {
|
scoped_com_initializer() : m_succeded(false), hr(0) {
|
||||||
@ -67,6 +110,7 @@ typedef generic_raii<void*, mapping_raii_free> mapping_raii;
|
|||||||
static inline HANDLE invalid_handle_value_getter(void) { return INVALID_HANDLE_VALUE; }
|
static inline HANDLE invalid_handle_value_getter(void) { return INVALID_HANDLE_VALUE; }
|
||||||
static inline void close_handle(HANDLE x) { CloseHandle(x); }
|
static inline void close_handle(HANDLE x) { CloseHandle(x); }
|
||||||
typedef generic_raii<HANDLE, close_handle, invalid_handle_value_getter> handle_raii;
|
typedef generic_raii<HANDLE, close_handle, invalid_handle_value_getter> handle_raii;
|
||||||
|
typedef generic_raii<HANDLE, close_handle> handle_raii_null;
|
||||||
|
|
||||||
struct prop_variant : PROPVARIANT {
|
struct prop_variant : PROPVARIANT {
|
||||||
prop_variant(VARTYPE vt=VT_EMPTY) noexcept : PROPVARIANT{} { PropVariantInit(this); this->vt = vt; }
|
prop_variant(VARTYPE vt=VT_EMPTY) noexcept : PROPVARIANT{} { PropVariantInit(this); this->vt = vt; }
|
||||||
|
Loading…
x
Reference in New Issue
Block a user