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
|
||||
#include <string>
|
||||
#define PY_SSIZE_T_CLEAN
|
||||
#define UNICODE
|
||||
#define _UNICODE
|
||||
#include <windows.h>
|
||||
#include <Python.h>
|
||||
#include <memory>
|
||||
#include <comdef.h>
|
||||
#include <system_error>
|
||||
#include "../cpp_binding.h"
|
||||
|
||||
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__)
|
||||
|
||||
// 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 { // {{{
|
||||
public:
|
||||
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 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> handle_raii_null;
|
||||
|
||||
struct prop_variant : PROPVARIANT {
|
||||
prop_variant(VARTYPE vt=VT_EMPTY) noexcept : PROPVARIANT{} { PropVariantInit(this); this->vt = vt; }
|
||||
|
Loading…
x
Reference in New Issue
Block a user