Skip to content

Commit 57bcbca

Browse files
authored
Merge pull request #68 from hakril/small_improvements
Add some ctypes generation + Improve RPCClient error message & error code parsing
2 parents e693024 + 68ea3c3 commit 57bcbca

7 files changed

Lines changed: 64 additions & 3 deletions

File tree

.github/workflows/tests.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ jobs:
1616
python-version: '3.11'
1717
- run:
1818
py .\ctypes_generation\generate.py
19+
- name: Check generated code can execute
20+
run: py -c "import windows.generated_def"
1921
tests:
2022
# Not a real dependency : but starting tests when ctypes generation is broken is not useful
2123
needs: generate_ctypes

ctypes_generation/definitions/defines/error_helper.txt

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,22 @@
22
#define ERROR_SEVERITY_SUCCESS 0x00000000
33
#define ERROR_SEVERITY_INFORMATIONAL 0x40000000
44
#define ERROR_SEVERITY_WARNING 0x80000000
5-
#define ERROR_SEVERITY_ERROR 0xC0000000
5+
#define ERROR_SEVERITY_ERROR 0xC0000000
6+
7+
// https://learn.microsoft.com/en-us/windows/win32/com/structure-of-com-error-codes
8+
// Define the facility codes
9+
//
10+
#define FACILITY_WINDOWS 0x8
11+
#define FACILITY_WIN32 0x7
12+
#define FACILITY_STORAGE 0x3
13+
#define FACILITY_RPC 0x1
14+
#define FACILITY_NULL 0x0
15+
#define FACILITY_ITF 0x4
16+
#define FACILITY_DISPATCH 0x2
17+
18+
19+
//
20+
// Define the severity codes
21+
//
22+
#define STATUS_SEVERITY_SUCCESS 0x0
23+
#define STATUS_SEVERITY_COERROR 0x2

ctypes_generation/definitions/defines/template.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,10 @@
1717

1818
def CTL_CODE(DeviceType, Function, Method, Access):
1919
return (((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method))
20+
21+
# https://learn.microsoft.com/en-us/windows/win32/api/winerror/nf-winerror-hresult_facility
22+
# Original MACRO:
23+
# #define HRESULT_FACILITY(hr) (((hr) >> 16) & 0x1fff)
24+
25+
def HRESULT_FACILITY(hr):
26+
return (((hr) >> 16) & 0x1fff)

tests/test_generated_def.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,12 @@ def test_CTL_CODE_macro():
113113
assert gdef.IOCTL_MOUNTMGR_CREATE_POINT == 0x006DC000
114114
assert gdef.IOCTL_MOUNTMGR_QUERY_POINTS == 0x006D0008
115115

116+
def test_HRESULT_FACILITY_macro():
117+
"""Test that the HRESULT_FACILITY() macro, (reimplemented in python in windef.py) returns the correct values"""
118+
assert gdef.HRESULT_FACILITY(0x800706d1) == gdef.FACILITY_WIN32 == 7
119+
# RPC_E_INVALID_HEADER(0x80010111)
120+
assert gdef.HRESULT_FACILITY(gdef.RPC_E_INVALID_HEADER) == gdef.FACILITY_RPC == 1
121+
116122

117123
# typedef struct _DnsRecordFlags
118124
# {

windows/generated_def/meta.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1158,6 +1158,13 @@
11581158
'EXIT_THREAD_DEBUG_EVENT',
11591159
'EXPORT_PRIVATE_KEYS',
11601160
'EXTENDED_STARTUPINFO_PRESENT',
1161+
'FACILITY_DISPATCH',
1162+
'FACILITY_ITF',
1163+
'FACILITY_NULL',
1164+
'FACILITY_RPC',
1165+
'FACILITY_STORAGE',
1166+
'FACILITY_WIN32',
1167+
'FACILITY_WINDOWS',
11611168
'FAILED_ACCESS_ACE_FLAG',
11621169
'FAX_CONFIG_QUERY',
11631170
'FAX_CONFIG_SET',
@@ -3006,6 +3013,8 @@
30063013
'STARTF_USESHOWWINDOW',
30073014
'STARTF_USESIZE',
30083015
'STARTF_USESTDHANDLES',
3016+
'STATUS_SEVERITY_COERROR',
3017+
'STATUS_SEVERITY_SUCCESS',
30093018
'STD_ERROR_HANDLE',
30103019
'STD_INPUT_HANDLE',
30113020
'STD_OUTPUT_HANDLE',

windows/generated_def/windef.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,13 @@
1717

1818
def CTL_CODE(DeviceType, Function, Method, Access):
1919
return (((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method))
20+
21+
# https://learn.microsoft.com/en-us/windows/win32/api/winerror/nf-winerror-hresult_facility
22+
# Original MACRO:
23+
# #define HRESULT_FACILITY(hr) (((hr) >> 16) & 0x1fff)
24+
25+
def HRESULT_FACILITY(hr):
26+
return (((hr) >> 16) & 0x1fff)
2027
from .ntstatus import *
2128
from .winerror import *
2229
BG_JOB_ENUM_ALL_USERS = make_flag("BG_JOB_ENUM_ALL_USERS", 0x0001)
@@ -516,6 +523,15 @@ def CTL_CODE(DeviceType, Function, Method, Access):
516523
ERROR_SEVERITY_INFORMATIONAL = make_flag("ERROR_SEVERITY_INFORMATIONAL", 0x40000000)
517524
ERROR_SEVERITY_WARNING = make_flag("ERROR_SEVERITY_WARNING", 0x80000000)
518525
ERROR_SEVERITY_ERROR = make_flag("ERROR_SEVERITY_ERROR", 0xC0000000)
526+
FACILITY_WINDOWS = make_flag("FACILITY_WINDOWS", 0x8)
527+
FACILITY_WIN32 = make_flag("FACILITY_WIN32", 0x7)
528+
FACILITY_STORAGE = make_flag("FACILITY_STORAGE", 0x3)
529+
FACILITY_RPC = make_flag("FACILITY_RPC", 0x1)
530+
FACILITY_NULL = make_flag("FACILITY_NULL", 0x0)
531+
FACILITY_ITF = make_flag("FACILITY_ITF", 0x4)
532+
FACILITY_DISPATCH = make_flag("FACILITY_DISPATCH", 0x2)
533+
STATUS_SEVERITY_SUCCESS = make_flag("STATUS_SEVERITY_SUCCESS", 0x0)
534+
STATUS_SEVERITY_COERROR = make_flag("STATUS_SEVERITY_COERROR", 0x2)
519535
EVENT_TRACE_FLAG_DISPATCHER = make_flag("EVENT_TRACE_FLAG_DISPATCHER", 0x00000800)
520536
EVENT_TRACE_FLAG_VIRTUAL_ALLOC = make_flag("EVENT_TRACE_FLAG_VIRTUAL_ALLOC", 0x00004000)
521537
EVENT_TRACE_FLAG_VAMAP = make_flag("EVENT_TRACE_FLAG_VAMAP", 0x00008000)

windows/rpc/client.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -205,8 +205,11 @@ def _get_request_type(self, response):
205205
"raise if request_type == RESPONSE_TYPE_FAIL"
206206
request_type = struct.unpack("<I", response.data[:4])[0]
207207
if request_type == gdef.RPC_RESPONSE_TYPE_FAIL:
208-
error_code = struct.unpack("<5I", response.data)[2]
209-
raise ValueError("RPC Response error {0} ({1!r})".format(error_code, KNOWN_RPC_ERROR_CODE.get(error_code, error_code)))
208+
effective_error_code = error_code = struct.unpack("<5I", response.data)[2]
209+
# https://learn.microsoft.com/en-us/windows/win32/com/structure-of-com-error-codes
210+
if gdef.HRESULT_FACILITY(error_code) == gdef.FACILITY_WIN32:
211+
effective_error_code = effective_error_code & 0xffff
212+
raise ValueError("RPC Response error {0:#x} ({1!r})".format(error_code, KNOWN_RPC_ERROR_CODE[effective_error_code]))
210213
return request_type
211214

212215
def _get_response_effective_data(self, response):

0 commit comments

Comments
 (0)