1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
|
#!python
#cython: language_level=3
#
# MIT License
#
# Copyright 2019 Eric Devolder
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
"""
Definitions to support compilation on Windows platform
"""
cdef extern from "Windows.h":
ctypedef unsigned long DWORD
ctypedef Py_UNICODE wchar_t
ctypedef wchar_t *LPWSTR
ctypedef const wchar_t *LPCWSTR
ctypedef char *LPSTR
ctypedef const char *LPCSTR
ctypedef void *PVOID
ctypedef const void *LPCVOID
ctypedef PVOID HANDLE
ctypedef HANDLE HLOCAL
ctypedef HANDLE HINSTANCE
ctypedef HINSTANCE HMODULE
ctypedef bint BOOL
ctypedef short INT16
ctypedef enum LANG_ID:
LANG_NEUTRAL
LANG_USER_DEFAULT
SUBLANG_DEFAULT
ctypedef enum FORMAT_FLAGS:
FORMAT_MESSAGE_ALLOCATE_BUFFER
FORMAT_MESSAGE_FROM_SYSTEM
FORMAT_MESSAGE_IGNORE_INSERTS
HMODULE LoadLibraryW(LPCWSTR lpLibFileName)
BOOL FreeLibrary(HMODULE hLinModule)
PVOID GetProcAddress(HMODULE hModule, LPCSTR lpProcName)
DWORD GetLastError()
DWORD MAKELANGID(INT16 p, INT16 s)
DWORD FormatMessageW(
DWORD dwFlags,
LPCVOID lpSource,
DWORD dwMessageId,
DWORD dwLanguageId,
LPWSTR lpBuffer,
DWORD nSize,
...
)
HLOCAL LocalFree(HLOCAL handle)
cdef inline winerror(so) with gil:
"""
returns the last error message, as a string.
If the string has '%1', it is substituted with the content of 'so' arg.
"""
#
# inspired from https://docs.microsoft.com/en-us/windows/desktop/debug/retrieving-the-last-error-code
#
cdef LPWSTR msgbuffer = NULL
dw = GetLastError()
errmsg = ""
if dw != 0:
# from https://docs.microsoft.com/en-us/windows/desktop/api/WinBase/nf-winbase-formatmessage
# at 'Security Remarks':
# In particular, it is unsafe to take an arbitrary system error code returned from an API
# and use FORMAT_MESSAGE_FROM_SYSTEM without FORMAT_MESSAGE_IGNORE_INSERTS.
#
# Given that remark, we are not attempting to parse inserts with a va_list.
# Instead, we only substitute '%1' with the value of so argument, on the returned string.
FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dw,
MAKELANGID(LANG_USER_DEFAULT, SUBLANG_DEFAULT),
<LPWSTR>&msgbuffer,
0,
NULL)
errmsg = <str>msgbuffer # C to python string copy
LocalFree(msgbuffer)
return errmsg.replace('%1', so)
#EOF
|