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
26 #include "wine/debug.h"
28 WINE_DEFAULT_DEBUG_CHANNEL(qmgr
);
30 BOOL
transitionJobState(BackgroundCopyJobImpl
*job
, BG_JOB_STATE from
, BG_JOB_STATE to
)
34 EnterCriticalSection(&globalMgr
.cs
);
35 if (job
->state
== from
)
40 LeaveCriticalSection(&globalMgr
.cs
);
46 IBackgroundCopyError IBackgroundCopyError_iface
;
48 BG_ERROR_CONTEXT context
;
50 IBackgroundCopyFile2
*file
;
53 static inline struct copy_error
*impl_from_IBackgroundCopyError(IBackgroundCopyError
*iface
)
55 return CONTAINING_RECORD(iface
, struct copy_error
, IBackgroundCopyError_iface
);
58 static HRESULT WINAPI
copy_error_QueryInterface(
59 IBackgroundCopyError
*iface
,
63 struct copy_error
*error
= impl_from_IBackgroundCopyError(iface
);
65 TRACE("(%p)->(%s %p)\n", error
, debugstr_guid(riid
), obj
);
67 if (IsEqualGUID(riid
, &IID_IUnknown
) || IsEqualGUID(riid
, &IID_IBackgroundCopyError
))
69 *obj
= &error
->IBackgroundCopyError_iface
;
74 WARN("interface %s not supported\n", debugstr_guid(riid
));
78 IBackgroundCopyError_AddRef(iface
);
82 static ULONG WINAPI
copy_error_AddRef(
83 IBackgroundCopyError
*iface
)
85 struct copy_error
*error
= impl_from_IBackgroundCopyError(iface
);
86 LONG refs
= InterlockedIncrement(&error
->refs
);
87 TRACE("(%p)->(%d)\n", error
, refs
);
91 static ULONG WINAPI
copy_error_Release(
92 IBackgroundCopyError
*iface
)
94 struct copy_error
*error
= impl_from_IBackgroundCopyError(iface
);
95 LONG refs
= InterlockedDecrement(&error
->refs
);
97 TRACE("(%p)->(%d)\n", error
, refs
);
101 if (error
->file
) IBackgroundCopyFile2_Release(error
->file
);
102 HeapFree(GetProcessHeap(), 0, error
);
107 static HRESULT WINAPI
copy_error_GetError(
108 IBackgroundCopyError
*iface
,
109 BG_ERROR_CONTEXT
*pContext
,
112 struct copy_error
*error
= impl_from_IBackgroundCopyError(iface
);
114 TRACE("(%p)->(%p %p)\n", error
, pContext
, pCode
);
116 *pContext
= error
->context
;
117 *pCode
= error
->code
;
119 TRACE("returning context %u error code 0x%08x\n", error
->context
, error
->code
);
123 static HRESULT WINAPI
copy_error_GetFile(
124 IBackgroundCopyError
*iface
,
125 IBackgroundCopyFile
**pVal
)
127 struct copy_error
*error
= impl_from_IBackgroundCopyError(iface
);
129 TRACE("(%p)->(%p)\n", error
, pVal
);
133 IBackgroundCopyFile2_AddRef(error
->file
);
134 *pVal
= (IBackgroundCopyFile
*)error
->file
;
138 return BG_E_FILE_NOT_AVAILABLE
;
141 static HRESULT WINAPI
copy_error_GetErrorDescription(
142 IBackgroundCopyError
*iface
,
144 LPWSTR
*pErrorDescription
)
146 struct copy_error
*error
= impl_from_IBackgroundCopyError(iface
);
147 FIXME("(%p)->(%p)\n", error
, pErrorDescription
);
151 static HRESULT WINAPI
copy_error_GetErrorContextDescription(
152 IBackgroundCopyError
*iface
,
154 LPWSTR
*pContextDescription
)
156 struct copy_error
*error
= impl_from_IBackgroundCopyError(iface
);
157 FIXME("(%p)->(%p)\n", error
, pContextDescription
);
161 static HRESULT WINAPI
copy_error_GetProtocol(
162 IBackgroundCopyError
*iface
,
165 struct copy_error
*error
= impl_from_IBackgroundCopyError(iface
);
166 FIXME("(%p)->(%p)\n", error
, pProtocol
);
170 static const IBackgroundCopyErrorVtbl copy_error_vtbl
=
172 copy_error_QueryInterface
,
177 copy_error_GetErrorDescription
,
178 copy_error_GetErrorContextDescription
,
179 copy_error_GetProtocol
182 static HRESULT
create_copy_error(
183 BG_ERROR_CONTEXT context
,
185 IBackgroundCopyFile2
*file
,
186 IBackgroundCopyError
**obj
)
188 struct copy_error
*error
;
190 TRACE("context %u code %08x file %p\n", context
, code
, file
);
192 if (!(error
= HeapAlloc(GetProcessHeap(), 0, sizeof(*error
) ))) return E_OUTOFMEMORY
;
193 error
->IBackgroundCopyError_iface
.lpVtbl
= ©_error_vtbl
;
195 error
->context
= context
;
198 if (error
->file
) IBackgroundCopyFile2_AddRef(error
->file
);
200 *obj
= &error
->IBackgroundCopyError_iface
;
201 TRACE("returning iface %p\n", *obj
);
205 static inline BOOL
is_job_done(const BackgroundCopyJobImpl
*job
)
207 return job
->state
== BG_JOB_STATE_CANCELLED
|| job
->state
== BG_JOB_STATE_ACKNOWLEDGED
;
210 static inline BackgroundCopyJobImpl
*impl_from_IBackgroundCopyJob3(IBackgroundCopyJob3
*iface
)
212 return CONTAINING_RECORD(iface
, BackgroundCopyJobImpl
, IBackgroundCopyJob3_iface
);
215 static HRESULT WINAPI
BackgroundCopyJob_QueryInterface(
216 IBackgroundCopyJob3
*iface
, REFIID riid
, void **obj
)
218 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
220 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
222 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
223 IsEqualGUID(riid
, &IID_IBackgroundCopyJob
) ||
224 IsEqualGUID(riid
, &IID_IBackgroundCopyJob2
) ||
225 IsEqualGUID(riid
, &IID_IBackgroundCopyJob3
))
227 *obj
= &This
->IBackgroundCopyJob3_iface
;
229 else if (IsEqualGUID(riid
, &IID_IBackgroundCopyJobHttpOptions
))
231 *obj
= &This
->IBackgroundCopyJobHttpOptions_iface
;
236 return E_NOINTERFACE
;
239 IBackgroundCopyJob3_AddRef(iface
);
243 static ULONG WINAPI
BackgroundCopyJob_AddRef(IBackgroundCopyJob3
*iface
)
245 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
246 ULONG ref
= InterlockedIncrement(&This
->ref
);
247 TRACE("(%p)->(%d)\n", This
, ref
);
251 static ULONG WINAPI
BackgroundCopyJob_Release(IBackgroundCopyJob3
*iface
)
253 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
254 ULONG i
, j
, ref
= InterlockedDecrement(&This
->ref
);
256 TRACE("(%p)->(%d)\n", This
, ref
);
260 This
->cs
.DebugInfo
->Spare
[0] = 0;
261 DeleteCriticalSection(&This
->cs
);
263 IBackgroundCopyCallback2_Release(This
->callback
);
264 HeapFree(GetProcessHeap(), 0, This
->displayName
);
265 HeapFree(GetProcessHeap(), 0, This
->description
);
266 HeapFree(GetProcessHeap(), 0, This
->http_options
.headers
);
267 for (i
= 0; i
< BG_AUTH_TARGET_PROXY
; i
++)
269 for (j
= 0; j
< BG_AUTH_SCHEME_PASSPORT
; j
++)
271 BG_AUTH_CREDENTIALS
*cred
= &This
->http_options
.creds
[i
][j
];
272 HeapFree(GetProcessHeap(), 0, cred
->Credentials
.Basic
.UserName
);
273 HeapFree(GetProcessHeap(), 0, cred
->Credentials
.Basic
.Password
);
276 CloseHandle(This
->wait
);
277 CloseHandle(This
->cancel
);
278 CloseHandle(This
->done
);
279 HeapFree(GetProcessHeap(), 0, This
);
285 /*** IBackgroundCopyJob methods ***/
287 static HRESULT WINAPI
BackgroundCopyJob_AddFileSet(
288 IBackgroundCopyJob3
*iface
,
290 BG_FILE_INFO
*pFileSet
)
292 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
296 TRACE("(%p)->(%d %p)\n", This
, cFileCount
, pFileSet
);
298 EnterCriticalSection(&This
->cs
);
300 for (i
= 0; i
< cFileCount
; ++i
)
302 BackgroundCopyFileImpl
*file
;
304 /* We should return E_INVALIDARG in these cases. */
305 FIXME("Check for valid filenames and supported protocols\n");
307 hr
= BackgroundCopyFileConstructor(This
, pFileSet
[i
].RemoteName
, pFileSet
[i
].LocalName
, &file
);
308 if (hr
!= S_OK
) break;
310 /* Add a reference to the file to file list */
311 list_add_head(&This
->files
, &file
->entryFromJob
);
312 This
->jobProgress
.BytesTotal
= BG_SIZE_UNKNOWN
;
313 ++This
->jobProgress
.FilesTotal
;
316 LeaveCriticalSection(&This
->cs
);
321 static HRESULT WINAPI
BackgroundCopyJob_AddFile(
322 IBackgroundCopyJob3
*iface
,
326 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
329 TRACE("(%p)->(%s %s)\n", This
, debugstr_w(RemoteUrl
), debugstr_w(LocalName
));
331 file
.RemoteName
= (LPWSTR
)RemoteUrl
;
332 file
.LocalName
= (LPWSTR
)LocalName
;
333 return IBackgroundCopyJob3_AddFileSet(iface
, 1, &file
);
336 static HRESULT WINAPI
BackgroundCopyJob_EnumFiles(
337 IBackgroundCopyJob3
*iface
,
338 IEnumBackgroundCopyFiles
**enum_files
)
340 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
341 TRACE("(%p)->(%p)\n", This
, enum_files
);
342 return EnumBackgroundCopyFilesConstructor(This
, enum_files
);
345 static HRESULT WINAPI
BackgroundCopyJob_Suspend(
346 IBackgroundCopyJob3
*iface
)
348 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
349 FIXME("(%p): stub\n", This
);
353 static HRESULT WINAPI
BackgroundCopyJob_Resume(
354 IBackgroundCopyJob3
*iface
)
356 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
359 TRACE("(%p)\n", This
);
361 EnterCriticalSection(&globalMgr
.cs
);
362 if (is_job_done(This
))
364 rv
= BG_E_INVALID_STATE
;
366 else if (This
->jobProgress
.FilesTransferred
== This
->jobProgress
.FilesTotal
)
370 else if (This
->state
!= BG_JOB_STATE_CONNECTING
371 && This
->state
!= BG_JOB_STATE_TRANSFERRING
)
373 This
->state
= BG_JOB_STATE_QUEUED
;
374 SetEvent(globalMgr
.jobEvent
);
376 LeaveCriticalSection(&globalMgr
.cs
);
381 static HRESULT WINAPI
BackgroundCopyJob_Cancel(
382 IBackgroundCopyJob3
*iface
)
384 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
387 TRACE("(%p)\n", This
);
389 EnterCriticalSection(&This
->cs
);
391 if (is_job_done(This
))
393 rv
= BG_E_INVALID_STATE
;
397 BackgroundCopyFileImpl
*file
;
399 if (This
->state
== BG_JOB_STATE_CONNECTING
|| This
->state
== BG_JOB_STATE_TRANSFERRING
)
401 This
->state
= BG_JOB_STATE_CANCELLED
;
402 SetEvent(This
->cancel
);
404 LeaveCriticalSection(&This
->cs
);
405 WaitForSingleObject(This
->done
, INFINITE
);
406 EnterCriticalSection(&This
->cs
);
409 LIST_FOR_EACH_ENTRY(file
, &This
->files
, BackgroundCopyFileImpl
, entryFromJob
)
411 if (file
->tempFileName
[0] && !DeleteFileW(file
->tempFileName
))
413 WARN("Couldn't delete %s (%u)\n", debugstr_w(file
->tempFileName
), GetLastError());
414 rv
= BG_S_UNABLE_TO_DELETE_FILES
;
416 if (file
->info
.LocalName
&& !DeleteFileW(file
->info
.LocalName
))
418 WARN("Couldn't delete %s (%u)\n", debugstr_w(file
->info
.LocalName
), GetLastError());
419 rv
= BG_S_UNABLE_TO_DELETE_FILES
;
422 This
->state
= BG_JOB_STATE_CANCELLED
;
425 LeaveCriticalSection(&This
->cs
);
429 static HRESULT WINAPI
BackgroundCopyJob_Complete(
430 IBackgroundCopyJob3
*iface
)
432 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
435 TRACE("(%p)\n", This
);
437 EnterCriticalSection(&This
->cs
);
439 if (is_job_done(This
))
441 rv
= BG_E_INVALID_STATE
;
445 BackgroundCopyFileImpl
*file
;
446 LIST_FOR_EACH_ENTRY(file
, &This
->files
, BackgroundCopyFileImpl
, entryFromJob
)
448 if (file
->fileProgress
.Completed
)
450 if (!MoveFileExW(file
->tempFileName
, file
->info
.LocalName
,
451 (MOVEFILE_COPY_ALLOWED
452 | MOVEFILE_REPLACE_EXISTING
453 | MOVEFILE_WRITE_THROUGH
)))
455 ERR("Couldn't rename file %s -> %s\n",
456 debugstr_w(file
->tempFileName
),
457 debugstr_w(file
->info
.LocalName
));
458 rv
= BG_S_PARTIAL_COMPLETE
;
462 rv
= BG_S_PARTIAL_COMPLETE
;
466 This
->state
= BG_JOB_STATE_ACKNOWLEDGED
;
467 LeaveCriticalSection(&This
->cs
);
472 static HRESULT WINAPI
BackgroundCopyJob_GetId(
473 IBackgroundCopyJob3
*iface
,
476 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
477 TRACE("(%p)->(%p)\n", This
, pVal
);
482 static HRESULT WINAPI
BackgroundCopyJob_GetType(
483 IBackgroundCopyJob3
*iface
,
486 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
488 TRACE("(%p)->(%p)\n", This
, pVal
);
497 static HRESULT WINAPI
BackgroundCopyJob_GetProgress(
498 IBackgroundCopyJob3
*iface
,
499 BG_JOB_PROGRESS
*pVal
)
501 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
503 TRACE("(%p)->(%p)\n", This
, pVal
);
508 EnterCriticalSection(&This
->cs
);
509 *pVal
= This
->jobProgress
;
510 LeaveCriticalSection(&This
->cs
);
515 static HRESULT WINAPI
BackgroundCopyJob_GetTimes(
516 IBackgroundCopyJob3
*iface
,
519 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
520 FIXME("(%p)->(%p): stub\n", This
, pVal
);
524 static HRESULT WINAPI
BackgroundCopyJob_GetState(
525 IBackgroundCopyJob3
*iface
,
528 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
530 TRACE("(%p)->(%p)\n", This
, pVal
);
535 /* Don't think we need a critical section for this */
540 static HRESULT WINAPI
BackgroundCopyJob_GetError(
541 IBackgroundCopyJob3
*iface
,
542 IBackgroundCopyError
**ppError
)
544 BackgroundCopyJobImpl
*job
= impl_from_IBackgroundCopyJob3(iface
);
546 TRACE("(%p)->(%p)\n", job
, ppError
);
548 if (!job
->error
.context
) return BG_E_ERROR_INFORMATION_UNAVAILABLE
;
550 return create_copy_error(job
->error
.context
, job
->error
.code
, job
->error
.file
, ppError
);
553 static HRESULT WINAPI
BackgroundCopyJob_GetOwner(
554 IBackgroundCopyJob3
*iface
,
557 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
558 FIXME("(%p)->(%p): stub\n", This
, pVal
);
562 static HRESULT WINAPI
BackgroundCopyJob_SetDisplayName(
563 IBackgroundCopyJob3
*iface
,
566 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
567 FIXME("(%p)->(%s): stub\n", This
, debugstr_w(Val
));
571 static HRESULT WINAPI
BackgroundCopyJob_GetDisplayName(
572 IBackgroundCopyJob3
*iface
,
575 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
577 TRACE("(%p)->(%p)\n", This
, pVal
);
579 return return_strval(This
->displayName
, pVal
);
582 static HRESULT WINAPI
BackgroundCopyJob_SetDescription(
583 IBackgroundCopyJob3
*iface
,
586 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
587 static const int max_description_len
= 1024;
591 TRACE("(%p)->(%s)\n", This
, debugstr_w(Val
));
593 if (!Val
) return E_INVALIDARG
;
596 if (len
> max_description_len
) return BG_E_STRING_TOO_LONG
;
598 EnterCriticalSection(&This
->cs
);
600 if (is_job_done(This
))
602 hr
= BG_E_INVALID_STATE
;
606 HeapFree(GetProcessHeap(), 0, This
->description
);
607 if ((This
->description
= HeapAlloc(GetProcessHeap(), 0, (len
+1)*sizeof(WCHAR
))))
608 strcpyW(This
->description
, Val
);
613 LeaveCriticalSection(&This
->cs
);
618 static HRESULT WINAPI
BackgroundCopyJob_GetDescription(
619 IBackgroundCopyJob3
*iface
,
622 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
624 TRACE("(%p)->(%p)\n", This
, pVal
);
626 return return_strval(This
->description
, pVal
);
629 static HRESULT WINAPI
BackgroundCopyJob_SetPriority(
630 IBackgroundCopyJob3
*iface
,
633 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
634 FIXME("(%p)->(%d): stub\n", This
, Val
);
638 static HRESULT WINAPI
BackgroundCopyJob_GetPriority(
639 IBackgroundCopyJob3
*iface
,
640 BG_JOB_PRIORITY
*pVal
)
642 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
643 FIXME("(%p)->(%p): stub\n", This
, pVal
);
647 static HRESULT WINAPI
BackgroundCopyJob_SetNotifyFlags(
648 IBackgroundCopyJob3
*iface
,
651 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
652 static const ULONG valid_flags
= BG_NOTIFY_JOB_TRANSFERRED
|
653 BG_NOTIFY_JOB_ERROR
|
655 BG_NOTIFY_JOB_MODIFICATION
|
656 BG_NOTIFY_FILE_TRANSFERRED
;
658 TRACE("(%p)->(0x%x)\n", This
, Val
);
660 if (is_job_done(This
)) return BG_E_INVALID_STATE
;
661 if (Val
& ~valid_flags
) return E_NOTIMPL
;
662 This
->notify_flags
= Val
;
666 static HRESULT WINAPI
BackgroundCopyJob_GetNotifyFlags(
667 IBackgroundCopyJob3
*iface
,
670 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
672 TRACE("(%p)->(%p)\n", This
, pVal
);
674 if (!pVal
) return E_INVALIDARG
;
676 *pVal
= This
->notify_flags
;
681 static HRESULT WINAPI
BackgroundCopyJob_SetNotifyInterface(
682 IBackgroundCopyJob3
*iface
,
685 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
688 TRACE("(%p)->(%p)\n", This
, Val
);
690 if (is_job_done(This
)) return BG_E_INVALID_STATE
;
694 IBackgroundCopyCallback2_Release(This
->callback
);
695 This
->callback
= NULL
;
696 This
->callback2
= FALSE
;
701 hr
= IUnknown_QueryInterface(Val
, &IID_IBackgroundCopyCallback2
, (void**)&This
->callback
);
703 hr
= IUnknown_QueryInterface(Val
, &IID_IBackgroundCopyCallback
, (void**)&This
->callback
);
705 This
->callback2
= TRUE
;
711 static HRESULT WINAPI
BackgroundCopyJob_GetNotifyInterface(
712 IBackgroundCopyJob3
*iface
,
715 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
717 TRACE("(%p)->(%p)\n", This
, pVal
);
719 if (!pVal
) return E_INVALIDARG
;
721 *pVal
= (IUnknown
*)This
->callback
;
723 IUnknown_AddRef(*pVal
);
728 static HRESULT WINAPI
BackgroundCopyJob_SetMinimumRetryDelay(
729 IBackgroundCopyJob3
*iface
,
732 FIXME("%u\n", Seconds
);
736 static HRESULT WINAPI
BackgroundCopyJob_GetMinimumRetryDelay(
737 IBackgroundCopyJob3
*iface
,
740 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
741 FIXME("(%p)->(%p): stub\n", This
, Seconds
);
746 static HRESULT WINAPI
BackgroundCopyJob_SetNoProgressTimeout(
747 IBackgroundCopyJob3
*iface
,
750 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
751 FIXME("(%p)->(%d): stub\n", This
, Seconds
);
755 static HRESULT WINAPI
BackgroundCopyJob_GetNoProgressTimeout(
756 IBackgroundCopyJob3
*iface
,
759 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
760 FIXME("(%p)->(%p): stub\n", This
, Seconds
);
765 static HRESULT WINAPI
BackgroundCopyJob_GetErrorCount(
766 IBackgroundCopyJob3
*iface
,
769 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
770 FIXME("(%p)->(%p): stub\n", This
, Errors
);
774 static HRESULT WINAPI
BackgroundCopyJob_SetProxySettings(
775 IBackgroundCopyJob3
*iface
,
776 BG_JOB_PROXY_USAGE ProxyUsage
,
777 const WCHAR
*ProxyList
,
778 const WCHAR
*ProxyBypassList
)
780 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
781 FIXME("(%p)->(%d %s %s): stub\n", This
, ProxyUsage
, debugstr_w(ProxyList
), debugstr_w(ProxyBypassList
));
785 static HRESULT WINAPI
BackgroundCopyJob_GetProxySettings(
786 IBackgroundCopyJob3
*iface
,
787 BG_JOB_PROXY_USAGE
*pProxyUsage
,
789 LPWSTR
*pProxyBypassList
)
791 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
792 FIXME("(%p)->(%p %p %p): stub\n", This
, pProxyUsage
, pProxyList
, pProxyBypassList
);
796 static HRESULT WINAPI
BackgroundCopyJob_TakeOwnership(
797 IBackgroundCopyJob3
*iface
)
799 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
800 FIXME("(%p): stub\n", This
);
804 static HRESULT WINAPI
BackgroundCopyJob_SetNotifyCmdLine(
805 IBackgroundCopyJob3
*iface
,
809 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
810 FIXME("(%p)->(%s %s): stub\n", This
, debugstr_w(prog
), debugstr_w(params
));
814 static HRESULT WINAPI
BackgroundCopyJob_GetNotifyCmdLine(
815 IBackgroundCopyJob3
*iface
,
819 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
820 FIXME("(%p)->(%p %p): stub\n", This
, prog
, params
);
824 static HRESULT WINAPI
BackgroundCopyJob_GetReplyProgress(
825 IBackgroundCopyJob3
*iface
,
826 BG_JOB_REPLY_PROGRESS
*progress
)
828 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
829 FIXME("(%p)->(%p): stub\n", This
, progress
);
833 static HRESULT WINAPI
BackgroundCopyJob_GetReplyData(
834 IBackgroundCopyJob3
*iface
,
838 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
839 FIXME("(%p)->(%p %p): stub\n", This
, pBuffer
, pLength
);
843 static HRESULT WINAPI
BackgroundCopyJob_SetReplyFileName(
844 IBackgroundCopyJob3
*iface
,
847 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
848 FIXME("(%p)->(%s): stub\n", This
, debugstr_w(filename
));
852 static HRESULT WINAPI
BackgroundCopyJob_GetReplyFileName(
853 IBackgroundCopyJob3
*iface
,
856 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
857 FIXME("(%p)->(%p): stub\n", This
, pFilename
);
861 static int index_from_target(BG_AUTH_TARGET target
)
863 if (!target
|| target
> BG_AUTH_TARGET_PROXY
) return -1;
867 static int index_from_scheme(BG_AUTH_SCHEME scheme
)
869 if (!scheme
|| scheme
> BG_AUTH_SCHEME_PASSPORT
) return -1;
873 static HRESULT WINAPI
BackgroundCopyJob_SetCredentials(
874 IBackgroundCopyJob3
*iface
,
875 BG_AUTH_CREDENTIALS
*cred
)
877 BackgroundCopyJobImpl
*job
= impl_from_IBackgroundCopyJob3(iface
);
878 BG_AUTH_CREDENTIALS
*new_cred
;
879 int idx_target
, idx_scheme
;
881 TRACE("(%p)->(%p)\n", job
, cred
);
883 if ((idx_target
= index_from_target(cred
->Target
)) < 0) return BG_E_INVALID_AUTH_TARGET
;
884 if ((idx_scheme
= index_from_scheme(cred
->Scheme
)) < 0) return BG_E_INVALID_AUTH_SCHEME
;
885 new_cred
= &job
->http_options
.creds
[idx_target
][idx_scheme
];
887 EnterCriticalSection(&job
->cs
);
889 new_cred
->Target
= cred
->Target
;
890 new_cred
->Scheme
= cred
->Scheme
;
892 if (cred
->Credentials
.Basic
.UserName
)
894 HeapFree(GetProcessHeap(), 0, new_cred
->Credentials
.Basic
.UserName
);
895 new_cred
->Credentials
.Basic
.UserName
= strdupW(cred
->Credentials
.Basic
.UserName
);
897 if (cred
->Credentials
.Basic
.Password
)
899 HeapFree(GetProcessHeap(), 0, new_cred
->Credentials
.Basic
.Password
);
900 new_cred
->Credentials
.Basic
.Password
= strdupW(cred
->Credentials
.Basic
.Password
);
903 LeaveCriticalSection(&job
->cs
);
907 static HRESULT WINAPI
BackgroundCopyJob_RemoveCredentials(
908 IBackgroundCopyJob3
*iface
,
909 BG_AUTH_TARGET target
,
910 BG_AUTH_SCHEME scheme
)
912 BackgroundCopyJobImpl
*job
= impl_from_IBackgroundCopyJob3(iface
);
913 BG_AUTH_CREDENTIALS
*new_cred
;
914 int idx_target
, idx_scheme
;
916 TRACE("(%p)->(%u %u)\n", job
, target
, scheme
);
918 if ((idx_target
= index_from_target(target
)) < 0) return BG_E_INVALID_AUTH_TARGET
;
919 if ((idx_scheme
= index_from_scheme(scheme
)) < 0) return BG_E_INVALID_AUTH_SCHEME
;
920 new_cred
= &job
->http_options
.creds
[idx_target
][idx_scheme
];
922 EnterCriticalSection(&job
->cs
);
924 new_cred
->Target
= new_cred
->Scheme
= 0;
925 HeapFree(GetProcessHeap(), 0, new_cred
->Credentials
.Basic
.UserName
);
926 new_cred
->Credentials
.Basic
.UserName
= NULL
;
927 HeapFree(GetProcessHeap(), 0, new_cred
->Credentials
.Basic
.Password
);
928 new_cred
->Credentials
.Basic
.Password
= NULL
;
930 LeaveCriticalSection(&job
->cs
);
934 static HRESULT WINAPI
BackgroundCopyJob_ReplaceRemotePrefix(
935 IBackgroundCopyJob3
*iface
,
939 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
940 FIXME("(%p)->(%s %s): stub\n", This
, debugstr_w(OldPrefix
), debugstr_w(NewPrefix
));
944 static HRESULT WINAPI
BackgroundCopyJob_AddFileWithRanges(
945 IBackgroundCopyJob3
*iface
,
949 BG_FILE_RANGE Ranges
[])
951 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
952 FIXME("(%p)->(%s %s %u %p): stub\n", This
, debugstr_w(RemoteUrl
), debugstr_w(LocalName
), RangeCount
, Ranges
);
956 static HRESULT WINAPI
BackgroundCopyJob_SetFileACLFlags(
957 IBackgroundCopyJob3
*iface
,
960 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
961 FIXME("(%p)->(%x): stub\n", This
, Flags
);
965 static HRESULT WINAPI
BackgroundCopyJob_GetFileACLFlags(
966 IBackgroundCopyJob3
*iface
,
969 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
970 FIXME("(%p)->(%p): stub\n", This
, Flags
);
974 static const IBackgroundCopyJob3Vtbl BackgroundCopyJob3Vtbl
=
976 BackgroundCopyJob_QueryInterface
,
977 BackgroundCopyJob_AddRef
,
978 BackgroundCopyJob_Release
,
979 BackgroundCopyJob_AddFileSet
,
980 BackgroundCopyJob_AddFile
,
981 BackgroundCopyJob_EnumFiles
,
982 BackgroundCopyJob_Suspend
,
983 BackgroundCopyJob_Resume
,
984 BackgroundCopyJob_Cancel
,
985 BackgroundCopyJob_Complete
,
986 BackgroundCopyJob_GetId
,
987 BackgroundCopyJob_GetType
,
988 BackgroundCopyJob_GetProgress
,
989 BackgroundCopyJob_GetTimes
,
990 BackgroundCopyJob_GetState
,
991 BackgroundCopyJob_GetError
,
992 BackgroundCopyJob_GetOwner
,
993 BackgroundCopyJob_SetDisplayName
,
994 BackgroundCopyJob_GetDisplayName
,
995 BackgroundCopyJob_SetDescription
,
996 BackgroundCopyJob_GetDescription
,
997 BackgroundCopyJob_SetPriority
,
998 BackgroundCopyJob_GetPriority
,
999 BackgroundCopyJob_SetNotifyFlags
,
1000 BackgroundCopyJob_GetNotifyFlags
,
1001 BackgroundCopyJob_SetNotifyInterface
,
1002 BackgroundCopyJob_GetNotifyInterface
,
1003 BackgroundCopyJob_SetMinimumRetryDelay
,
1004 BackgroundCopyJob_GetMinimumRetryDelay
,
1005 BackgroundCopyJob_SetNoProgressTimeout
,
1006 BackgroundCopyJob_GetNoProgressTimeout
,
1007 BackgroundCopyJob_GetErrorCount
,
1008 BackgroundCopyJob_SetProxySettings
,
1009 BackgroundCopyJob_GetProxySettings
,
1010 BackgroundCopyJob_TakeOwnership
,
1011 BackgroundCopyJob_SetNotifyCmdLine
,
1012 BackgroundCopyJob_GetNotifyCmdLine
,
1013 BackgroundCopyJob_GetReplyProgress
,
1014 BackgroundCopyJob_GetReplyData
,
1015 BackgroundCopyJob_SetReplyFileName
,
1016 BackgroundCopyJob_GetReplyFileName
,
1017 BackgroundCopyJob_SetCredentials
,
1018 BackgroundCopyJob_RemoveCredentials
,
1019 BackgroundCopyJob_ReplaceRemotePrefix
,
1020 BackgroundCopyJob_AddFileWithRanges
,
1021 BackgroundCopyJob_SetFileACLFlags
,
1022 BackgroundCopyJob_GetFileACLFlags
1025 static inline BackgroundCopyJobImpl
*impl_from_IBackgroundCopyJobHttpOptions(
1026 IBackgroundCopyJobHttpOptions
*iface
)
1028 return CONTAINING_RECORD(iface
, BackgroundCopyJobImpl
, IBackgroundCopyJobHttpOptions_iface
);
1031 static HRESULT WINAPI
http_options_QueryInterface(
1032 IBackgroundCopyJobHttpOptions
*iface
,
1036 BackgroundCopyJobImpl
*job
= impl_from_IBackgroundCopyJobHttpOptions(iface
);
1037 return IBackgroundCopyJob3_QueryInterface(&job
->IBackgroundCopyJob3_iface
, riid
, ppvObject
);
1040 static ULONG WINAPI
http_options_AddRef(
1041 IBackgroundCopyJobHttpOptions
*iface
)
1043 BackgroundCopyJobImpl
*job
= impl_from_IBackgroundCopyJobHttpOptions(iface
);
1044 return IBackgroundCopyJob3_AddRef(&job
->IBackgroundCopyJob3_iface
);
1047 static ULONG WINAPI
http_options_Release(
1048 IBackgroundCopyJobHttpOptions
*iface
)
1050 BackgroundCopyJobImpl
*job
= impl_from_IBackgroundCopyJobHttpOptions(iface
);
1051 return IBackgroundCopyJob3_Release(&job
->IBackgroundCopyJob3_iface
);
1054 static HRESULT WINAPI
http_options_SetClientCertificateByID(
1055 IBackgroundCopyJobHttpOptions
*iface
,
1056 BG_CERT_STORE_LOCATION StoreLocation
,
1058 BYTE
*pCertHashBlob
)
1064 static HRESULT WINAPI
http_options_SetClientCertificateByName(
1065 IBackgroundCopyJobHttpOptions
*iface
,
1066 BG_CERT_STORE_LOCATION StoreLocation
,
1068 LPCWSTR SubjectName
)
1074 static HRESULT WINAPI
http_options_RemoveClientCertificate(
1075 IBackgroundCopyJobHttpOptions
*iface
)
1081 static HRESULT WINAPI
http_options_GetClientCertificate(
1082 IBackgroundCopyJobHttpOptions
*iface
,
1083 BG_CERT_STORE_LOCATION
*pStoreLocation
,
1085 BYTE
**ppCertHashBlob
,
1086 LPWSTR
*pSubjectName
)
1092 static HRESULT WINAPI
http_options_SetCustomHeaders(
1093 IBackgroundCopyJobHttpOptions
*iface
,
1094 LPCWSTR RequestHeaders
)
1096 BackgroundCopyJobImpl
*job
= impl_from_IBackgroundCopyJobHttpOptions(iface
);
1098 TRACE("(%p)->(%s)\n", iface
, debugstr_w(RequestHeaders
));
1100 EnterCriticalSection(&job
->cs
);
1104 WCHAR
*headers
= strdupW(RequestHeaders
);
1107 LeaveCriticalSection(&job
->cs
);
1108 return E_OUTOFMEMORY
;
1110 HeapFree(GetProcessHeap(), 0, job
->http_options
.headers
);
1111 job
->http_options
.headers
= headers
;
1115 HeapFree(GetProcessHeap(), 0, job
->http_options
.headers
);
1116 job
->http_options
.headers
= NULL
;
1119 LeaveCriticalSection(&job
->cs
);
1123 static HRESULT WINAPI
http_options_GetCustomHeaders(
1124 IBackgroundCopyJobHttpOptions
*iface
,
1125 LPWSTR
*pRequestHeaders
)
1127 BackgroundCopyJobImpl
*job
= impl_from_IBackgroundCopyJobHttpOptions(iface
);
1129 TRACE("(%p)->(%p)\n", iface
, pRequestHeaders
);
1131 EnterCriticalSection(&job
->cs
);
1133 if (job
->http_options
.headers
)
1135 WCHAR
*headers
= co_strdupW(job
->http_options
.headers
);
1138 LeaveCriticalSection(&job
->cs
);
1139 return E_OUTOFMEMORY
;
1141 *pRequestHeaders
= headers
;
1142 LeaveCriticalSection(&job
->cs
);
1146 *pRequestHeaders
= NULL
;
1147 LeaveCriticalSection(&job
->cs
);
1151 static HRESULT WINAPI
http_options_SetSecurityFlags(
1152 IBackgroundCopyJobHttpOptions
*iface
,
1155 BackgroundCopyJobImpl
*job
= impl_from_IBackgroundCopyJobHttpOptions(iface
);
1157 TRACE("(%p)->(0x%08x)\n", iface
, Flags
);
1159 job
->http_options
.flags
= Flags
;
1163 static HRESULT WINAPI
http_options_GetSecurityFlags(
1164 IBackgroundCopyJobHttpOptions
*iface
,
1167 BackgroundCopyJobImpl
*job
= impl_from_IBackgroundCopyJobHttpOptions(iface
);
1169 TRACE("(%p)->(%p)\n", iface
, pFlags
);
1171 *pFlags
= job
->http_options
.flags
;
1175 static const IBackgroundCopyJobHttpOptionsVtbl http_options_vtbl
=
1177 http_options_QueryInterface
,
1178 http_options_AddRef
,
1179 http_options_Release
,
1180 http_options_SetClientCertificateByID
,
1181 http_options_SetClientCertificateByName
,
1182 http_options_RemoveClientCertificate
,
1183 http_options_GetClientCertificate
,
1184 http_options_SetCustomHeaders
,
1185 http_options_GetCustomHeaders
,
1186 http_options_SetSecurityFlags
,
1187 http_options_GetSecurityFlags
1190 HRESULT
BackgroundCopyJobConstructor(LPCWSTR displayName
, BG_JOB_TYPE type
, GUID
*job_id
, BackgroundCopyJobImpl
**job
)
1193 BackgroundCopyJobImpl
*This
;
1195 TRACE("(%s,%d,%p)\n", debugstr_w(displayName
), type
, job
);
1197 This
= HeapAlloc(GetProcessHeap(), 0, sizeof *This
);
1199 return E_OUTOFMEMORY
;
1201 This
->IBackgroundCopyJob3_iface
.lpVtbl
= &BackgroundCopyJob3Vtbl
;
1202 This
->IBackgroundCopyJobHttpOptions_iface
.lpVtbl
= &http_options_vtbl
;
1203 InitializeCriticalSection(&This
->cs
);
1204 This
->cs
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": BackgroundCopyJobImpl.cs");
1209 This
->displayName
= strdupW(displayName
);
1210 if (!This
->displayName
)
1212 This
->cs
.DebugInfo
->Spare
[0] = 0;
1213 DeleteCriticalSection(&This
->cs
);
1214 HeapFree(GetProcessHeap(), 0, This
);
1215 return E_OUTOFMEMORY
;
1218 hr
= CoCreateGuid(&This
->jobId
);
1221 This
->cs
.DebugInfo
->Spare
[0] = 0;
1222 DeleteCriticalSection(&This
->cs
);
1223 HeapFree(GetProcessHeap(), 0, This
->displayName
);
1224 HeapFree(GetProcessHeap(), 0, This
);
1227 *job_id
= This
->jobId
;
1229 list_init(&This
->files
);
1230 This
->jobProgress
.BytesTotal
= 0;
1231 This
->jobProgress
.BytesTransferred
= 0;
1232 This
->jobProgress
.FilesTotal
= 0;
1233 This
->jobProgress
.FilesTransferred
= 0;
1235 This
->state
= BG_JOB_STATE_SUSPENDED
;
1236 This
->description
= NULL
;
1237 This
->notify_flags
= BG_NOTIFY_JOB_ERROR
| BG_NOTIFY_JOB_TRANSFERRED
;
1238 This
->callback
= NULL
;
1239 This
->callback2
= FALSE
;
1241 This
->error
.context
= 0;
1242 This
->error
.code
= 0;
1243 This
->error
.file
= NULL
;
1245 memset(&This
->http_options
, 0, sizeof(This
->http_options
));
1247 This
->wait
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
1248 This
->cancel
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
1249 This
->done
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
1253 TRACE("created job %s:%p\n", debugstr_guid(&This
->jobId
), This
);
1258 void processJob(BackgroundCopyJobImpl
*job
)
1262 BackgroundCopyFileImpl
*file
;
1265 EnterCriticalSection(&job
->cs
);
1266 LIST_FOR_EACH_ENTRY(file
, &job
->files
, BackgroundCopyFileImpl
, entryFromJob
)
1267 if (!file
->fileProgress
.Completed
)
1272 LeaveCriticalSection(&job
->cs
);
1275 transitionJobState(job
, BG_JOB_STATE_QUEUED
, BG_JOB_STATE_TRANSFERRED
);
1279 if (!processFile(file
, job
))