Fix winapi
This commit is contained in:
parent
0e4ce3762a
commit
2d738fa08b
|
@ -18,71 +18,71 @@ except ImportError:
|
||||||
# jaraco.windows.error
|
# jaraco.windows.error
|
||||||
|
|
||||||
def format_system_message(errno):
|
def format_system_message(errno):
|
||||||
"""
|
"""
|
||||||
Call FormatMessage with a system error number to retrieve
|
Call FormatMessage with a system error number to retrieve
|
||||||
the descriptive error message.
|
the descriptive error message.
|
||||||
"""
|
"""
|
||||||
# first some flags used by FormatMessageW
|
# first some flags used by FormatMessageW
|
||||||
ALLOCATE_BUFFER = 0x100
|
ALLOCATE_BUFFER = 0x100
|
||||||
ARGUMENT_ARRAY = 0x2000
|
ARGUMENT_ARRAY = 0x2000
|
||||||
FROM_HMODULE = 0x800
|
FROM_HMODULE = 0x800
|
||||||
FROM_STRING = 0x400
|
FROM_STRING = 0x400
|
||||||
FROM_SYSTEM = 0x1000
|
FROM_SYSTEM = 0x1000
|
||||||
IGNORE_INSERTS = 0x200
|
IGNORE_INSERTS = 0x200
|
||||||
|
|
||||||
# Let FormatMessageW allocate the buffer (we'll free it below)
|
# Let FormatMessageW allocate the buffer (we'll free it below)
|
||||||
# Also, let it know we want a system error message.
|
# Also, let it know we want a system error message.
|
||||||
flags = ALLOCATE_BUFFER | FROM_SYSTEM
|
flags = ALLOCATE_BUFFER | FROM_SYSTEM
|
||||||
source = None
|
source = None
|
||||||
message_id = errno
|
message_id = errno
|
||||||
language_id = 0
|
language_id = 0
|
||||||
result_buffer = ctypes.wintypes.LPWSTR()
|
result_buffer = ctypes.wintypes.LPWSTR()
|
||||||
buffer_size = 0
|
buffer_size = 0
|
||||||
arguments = None
|
arguments = None
|
||||||
bytes = ctypes.windll.kernel32.FormatMessageW(
|
format_bytes = ctypes.windll.kernel32.FormatMessageW(
|
||||||
flags,
|
flags,
|
||||||
source,
|
source,
|
||||||
message_id,
|
message_id,
|
||||||
language_id,
|
language_id,
|
||||||
ctypes.byref(result_buffer),
|
ctypes.byref(result_buffer),
|
||||||
buffer_size,
|
buffer_size,
|
||||||
arguments,
|
arguments,
|
||||||
)
|
)
|
||||||
# note the following will cause an infinite loop if GetLastError
|
# note the following will cause an infinite loop if GetLastError
|
||||||
# repeatedly returns an error that cannot be formatted, although
|
# repeatedly returns an error that cannot be formatted, although
|
||||||
# this should not happen.
|
# this should not happen.
|
||||||
handle_nonzero_success(bytes)
|
handle_nonzero_success(format_bytes)
|
||||||
message = result_buffer.value
|
message = result_buffer.value
|
||||||
ctypes.windll.kernel32.LocalFree(result_buffer)
|
ctypes.windll.kernel32.LocalFree(result_buffer)
|
||||||
return message
|
return message
|
||||||
|
|
||||||
|
|
||||||
class WindowsError(__builtin__.WindowsError):
|
class WindowsError(builtins.WindowsError):
|
||||||
"more info about errors at http://msdn.microsoft.com/en-us/library/ms681381(VS.85).aspx"
|
"more info about errors at http://msdn.microsoft.com/en-us/library/ms681381(VS.85).aspx"
|
||||||
|
|
||||||
def __init__(self, value=None):
|
def __init__(self, value=None):
|
||||||
if value is None:
|
if value is None:
|
||||||
value = ctypes.windll.kernel32.GetLastError()
|
value = ctypes.windll.kernel32.GetLastError()
|
||||||
strerror = format_system_message(value)
|
strerror = format_system_message(value)
|
||||||
super(WindowsError, self).__init__(value, strerror)
|
super(WindowsError, self).__init__(value, strerror)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def message(self):
|
def message(self):
|
||||||
return self.strerror
|
return self.strerror
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def code(self):
|
def code(self):
|
||||||
return self.winerror
|
return self.winerror
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.message
|
return self.message
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return '{self.__class__.__name__}({self.winerror})'.format(**vars())
|
return '{self.__class__.__name__}({self.winerror})'.format(**vars())
|
||||||
|
|
||||||
def handle_nonzero_success(result):
|
def handle_nonzero_success(result):
|
||||||
if result == 0:
|
if result == 0:
|
||||||
raise WindowsError()
|
raise WindowsError()
|
||||||
|
|
||||||
|
|
||||||
#####################
|
#####################
|
||||||
|
@ -90,12 +90,12 @@ def handle_nonzero_success(result):
|
||||||
|
|
||||||
CreateFileMapping = ctypes.windll.kernel32.CreateFileMappingW
|
CreateFileMapping = ctypes.windll.kernel32.CreateFileMappingW
|
||||||
CreateFileMapping.argtypes = [
|
CreateFileMapping.argtypes = [
|
||||||
ctypes.wintypes.HANDLE,
|
ctypes.wintypes.HANDLE,
|
||||||
ctypes.c_void_p,
|
ctypes.c_void_p,
|
||||||
ctypes.wintypes.DWORD,
|
ctypes.wintypes.DWORD,
|
||||||
ctypes.wintypes.DWORD,
|
ctypes.wintypes.DWORD,
|
||||||
ctypes.wintypes.DWORD,
|
ctypes.wintypes.DWORD,
|
||||||
ctypes.wintypes.LPWSTR,
|
ctypes.wintypes.LPWSTR,
|
||||||
]
|
]
|
||||||
CreateFileMapping.restype = ctypes.wintypes.HANDLE
|
CreateFileMapping.restype = ctypes.wintypes.HANDLE
|
||||||
|
|
||||||
|
@ -103,171 +103,171 @@ MapViewOfFile = ctypes.windll.kernel32.MapViewOfFile
|
||||||
MapViewOfFile.restype = ctypes.wintypes.HANDLE
|
MapViewOfFile.restype = ctypes.wintypes.HANDLE
|
||||||
|
|
||||||
class MemoryMap(object):
|
class MemoryMap(object):
|
||||||
"""
|
"""
|
||||||
A memory map object which can have security attributes overrideden.
|
A memory map object which can have security attributes overrideden.
|
||||||
"""
|
"""
|
||||||
def __init__(self, name, length, security_attributes=None):
|
def __init__(self, name, length, security_attributes=None):
|
||||||
self.name = name
|
self.name = name
|
||||||
self.length = length
|
self.length = length
|
||||||
self.security_attributes = security_attributes
|
self.security_attributes = security_attributes
|
||||||
self.pos = 0
|
self.pos = 0
|
||||||
|
|
||||||
def __enter__(self):
|
def __enter__(self):
|
||||||
p_SA = (
|
p_SA = (
|
||||||
ctypes.byref(self.security_attributes)
|
ctypes.byref(self.security_attributes)
|
||||||
if self.security_attributes else None
|
if self.security_attributes else None
|
||||||
)
|
)
|
||||||
INVALID_HANDLE_VALUE = -1
|
INVALID_HANDLE_VALUE = -1
|
||||||
PAGE_READWRITE = 0x4
|
PAGE_READWRITE = 0x4
|
||||||
FILE_MAP_WRITE = 0x2
|
FILE_MAP_WRITE = 0x2
|
||||||
filemap = ctypes.windll.kernel32.CreateFileMappingW(
|
filemap = ctypes.windll.kernel32.CreateFileMappingW(
|
||||||
INVALID_HANDLE_VALUE, p_SA, PAGE_READWRITE, 0, self.length,
|
INVALID_HANDLE_VALUE, p_SA, PAGE_READWRITE, 0, self.length,
|
||||||
unicode(self.name))
|
u(self.name))
|
||||||
handle_nonzero_success(filemap)
|
handle_nonzero_success(filemap)
|
||||||
if filemap == INVALID_HANDLE_VALUE:
|
if filemap == INVALID_HANDLE_VALUE:
|
||||||
raise Exception("Failed to create file mapping")
|
raise Exception("Failed to create file mapping")
|
||||||
self.filemap = filemap
|
self.filemap = filemap
|
||||||
self.view = MapViewOfFile(filemap, FILE_MAP_WRITE, 0, 0, 0)
|
self.view = MapViewOfFile(filemap, FILE_MAP_WRITE, 0, 0, 0)
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def seek(self, pos):
|
def seek(self, pos):
|
||||||
self.pos = pos
|
self.pos = pos
|
||||||
|
|
||||||
def write(self, msg):
|
def write(self, msg):
|
||||||
ctypes.windll.msvcrt.memcpy(self.view + self.pos, msg, len(msg))
|
ctypes.windll.msvcrt.memcpy(self.view + self.pos, msg, len(msg))
|
||||||
self.pos += len(msg)
|
self.pos += len(msg)
|
||||||
|
|
||||||
def read(self, n):
|
def read(self, n):
|
||||||
"""
|
"""
|
||||||
Read n bytes from mapped view.
|
Read n bytes from mapped view.
|
||||||
"""
|
"""
|
||||||
out = ctypes.create_string_buffer(n)
|
out = ctypes.create_string_buffer(n)
|
||||||
ctypes.windll.msvcrt.memcpy(out, self.view + self.pos, n)
|
ctypes.windll.msvcrt.memcpy(out, self.view + self.pos, n)
|
||||||
self.pos += n
|
self.pos += n
|
||||||
return out.raw
|
return out.raw
|
||||||
|
|
||||||
def __exit__(self, exc_type, exc_val, tb):
|
def __exit__(self, exc_type, exc_val, tb):
|
||||||
ctypes.windll.kernel32.UnmapViewOfFile(self.view)
|
ctypes.windll.kernel32.UnmapViewOfFile(self.view)
|
||||||
ctypes.windll.kernel32.CloseHandle(self.filemap)
|
ctypes.windll.kernel32.CloseHandle(self.filemap)
|
||||||
|
|
||||||
#########################
|
#########################
|
||||||
# jaraco.windows.security
|
# jaraco.windows.security
|
||||||
|
|
||||||
class TokenInformationClass:
|
class TokenInformationClass:
|
||||||
TokenUser = 1
|
TokenUser = 1
|
||||||
|
|
||||||
class TOKEN_USER(ctypes.Structure):
|
class TOKEN_USER(ctypes.Structure):
|
||||||
num = 1
|
num = 1
|
||||||
_fields_ = [
|
_fields_ = [
|
||||||
('SID', ctypes.c_void_p),
|
('SID', ctypes.c_void_p),
|
||||||
('ATTRIBUTES', ctypes.wintypes.DWORD),
|
('ATTRIBUTES', ctypes.wintypes.DWORD),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class SECURITY_DESCRIPTOR(ctypes.Structure):
|
class SECURITY_DESCRIPTOR(ctypes.Structure):
|
||||||
"""
|
"""
|
||||||
typedef struct _SECURITY_DESCRIPTOR
|
typedef struct _SECURITY_DESCRIPTOR
|
||||||
{
|
{
|
||||||
UCHAR Revision;
|
UCHAR Revision;
|
||||||
UCHAR Sbz1;
|
UCHAR Sbz1;
|
||||||
SECURITY_DESCRIPTOR_CONTROL Control;
|
SECURITY_DESCRIPTOR_CONTROL Control;
|
||||||
PSID Owner;
|
PSID Owner;
|
||||||
PSID Group;
|
PSID Group;
|
||||||
PACL Sacl;
|
PACL Sacl;
|
||||||
PACL Dacl;
|
PACL Dacl;
|
||||||
} SECURITY_DESCRIPTOR;
|
} SECURITY_DESCRIPTOR;
|
||||||
"""
|
"""
|
||||||
SECURITY_DESCRIPTOR_CONTROL = ctypes.wintypes.USHORT
|
SECURITY_DESCRIPTOR_CONTROL = ctypes.wintypes.USHORT
|
||||||
REVISION = 1
|
REVISION = 1
|
||||||
|
|
||||||
_fields_ = [
|
_fields_ = [
|
||||||
('Revision', ctypes.c_ubyte),
|
('Revision', ctypes.c_ubyte),
|
||||||
('Sbz1', ctypes.c_ubyte),
|
('Sbz1', ctypes.c_ubyte),
|
||||||
('Control', SECURITY_DESCRIPTOR_CONTROL),
|
('Control', SECURITY_DESCRIPTOR_CONTROL),
|
||||||
('Owner', ctypes.c_void_p),
|
('Owner', ctypes.c_void_p),
|
||||||
('Group', ctypes.c_void_p),
|
('Group', ctypes.c_void_p),
|
||||||
('Sacl', ctypes.c_void_p),
|
('Sacl', ctypes.c_void_p),
|
||||||
('Dacl', ctypes.c_void_p),
|
('Dacl', ctypes.c_void_p),
|
||||||
]
|
]
|
||||||
|
|
||||||
class SECURITY_ATTRIBUTES(ctypes.Structure):
|
class SECURITY_ATTRIBUTES(ctypes.Structure):
|
||||||
"""
|
"""
|
||||||
typedef struct _SECURITY_ATTRIBUTES {
|
typedef struct _SECURITY_ATTRIBUTES {
|
||||||
DWORD nLength;
|
DWORD nLength;
|
||||||
LPVOID lpSecurityDescriptor;
|
LPVOID lpSecurityDescriptor;
|
||||||
BOOL bInheritHandle;
|
BOOL bInheritHandle;
|
||||||
} SECURITY_ATTRIBUTES;
|
} SECURITY_ATTRIBUTES;
|
||||||
"""
|
"""
|
||||||
_fields_ = [
|
_fields_ = [
|
||||||
('nLength', ctypes.wintypes.DWORD),
|
('nLength', ctypes.wintypes.DWORD),
|
||||||
('lpSecurityDescriptor', ctypes.c_void_p),
|
('lpSecurityDescriptor', ctypes.c_void_p),
|
||||||
('bInheritHandle', ctypes.wintypes.BOOL),
|
('bInheritHandle', ctypes.wintypes.BOOL),
|
||||||
]
|
]
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(SECURITY_ATTRIBUTES, self).__init__(*args, **kwargs)
|
super(SECURITY_ATTRIBUTES, self).__init__(*args, **kwargs)
|
||||||
self.nLength = ctypes.sizeof(SECURITY_ATTRIBUTES)
|
self.nLength = ctypes.sizeof(SECURITY_ATTRIBUTES)
|
||||||
|
|
||||||
def _get_descriptor(self):
|
def _get_descriptor(self):
|
||||||
return self._descriptor
|
return self._descriptor
|
||||||
def _set_descriptor(self, descriptor):
|
def _set_descriptor(self, descriptor):
|
||||||
self._descriptor = descriptor
|
self._descriptor = descriptor
|
||||||
self.lpSecurityDescriptor = ctypes.addressof(descriptor)
|
self.lpSecurityDescriptor = ctypes.addressof(descriptor)
|
||||||
descriptor = property(_get_descriptor, _set_descriptor)
|
descriptor = property(_get_descriptor, _set_descriptor)
|
||||||
|
|
||||||
def GetTokenInformation(token, information_class):
|
def GetTokenInformation(token, information_class):
|
||||||
"""
|
"""
|
||||||
Given a token, get the token information for it.
|
Given a token, get the token information for it.
|
||||||
"""
|
"""
|
||||||
data_size = ctypes.wintypes.DWORD()
|
data_size = ctypes.wintypes.DWORD()
|
||||||
ctypes.windll.advapi32.GetTokenInformation(token, information_class.num,
|
ctypes.windll.advapi32.GetTokenInformation(token, information_class.num,
|
||||||
0, 0, ctypes.byref(data_size))
|
0, 0, ctypes.byref(data_size))
|
||||||
data = ctypes.create_string_buffer(data_size.value)
|
data = ctypes.create_string_buffer(data_size.value)
|
||||||
handle_nonzero_success(ctypes.windll.advapi32.GetTokenInformation(token,
|
handle_nonzero_success(ctypes.windll.advapi32.GetTokenInformation(token,
|
||||||
information_class.num,
|
information_class.num,
|
||||||
ctypes.byref(data), ctypes.sizeof(data),
|
ctypes.byref(data), ctypes.sizeof(data),
|
||||||
ctypes.byref(data_size)))
|
ctypes.byref(data_size)))
|
||||||
return ctypes.cast(data, ctypes.POINTER(TOKEN_USER)).contents
|
return ctypes.cast(data, ctypes.POINTER(TOKEN_USER)).contents
|
||||||
|
|
||||||
class TokenAccess:
|
class TokenAccess:
|
||||||
TOKEN_QUERY = 0x8
|
TOKEN_QUERY = 0x8
|
||||||
|
|
||||||
def OpenProcessToken(proc_handle, access):
|
def OpenProcessToken(proc_handle, access):
|
||||||
result = ctypes.wintypes.HANDLE()
|
result = ctypes.wintypes.HANDLE()
|
||||||
proc_handle = ctypes.wintypes.HANDLE(proc_handle)
|
proc_handle = ctypes.wintypes.HANDLE(proc_handle)
|
||||||
handle_nonzero_success(ctypes.windll.advapi32.OpenProcessToken(
|
handle_nonzero_success(ctypes.windll.advapi32.OpenProcessToken(
|
||||||
proc_handle, access, ctypes.byref(result)))
|
proc_handle, access, ctypes.byref(result)))
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def get_current_user():
|
def get_current_user():
|
||||||
"""
|
"""
|
||||||
Return a TOKEN_USER for the owner of this process.
|
Return a TOKEN_USER for the owner of this process.
|
||||||
"""
|
"""
|
||||||
process = OpenProcessToken(
|
process = OpenProcessToken(
|
||||||
ctypes.windll.kernel32.GetCurrentProcess(),
|
ctypes.windll.kernel32.GetCurrentProcess(),
|
||||||
TokenAccess.TOKEN_QUERY,
|
TokenAccess.TOKEN_QUERY,
|
||||||
)
|
)
|
||||||
return GetTokenInformation(process, TOKEN_USER)
|
return GetTokenInformation(process, TOKEN_USER)
|
||||||
|
|
||||||
def get_security_attributes_for_user(user=None):
|
def get_security_attributes_for_user(user=None):
|
||||||
"""
|
"""
|
||||||
Return a SECURITY_ATTRIBUTES structure with the SID set to the
|
Return a SECURITY_ATTRIBUTES structure with the SID set to the
|
||||||
specified user (uses current user if none is specified).
|
specified user (uses current user if none is specified).
|
||||||
"""
|
"""
|
||||||
if user is None:
|
if user is None:
|
||||||
user = get_current_user()
|
user = get_current_user()
|
||||||
|
|
||||||
assert isinstance(user, TOKEN_USER), "user must be TOKEN_USER instance"
|
assert isinstance(user, TOKEN_USER), "user must be TOKEN_USER instance"
|
||||||
|
|
||||||
SD = SECURITY_DESCRIPTOR()
|
SD = SECURITY_DESCRIPTOR()
|
||||||
SA = SECURITY_ATTRIBUTES()
|
SA = SECURITY_ATTRIBUTES()
|
||||||
# by attaching the actual security descriptor, it will be garbage-
|
# by attaching the actual security descriptor, it will be garbage-
|
||||||
# collected with the security attributes
|
# collected with the security attributes
|
||||||
SA.descriptor = SD
|
SA.descriptor = SD
|
||||||
SA.bInheritHandle = 1
|
SA.bInheritHandle = 1
|
||||||
|
|
||||||
ctypes.windll.advapi32.InitializeSecurityDescriptor(ctypes.byref(SD),
|
ctypes.windll.advapi32.InitializeSecurityDescriptor(ctypes.byref(SD),
|
||||||
SECURITY_DESCRIPTOR.REVISION)
|
SECURITY_DESCRIPTOR.REVISION)
|
||||||
ctypes.windll.advapi32.SetSecurityDescriptorOwner(ctypes.byref(SD),
|
ctypes.windll.advapi32.SetSecurityDescriptorOwner(ctypes.byref(SD),
|
||||||
user.SID, 0)
|
user.SID, 0)
|
||||||
return SA
|
return SA
|
||||||
|
|
Loading…
Reference in New Issue