Merge pull request #68 from hakril/small_improvements

Add some ctypes generation + Improve RPCClient error message & error code parsing
This commit is contained in:
hakril
2025-01-08 11:21:17 -08:00
committed by GitHub
7 changed files with 64 additions and 3 deletions
+2
View File
@@ -16,6 +16,8 @@ jobs:
python-version: '3.11'
- run:
py .\ctypes_generation\generate.py
- name: Check generated code can execute
run: py -c "import windows.generated_def"
tests:
# Not a real dependency : but starting tests when ctypes generation is broken is not useful
needs: generate_ctypes
@@ -2,4 +2,22 @@
#define ERROR_SEVERITY_SUCCESS 0x00000000
#define ERROR_SEVERITY_INFORMATIONAL 0x40000000
#define ERROR_SEVERITY_WARNING 0x80000000
#define ERROR_SEVERITY_ERROR 0xC0000000
#define ERROR_SEVERITY_ERROR 0xC0000000
// https://learn.microsoft.com/en-us/windows/win32/com/structure-of-com-error-codes
// Define the facility codes
//
#define FACILITY_WINDOWS 0x8
#define FACILITY_WIN32 0x7
#define FACILITY_STORAGE 0x3
#define FACILITY_RPC 0x1
#define FACILITY_NULL 0x0
#define FACILITY_ITF 0x4
#define FACILITY_DISPATCH 0x2
//
// Define the severity codes
//
#define STATUS_SEVERITY_SUCCESS 0x0
#define STATUS_SEVERITY_COERROR 0x2
@@ -17,3 +17,10 @@ NATIVE_WORD_MAX_VALUE = 0xffffffff if bitness == 32 else 0xffffffffffffffff
def CTL_CODE(DeviceType, Function, Method, Access):
return (((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method))
# https://learn.microsoft.com/en-us/windows/win32/api/winerror/nf-winerror-hresult_facility
# Original MACRO:
# #define HRESULT_FACILITY(hr) (((hr) >> 16) & 0x1fff)
def HRESULT_FACILITY(hr):
return (((hr) >> 16) & 0x1fff)
+6
View File
@@ -113,6 +113,12 @@ def test_CTL_CODE_macro():
assert gdef.IOCTL_MOUNTMGR_CREATE_POINT == 0x006DC000
assert gdef.IOCTL_MOUNTMGR_QUERY_POINTS == 0x006D0008
def test_HRESULT_FACILITY_macro():
"""Test that the HRESULT_FACILITY() macro, (reimplemented in python in windef.py) returns the correct values"""
assert gdef.HRESULT_FACILITY(0x800706d1) == gdef.FACILITY_WIN32 == 7
# RPC_E_INVALID_HEADER(0x80010111)
assert gdef.HRESULT_FACILITY(gdef.RPC_E_INVALID_HEADER) == gdef.FACILITY_RPC == 1
# typedef struct _DnsRecordFlags
# {
+9
View File
@@ -1158,6 +1158,13 @@ windef = {'ABOVE_NORMAL_PRIORITY_CLASS',
'EXIT_THREAD_DEBUG_EVENT',
'EXPORT_PRIVATE_KEYS',
'EXTENDED_STARTUPINFO_PRESENT',
'FACILITY_DISPATCH',
'FACILITY_ITF',
'FACILITY_NULL',
'FACILITY_RPC',
'FACILITY_STORAGE',
'FACILITY_WIN32',
'FACILITY_WINDOWS',
'FAILED_ACCESS_ACE_FLAG',
'FAX_CONFIG_QUERY',
'FAX_CONFIG_SET',
@@ -3006,6 +3013,8 @@ windef = {'ABOVE_NORMAL_PRIORITY_CLASS',
'STARTF_USESHOWWINDOW',
'STARTF_USESIZE',
'STARTF_USESTDHANDLES',
'STATUS_SEVERITY_COERROR',
'STATUS_SEVERITY_SUCCESS',
'STD_ERROR_HANDLE',
'STD_INPUT_HANDLE',
'STD_OUTPUT_HANDLE',
+16
View File
@@ -17,6 +17,13 @@ NATIVE_WORD_MAX_VALUE = 0xffffffff if bitness == 32 else 0xffffffffffffffff
def CTL_CODE(DeviceType, Function, Method, Access):
return (((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method))
# https://learn.microsoft.com/en-us/windows/win32/api/winerror/nf-winerror-hresult_facility
# Original MACRO:
# #define HRESULT_FACILITY(hr) (((hr) >> 16) & 0x1fff)
def HRESULT_FACILITY(hr):
return (((hr) >> 16) & 0x1fff)
from .ntstatus import *
from .winerror import *
BG_JOB_ENUM_ALL_USERS = make_flag("BG_JOB_ENUM_ALL_USERS", 0x0001)
@@ -516,6 +523,15 @@ ERROR_SEVERITY_SUCCESS = make_flag("ERROR_SEVERITY_SUCCESS", 0x00000000)
ERROR_SEVERITY_INFORMATIONAL = make_flag("ERROR_SEVERITY_INFORMATIONAL", 0x40000000)
ERROR_SEVERITY_WARNING = make_flag("ERROR_SEVERITY_WARNING", 0x80000000)
ERROR_SEVERITY_ERROR = make_flag("ERROR_SEVERITY_ERROR", 0xC0000000)
FACILITY_WINDOWS = make_flag("FACILITY_WINDOWS", 0x8)
FACILITY_WIN32 = make_flag("FACILITY_WIN32", 0x7)
FACILITY_STORAGE = make_flag("FACILITY_STORAGE", 0x3)
FACILITY_RPC = make_flag("FACILITY_RPC", 0x1)
FACILITY_NULL = make_flag("FACILITY_NULL", 0x0)
FACILITY_ITF = make_flag("FACILITY_ITF", 0x4)
FACILITY_DISPATCH = make_flag("FACILITY_DISPATCH", 0x2)
STATUS_SEVERITY_SUCCESS = make_flag("STATUS_SEVERITY_SUCCESS", 0x0)
STATUS_SEVERITY_COERROR = make_flag("STATUS_SEVERITY_COERROR", 0x2)
EVENT_TRACE_FLAG_DISPATCHER = make_flag("EVENT_TRACE_FLAG_DISPATCHER", 0x00000800)
EVENT_TRACE_FLAG_VIRTUAL_ALLOC = make_flag("EVENT_TRACE_FLAG_VIRTUAL_ALLOC", 0x00004000)
EVENT_TRACE_FLAG_VAMAP = make_flag("EVENT_TRACE_FLAG_VAMAP", 0x00008000)
+5 -2
View File
@@ -205,8 +205,11 @@ class RPCClient(object):
"raise if request_type == RESPONSE_TYPE_FAIL"
request_type = struct.unpack("<I", response.data[:4])[0]
if request_type == gdef.RPC_RESPONSE_TYPE_FAIL:
error_code = struct.unpack("<5I", response.data)[2]
raise ValueError("RPC Response error {0} ({1!r})".format(error_code, KNOWN_RPC_ERROR_CODE.get(error_code, error_code)))
effective_error_code = error_code = struct.unpack("<5I", response.data)[2]
# https://learn.microsoft.com/en-us/windows/win32/com/structure-of-com-error-codes
if gdef.HRESULT_FACILITY(error_code) == gdef.FACILITY_WIN32:
effective_error_code = effective_error_code & 0xffff
raise ValueError("RPC Response error {0:#x} ({1!r})".format(error_code, KNOWN_RPC_ERROR_CODE[effective_error_code]))
return request_type
def _get_response_effective_data(self, response):