I've written this minimal reproducible example to calculate the Desktop folder on Windows "the hard way" (using SHGetKnownFolderPath), but I seem to end up with a Success error code while the output buffer only yields b'C' when dereferenced via the .result property of c_char_p. What am I doing wrong? My code does this: Converts the desired GUID into the cursed _GUID struct format according to Microsoft's specification Allocates result_ptr = c_char_p() which is initially a NULL pointer but will be overwritten with the pointer to the result Calls SHGetKnownFolderPath with the desired GUID struct, no flags, on the current user, passing our result_ptr by reference so its value can be overwritten If SHGetKnownFolderPath indicated success, dereferences result_ptr using .value I'm getting a result which is only a single char long, but I thought that c_char_p is supposed to be the pointer to the start of a null-terminated string. Is Windows writing a bogus string into my pointer, am I reading its value out wrongly, or have I made some other error in building my function? import contextlib import ctypes import ctypes.wintypes import functools import os import pathlib import types import uuid try: wintypes_GUID = ctypes.wintypes.GUID except AttributeError: class wintypes_GUID(ctypes.Structure): # https://learn.microsoft.com/en-us/windows/win32/api/guiddef/ns-guiddef-guid # https://github.com/enthought/comtypes/blob/1.3.1/comtypes/GUID.py _fields_ = [ ('Data1', ctypes.c_ulong), ('Data2', ctypes.c_ushort), ('Data3', ctypes.c_ushort), ('Data4', ctypes.c_ubyte * 8) ] @classmethod def _from_uuid(cls, u): u = uuid.UUID(u) u_str = f'{{{u!s}}}' result = wintypes_GUID() errno = ctypes.oledll.ole32.CLSIDFromString(u_str, ctypes.byref(result)) if errno == 0: return result else: raise RuntimeError(f'CLSIDFromString returned error code {errno}') DESKTOP_UUID = 'B4BFCC3A-DB2C-424C-B029-7FE99A87C641' def get_known_folder(uuid): # FIXME this doesn't work, seemingly returning just b'C' no matter what result_ptr = ctypes.c_char_p() with _freeing(ctypes.oledll.ole32.CoTaskMemFree, result_ptr): errno = ctypes.windll.shell32.SHGetKnownFolderPath( ctypes.pointer(wintypes_GUID._from_uuid(uuid)), 0, None, ctypes.byref(result_ptr) ) if errno == 0: result = result_ptr.value if len(result) < 2: import warnings warnings.warn(f'result_ptr.value == {result!r}') return pathlib.Path(os.fsdecode(result)) else: raise RuntimeError(f'Shell32.SHGetKnownFolderPath returned error code {errno}') @contextlib.contextmanager def _freeing(freefunc, obj): try: yield obj finally: freefunc(obj) assert get_known_folder(DESKTOP_UUID) ==\ pathlib.Path('~/Desktop').expanduser(),\ f'Result: {get_known_folder(DESKTOP_UUID)!r}; expcected: {pathlib.Path("~/Desktop").expanduser()!r}' Continue reading...