Skip to content

Instantly share code, notes, and snippets.

@EBNull
Last active April 11, 2024 04:34
Show Gist options
  • Save EBNull/6135237 to your computer and use it in GitHub Desktop.
Save EBNull/6135237 to your computer and use it in GitHub Desktop.
FormatMessage() in python, for system messages.
__all__ = (
FormatMessageSystem,
LCID_ENGLISH,
LCID_NEUTRAL,
)
import ctypes
import ctypes.wintypes
LANG_NEUTRAL = 0x00
SUBLANG_NEUTRAL = 0x00
SUBLANG_DEFAULT = 0x01
LANG_ENGLISH = 0x09
SUBLANG_ENGLISH_US = 0x01
def MAKELANGID(primary, sublang):
return (primary & 0xFF) | (sublang & 0xFF) << 16
LCID_ENGLISH = MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US)
LCID_DEFAULT = MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT)
LCID_NEUTRAL = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL)
assert LCID_NEUTRAL == 0
FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x00000100
FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000
FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200
# Note: You probably want to use the builtin ctypes.FormatError instead: https://docs.python.org/3/library/ctypes.html#ctypes.FormatError
# CPython impl: https://github.com/python/cpython/blob/13c1c3556f2c12d0be2af890fabfbf44280b845c/Modules/_ctypes/callproc.c#L254
def FormatMessageSystem(id, langid=LCID_ENGLISH):
sys_flag = FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS
bufptr = ctypes.wintypes.LPWSTR()
chars = ctypes.windll.kernel32.FormatMessageW(sys_flag, None, id, langid, ctypes.byref(bufptr), 0, None)
if chars == 0:
chars = ctypes.windll.kernel32.FormatMessageW(sys_flag, None, id, LCID_NEUTRAL, ctypes.byref(bufptr), 0, None)
if chars == 0:
#XXX: You probably want to call GetLastError() here
return "FormatMessageW failed"
val = bufptr.value[:chars]
ctypes.windll.kernel32.LocalFree(bufptr)
return val
@brianmaissy
Copy link

in case it might be useful to anyone else, it looks like ctypes has this functionality built in:
https://docs.python.org/3/library/ctypes.html#ctypes.FormatError

@EBNull
Copy link
Author

EBNull commented Jan 29, 2020

Huh, good catch, it does, and apparently has since 2.5. CPython source: https://github.com/python/cpython/blob/13c1c3556f2c12d0be2af890fabfbf44280b845c/Modules/_ctypes/callproc.c#L254

I suppose this Python implementation would be useful if you wanted a specific language.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment