diff --git a/windows/bits.py b/windows/bits.py new file mode 100644 index 0000000..3c00298 --- /dev/null +++ b/windows/bits.py @@ -0,0 +1,92 @@ +import windows +import windows.com +from windows.generated_def.interfaces import IBackgroundCopyManager, IEnumBackgroundCopyJobs, IBackgroundCopyJob, IBackgroundCopyCallback, COMImplementation, IUnknown +from windows.generated_def import DWORD, BG_JOB_TYPE_UPLOAD, BG_JOB_STATE_SUSPENDED + +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") + + + + +import threading + + + +class BitsCopyCallback(COMImplementation): + IMPLEMENT = IBackgroundCopyCallback + + def JobError(self, 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 + + def JobError(self, job, error): + 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)) \ No newline at end of file