2 * Background Copy Job Interface for BITS
4 * Copyright 2007 Google (Roy Shea)
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
27 #include "wine/debug.h"
29 WINE_DEFAULT_DEBUG_CHANNEL(qmgr
);
31 static inline BackgroundCopyJobImpl
*impl_from_IBackgroundCopyJob2(IBackgroundCopyJob2
*iface
)
33 return CONTAINING_RECORD(iface
, BackgroundCopyJobImpl
, IBackgroundCopyJob2_iface
);
36 static HRESULT WINAPI
BITS_IBackgroundCopyJob_QueryInterface(
37 IBackgroundCopyJob2
*iface
, REFIID riid
, void **obj
)
39 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob2(iface
);
41 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
43 if (IsEqualGUID(riid
, &IID_IUnknown
)
44 || IsEqualGUID(riid
, &IID_IBackgroundCopyJob
)
45 || IsEqualGUID(riid
, &IID_IBackgroundCopyJob2
))
48 IBackgroundCopyJob2_AddRef(iface
);
56 static ULONG WINAPI
BITS_IBackgroundCopyJob_AddRef(IBackgroundCopyJob2
*iface
)
58 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob2(iface
);
59 ULONG ref
= InterlockedIncrement(&This
->ref
);
60 TRACE("(%p)->(%d)\n", This
, ref
);
64 static ULONG WINAPI
BITS_IBackgroundCopyJob_Release(IBackgroundCopyJob2
*iface
)
66 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob2(iface
);
67 ULONG ref
= InterlockedDecrement(&This
->ref
);
69 TRACE("(%p)->(%d)\n", This
, ref
);
73 This
->cs
.DebugInfo
->Spare
[0] = 0;
74 DeleteCriticalSection(&This
->cs
);
75 HeapFree(GetProcessHeap(), 0, This
->displayName
);
76 HeapFree(GetProcessHeap(), 0, This
);
82 /*** IBackgroundCopyJob methods ***/
84 static HRESULT WINAPI
BITS_IBackgroundCopyJob_AddFileSet(
85 IBackgroundCopyJob2
*iface
,
87 BG_FILE_INFO
*pFileSet
)
90 for (i
= 0; i
< cFileCount
; ++i
)
92 HRESULT hr
= IBackgroundCopyJob2_AddFile(iface
, pFileSet
[i
].RemoteName
,
93 pFileSet
[i
].LocalName
);
100 static HRESULT WINAPI
BITS_IBackgroundCopyJob_AddFile(
101 IBackgroundCopyJob2
*iface
,
105 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob2(iface
);
106 BackgroundCopyFileImpl
*file
;
109 /* We should return E_INVALIDARG in these cases. */
110 FIXME("Check for valid filenames and supported protocols\n");
112 res
= BackgroundCopyFileConstructor(This
, RemoteUrl
, LocalName
, &file
);
116 /* Add a reference to the file to file list */
117 IBackgroundCopyFile_AddRef(&file
->IBackgroundCopyFile_iface
);
118 EnterCriticalSection(&This
->cs
);
119 list_add_head(&This
->files
, &file
->entryFromJob
);
120 This
->jobProgress
.BytesTotal
= BG_SIZE_UNKNOWN
;
121 ++This
->jobProgress
.FilesTotal
;
122 LeaveCriticalSection(&This
->cs
);
127 static HRESULT WINAPI
BITS_IBackgroundCopyJob_EnumFiles(
128 IBackgroundCopyJob2
*iface
,
129 IEnumBackgroundCopyFiles
**enum_files
)
131 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob2(iface
);
132 TRACE("(%p)->(%p)\n", This
, enum_files
);
133 return EnumBackgroundCopyFilesConstructor(This
, enum_files
);
136 static HRESULT WINAPI
BITS_IBackgroundCopyJob_Suspend(
137 IBackgroundCopyJob2
*iface
)
139 FIXME("Not implemented\n");
143 static HRESULT WINAPI
BITS_IBackgroundCopyJob_Resume(
144 IBackgroundCopyJob2
*iface
)
146 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob2(iface
);
149 EnterCriticalSection(&globalMgr
.cs
);
150 if (This
->state
== BG_JOB_STATE_CANCELLED
151 || This
->state
== BG_JOB_STATE_ACKNOWLEDGED
)
153 rv
= BG_E_INVALID_STATE
;
155 else if (This
->jobProgress
.FilesTransferred
== This
->jobProgress
.FilesTotal
)
159 else if (This
->state
!= BG_JOB_STATE_CONNECTING
160 && This
->state
!= BG_JOB_STATE_TRANSFERRING
)
162 This
->state
= BG_JOB_STATE_QUEUED
;
163 SetEvent(globalMgr
.jobEvent
);
165 LeaveCriticalSection(&globalMgr
.cs
);
170 static HRESULT WINAPI
BITS_IBackgroundCopyJob_Cancel(
171 IBackgroundCopyJob2
*iface
)
173 FIXME("Not implemented\n");
177 static HRESULT WINAPI
BITS_IBackgroundCopyJob_Complete(
178 IBackgroundCopyJob2
*iface
)
180 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob2(iface
);
183 EnterCriticalSection(&This
->cs
);
185 if (This
->state
== BG_JOB_STATE_CANCELLED
186 || This
->state
== BG_JOB_STATE_ACKNOWLEDGED
)
188 rv
= BG_E_INVALID_STATE
;
192 BackgroundCopyFileImpl
*file
;
193 LIST_FOR_EACH_ENTRY(file
, &This
->files
, BackgroundCopyFileImpl
, entryFromJob
)
195 if (file
->fileProgress
.Completed
)
197 if (!MoveFileExW(file
->tempFileName
, file
->info
.LocalName
,
198 (MOVEFILE_COPY_ALLOWED
199 | MOVEFILE_REPLACE_EXISTING
200 | MOVEFILE_WRITE_THROUGH
)))
202 ERR("Couldn't rename file %s -> %s\n",
203 debugstr_w(file
->tempFileName
),
204 debugstr_w(file
->info
.LocalName
));
205 rv
= BG_S_PARTIAL_COMPLETE
;
209 rv
= BG_S_PARTIAL_COMPLETE
;
213 This
->state
= BG_JOB_STATE_ACKNOWLEDGED
;
214 LeaveCriticalSection(&This
->cs
);
219 static HRESULT WINAPI
BITS_IBackgroundCopyJob_GetId(
220 IBackgroundCopyJob2
*iface
,
223 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob2(iface
);
228 static HRESULT WINAPI
BITS_IBackgroundCopyJob_GetType(
229 IBackgroundCopyJob2
*iface
,
232 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob2(iface
);
241 static HRESULT WINAPI
BITS_IBackgroundCopyJob_GetProgress(
242 IBackgroundCopyJob2
*iface
,
243 BG_JOB_PROGRESS
*pVal
)
245 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob2(iface
);
250 EnterCriticalSection(&This
->cs
);
251 pVal
->BytesTotal
= This
->jobProgress
.BytesTotal
;
252 pVal
->BytesTransferred
= This
->jobProgress
.BytesTransferred
;
253 pVal
->FilesTotal
= This
->jobProgress
.FilesTotal
;
254 pVal
->FilesTransferred
= This
->jobProgress
.FilesTransferred
;
255 LeaveCriticalSection(&This
->cs
);
260 static HRESULT WINAPI
BITS_IBackgroundCopyJob_GetTimes(
261 IBackgroundCopyJob2
*iface
,
264 FIXME("Not implemented\n");
268 static HRESULT WINAPI
BITS_IBackgroundCopyJob_GetState(
269 IBackgroundCopyJob2
*iface
,
272 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob2(iface
);
277 /* Don't think we need a critical section for this */
282 static HRESULT WINAPI
BITS_IBackgroundCopyJob_GetError(
283 IBackgroundCopyJob2
*iface
,
284 IBackgroundCopyError
**ppError
)
286 FIXME("Not implemented\n");
290 static HRESULT WINAPI
BITS_IBackgroundCopyJob_GetOwner(
291 IBackgroundCopyJob2
*iface
,
294 FIXME("Not implemented\n");
298 static HRESULT WINAPI
BITS_IBackgroundCopyJob_SetDisplayName(
299 IBackgroundCopyJob2
*iface
,
302 FIXME("Not implemented\n");
306 static HRESULT WINAPI
BITS_IBackgroundCopyJob_GetDisplayName(
307 IBackgroundCopyJob2
*iface
,
310 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob2(iface
);
316 n
= (lstrlenW(This
->displayName
) + 1) * sizeof **pVal
;
317 *pVal
= CoTaskMemAlloc(n
);
319 return E_OUTOFMEMORY
;
320 memcpy(*pVal
, This
->displayName
, n
);
324 static HRESULT WINAPI
BITS_IBackgroundCopyJob_SetDescription(
325 IBackgroundCopyJob2
*iface
,
328 FIXME("Not implemented\n");
332 static HRESULT WINAPI
BITS_IBackgroundCopyJob_GetDescription(
333 IBackgroundCopyJob2
*iface
,
336 FIXME("Not implemented\n");
340 static HRESULT WINAPI
BITS_IBackgroundCopyJob_SetPriority(
341 IBackgroundCopyJob2
*iface
,
344 FIXME("(%p,0x%08x) stub\n", iface
, Val
);
348 static HRESULT WINAPI
BITS_IBackgroundCopyJob_GetPriority(
349 IBackgroundCopyJob2
*iface
,
350 BG_JOB_PRIORITY
*pVal
)
352 FIXME("Not implemented\n");
356 static HRESULT WINAPI
BITS_IBackgroundCopyJob_SetNotifyFlags(
357 IBackgroundCopyJob2
*iface
,
360 FIXME("Not implemented\n");
364 static HRESULT WINAPI
BITS_IBackgroundCopyJob_GetNotifyFlags(
365 IBackgroundCopyJob2
*iface
,
368 FIXME("Not implemented\n");
372 static HRESULT WINAPI
BITS_IBackgroundCopyJob_SetNotifyInterface(
373 IBackgroundCopyJob2
*iface
,
376 FIXME("Not implemented\n");
380 static HRESULT WINAPI
BITS_IBackgroundCopyJob_GetNotifyInterface(
381 IBackgroundCopyJob2
*iface
,
384 FIXME("Not implemented\n");
388 static HRESULT WINAPI
BITS_IBackgroundCopyJob_SetMinimumRetryDelay(
389 IBackgroundCopyJob2
*iface
,
392 FIXME("%u\n", Seconds
);
396 static HRESULT WINAPI
BITS_IBackgroundCopyJob_GetMinimumRetryDelay(
397 IBackgroundCopyJob2
*iface
,
400 FIXME("%p\n", Seconds
);
405 static HRESULT WINAPI
BITS_IBackgroundCopyJob_SetNoProgressTimeout(
406 IBackgroundCopyJob2
*iface
,
409 FIXME("%u\n", Seconds
);
413 static HRESULT WINAPI
BITS_IBackgroundCopyJob_GetNoProgressTimeout(
414 IBackgroundCopyJob2
*iface
,
417 FIXME("%p\n", Seconds
);
422 static HRESULT WINAPI
BITS_IBackgroundCopyJob_GetErrorCount(
423 IBackgroundCopyJob2
*iface
,
426 FIXME("Not implemented\n");
430 static HRESULT WINAPI
BITS_IBackgroundCopyJob_SetProxySettings(
431 IBackgroundCopyJob2
*iface
,
432 BG_JOB_PROXY_USAGE ProxyUsage
,
433 const WCHAR
*ProxyList
,
434 const WCHAR
*ProxyBypassList
)
436 FIXME("Not implemented\n");
440 static HRESULT WINAPI
BITS_IBackgroundCopyJob_GetProxySettings(
441 IBackgroundCopyJob2
*iface
,
442 BG_JOB_PROXY_USAGE
*pProxyUsage
,
444 LPWSTR
*pProxyBypassList
)
446 FIXME("Not implemented\n");
450 static HRESULT WINAPI
BITS_IBackgroundCopyJob_TakeOwnership(
451 IBackgroundCopyJob2
*iface
)
453 FIXME("Not implemented\n");
457 static HRESULT WINAPI
BITS_IBackgroundCopyJob_SetNotifyCmdLine(
458 IBackgroundCopyJob2
*iface
,
462 FIXME("Not implemented\n");
466 static HRESULT WINAPI
BITS_IBackgroundCopyJob_GetNotifyCmdLine(
467 IBackgroundCopyJob2
*iface
,
471 FIXME("Not implemented\n");
475 static HRESULT WINAPI
BITS_IBackgroundCopyJob_GetReplyProgress(
476 IBackgroundCopyJob2
*iface
,
477 BG_JOB_REPLY_PROGRESS
*progress
)
479 FIXME("Not implemented\n");
483 static HRESULT WINAPI
BITS_IBackgroundCopyJob_GetReplyData(
484 IBackgroundCopyJob2
*iface
,
488 FIXME("Not implemented\n");
492 static HRESULT WINAPI
BITS_IBackgroundCopyJob_SetReplyFileName(
493 IBackgroundCopyJob2
*iface
,
496 FIXME("Not implemented\n");
500 static HRESULT WINAPI
BITS_IBackgroundCopyJob_GetReplyFileName(
501 IBackgroundCopyJob2
*iface
,
504 FIXME("Not implemented\n");
508 static HRESULT WINAPI
BITS_IBackgroundCopyJob_SetCredentials(
509 IBackgroundCopyJob2
*iface
,
510 BG_AUTH_CREDENTIALS
*cred
)
512 FIXME("Not implemented\n");
516 static HRESULT WINAPI
BITS_IBackgroundCopyJob_RemoveCredentials(
517 IBackgroundCopyJob2
*iface
,
518 BG_AUTH_TARGET target
,
519 BG_AUTH_SCHEME scheme
)
521 FIXME("Not implemented\n");
525 static const IBackgroundCopyJob2Vtbl BITS_IBackgroundCopyJob_Vtbl
=
527 BITS_IBackgroundCopyJob_QueryInterface
,
528 BITS_IBackgroundCopyJob_AddRef
,
529 BITS_IBackgroundCopyJob_Release
,
530 BITS_IBackgroundCopyJob_AddFileSet
,
531 BITS_IBackgroundCopyJob_AddFile
,
532 BITS_IBackgroundCopyJob_EnumFiles
,
533 BITS_IBackgroundCopyJob_Suspend
,
534 BITS_IBackgroundCopyJob_Resume
,
535 BITS_IBackgroundCopyJob_Cancel
,
536 BITS_IBackgroundCopyJob_Complete
,
537 BITS_IBackgroundCopyJob_GetId
,
538 BITS_IBackgroundCopyJob_GetType
,
539 BITS_IBackgroundCopyJob_GetProgress
,
540 BITS_IBackgroundCopyJob_GetTimes
,
541 BITS_IBackgroundCopyJob_GetState
,
542 BITS_IBackgroundCopyJob_GetError
,
543 BITS_IBackgroundCopyJob_GetOwner
,
544 BITS_IBackgroundCopyJob_SetDisplayName
,
545 BITS_IBackgroundCopyJob_GetDisplayName
,
546 BITS_IBackgroundCopyJob_SetDescription
,
547 BITS_IBackgroundCopyJob_GetDescription
,
548 BITS_IBackgroundCopyJob_SetPriority
,
549 BITS_IBackgroundCopyJob_GetPriority
,
550 BITS_IBackgroundCopyJob_SetNotifyFlags
,
551 BITS_IBackgroundCopyJob_GetNotifyFlags
,
552 BITS_IBackgroundCopyJob_SetNotifyInterface
,
553 BITS_IBackgroundCopyJob_GetNotifyInterface
,
554 BITS_IBackgroundCopyJob_SetMinimumRetryDelay
,
555 BITS_IBackgroundCopyJob_GetMinimumRetryDelay
,
556 BITS_IBackgroundCopyJob_SetNoProgressTimeout
,
557 BITS_IBackgroundCopyJob_GetNoProgressTimeout
,
558 BITS_IBackgroundCopyJob_GetErrorCount
,
559 BITS_IBackgroundCopyJob_SetProxySettings
,
560 BITS_IBackgroundCopyJob_GetProxySettings
,
561 BITS_IBackgroundCopyJob_TakeOwnership
,
562 BITS_IBackgroundCopyJob_SetNotifyCmdLine
,
563 BITS_IBackgroundCopyJob_GetNotifyCmdLine
,
564 BITS_IBackgroundCopyJob_GetReplyProgress
,
565 BITS_IBackgroundCopyJob_GetReplyData
,
566 BITS_IBackgroundCopyJob_SetReplyFileName
,
567 BITS_IBackgroundCopyJob_GetReplyFileName
,
568 BITS_IBackgroundCopyJob_SetCredentials
,
569 BITS_IBackgroundCopyJob_RemoveCredentials
572 HRESULT
BackgroundCopyJobConstructor(LPCWSTR displayName
, BG_JOB_TYPE type
, GUID
*job_id
, BackgroundCopyJobImpl
**job
)
575 BackgroundCopyJobImpl
*This
;
578 TRACE("(%s,%d,%p)\n", debugstr_w(displayName
), type
, job
);
580 This
= HeapAlloc(GetProcessHeap(), 0, sizeof *This
);
582 return E_OUTOFMEMORY
;
584 This
->IBackgroundCopyJob2_iface
.lpVtbl
= &BITS_IBackgroundCopyJob_Vtbl
;
585 InitializeCriticalSection(&This
->cs
);
586 This
->cs
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": BackgroundCopyJobImpl.cs");
591 n
= (lstrlenW(displayName
) + 1) * sizeof *displayName
;
592 This
->displayName
= HeapAlloc(GetProcessHeap(), 0, n
);
593 if (!This
->displayName
)
595 This
->cs
.DebugInfo
->Spare
[0] = 0;
596 DeleteCriticalSection(&This
->cs
);
597 HeapFree(GetProcessHeap(), 0, This
);
598 return E_OUTOFMEMORY
;
600 memcpy(This
->displayName
, displayName
, n
);
602 hr
= CoCreateGuid(&This
->jobId
);
605 This
->cs
.DebugInfo
->Spare
[0] = 0;
606 DeleteCriticalSection(&This
->cs
);
607 HeapFree(GetProcessHeap(), 0, This
->displayName
);
608 HeapFree(GetProcessHeap(), 0, This
);
611 *job_id
= This
->jobId
;
613 list_init(&This
->files
);
614 This
->jobProgress
.BytesTotal
= 0;
615 This
->jobProgress
.BytesTransferred
= 0;
616 This
->jobProgress
.FilesTotal
= 0;
617 This
->jobProgress
.FilesTransferred
= 0;
619 This
->state
= BG_JOB_STATE_SUSPENDED
;
625 void processJob(BackgroundCopyJobImpl
*job
)
629 BackgroundCopyFileImpl
*file
;
632 EnterCriticalSection(&job
->cs
);
633 LIST_FOR_EACH_ENTRY(file
, &job
->files
, BackgroundCopyFileImpl
, entryFromJob
)
634 if (!file
->fileProgress
.Completed
)
639 LeaveCriticalSection(&job
->cs
);
642 transitionJobState(job
, BG_JOB_STATE_QUEUED
, BG_JOB_STATE_TRANSFERRED
);
646 if (!processFile(file
, job
))