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 This
->error
.context
= 0;
375 This
->error
.code
= S_OK
;
376 if (This
->error
.file
)
378 IBackgroundCopyFile2_Release(This
->error
.file
);
379 This
->error
.file
= NULL
;
381 SetEvent(globalMgr
.jobEvent
);
383 LeaveCriticalSection(&globalMgr
.cs
);
388 static HRESULT WINAPI
BackgroundCopyJob_Cancel(
389 IBackgroundCopyJob3
*iface
)
391 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
394 TRACE("(%p)\n", This
);
396 EnterCriticalSection(&This
->cs
);
398 if (is_job_done(This
))
400 rv
= BG_E_INVALID_STATE
;
404 BackgroundCopyFileImpl
*file
;
406 if (This
->state
== BG_JOB_STATE_CONNECTING
|| This
->state
== BG_JOB_STATE_TRANSFERRING
)
408 This
->state
= BG_JOB_STATE_CANCELLED
;
409 SetEvent(This
->cancel
);
411 LeaveCriticalSection(&This
->cs
);
412 WaitForSingleObject(This
->done
, INFINITE
);
413 EnterCriticalSection(&This
->cs
);
416 LIST_FOR_EACH_ENTRY(file
, &This
->files
, BackgroundCopyFileImpl
, entryFromJob
)
418 if (file
->tempFileName
[0] && !DeleteFileW(file
->tempFileName
))
420 WARN("Couldn't delete %s (%u)\n", debugstr_w(file
->tempFileName
), GetLastError());
421 rv
= BG_S_UNABLE_TO_DELETE_FILES
;
423 if (file
->info
.LocalName
&& !DeleteFileW(file
->info
.LocalName
))
425 WARN("Couldn't delete %s (%u)\n", debugstr_w(file
->info
.LocalName
), GetLastError());
426 rv
= BG_S_UNABLE_TO_DELETE_FILES
;
429 This
->state
= BG_JOB_STATE_CANCELLED
;
432 LeaveCriticalSection(&This
->cs
);
436 static HRESULT WINAPI
BackgroundCopyJob_Complete(
437 IBackgroundCopyJob3
*iface
)
439 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
442 TRACE("(%p)\n", This
);
444 EnterCriticalSection(&This
->cs
);
446 if (is_job_done(This
))
448 rv
= BG_E_INVALID_STATE
;
452 BackgroundCopyFileImpl
*file
;
453 LIST_FOR_EACH_ENTRY(file
, &This
->files
, BackgroundCopyFileImpl
, entryFromJob
)
455 if (file
->fileProgress
.Completed
)
457 if (!MoveFileExW(file
->tempFileName
, file
->info
.LocalName
,
458 (MOVEFILE_COPY_ALLOWED
459 | MOVEFILE_REPLACE_EXISTING
460 | MOVEFILE_WRITE_THROUGH
)))
462 ERR("Couldn't rename file %s -> %s\n",
463 debugstr_w(file
->tempFileName
),
464 debugstr_w(file
->info
.LocalName
));
465 rv
= BG_S_PARTIAL_COMPLETE
;
469 rv
= BG_S_PARTIAL_COMPLETE
;
473 This
->state
= BG_JOB_STATE_ACKNOWLEDGED
;
474 LeaveCriticalSection(&This
->cs
);
479 static HRESULT WINAPI
BackgroundCopyJob_GetId(
480 IBackgroundCopyJob3
*iface
,
483 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
484 TRACE("(%p)->(%p)\n", This
, pVal
);
489 static HRESULT WINAPI
BackgroundCopyJob_GetType(
490 IBackgroundCopyJob3
*iface
,
493 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
495 TRACE("(%p)->(%p)\n", This
, pVal
);
504 static HRESULT WINAPI
BackgroundCopyJob_GetProgress(
505 IBackgroundCopyJob3
*iface
,
506 BG_JOB_PROGRESS
*pVal
)
508 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
510 TRACE("(%p)->(%p)\n", This
, pVal
);
515 EnterCriticalSection(&This
->cs
);
516 *pVal
= This
->jobProgress
;
517 LeaveCriticalSection(&This
->cs
);
522 static HRESULT WINAPI
BackgroundCopyJob_GetTimes(
523 IBackgroundCopyJob3
*iface
,
526 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
527 FIXME("(%p)->(%p): stub\n", This
, pVal
);
531 static HRESULT WINAPI
BackgroundCopyJob_GetState(
532 IBackgroundCopyJob3
*iface
,
535 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
537 TRACE("(%p)->(%p)\n", This
, pVal
);
542 /* Don't think we need a critical section for this */
547 static HRESULT WINAPI
BackgroundCopyJob_GetError(
548 IBackgroundCopyJob3
*iface
,
549 IBackgroundCopyError
**ppError
)
551 BackgroundCopyJobImpl
*job
= impl_from_IBackgroundCopyJob3(iface
);
553 TRACE("(%p)->(%p)\n", job
, ppError
);
555 if (!job
->error
.context
) return BG_E_ERROR_INFORMATION_UNAVAILABLE
;
557 return create_copy_error(job
->error
.context
, job
->error
.code
, job
->error
.file
, ppError
);
560 static HRESULT WINAPI
BackgroundCopyJob_GetOwner(
561 IBackgroundCopyJob3
*iface
,
564 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
565 FIXME("(%p)->(%p): stub\n", This
, pVal
);
569 static HRESULT WINAPI
BackgroundCopyJob_SetDisplayName(
570 IBackgroundCopyJob3
*iface
,
573 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
574 FIXME("(%p)->(%s): stub\n", This
, debugstr_w(Val
));
578 static HRESULT WINAPI
BackgroundCopyJob_GetDisplayName(
579 IBackgroundCopyJob3
*iface
,
582 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
584 TRACE("(%p)->(%p)\n", This
, pVal
);
586 return return_strval(This
->displayName
, pVal
);
589 static HRESULT WINAPI
BackgroundCopyJob_SetDescription(
590 IBackgroundCopyJob3
*iface
,
593 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
594 static const int max_description_len
= 1024;
598 TRACE("(%p)->(%s)\n", This
, debugstr_w(Val
));
600 if (!Val
) return E_INVALIDARG
;
603 if (len
> max_description_len
) return BG_E_STRING_TOO_LONG
;
605 EnterCriticalSection(&This
->cs
);
607 if (is_job_done(This
))
609 hr
= BG_E_INVALID_STATE
;
613 HeapFree(GetProcessHeap(), 0, This
->description
);
614 if ((This
->description
= HeapAlloc(GetProcessHeap(), 0, (len
+1)*sizeof(WCHAR
))))
615 strcpyW(This
->description
, Val
);
620 LeaveCriticalSection(&This
->cs
);
625 static HRESULT WINAPI
BackgroundCopyJob_GetDescription(
626 IBackgroundCopyJob3
*iface
,
629 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
631 TRACE("(%p)->(%p)\n", This
, pVal
);
633 return return_strval(This
->description
, pVal
);
636 static HRESULT WINAPI
BackgroundCopyJob_SetPriority(
637 IBackgroundCopyJob3
*iface
,
640 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
641 FIXME("(%p)->(%d): stub\n", This
, Val
);
645 static HRESULT WINAPI
BackgroundCopyJob_GetPriority(
646 IBackgroundCopyJob3
*iface
,
647 BG_JOB_PRIORITY
*pVal
)
649 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
650 FIXME("(%p)->(%p): stub\n", This
, pVal
);
654 static HRESULT WINAPI
BackgroundCopyJob_SetNotifyFlags(
655 IBackgroundCopyJob3
*iface
,
658 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
659 static const ULONG valid_flags
= BG_NOTIFY_JOB_TRANSFERRED
|
660 BG_NOTIFY_JOB_ERROR
|
662 BG_NOTIFY_JOB_MODIFICATION
|
663 BG_NOTIFY_FILE_TRANSFERRED
;
665 TRACE("(%p)->(0x%x)\n", This
, Val
);
667 if (is_job_done(This
)) return BG_E_INVALID_STATE
;
668 if (Val
& ~valid_flags
) return E_NOTIMPL
;
669 This
->notify_flags
= Val
;
673 static HRESULT WINAPI
BackgroundCopyJob_GetNotifyFlags(
674 IBackgroundCopyJob3
*iface
,
677 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
679 TRACE("(%p)->(%p)\n", This
, pVal
);
681 if (!pVal
) return E_INVALIDARG
;
683 *pVal
= This
->notify_flags
;
688 static HRESULT WINAPI
BackgroundCopyJob_SetNotifyInterface(
689 IBackgroundCopyJob3
*iface
,
692 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
695 TRACE("(%p)->(%p)\n", This
, Val
);
697 if (is_job_done(This
)) return BG_E_INVALID_STATE
;
701 IBackgroundCopyCallback2_Release(This
->callback
);
702 This
->callback
= NULL
;
703 This
->callback2
= FALSE
;
708 hr
= IUnknown_QueryInterface(Val
, &IID_IBackgroundCopyCallback2
, (void**)&This
->callback
);
710 hr
= IUnknown_QueryInterface(Val
, &IID_IBackgroundCopyCallback
, (void**)&This
->callback
);
712 This
->callback2
= TRUE
;
718 static HRESULT WINAPI
BackgroundCopyJob_GetNotifyInterface(
719 IBackgroundCopyJob3
*iface
,
722 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
724 TRACE("(%p)->(%p)\n", This
, pVal
);
726 if (!pVal
) return E_INVALIDARG
;
728 *pVal
= (IUnknown
*)This
->callback
;
730 IUnknown_AddRef(*pVal
);
735 static HRESULT WINAPI
BackgroundCopyJob_SetMinimumRetryDelay(
736 IBackgroundCopyJob3
*iface
,
739 FIXME("%u\n", Seconds
);
743 static HRESULT WINAPI
BackgroundCopyJob_GetMinimumRetryDelay(
744 IBackgroundCopyJob3
*iface
,
747 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
748 FIXME("(%p)->(%p): stub\n", This
, Seconds
);
753 static HRESULT WINAPI
BackgroundCopyJob_SetNoProgressTimeout(
754 IBackgroundCopyJob3
*iface
,
757 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
758 FIXME("(%p)->(%d): stub\n", This
, Seconds
);
762 static HRESULT WINAPI
BackgroundCopyJob_GetNoProgressTimeout(
763 IBackgroundCopyJob3
*iface
,
766 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
767 FIXME("(%p)->(%p): stub\n", This
, Seconds
);
772 static HRESULT WINAPI
BackgroundCopyJob_GetErrorCount(
773 IBackgroundCopyJob3
*iface
,
776 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
777 FIXME("(%p)->(%p): stub\n", This
, Errors
);
781 static HRESULT WINAPI
BackgroundCopyJob_SetProxySettings(
782 IBackgroundCopyJob3
*iface
,
783 BG_JOB_PROXY_USAGE ProxyUsage
,
784 const WCHAR
*ProxyList
,
785 const WCHAR
*ProxyBypassList
)
787 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
788 FIXME("(%p)->(%d %s %s): stub\n", This
, ProxyUsage
, debugstr_w(ProxyList
), debugstr_w(ProxyBypassList
));
792 static HRESULT WINAPI
BackgroundCopyJob_GetProxySettings(
793 IBackgroundCopyJob3
*iface
,
794 BG_JOB_PROXY_USAGE
*pProxyUsage
,
796 LPWSTR
*pProxyBypassList
)
798 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
799 FIXME("(%p)->(%p %p %p): stub\n", This
, pProxyUsage
, pProxyList
, pProxyBypassList
);
803 static HRESULT WINAPI
BackgroundCopyJob_TakeOwnership(
804 IBackgroundCopyJob3
*iface
)
806 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
807 FIXME("(%p): stub\n", This
);
811 static HRESULT WINAPI
BackgroundCopyJob_SetNotifyCmdLine(
812 IBackgroundCopyJob3
*iface
,
816 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
817 FIXME("(%p)->(%s %s): stub\n", This
, debugstr_w(prog
), debugstr_w(params
));
821 static HRESULT WINAPI
BackgroundCopyJob_GetNotifyCmdLine(
822 IBackgroundCopyJob3
*iface
,
826 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
827 FIXME("(%p)->(%p %p): stub\n", This
, prog
, params
);
831 static HRESULT WINAPI
BackgroundCopyJob_GetReplyProgress(
832 IBackgroundCopyJob3
*iface
,
833 BG_JOB_REPLY_PROGRESS
*progress
)
835 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
836 FIXME("(%p)->(%p): stub\n", This
, progress
);
840 static HRESULT WINAPI
BackgroundCopyJob_GetReplyData(
841 IBackgroundCopyJob3
*iface
,
845 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
846 FIXME("(%p)->(%p %p): stub\n", This
, pBuffer
, pLength
);
850 static HRESULT WINAPI
BackgroundCopyJob_SetReplyFileName(
851 IBackgroundCopyJob3
*iface
,
854 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
855 FIXME("(%p)->(%s): stub\n", This
, debugstr_w(filename
));
859 static HRESULT WINAPI
BackgroundCopyJob_GetReplyFileName(
860 IBackgroundCopyJob3
*iface
,
863 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
864 FIXME("(%p)->(%p): stub\n", This
, pFilename
);
868 static int index_from_target(BG_AUTH_TARGET target
)
870 if (!target
|| target
> BG_AUTH_TARGET_PROXY
) return -1;
874 static int index_from_scheme(BG_AUTH_SCHEME scheme
)
876 if (!scheme
|| scheme
> BG_AUTH_SCHEME_PASSPORT
) return -1;
880 static HRESULT WINAPI
BackgroundCopyJob_SetCredentials(
881 IBackgroundCopyJob3
*iface
,
882 BG_AUTH_CREDENTIALS
*cred
)
884 BackgroundCopyJobImpl
*job
= impl_from_IBackgroundCopyJob3(iface
);
885 BG_AUTH_CREDENTIALS
*new_cred
;
886 int idx_target
, idx_scheme
;
888 TRACE("(%p)->(%p)\n", job
, cred
);
890 if ((idx_target
= index_from_target(cred
->Target
)) < 0) return BG_E_INVALID_AUTH_TARGET
;
891 if ((idx_scheme
= index_from_scheme(cred
->Scheme
)) < 0) return BG_E_INVALID_AUTH_SCHEME
;
892 new_cred
= &job
->http_options
.creds
[idx_target
][idx_scheme
];
894 EnterCriticalSection(&job
->cs
);
896 new_cred
->Target
= cred
->Target
;
897 new_cred
->Scheme
= cred
->Scheme
;
899 if (cred
->Credentials
.Basic
.UserName
)
901 HeapFree(GetProcessHeap(), 0, new_cred
->Credentials
.Basic
.UserName
);
902 new_cred
->Credentials
.Basic
.UserName
= strdupW(cred
->Credentials
.Basic
.UserName
);
904 if (cred
->Credentials
.Basic
.Password
)
906 HeapFree(GetProcessHeap(), 0, new_cred
->Credentials
.Basic
.Password
);
907 new_cred
->Credentials
.Basic
.Password
= strdupW(cred
->Credentials
.Basic
.Password
);
910 LeaveCriticalSection(&job
->cs
);
914 static HRESULT WINAPI
BackgroundCopyJob_RemoveCredentials(
915 IBackgroundCopyJob3
*iface
,
916 BG_AUTH_TARGET target
,
917 BG_AUTH_SCHEME scheme
)
919 BackgroundCopyJobImpl
*job
= impl_from_IBackgroundCopyJob3(iface
);
920 BG_AUTH_CREDENTIALS
*new_cred
;
921 int idx_target
, idx_scheme
;
923 TRACE("(%p)->(%u %u)\n", job
, target
, scheme
);
925 if ((idx_target
= index_from_target(target
)) < 0) return BG_E_INVALID_AUTH_TARGET
;
926 if ((idx_scheme
= index_from_scheme(scheme
)) < 0) return BG_E_INVALID_AUTH_SCHEME
;
927 new_cred
= &job
->http_options
.creds
[idx_target
][idx_scheme
];
929 EnterCriticalSection(&job
->cs
);
931 new_cred
->Target
= new_cred
->Scheme
= 0;
932 HeapFree(GetProcessHeap(), 0, new_cred
->Credentials
.Basic
.UserName
);
933 new_cred
->Credentials
.Basic
.UserName
= NULL
;
934 HeapFree(GetProcessHeap(), 0, new_cred
->Credentials
.Basic
.Password
);
935 new_cred
->Credentials
.Basic
.Password
= NULL
;
937 LeaveCriticalSection(&job
->cs
);
941 static HRESULT WINAPI
BackgroundCopyJob_ReplaceRemotePrefix(
942 IBackgroundCopyJob3
*iface
,
946 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
947 FIXME("(%p)->(%s %s): stub\n", This
, debugstr_w(OldPrefix
), debugstr_w(NewPrefix
));
951 static HRESULT WINAPI
BackgroundCopyJob_AddFileWithRanges(
952 IBackgroundCopyJob3
*iface
,
956 BG_FILE_RANGE Ranges
[])
958 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
959 FIXME("(%p)->(%s %s %u %p): stub\n", This
, debugstr_w(RemoteUrl
), debugstr_w(LocalName
), RangeCount
, Ranges
);
963 static HRESULT WINAPI
BackgroundCopyJob_SetFileACLFlags(
964 IBackgroundCopyJob3
*iface
,
967 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
968 FIXME("(%p)->(%x): stub\n", This
, Flags
);
972 static HRESULT WINAPI
BackgroundCopyJob_GetFileACLFlags(
973 IBackgroundCopyJob3
*iface
,
976 BackgroundCopyJobImpl
*This
= impl_from_IBackgroundCopyJob3(iface
);
977 FIXME("(%p)->(%p): stub\n", This
, Flags
);
981 static const IBackgroundCopyJob3Vtbl BackgroundCopyJob3Vtbl
=
983 BackgroundCopyJob_QueryInterface
,
984 BackgroundCopyJob_AddRef
,
985 BackgroundCopyJob_Release
,
986 BackgroundCopyJob_AddFileSet
,
987 BackgroundCopyJob_AddFile
,
988 BackgroundCopyJob_EnumFiles
,
989 BackgroundCopyJob_Suspend
,
990 BackgroundCopyJob_Resume
,
991 BackgroundCopyJob_Cancel
,
992 BackgroundCopyJob_Complete
,
993 BackgroundCopyJob_GetId
,
994 BackgroundCopyJob_GetType
,
995 BackgroundCopyJob_GetProgress
,
996 BackgroundCopyJob_GetTimes
,
997 BackgroundCopyJob_GetState
,
998 BackgroundCopyJob_GetError
,
999 BackgroundCopyJob_GetOwner
,
1000 BackgroundCopyJob_SetDisplayName
,
1001 BackgroundCopyJob_GetDisplayName
,
1002 BackgroundCopyJob_SetDescription
,
1003 BackgroundCopyJob_GetDescription
,
1004 BackgroundCopyJob_SetPriority
,
1005 BackgroundCopyJob_GetPriority
,
1006 BackgroundCopyJob_SetNotifyFlags
,
1007 BackgroundCopyJob_GetNotifyFlags
,
1008 BackgroundCopyJob_SetNotifyInterface
,
1009 BackgroundCopyJob_GetNotifyInterface
,
1010 BackgroundCopyJob_SetMinimumRetryDelay
,
1011 BackgroundCopyJob_GetMinimumRetryDelay
,
1012 BackgroundCopyJob_SetNoProgressTimeout
,
1013 BackgroundCopyJob_GetNoProgressTimeout
,
1014 BackgroundCopyJob_GetErrorCount
,
1015 BackgroundCopyJob_SetProxySettings
,
1016 BackgroundCopyJob_GetProxySettings
,
1017 BackgroundCopyJob_TakeOwnership
,
1018 BackgroundCopyJob_SetNotifyCmdLine
,
1019 BackgroundCopyJob_GetNotifyCmdLine
,
1020 BackgroundCopyJob_GetReplyProgress
,
1021 BackgroundCopyJob_GetReplyData
,
1022 BackgroundCopyJob_SetReplyFileName
,
1023 BackgroundCopyJob_GetReplyFileName
,
1024 BackgroundCopyJob_SetCredentials
,
1025 BackgroundCopyJob_RemoveCredentials
,
1026 BackgroundCopyJob_ReplaceRemotePrefix
,
1027 BackgroundCopyJob_AddFileWithRanges
,
1028 BackgroundCopyJob_SetFileACLFlags
,
1029 BackgroundCopyJob_GetFileACLFlags
1032 static inline BackgroundCopyJobImpl
*impl_from_IBackgroundCopyJobHttpOptions(
1033 IBackgroundCopyJobHttpOptions
*iface
)
1035 return CONTAINING_RECORD(iface
, BackgroundCopyJobImpl
, IBackgroundCopyJobHttpOptions_iface
);
1038 static HRESULT WINAPI
http_options_QueryInterface(
1039 IBackgroundCopyJobHttpOptions
*iface
,
1043 BackgroundCopyJobImpl
*job
= impl_from_IBackgroundCopyJobHttpOptions(iface
);
1044 return IBackgroundCopyJob3_QueryInterface(&job
->IBackgroundCopyJob3_iface
, riid
, ppvObject
);
1047 static ULONG WINAPI
http_options_AddRef(
1048 IBackgroundCopyJobHttpOptions
*iface
)
1050 BackgroundCopyJobImpl
*job
= impl_from_IBackgroundCopyJobHttpOptions(iface
);
1051 return IBackgroundCopyJob3_AddRef(&job
->IBackgroundCopyJob3_iface
);
1054 static ULONG WINAPI
http_options_Release(
1055 IBackgroundCopyJobHttpOptions
*iface
)
1057 BackgroundCopyJobImpl
*job
= impl_from_IBackgroundCopyJobHttpOptions(iface
);
1058 return IBackgroundCopyJob3_Release(&job
->IBackgroundCopyJob3_iface
);
1061 static HRESULT WINAPI
http_options_SetClientCertificateByID(
1062 IBackgroundCopyJobHttpOptions
*iface
,
1063 BG_CERT_STORE_LOCATION StoreLocation
,
1065 BYTE
*pCertHashBlob
)
1071 static HRESULT WINAPI
http_options_SetClientCertificateByName(
1072 IBackgroundCopyJobHttpOptions
*iface
,
1073 BG_CERT_STORE_LOCATION StoreLocation
,
1075 LPCWSTR SubjectName
)
1081 static HRESULT WINAPI
http_options_RemoveClientCertificate(
1082 IBackgroundCopyJobHttpOptions
*iface
)
1088 static HRESULT WINAPI
http_options_GetClientCertificate(
1089 IBackgroundCopyJobHttpOptions
*iface
,
1090 BG_CERT_STORE_LOCATION
*pStoreLocation
,
1092 BYTE
**ppCertHashBlob
,
1093 LPWSTR
*pSubjectName
)
1099 static HRESULT WINAPI
http_options_SetCustomHeaders(
1100 IBackgroundCopyJobHttpOptions
*iface
,
1101 LPCWSTR RequestHeaders
)
1103 BackgroundCopyJobImpl
*job
= impl_from_IBackgroundCopyJobHttpOptions(iface
);
1105 TRACE("(%p)->(%s)\n", iface
, debugstr_w(RequestHeaders
));
1107 EnterCriticalSection(&job
->cs
);
1111 WCHAR
*headers
= strdupW(RequestHeaders
);
1114 LeaveCriticalSection(&job
->cs
);
1115 return E_OUTOFMEMORY
;
1117 HeapFree(GetProcessHeap(), 0, job
->http_options
.headers
);
1118 job
->http_options
.headers
= headers
;
1122 HeapFree(GetProcessHeap(), 0, job
->http_options
.headers
);
1123 job
->http_options
.headers
= NULL
;
1126 LeaveCriticalSection(&job
->cs
);
1130 static HRESULT WINAPI
http_options_GetCustomHeaders(
1131 IBackgroundCopyJobHttpOptions
*iface
,
1132 LPWSTR
*pRequestHeaders
)
1134 BackgroundCopyJobImpl
*job
= impl_from_IBackgroundCopyJobHttpOptions(iface
);
1136 TRACE("(%p)->(%p)\n", iface
, pRequestHeaders
);
1138 EnterCriticalSection(&job
->cs
);
1140 if (job
->http_options
.headers
)
1142 WCHAR
*headers
= co_strdupW(job
->http_options
.headers
);
1145 LeaveCriticalSection(&job
->cs
);
1146 return E_OUTOFMEMORY
;
1148 *pRequestHeaders
= headers
;
1149 LeaveCriticalSection(&job
->cs
);
1153 *pRequestHeaders
= NULL
;
1154 LeaveCriticalSection(&job
->cs
);
1158 static HRESULT WINAPI
http_options_SetSecurityFlags(
1159 IBackgroundCopyJobHttpOptions
*iface
,
1162 BackgroundCopyJobImpl
*job
= impl_from_IBackgroundCopyJobHttpOptions(iface
);
1164 TRACE("(%p)->(0x%08x)\n", iface
, Flags
);
1166 job
->http_options
.flags
= Flags
;
1170 static HRESULT WINAPI
http_options_GetSecurityFlags(
1171 IBackgroundCopyJobHttpOptions
*iface
,
1174 BackgroundCopyJobImpl
*job
= impl_from_IBackgroundCopyJobHttpOptions(iface
);
1176 TRACE("(%p)->(%p)\n", iface
, pFlags
);
1178 *pFlags
= job
->http_options
.flags
;
1182 static const IBackgroundCopyJobHttpOptionsVtbl http_options_vtbl
=
1184 http_options_QueryInterface
,
1185 http_options_AddRef
,
1186 http_options_Release
,
1187 http_options_SetClientCertificateByID
,
1188 http_options_SetClientCertificateByName
,
1189 http_options_RemoveClientCertificate
,
1190 http_options_GetClientCertificate
,
1191 http_options_SetCustomHeaders
,
1192 http_options_GetCustomHeaders
,
1193 http_options_SetSecurityFlags
,
1194 http_options_GetSecurityFlags
1197 HRESULT
BackgroundCopyJobConstructor(LPCWSTR displayName
, BG_JOB_TYPE type
, GUID
*job_id
, BackgroundCopyJobImpl
**job
)
1200 BackgroundCopyJobImpl
*This
;
1202 TRACE("(%s,%d,%p)\n", debugstr_w(displayName
), type
, job
);
1204 This
= HeapAlloc(GetProcessHeap(), 0, sizeof *This
);
1206 return E_OUTOFMEMORY
;
1208 This
->IBackgroundCopyJob3_iface
.lpVtbl
= &BackgroundCopyJob3Vtbl
;
1209 This
->IBackgroundCopyJobHttpOptions_iface
.lpVtbl
= &http_options_vtbl
;
1210 InitializeCriticalSection(&This
->cs
);
1211 This
->cs
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": BackgroundCopyJobImpl.cs");
1216 This
->displayName
= strdupW(displayName
);
1217 if (!This
->displayName
)
1219 This
->cs
.DebugInfo
->Spare
[0] = 0;
1220 DeleteCriticalSection(&This
->cs
);
1221 HeapFree(GetProcessHeap(), 0, This
);
1222 return E_OUTOFMEMORY
;
1225 hr
= CoCreateGuid(&This
->jobId
);
1228 This
->cs
.DebugInfo
->Spare
[0] = 0;
1229 DeleteCriticalSection(&This
->cs
);
1230 HeapFree(GetProcessHeap(), 0, This
->displayName
);
1231 HeapFree(GetProcessHeap(), 0, This
);
1234 *job_id
= This
->jobId
;
1236 list_init(&This
->files
);
1237 This
->jobProgress
.BytesTotal
= 0;
1238 This
->jobProgress
.BytesTransferred
= 0;
1239 This
->jobProgress
.FilesTotal
= 0;
1240 This
->jobProgress
.FilesTransferred
= 0;
1242 This
->state
= BG_JOB_STATE_SUSPENDED
;
1243 This
->description
= NULL
;
1244 This
->notify_flags
= BG_NOTIFY_JOB_ERROR
| BG_NOTIFY_JOB_TRANSFERRED
;
1245 This
->callback
= NULL
;
1246 This
->callback2
= FALSE
;
1248 This
->error
.context
= 0;
1249 This
->error
.code
= S_OK
;
1250 This
->error
.file
= NULL
;
1252 memset(&This
->http_options
, 0, sizeof(This
->http_options
));
1254 This
->wait
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
1255 This
->cancel
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
1256 This
->done
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
1260 TRACE("created job %s:%p\n", debugstr_guid(&This
->jobId
), This
);
1265 void processJob(BackgroundCopyJobImpl
*job
)
1269 BackgroundCopyFileImpl
*file
;
1272 EnterCriticalSection(&job
->cs
);
1273 LIST_FOR_EACH_ENTRY(file
, &job
->files
, BackgroundCopyFileImpl
, entryFromJob
)
1274 if (!file
->fileProgress
.Completed
)
1279 LeaveCriticalSection(&job
->cs
);
1282 transitionJobState(job
, BG_JOB_STATE_QUEUED
, BG_JOB_STATE_TRANSFERRED
);
1286 if (!processFile(file
, job
))