Skip to content

Instantly share code, notes, and snippets.

@cwalv
Created June 27, 2012 00:45
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save cwalv/3000500 to your computer and use it in GitHub Desktop.
Save cwalv/3000500 to your computer and use it in GitHub Desktop.
python ctypes win32 Get/SetTimeZoneInformation
from contextlib import contextmanager
import ctypes
from ctypes.wintypes import WORD, DWORD, LONG, WCHAR, HANDLE
k32 = ctypes.windll.kernel32
a32 = ctypes.windll.advapi32
class SYSTEMTIME(ctypes.Structure):
_fields_ = [
('wYear', WORD),
('wMonth', WORD),
('wDayOfWeek', WORD),
('wDay', WORD),
('wHour', WORD),
('wMinute', WORD),
('wSecond', WORD),
('wMilliseconds', WORD),
]
def __str__(self):
lines = [' %s: %s'% (k, str(getattr(self, k)))
for k, t in self._fields_]
return '\n'.join(lines)
class TIME_ZONE_INFORMATION(ctypes.Structure):
_fields_ = [
('Bias', LONG),
('StandardName', WCHAR * 32),
('StandardDate', SYSTEMTIME),
('StandardBias', LONG),
('DaylightName', WCHAR * 32),
('DaylightDate', SYSTEMTIME),
('DaylightBias', LONG),
]
def __str__(self):
lines = ['%s: %s'% (k, str(getattr(self, k)))
for k, t in self._fields_]
return '\n'.join(lines)
class LUID(ctypes.Structure):
_fields_ = [
('LowPart', DWORD),
('HighPart', LONG)
]
class LUID_AND_ATTRIBUTES(ctypes.Structure):
_fields_ = [
('Luid', LUID),
('Attributes', DWORD)
]
class TOKEN_PRIVILEGES(ctypes.Structure):
_fields_ = [
('PrivilegeCount', DWORD),
('Privileges', LUID_AND_ATTRIBUTES * 1)
]
def getErrorText():
buff = ctypes.create_string_buffer(1024)
errCode = k32.GetLastError() & 0xFFFF
k32.FormatMessageA(0x1000, 0, errCode, 0, buff, buff._length_, 0)
return buff.value.strip()
def GetTimeZoneInformation():
tzi = TIME_ZONE_INFORMATION()
k32.GetTimeZoneInformation(ctypes.byref(tzi))
return tzi
@contextmanager
def enableSetTimeZone():
''' see http://msdn.microsoft.com/en-us/library/windows/desktop/ms724944(v=vs.85).aspx
'''
TOKEN_ADJUST_PRIVILEGES = 0x0020
TOKEN_QUERY = 0x0008
SE_PRIVILEGE_ENABLED = 0x0002
hToken = HANDLE()
k32.OpenProcessToken(
k32.GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,
ctypes.byref(hToken))
tkp = TOKEN_PRIVILEGES()
a32.LookupPrivilegeValueA(
0, "SeTimeZonePrivilege", ctypes.byref(tkp.Privileges[0].Luid))
tkp.PrivilegeCount = 1
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED
a32.AdjustTokenPrivileges(hToken, 0, ctypes.byref(tkp), 0, 0, 0)
# Enabled; do what you want
yield
# Done; disable ..
tkp.Privileges[0].Attributes = 0
a32.AdjustTokenPrivileges(hToken, 0, ctypes.byref(tkp), 0, 0, 0)
def SetTimeZoneInformation(tzi):
if not isinstance(tzi, TIME_ZONE_INFORMATION):
raise ValueError("invalid 'tzi' argument")
with enableSetTimeZone():
rv = k32.SetTimeZoneInformation(ctypes.byref(tzi))
if rv == 0:
raise Exception(getErrorText())
tzi = GetTimeZoneInformation()
print tzi
SetTimeZoneInformation(tzi)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment