mirror of
https://github.com/hakril/PythonForWindows
synced 2026-06-08 14:31:45 +00:00
Moved bits.py to winobject/ + added windows.system.bits as entrypoint
This commit is contained in:
-107
@@ -1,107 +0,0 @@
|
||||
import threading
|
||||
|
||||
import windows
|
||||
import windows.com
|
||||
from windows.generated_def.interfaces import (IBackgroundCopyManager, IEnumBackgroundCopyJobs, IBackgroundCopyJob,
|
||||
IBackgroundCopyCallback, COMImplementation, IUnknown, IBackgroundCopyError)
|
||||
from windows.generated_def import DWORD, BG_JOB_TYPE_UPLOAD, BG_JOB_STATE_SUSPENDED, BG_ERROR_CONTEXT, HRESULT
|
||||
|
||||
BackgroundCopyManager = windows.com.IID.from_string("4991d34b-80a1-4291-83b6-3328366b9097")
|
||||
BackgroundCopyManager1_5 = windows.com.IID.from_string("f087771f-d74f-4c1a-bb8a-e16aca9124ea")
|
||||
BackgroundCopyManager2_0 = windows.com.IID.from_string("6d18ad12-bde3-4393-b311-099c346e6df9s")
|
||||
BackgroundCopyManager2_5 = windows.com.IID.from_string("03ca98d6-ff5d-49b8-abc6-03dd84127020")
|
||||
BackgroundCopyManager3_0 = windows.com.IID.from_string("659cdea7-489e-11d9-a9cd-000d56965251")
|
||||
|
||||
|
||||
class BitsCopyCallback(COMImplementation):
|
||||
IMPLEMENT = IBackgroundCopyCallback
|
||||
|
||||
def JobError(self, this, job, error):
|
||||
return True
|
||||
|
||||
def JobTransferred(self, this, job):
|
||||
#copy_terminated.set()
|
||||
return True
|
||||
|
||||
def JobModification(self, job, reserved):
|
||||
return True
|
||||
|
||||
class BitsCopyCallbackSetEvent(BitsCopyCallback):
|
||||
def __init__(self, event):
|
||||
super(BitsCopyCallbackSetEvent, self).__init__()
|
||||
self.event = event
|
||||
|
||||
# With the current generated_def.interface design, the current
|
||||
# prototype is:
|
||||
# ctypes.WINFUNCTYPE(HRESULT, PVOID, PVOID)(4, "JobError")
|
||||
# How should I address that ?
|
||||
def JobError(self, this, job, error):
|
||||
job = BitsCopyJob(job)
|
||||
error = BitsCopyError(error)
|
||||
errcode, errctx = error.error
|
||||
print("Copy failed with error code <{0:#x}> (ctx={1})".format(errcode, errctx))
|
||||
print("see <https://msdn.microsoft.com/en-us/library/windows/desktop/aa362823(v=vs.85).aspx>")
|
||||
self.event.set()
|
||||
return True
|
||||
|
||||
def JobTransferred(self, this, job):
|
||||
self.event.set()
|
||||
return True
|
||||
|
||||
class BitsCopyManager(IBackgroundCopyManager):
|
||||
@property
|
||||
def jobs(self):
|
||||
jobsenum = IEnumBackgroundCopyJobs()
|
||||
self.EnumJobs(0, jobsenum)
|
||||
res = []
|
||||
nbretrieved = DWORD()
|
||||
while True:
|
||||
current = BitsCopyJob()
|
||||
jobsenum.Next(1, current, nbretrieved)
|
||||
if not nbretrieved.value:
|
||||
break
|
||||
res.append(current)
|
||||
return res
|
||||
|
||||
def create(self, name, jobtype):
|
||||
myjob_uuid = windows.com.IID()
|
||||
newjob = BitsCopyJob()
|
||||
self.CreateJob(name, jobtype, myjob_uuid, newjob)
|
||||
return newjob
|
||||
|
||||
class BitsCopyJob(IBackgroundCopyJob):
|
||||
@property
|
||||
def iid(self):
|
||||
res = windows.com.IID()
|
||||
self.GetId(res)
|
||||
res.update_strid()
|
||||
return res
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
x = windows.generated_def.BG_JOB_STATE()
|
||||
self.GetState(x)
|
||||
return x
|
||||
|
||||
def wait(self):
|
||||
if self.state.value == BG_JOB_STATE_SUSPENDED:
|
||||
raise ValueError("Cannot wait a BG_JOB_STATE_SUSPENDED job")
|
||||
event = threading.Event()
|
||||
callback_event = BitsCopyCallbackSetEvent(event)
|
||||
self.SetNotifyInterface(callback_event)
|
||||
self.SetNotifyFlags(1 | 2) # BG_NOTIFY_JOB_TRANSFERRED | BG_NOTIFY_JOB_ERROR
|
||||
event.wait()
|
||||
return True
|
||||
|
||||
|
||||
def __repr__(self):
|
||||
return '<{0} iid="{1}" at {2:#08x}>'.format(type(self).__name__, self.iid.to_string(), id(self))
|
||||
|
||||
|
||||
class BitsCopyError(IBackgroundCopyError):
|
||||
@property
|
||||
def error(self):
|
||||
err_ctx = BG_ERROR_CONTEXT()
|
||||
err = HRESULT()
|
||||
self.GetError(err_ctx, err)
|
||||
return (err.value & 0xffffffff, err_ctx)
|
||||
@@ -0,0 +1,264 @@
|
||||
import threading
|
||||
|
||||
import windows
|
||||
import windows.com
|
||||
from windows.com import COMImplementation
|
||||
from windows.generated_def.interfaces import (IBackgroundCopyManager, IEnumBackgroundCopyJobs, IBackgroundCopyJob,
|
||||
IBackgroundCopyCallback, IUnknown, IBackgroundCopyError, IEnumBackgroundCopyFiles,
|
||||
IBackgroundCopyFile)
|
||||
import windows.generated_def as gdef
|
||||
|
||||
BackgroundCopyManager = windows.com.IID.from_string("4991d34b-80a1-4291-83b6-3328366b9097")
|
||||
BackgroundCopyManager1_5 = windows.com.IID.from_string("f087771f-d74f-4c1a-bb8a-e16aca9124ea")
|
||||
BackgroundCopyManager2_0 = windows.com.IID.from_string("6d18ad12-bde3-4393-b311-099c346e6df9s")
|
||||
BackgroundCopyManager2_5 = windows.com.IID.from_string("03ca98d6-ff5d-49b8-abc6-03dd84127020")
|
||||
BackgroundCopyManager3_0 = windows.com.IID.from_string("659cdea7-489e-11d9-a9cd-000d56965251")
|
||||
|
||||
BITS_CLS_BY_VERSION = {
|
||||
(1,0): BackgroundCopyManager,
|
||||
(1,5): BackgroundCopyManager1_5,
|
||||
(2,0): BackgroundCopyManager2_0,
|
||||
(2,5): BackgroundCopyManager2_5,
|
||||
(3,0): BackgroundCopyManager3_0,
|
||||
}
|
||||
|
||||
|
||||
class BitsCopyCallback(COMImplementation):
|
||||
IMPLEMENT = IBackgroundCopyCallback
|
||||
|
||||
def JobError(self, this, job, error):
|
||||
return True
|
||||
|
||||
def JobTransferred(self, this, job):
|
||||
#copy_terminated.set()
|
||||
return True
|
||||
|
||||
def JobModification(self, job, reserved):
|
||||
return True
|
||||
|
||||
class BitsCopyCallbackSetEvent(BitsCopyCallback):
|
||||
def __init__(self, event):
|
||||
super(BitsCopyCallbackSetEvent, self).__init__()
|
||||
self.event = event
|
||||
|
||||
# With the current generated_def.interface design, the current
|
||||
# prototype is:
|
||||
# ctypes.WINFUNCTYPE(HRESULT, PVOID, PVOID)(4, "JobError")
|
||||
# How should I address that ?
|
||||
def JobError(self, this, job, error):
|
||||
job = BitsCopyJob(job)
|
||||
error = BitsCopyError(error)
|
||||
errcode, errctx = error.error
|
||||
print("Copy failed with error code <{0:#x}> (ctx={1})".format(errcode, errctx))
|
||||
print("see <https://msdn.microsoft.com/en-us/library/windows/desktop/aa362823(v=vs.85).aspx>")
|
||||
self.event.set()
|
||||
return True
|
||||
|
||||
def JobTransferred(self, this, job):
|
||||
self.event.set()
|
||||
return True
|
||||
|
||||
class BitsCopyManager(IBackgroundCopyManager):
|
||||
def get_jobs(self, flags=0):
|
||||
jobsenum = IEnumBackgroundCopyJobs()
|
||||
self.EnumJobs(flags, jobsenum)
|
||||
res = []
|
||||
nbretrieved = gdef.DWORD()
|
||||
while True:
|
||||
current = BitsCopyJob()
|
||||
jobsenum.Next(1, current, nbretrieved)
|
||||
if not nbretrieved.value:
|
||||
break
|
||||
res.append(current.promote())
|
||||
jobsenum.Release()
|
||||
return res
|
||||
|
||||
@property
|
||||
def jobs(self):
|
||||
return self.get_jobs()
|
||||
|
||||
def create(self, name, jobtype):
|
||||
myjob_uuid = windows.com.IID()
|
||||
newjob = BitsCopyJob()
|
||||
self.CreateJob(name, jobtype, myjob_uuid, newjob)
|
||||
return newjob.promote()
|
||||
|
||||
class BitsCopyJob(IBackgroundCopyJob):
|
||||
version = 1
|
||||
@property
|
||||
def owner(self):
|
||||
owner = gdef.LPWSTR()
|
||||
self.GetOwner(owner)
|
||||
data = owner.value
|
||||
windows.winproxy.CoTaskMemFree(owner)
|
||||
return data
|
||||
|
||||
|
||||
@property
|
||||
def iid(self):
|
||||
res = windows.com.IID()
|
||||
self.GetId(res)
|
||||
res.update_strid()
|
||||
return res
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
x = gdef.BG_JOB_STATE()
|
||||
self.GetState(x)
|
||||
return x.value
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
descr = gdef.LPWSTR()
|
||||
self.GetDisplayName(descr)
|
||||
data = descr.value
|
||||
windows.winproxy.CoTaskMemFree(descr)
|
||||
return data
|
||||
|
||||
@property
|
||||
def description(self):
|
||||
descr = gdef.LPWSTR()
|
||||
self.GetDescription(descr)
|
||||
data = descr.value
|
||||
windows.winproxy.CoTaskMemFree(descr)
|
||||
return data
|
||||
|
||||
@property
|
||||
def files(self):
|
||||
enum = IEnumBackgroundCopyFiles()
|
||||
self.EnumFiles(enum)
|
||||
count = gdef.ULONG()
|
||||
enum.GetCount(count)
|
||||
if not count:
|
||||
return []
|
||||
res_size = gdef.ULONG()
|
||||
array = (BitsFile * count.value)()
|
||||
enum.Next(count.value, array, res_size)
|
||||
return array[:res_size.value]
|
||||
|
||||
@property
|
||||
def type(self):
|
||||
res = gdef.BG_JOB_TYPE()
|
||||
self.GetType(res)
|
||||
return res.value
|
||||
|
||||
@property
|
||||
def priority(self):
|
||||
priority = gdef.BG_JOB_PRIORITY()
|
||||
self.GetPriority(priority)
|
||||
return priority.value
|
||||
|
||||
@property
|
||||
def minimum_retry_delay(self):
|
||||
retry_delay = gdef.ULONG()
|
||||
self.GetMinimumRetryDelay(retry_delay)
|
||||
return retry_delay.value
|
||||
|
||||
@property
|
||||
def proxy_settings(self):
|
||||
ProxyUsage = gdef.BG_JOB_PROXY_USAGE()
|
||||
ProxyList = gdef.LPWSTR()
|
||||
ProxyBypassList = gdef.LPWSTR()
|
||||
self.GetProxySettings(ProxyUsage, ProxyList, ProxyBypassList)
|
||||
result = ProxyUsage.value, ProxyList.value, ProxyBypassList.value
|
||||
windows.winproxy.CoTaskMemFree(ProxyList)
|
||||
windows.winproxy.CoTaskMemFree(ProxyBypassList)
|
||||
return result
|
||||
|
||||
@property
|
||||
def times(self):
|
||||
res = gdef.BG_JOB_TIMES()
|
||||
self.GetTimes(res)
|
||||
return res
|
||||
|
||||
|
||||
def wait(self):
|
||||
if self.state.value == gdef.BG_JOB_STATE_SUSPENDED:
|
||||
raise ValueError("Cannot wait a BG_JOB_STATE_SUSPENDED job")
|
||||
event = threading.Event()
|
||||
callback_event = BitsCopyCallbackSetEvent(event)
|
||||
self.SetNotifyInterface(callback_event)
|
||||
self.SetNotifyFlags(1 | 2) # BG_NOTIFY_JOB_TRANSFERRED | BG_NOTIFY_JOB_ERROR
|
||||
event.wait()
|
||||
return True
|
||||
|
||||
|
||||
def promote(self):
|
||||
try:
|
||||
return self.query(BitsCopyJob2)
|
||||
except WindowsError as e:
|
||||
return self
|
||||
|
||||
|
||||
def __repr__(self):
|
||||
return '<{0} iid="{1}" at {2:#08x}>'.format(type(self).__name__, self.iid.to_string(), id(self))
|
||||
|
||||
|
||||
class BitsCopyJob2(gdef.IBackgroundCopyJob2, BitsCopyJob):
|
||||
version = 2
|
||||
@property
|
||||
def notify_cmdline(self):
|
||||
path = gdef.LPWSTR()
|
||||
params = gdef.LPWSTR()
|
||||
self.GetNotifyCmdLine(path, params)
|
||||
strpath, strparams = path.value, params.value
|
||||
windows.winproxy.CoTaskMemFree(path)
|
||||
windows.winproxy.CoTaskMemFree(params)
|
||||
return strpath, strparams
|
||||
|
||||
|
||||
class BitsFile(IBackgroundCopyFile):
|
||||
version = 1
|
||||
@property
|
||||
def local_name(self):
|
||||
name = gdef.LPWSTR()
|
||||
self.GetLocalName(name)
|
||||
data = name.value
|
||||
windows.winproxy.CoTaskMemFree(name)
|
||||
return data
|
||||
|
||||
@property
|
||||
def remote_name(self):
|
||||
name = gdef.LPWSTR()
|
||||
self.GetRemoteName(name)
|
||||
data = name.value
|
||||
windows.winproxy.CoTaskMemFree(name)
|
||||
return data
|
||||
|
||||
@property
|
||||
def progress(self):
|
||||
progress = gdef.BG_FILE_PROGRESS()
|
||||
self.GetProgress(progress)
|
||||
return progress
|
||||
|
||||
def promote(self):
|
||||
try:
|
||||
return self.query(BitsFile3)
|
||||
except WindowsError as e:
|
||||
return self
|
||||
|
||||
class BitsFile3(gdef.IBackgroundCopyFile3, BitsFile):
|
||||
version = 3
|
||||
@property
|
||||
def temporary_name(self):
|
||||
name = gdef.LPWSTR()
|
||||
self.GetTemporaryName(name)
|
||||
data = name.value
|
||||
windows.winproxy.CoTaskMemFree(name)
|
||||
return data
|
||||
|
||||
class BitsCopyError(IBackgroundCopyError):
|
||||
@property
|
||||
def error(self):
|
||||
err_ctx = gdef.BG_ERROR_CONTEXT()
|
||||
err = gdef.HRESULT()
|
||||
self.GetError(err_ctx, err)
|
||||
return (err.value & 0xffffffff, err_ctx)
|
||||
|
||||
|
||||
def create_manager(version=(3,0)):
|
||||
windows.com.init()
|
||||
clsid = BITS_CLS_BY_VERSION[version]
|
||||
manager = BitsCopyManager()
|
||||
windows.com.create_instance(clsid, manager)
|
||||
return manager
|
||||
@@ -24,6 +24,7 @@ from windows.winobject import event_log
|
||||
from windows.winobject import event_trace
|
||||
from windows.winobject import task_scheduler
|
||||
from windows.winobject import system_module
|
||||
from windows.winobject import bits
|
||||
|
||||
from windows.dbgprint import dbgprint
|
||||
|
||||
@@ -134,6 +135,10 @@ class System(object):
|
||||
"""
|
||||
return windows.winobject.object_manager.ObjectManager()
|
||||
|
||||
@utils.fixedpropety
|
||||
def bits(self):
|
||||
return bits.create_manager()
|
||||
|
||||
#TODO: use GetComputerNameExA ? and recover other names ?
|
||||
@utils.fixedpropety
|
||||
def computer_name(self):
|
||||
|
||||
Reference in New Issue
Block a user