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_IBackgroundCopyJob4(IBackgroundCopyJob4
*iface
)
212 return CONTAINING_RECORD(iface
, BackgroundCopyJobImpl
, IBackgroundCopyJob4_iface
);
215 static HRESULT WINAPI
BackgroundCopyJob_QueryInterface(IBackgroundCopyJob4
*iface
, REFIID riid
, void **obj
)
217 BackgroundCopyJobImpl
*job
= impl_from_IBackgroundCopyJob4(iface
);
219 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), obj
);
221 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
222 IsEqualGUID(riid
, &IID_IBackgroundCopyJob
) ||
223 IsEqualGUID(riid
, &IID_IBackgroundCopyJob2
) ||
224 IsEqualGUID(riid
, &IID_IBackgroundCopyJob3
) ||
225 IsEqualGUID(riid
, &IID_IBackgroundCopyJob4
))
227 *obj
= &job
->IBackgroundCopyJob4_iface
;
229 else if (IsEqualGUID(riid
, &IID_IBackgroundCopyJobHttpOptions
))
231 *obj
= &job
->IBackgroundCopyJobHttpOptions_iface
;
235 WARN("Unsupported interface %s.\n", debugstr_guid(riid
));
237 return E_NOINTERFACE
;
240 IBackgroundCopyJob4_AddRef(iface
);
244 static ULONG WINAPI
BackgroundCopyJob_AddRef(IBackgroundCopyJob4
*iface
)
246 BackgroundCopyJobImpl
*job
= impl_from_IBackgroundCopyJob4(iface
);
247 ULONG refcount
= InterlockedIncrement(&job
->ref
);
248 TRACE("%p, refcount %d.\n", iface
, refcount
);
252 static ULONG WINAPI
BackgroundCopyJob_Release(IBackgroundCopyJob4
*iface
)
254 BackgroundCopyJobImpl
*job
= impl_from_IBackgroundCopyJob4(iface
);
255 ULONG i
, j
, ref
= InterlockedDecrement(&job
->ref
);
257 TRACE("%p, refcount %d.\n", iface
, ref
);
261 job
->cs
.DebugInfo
->Spare
[0] = 0;
262 DeleteCriticalSection(&job
->cs
);
264 IBackgroundCopyCallback2_Release(job
->callback
);
265 HeapFree(GetProcessHeap(), 0, job
->displayName
);
266 HeapFree(GetProcessHeap(), 0, job
->description
);
267 HeapFree(GetProcessHeap(), 0, job
->http_options
.headers
);
268 for (i
= 0; i
< BG_AUTH_TARGET_PROXY
; i
++)
270 for (j
= 0; j
< BG_AUTH_SCHEME_PASSPORT
; j
++)
272 BG_AUTH_CREDENTIALS
*cred
= &job
->http_options
.creds
[i
][j
];
273 HeapFree(GetProcessHeap(), 0, cred
->Credentials
.Basic
.UserName
);
274 HeapFree(GetProcessHeap(), 0, cred
->Credentials
.Basic
.Password
);
277 CloseHandle(job
->wait
);
278 CloseHandle(job
->cancel
);
279 CloseHandle(job
->done
);
280 HeapFree(GetProcessHeap(), 0, job
);
286 /*** IBackgroundCopyJob methods ***/
288 static HRESULT WINAPI
BackgroundCopyJob_AddFileSet(IBackgroundCopyJob4
*iface
, ULONG cFileCount
, BG_FILE_INFO
*pFileSet
)
290 BackgroundCopyJobImpl
*job
= impl_from_IBackgroundCopyJob4(iface
);
294 TRACE("%p, %u, %p.\n", iface
, cFileCount
, pFileSet
);
296 EnterCriticalSection(&job
->cs
);
298 for (i
= 0; i
< cFileCount
; ++i
)
300 BackgroundCopyFileImpl
*file
;
302 /* We should return E_INVALIDARG in these cases. */
303 FIXME("Check for valid filenames and supported protocols\n");
305 hr
= BackgroundCopyFileConstructor(job
, pFileSet
[i
].RemoteName
, pFileSet
[i
].LocalName
, &file
);
306 if (hr
!= S_OK
) break;
308 /* Add a reference to the file to file list */
309 list_add_head(&job
->files
, &file
->entryFromJob
);
310 job
->jobProgress
.BytesTotal
= BG_SIZE_UNKNOWN
;
311 ++job
->jobProgress
.FilesTotal
;
314 LeaveCriticalSection(&job
->cs
);
319 static HRESULT WINAPI
BackgroundCopyJob_AddFile(IBackgroundCopyJob4
*iface
, LPCWSTR RemoteUrl
, LPCWSTR LocalName
)
323 TRACE("%p, %s, %s.\n", iface
, debugstr_w(RemoteUrl
), debugstr_w(LocalName
));
325 file
.RemoteName
= (LPWSTR
)RemoteUrl
;
326 file
.LocalName
= (LPWSTR
)LocalName
;
327 return IBackgroundCopyJob4_AddFileSet(iface
, 1, &file
);
330 static HRESULT WINAPI
BackgroundCopyJob_EnumFiles(IBackgroundCopyJob4
*iface
, IEnumBackgroundCopyFiles
**enum_files
)
332 BackgroundCopyJobImpl
*job
= impl_from_IBackgroundCopyJob4(iface
);
333 TRACE("%p, %p.\n", iface
, enum_files
);
334 return EnumBackgroundCopyFilesConstructor(job
, enum_files
);
337 static HRESULT WINAPI
BackgroundCopyJob_Suspend(IBackgroundCopyJob4
*iface
)
339 FIXME("(%p): stub\n", iface
);
343 static HRESULT WINAPI
BackgroundCopyJob_Resume(IBackgroundCopyJob4
*iface
)
345 BackgroundCopyJobImpl
*job
= impl_from_IBackgroundCopyJob4(iface
);
348 TRACE("%p.\n", iface
);
350 EnterCriticalSection(&globalMgr
.cs
);
351 if (is_job_done(job
))
353 hr
= BG_E_INVALID_STATE
;
355 else if (job
->jobProgress
.FilesTransferred
== job
->jobProgress
.FilesTotal
)
359 else if (job
->state
!= BG_JOB_STATE_CONNECTING
360 && job
->state
!= BG_JOB_STATE_TRANSFERRING
)
362 job
->state
= BG_JOB_STATE_QUEUED
;
363 job
->error
.context
= 0;
364 job
->error
.code
= S_OK
;
367 IBackgroundCopyFile2_Release(job
->error
.file
);
368 job
->error
.file
= NULL
;
370 SetEvent(globalMgr
.jobEvent
);
372 LeaveCriticalSection(&globalMgr
.cs
);
377 static HRESULT WINAPI
BackgroundCopyJob_Cancel(IBackgroundCopyJob4
*iface
)
379 BackgroundCopyJobImpl
*job
= impl_from_IBackgroundCopyJob4(iface
);
382 TRACE("%p.\n", iface
);
384 EnterCriticalSection(&job
->cs
);
386 if (is_job_done(job
))
388 hr
= BG_E_INVALID_STATE
;
392 BackgroundCopyFileImpl
*file
;
394 if (job
->state
== BG_JOB_STATE_CONNECTING
|| job
->state
== BG_JOB_STATE_TRANSFERRING
)
396 job
->state
= BG_JOB_STATE_CANCELLED
;
397 SetEvent(job
->cancel
);
399 LeaveCriticalSection(&job
->cs
);
400 WaitForSingleObject(job
->done
, INFINITE
);
401 EnterCriticalSection(&job
->cs
);
404 LIST_FOR_EACH_ENTRY(file
, &job
->files
, BackgroundCopyFileImpl
, entryFromJob
)
406 if (file
->tempFileName
[0] && !DeleteFileW(file
->tempFileName
))
408 WARN("Couldn't delete %s (%u)\n", debugstr_w(file
->tempFileName
), GetLastError());
409 hr
= BG_S_UNABLE_TO_DELETE_FILES
;
411 if (file
->info
.LocalName
&& !DeleteFileW(file
->info
.LocalName
))
413 WARN("Couldn't delete %s (%u)\n", debugstr_w(file
->info
.LocalName
), GetLastError());
414 hr
= BG_S_UNABLE_TO_DELETE_FILES
;
417 job
->state
= BG_JOB_STATE_CANCELLED
;
420 LeaveCriticalSection(&job
->cs
);
424 static HRESULT WINAPI
BackgroundCopyJob_Complete(IBackgroundCopyJob4
*iface
)
426 BackgroundCopyJobImpl
*job
= impl_from_IBackgroundCopyJob4(iface
);
429 TRACE("%p.\n", iface
);
431 EnterCriticalSection(&job
->cs
);
433 if (is_job_done(job
))
435 hr
= BG_E_INVALID_STATE
;
439 BackgroundCopyFileImpl
*file
;
440 LIST_FOR_EACH_ENTRY(file
, &job
->files
, BackgroundCopyFileImpl
, entryFromJob
)
442 if (file
->fileProgress
.Completed
)
444 if (!MoveFileExW(file
->tempFileName
, file
->info
.LocalName
,
445 (MOVEFILE_COPY_ALLOWED
446 | MOVEFILE_REPLACE_EXISTING
447 | MOVEFILE_WRITE_THROUGH
)))
449 ERR("Couldn't rename file %s -> %s\n",
450 debugstr_w(file
->tempFileName
),
451 debugstr_w(file
->info
.LocalName
));
452 hr
= BG_S_PARTIAL_COMPLETE
;
456 hr
= BG_S_PARTIAL_COMPLETE
;
460 job
->state
= BG_JOB_STATE_ACKNOWLEDGED
;
461 LeaveCriticalSection(&job
->cs
);
466 static HRESULT WINAPI
BackgroundCopyJob_GetId(IBackgroundCopyJob4
*iface
, GUID
*id
)
468 BackgroundCopyJobImpl
*job
= impl_from_IBackgroundCopyJob4(iface
);
470 TRACE("%p, %p.\n", iface
, id
);
477 static HRESULT WINAPI
BackgroundCopyJob_GetType(IBackgroundCopyJob4
*iface
, BG_JOB_TYPE
*job_type
)
479 BackgroundCopyJobImpl
*job
= impl_from_IBackgroundCopyJob4(iface
);
481 TRACE("%p, %p.\n", iface
, job_type
);
486 *job_type
= job
->type
;
490 static HRESULT WINAPI
BackgroundCopyJob_GetProgress(IBackgroundCopyJob4
*iface
, BG_JOB_PROGRESS
*progress
)
492 BackgroundCopyJobImpl
*job
= impl_from_IBackgroundCopyJob4(iface
);
494 TRACE("%p, %p.\n", iface
, progress
);
499 EnterCriticalSection(&job
->cs
);
500 *progress
= job
->jobProgress
;
501 LeaveCriticalSection(&job
->cs
);
506 static HRESULT WINAPI
BackgroundCopyJob_GetTimes(IBackgroundCopyJob4
*iface
, BG_JOB_TIMES
*pVal
)
508 FIXME("%p, %p: stub\n", iface
, pVal
);
512 static HRESULT WINAPI
BackgroundCopyJob_GetState(IBackgroundCopyJob4
*iface
, BG_JOB_STATE
*state
)
514 BackgroundCopyJobImpl
*job
= impl_from_IBackgroundCopyJob4(iface
);
516 TRACE("%p, %p.\n", iface
, state
);
521 /* Don't think we need a critical section for this */
526 static HRESULT WINAPI
BackgroundCopyJob_GetError(IBackgroundCopyJob4
*iface
, IBackgroundCopyError
**ppError
)
528 BackgroundCopyJobImpl
*job
= impl_from_IBackgroundCopyJob4(iface
);
530 TRACE("%p, %p.\n", iface
, ppError
);
532 if (!job
->error
.context
) return BG_E_ERROR_INFORMATION_UNAVAILABLE
;
534 return create_copy_error(job
->error
.context
, job
->error
.code
, job
->error
.file
, ppError
);
537 static HRESULT WINAPI
BackgroundCopyJob_GetOwner(IBackgroundCopyJob4
*iface
, LPWSTR
*owner
)
539 FIXME("%p, %p: stub\n", iface
, owner
);
543 static HRESULT WINAPI
BackgroundCopyJob_SetDisplayName(IBackgroundCopyJob4
*iface
, LPCWSTR name
)
545 FIXME("%p, %s: stub\n", iface
, debugstr_w(name
));
549 static HRESULT WINAPI
BackgroundCopyJob_GetDisplayName(IBackgroundCopyJob4
*iface
, LPWSTR
*name
)
551 BackgroundCopyJobImpl
*job
= impl_from_IBackgroundCopyJob4(iface
);
553 TRACE("%p, %p.\n", iface
, name
);
555 return return_strval(job
->displayName
, name
);
558 static HRESULT WINAPI
BackgroundCopyJob_SetDescription(IBackgroundCopyJob4
*iface
, LPCWSTR desc
)
560 BackgroundCopyJobImpl
*job
= impl_from_IBackgroundCopyJob4(iface
);
561 static const int max_description_len
= 1024;
565 TRACE("%p, %s.\n", iface
, debugstr_w(desc
));
570 len
= lstrlenW(desc
);
571 if (len
> max_description_len
) return BG_E_STRING_TOO_LONG
;
573 EnterCriticalSection(&job
->cs
);
575 if (is_job_done(job
))
577 hr
= BG_E_INVALID_STATE
;
581 HeapFree(GetProcessHeap(), 0, job
->description
);
582 if ((job
->description
= HeapAlloc(GetProcessHeap(), 0, (len
+1)*sizeof(WCHAR
))))
583 lstrcpyW(job
->description
, desc
);
588 LeaveCriticalSection(&job
->cs
);
593 static HRESULT WINAPI
BackgroundCopyJob_GetDescription(IBackgroundCopyJob4
*iface
, LPWSTR
*desc
)
595 BackgroundCopyJobImpl
*job
= impl_from_IBackgroundCopyJob4(iface
);
597 TRACE("%p, %p.\n", iface
, desc
);
599 return return_strval(job
->description
, desc
);
602 static HRESULT WINAPI
BackgroundCopyJob_SetPriority(IBackgroundCopyJob4
*iface
, BG_JOB_PRIORITY priority
)
604 FIXME("%p, %d: stub\n", iface
, priority
);
608 static HRESULT WINAPI
BackgroundCopyJob_GetPriority(IBackgroundCopyJob4
*iface
, BG_JOB_PRIORITY
*priority
)
610 FIXME("%p, %p: stub\n", iface
, priority
);
614 static HRESULT WINAPI
BackgroundCopyJob_SetNotifyFlags(IBackgroundCopyJob4
*iface
, ULONG flags
)
616 BackgroundCopyJobImpl
*job
= impl_from_IBackgroundCopyJob4(iface
);
617 static const ULONG valid_flags
= BG_NOTIFY_JOB_TRANSFERRED
|
618 BG_NOTIFY_JOB_ERROR
|
620 BG_NOTIFY_JOB_MODIFICATION
|
621 BG_NOTIFY_FILE_TRANSFERRED
;
623 TRACE("%p, %#x.\n", iface
, flags
);
625 if (is_job_done(job
)) return BG_E_INVALID_STATE
;
626 if (flags
& ~valid_flags
) return E_NOTIMPL
;
627 job
->notify_flags
= flags
;
631 static HRESULT WINAPI
BackgroundCopyJob_GetNotifyFlags(IBackgroundCopyJob4
*iface
, ULONG
*flags
)
633 BackgroundCopyJobImpl
*job
= impl_from_IBackgroundCopyJob4(iface
);
635 TRACE("%p, %p.\n", iface
, flags
);
637 if (!flags
) return E_INVALIDARG
;
639 *flags
= job
->notify_flags
;
644 static HRESULT WINAPI
BackgroundCopyJob_SetNotifyInterface(IBackgroundCopyJob4
*iface
, IUnknown
*callback
)
646 BackgroundCopyJobImpl
*job
= impl_from_IBackgroundCopyJob4(iface
);
649 TRACE("%p, %p.\n", iface
, callback
);
651 if (is_job_done(job
)) return BG_E_INVALID_STATE
;
655 IBackgroundCopyCallback2_Release(job
->callback
);
656 job
->callback
= NULL
;
657 job
->callback2
= FALSE
;
662 hr
= IUnknown_QueryInterface(callback
, &IID_IBackgroundCopyCallback2
, (void **)&job
->callback
);
664 hr
= IUnknown_QueryInterface(callback
, &IID_IBackgroundCopyCallback
, (void**)&job
->callback
);
666 job
->callback2
= TRUE
;
672 static HRESULT WINAPI
BackgroundCopyJob_GetNotifyInterface(IBackgroundCopyJob4
*iface
, IUnknown
**callback
)
674 BackgroundCopyJobImpl
*job
= impl_from_IBackgroundCopyJob4(iface
);
676 TRACE("%p, %p.\n", iface
, callback
);
678 if (!callback
) return E_INVALIDARG
;
680 *callback
= (IUnknown
*)job
->callback
;
682 IUnknown_AddRef(*callback
);
687 static HRESULT WINAPI
BackgroundCopyJob_SetMinimumRetryDelay(IBackgroundCopyJob4
*iface
, ULONG delay
)
689 FIXME("%p, %u.\n", iface
, delay
);
693 static HRESULT WINAPI
BackgroundCopyJob_GetMinimumRetryDelay(IBackgroundCopyJob4
*iface
, ULONG
*delay
)
695 FIXME("%p, %p: stub\n", iface
, delay
);
700 static HRESULT WINAPI
BackgroundCopyJob_SetNoProgressTimeout(IBackgroundCopyJob4
*iface
, ULONG timeout
)
702 FIXME("%p, %u.: stub\n", iface
, timeout
);
706 static HRESULT WINAPI
BackgroundCopyJob_GetNoProgressTimeout(IBackgroundCopyJob4
*iface
, ULONG
*timeout
)
708 FIXME("%p, %p: stub\n", iface
, timeout
);
713 static HRESULT WINAPI
BackgroundCopyJob_GetErrorCount(IBackgroundCopyJob4
*iface
, ULONG
*count
)
715 FIXME("%p, %p: stub\n", iface
, count
);
719 static HRESULT WINAPI
BackgroundCopyJob_SetProxySettings(IBackgroundCopyJob4
*iface
, BG_JOB_PROXY_USAGE proxy_usage
,
720 const WCHAR
*proxy_list
, const WCHAR
*proxy_bypass_list
)
722 FIXME("%p, %d, %s, %s: stub\n", iface
, proxy_usage
, debugstr_w(proxy_list
), debugstr_w(proxy_bypass_list
));
726 static HRESULT WINAPI
BackgroundCopyJob_GetProxySettings(IBackgroundCopyJob4
*iface
, BG_JOB_PROXY_USAGE
*proxy_usage
,
727 LPWSTR
*proxy_list
, LPWSTR
*proxy_bypass_list
)
729 FIXME("%p, %p, %p, %p: stub\n", iface
, proxy_usage
, proxy_list
, proxy_bypass_list
);
733 static HRESULT WINAPI
BackgroundCopyJob_TakeOwnership(IBackgroundCopyJob4
*iface
)
735 FIXME("%p: stub\n", iface
);
739 static HRESULT WINAPI
BackgroundCopyJob_SetNotifyCmdLine(IBackgroundCopyJob4
*iface
, LPCWSTR prog
, LPCWSTR params
)
741 FIXME("%p, %s, %s: stub\n", iface
, debugstr_w(prog
), debugstr_w(params
));
745 static HRESULT WINAPI
BackgroundCopyJob_GetNotifyCmdLine(IBackgroundCopyJob4
*iface
, LPWSTR
*prog
, LPWSTR
*params
)
747 FIXME("%p, %p, %p: stub\n", iface
, prog
, params
);
751 static HRESULT WINAPI
BackgroundCopyJob_GetReplyProgress(IBackgroundCopyJob4
*iface
, BG_JOB_REPLY_PROGRESS
*progress
)
753 FIXME("%p, %p: stub\n", iface
, progress
);
757 static HRESULT WINAPI
BackgroundCopyJob_GetReplyData(IBackgroundCopyJob4
*iface
, byte
**buffer
, UINT64
*length
)
759 FIXME("%p, %p, %p: stub\n", iface
, buffer
, length
);
763 static HRESULT WINAPI
BackgroundCopyJob_SetReplyFileName(IBackgroundCopyJob4
*iface
, LPCWSTR filename
)
765 FIXME("%p, %s: stub\n", iface
, debugstr_w(filename
));
769 static HRESULT WINAPI
BackgroundCopyJob_GetReplyFileName(IBackgroundCopyJob4
*iface
, LPWSTR
*filename
)
771 FIXME("%p, %p: stub\n", iface
, filename
);
775 static int index_from_target(BG_AUTH_TARGET target
)
777 if (!target
|| target
> BG_AUTH_TARGET_PROXY
) return -1;
781 static int index_from_scheme(BG_AUTH_SCHEME scheme
)
783 if (!scheme
|| scheme
> BG_AUTH_SCHEME_PASSPORT
) return -1;
787 static HRESULT WINAPI
BackgroundCopyJob_SetCredentials(IBackgroundCopyJob4
*iface
, BG_AUTH_CREDENTIALS
*cred
)
789 BackgroundCopyJobImpl
*job
= impl_from_IBackgroundCopyJob4(iface
);
790 BG_AUTH_CREDENTIALS
*new_cred
;
791 int idx_target
, idx_scheme
;
793 TRACE("%p, %p.\n", iface
, cred
);
795 if ((idx_target
= index_from_target(cred
->Target
)) < 0) return BG_E_INVALID_AUTH_TARGET
;
796 if ((idx_scheme
= index_from_scheme(cred
->Scheme
)) < 0) return BG_E_INVALID_AUTH_SCHEME
;
797 new_cred
= &job
->http_options
.creds
[idx_target
][idx_scheme
];
799 EnterCriticalSection(&job
->cs
);
801 new_cred
->Target
= cred
->Target
;
802 new_cred
->Scheme
= cred
->Scheme
;
804 if (cred
->Credentials
.Basic
.UserName
)
806 HeapFree(GetProcessHeap(), 0, new_cred
->Credentials
.Basic
.UserName
);
807 new_cred
->Credentials
.Basic
.UserName
= strdupW(cred
->Credentials
.Basic
.UserName
);
809 if (cred
->Credentials
.Basic
.Password
)
811 HeapFree(GetProcessHeap(), 0, new_cred
->Credentials
.Basic
.Password
);
812 new_cred
->Credentials
.Basic
.Password
= strdupW(cred
->Credentials
.Basic
.Password
);
815 LeaveCriticalSection(&job
->cs
);
819 static HRESULT WINAPI
BackgroundCopyJob_RemoveCredentials(
820 IBackgroundCopyJob4
*iface
,
821 BG_AUTH_TARGET target
,
822 BG_AUTH_SCHEME scheme
)
824 BackgroundCopyJobImpl
*job
= impl_from_IBackgroundCopyJob4(iface
);
825 BG_AUTH_CREDENTIALS
*new_cred
;
826 int idx_target
, idx_scheme
;
828 TRACE("%p, %u, %u.\n", iface
, target
, scheme
);
830 if ((idx_target
= index_from_target(target
)) < 0) return BG_E_INVALID_AUTH_TARGET
;
831 if ((idx_scheme
= index_from_scheme(scheme
)) < 0) return BG_E_INVALID_AUTH_SCHEME
;
832 new_cred
= &job
->http_options
.creds
[idx_target
][idx_scheme
];
834 EnterCriticalSection(&job
->cs
);
836 new_cred
->Target
= new_cred
->Scheme
= 0;
837 HeapFree(GetProcessHeap(), 0, new_cred
->Credentials
.Basic
.UserName
);
838 new_cred
->Credentials
.Basic
.UserName
= NULL
;
839 HeapFree(GetProcessHeap(), 0, new_cred
->Credentials
.Basic
.Password
);
840 new_cred
->Credentials
.Basic
.Password
= NULL
;
842 LeaveCriticalSection(&job
->cs
);
846 static HRESULT WINAPI
BackgroundCopyJob_ReplaceRemotePrefix(
847 IBackgroundCopyJob4
*iface
,
851 FIXME("%p, %s, %s: stub\n", iface
, debugstr_w(OldPrefix
), debugstr_w(NewPrefix
));
855 static HRESULT WINAPI
BackgroundCopyJob_AddFileWithRanges(
856 IBackgroundCopyJob4
*iface
,
860 BG_FILE_RANGE Ranges
[])
862 FIXME("%p, %s, %s, %u, %p: stub\n", iface
, debugstr_w(RemoteUrl
), debugstr_w(LocalName
), RangeCount
, Ranges
);
866 static HRESULT WINAPI
BackgroundCopyJob_SetFileACLFlags(IBackgroundCopyJob4
*iface
, DWORD flags
)
868 FIXME("%p, %#x: stub\n", iface
, flags
);
872 static HRESULT WINAPI
BackgroundCopyJob_GetFileACLFlags(IBackgroundCopyJob4
*iface
, DWORD
*flags
)
874 FIXME("%p, %p: stub\n", iface
, flags
);
878 static HRESULT WINAPI
BackgroundCopyJob_SetPeerCachingFlags(IBackgroundCopyJob4
*iface
, DWORD flags
)
880 FIXME("%p, %#x.\n", iface
, flags
);
884 static HRESULT WINAPI
BackgroundCopyJob_GetPeerCachingFlags(IBackgroundCopyJob4
*iface
, DWORD
*flags
)
886 FIXME("%p, %p.\n", iface
, flags
);
890 static HRESULT WINAPI
BackgroundCopyJob_GetOwnerIntegrityLevel(IBackgroundCopyJob4
*iface
, ULONG
*level
)
892 FIXME("%p, %p.\n", iface
, level
);
896 static HRESULT WINAPI
BackgroundCopyJob_GetOwnerElevationState(IBackgroundCopyJob4
*iface
, BOOL
*elevated
)
898 FIXME("%p, %p.\n", iface
, elevated
);
902 static HRESULT WINAPI
BackgroundCopyJob_SetMaximumDownloadTime(IBackgroundCopyJob4
*iface
, ULONG timeout
)
904 FIXME("%p, %u.\n", iface
, timeout
);
908 static HRESULT WINAPI
BackgroundCopyJob_GetMaximumDownloadTime(IBackgroundCopyJob4
*iface
, ULONG
*timeout
)
910 FIXME("%p, %p.\n", iface
, timeout
);
914 static const IBackgroundCopyJob4Vtbl BackgroundCopyJobVtbl
=
916 BackgroundCopyJob_QueryInterface
,
917 BackgroundCopyJob_AddRef
,
918 BackgroundCopyJob_Release
,
919 BackgroundCopyJob_AddFileSet
,
920 BackgroundCopyJob_AddFile
,
921 BackgroundCopyJob_EnumFiles
,
922 BackgroundCopyJob_Suspend
,
923 BackgroundCopyJob_Resume
,
924 BackgroundCopyJob_Cancel
,
925 BackgroundCopyJob_Complete
,
926 BackgroundCopyJob_GetId
,
927 BackgroundCopyJob_GetType
,
928 BackgroundCopyJob_GetProgress
,
929 BackgroundCopyJob_GetTimes
,
930 BackgroundCopyJob_GetState
,
931 BackgroundCopyJob_GetError
,
932 BackgroundCopyJob_GetOwner
,
933 BackgroundCopyJob_SetDisplayName
,
934 BackgroundCopyJob_GetDisplayName
,
935 BackgroundCopyJob_SetDescription
,
936 BackgroundCopyJob_GetDescription
,
937 BackgroundCopyJob_SetPriority
,
938 BackgroundCopyJob_GetPriority
,
939 BackgroundCopyJob_SetNotifyFlags
,
940 BackgroundCopyJob_GetNotifyFlags
,
941 BackgroundCopyJob_SetNotifyInterface
,
942 BackgroundCopyJob_GetNotifyInterface
,
943 BackgroundCopyJob_SetMinimumRetryDelay
,
944 BackgroundCopyJob_GetMinimumRetryDelay
,
945 BackgroundCopyJob_SetNoProgressTimeout
,
946 BackgroundCopyJob_GetNoProgressTimeout
,
947 BackgroundCopyJob_GetErrorCount
,
948 BackgroundCopyJob_SetProxySettings
,
949 BackgroundCopyJob_GetProxySettings
,
950 BackgroundCopyJob_TakeOwnership
,
951 BackgroundCopyJob_SetNotifyCmdLine
,
952 BackgroundCopyJob_GetNotifyCmdLine
,
953 BackgroundCopyJob_GetReplyProgress
,
954 BackgroundCopyJob_GetReplyData
,
955 BackgroundCopyJob_SetReplyFileName
,
956 BackgroundCopyJob_GetReplyFileName
,
957 BackgroundCopyJob_SetCredentials
,
958 BackgroundCopyJob_RemoveCredentials
,
959 BackgroundCopyJob_ReplaceRemotePrefix
,
960 BackgroundCopyJob_AddFileWithRanges
,
961 BackgroundCopyJob_SetFileACLFlags
,
962 BackgroundCopyJob_GetFileACLFlags
,
963 BackgroundCopyJob_SetPeerCachingFlags
,
964 BackgroundCopyJob_GetPeerCachingFlags
,
965 BackgroundCopyJob_GetOwnerIntegrityLevel
,
966 BackgroundCopyJob_GetOwnerElevationState
,
967 BackgroundCopyJob_SetMaximumDownloadTime
,
968 BackgroundCopyJob_GetMaximumDownloadTime
,
971 static inline BackgroundCopyJobImpl
*impl_from_IBackgroundCopyJobHttpOptions(
972 IBackgroundCopyJobHttpOptions
*iface
)
974 return CONTAINING_RECORD(iface
, BackgroundCopyJobImpl
, IBackgroundCopyJobHttpOptions_iface
);
977 static HRESULT WINAPI
http_options_QueryInterface(
978 IBackgroundCopyJobHttpOptions
*iface
,
982 BackgroundCopyJobImpl
*job
= impl_from_IBackgroundCopyJobHttpOptions(iface
);
983 return IBackgroundCopyJob4_QueryInterface(&job
->IBackgroundCopyJob4_iface
, riid
, ppvObject
);
986 static ULONG WINAPI
http_options_AddRef(
987 IBackgroundCopyJobHttpOptions
*iface
)
989 BackgroundCopyJobImpl
*job
= impl_from_IBackgroundCopyJobHttpOptions(iface
);
990 return IBackgroundCopyJob4_AddRef(&job
->IBackgroundCopyJob4_iface
);
993 static ULONG WINAPI
http_options_Release(
994 IBackgroundCopyJobHttpOptions
*iface
)
996 BackgroundCopyJobImpl
*job
= impl_from_IBackgroundCopyJobHttpOptions(iface
);
997 return IBackgroundCopyJob4_Release(&job
->IBackgroundCopyJob4_iface
);
1000 static HRESULT WINAPI
http_options_SetClientCertificateByID(
1001 IBackgroundCopyJobHttpOptions
*iface
,
1002 BG_CERT_STORE_LOCATION StoreLocation
,
1004 BYTE
*pCertHashBlob
)
1010 static HRESULT WINAPI
http_options_SetClientCertificateByName(
1011 IBackgroundCopyJobHttpOptions
*iface
,
1012 BG_CERT_STORE_LOCATION StoreLocation
,
1014 LPCWSTR SubjectName
)
1020 static HRESULT WINAPI
http_options_RemoveClientCertificate(
1021 IBackgroundCopyJobHttpOptions
*iface
)
1027 static HRESULT WINAPI
http_options_GetClientCertificate(
1028 IBackgroundCopyJobHttpOptions
*iface
,
1029 BG_CERT_STORE_LOCATION
*pStoreLocation
,
1031 BYTE
**ppCertHashBlob
,
1032 LPWSTR
*pSubjectName
)
1038 static HRESULT WINAPI
http_options_SetCustomHeaders(
1039 IBackgroundCopyJobHttpOptions
*iface
,
1040 LPCWSTR RequestHeaders
)
1042 BackgroundCopyJobImpl
*job
= impl_from_IBackgroundCopyJobHttpOptions(iface
);
1044 TRACE("(%p)->(%s)\n", iface
, debugstr_w(RequestHeaders
));
1046 EnterCriticalSection(&job
->cs
);
1050 WCHAR
*headers
= strdupW(RequestHeaders
);
1053 LeaveCriticalSection(&job
->cs
);
1054 return E_OUTOFMEMORY
;
1056 HeapFree(GetProcessHeap(), 0, job
->http_options
.headers
);
1057 job
->http_options
.headers
= headers
;
1061 HeapFree(GetProcessHeap(), 0, job
->http_options
.headers
);
1062 job
->http_options
.headers
= NULL
;
1065 LeaveCriticalSection(&job
->cs
);
1069 static HRESULT WINAPI
http_options_GetCustomHeaders(
1070 IBackgroundCopyJobHttpOptions
*iface
,
1071 LPWSTR
*pRequestHeaders
)
1073 BackgroundCopyJobImpl
*job
= impl_from_IBackgroundCopyJobHttpOptions(iface
);
1075 TRACE("(%p)->(%p)\n", iface
, pRequestHeaders
);
1077 EnterCriticalSection(&job
->cs
);
1079 if (job
->http_options
.headers
)
1081 WCHAR
*headers
= co_strdupW(job
->http_options
.headers
);
1084 LeaveCriticalSection(&job
->cs
);
1085 return E_OUTOFMEMORY
;
1087 *pRequestHeaders
= headers
;
1088 LeaveCriticalSection(&job
->cs
);
1092 *pRequestHeaders
= NULL
;
1093 LeaveCriticalSection(&job
->cs
);
1097 static HRESULT WINAPI
http_options_SetSecurityFlags(
1098 IBackgroundCopyJobHttpOptions
*iface
,
1101 BackgroundCopyJobImpl
*job
= impl_from_IBackgroundCopyJobHttpOptions(iface
);
1103 TRACE("(%p)->(0x%08x)\n", iface
, Flags
);
1105 job
->http_options
.flags
= Flags
;
1109 static HRESULT WINAPI
http_options_GetSecurityFlags(
1110 IBackgroundCopyJobHttpOptions
*iface
,
1113 BackgroundCopyJobImpl
*job
= impl_from_IBackgroundCopyJobHttpOptions(iface
);
1115 TRACE("(%p)->(%p)\n", iface
, pFlags
);
1117 *pFlags
= job
->http_options
.flags
;
1121 static const IBackgroundCopyJobHttpOptionsVtbl http_options_vtbl
=
1123 http_options_QueryInterface
,
1124 http_options_AddRef
,
1125 http_options_Release
,
1126 http_options_SetClientCertificateByID
,
1127 http_options_SetClientCertificateByName
,
1128 http_options_RemoveClientCertificate
,
1129 http_options_GetClientCertificate
,
1130 http_options_SetCustomHeaders
,
1131 http_options_GetCustomHeaders
,
1132 http_options_SetSecurityFlags
,
1133 http_options_GetSecurityFlags
1136 HRESULT
BackgroundCopyJobConstructor(LPCWSTR displayName
, BG_JOB_TYPE type
, GUID
*job_id
, BackgroundCopyJobImpl
**job
)
1139 BackgroundCopyJobImpl
*This
;
1141 TRACE("(%s,%d,%p)\n", debugstr_w(displayName
), type
, job
);
1143 This
= HeapAlloc(GetProcessHeap(), 0, sizeof *This
);
1145 return E_OUTOFMEMORY
;
1147 This
->IBackgroundCopyJob4_iface
.lpVtbl
= &BackgroundCopyJobVtbl
;
1148 This
->IBackgroundCopyJobHttpOptions_iface
.lpVtbl
= &http_options_vtbl
;
1149 InitializeCriticalSection(&This
->cs
);
1150 This
->cs
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": BackgroundCopyJobImpl.cs");
1155 This
->displayName
= strdupW(displayName
);
1156 if (!This
->displayName
)
1158 This
->cs
.DebugInfo
->Spare
[0] = 0;
1159 DeleteCriticalSection(&This
->cs
);
1160 HeapFree(GetProcessHeap(), 0, This
);
1161 return E_OUTOFMEMORY
;
1164 hr
= CoCreateGuid(&This
->jobId
);
1167 This
->cs
.DebugInfo
->Spare
[0] = 0;
1168 DeleteCriticalSection(&This
->cs
);
1169 HeapFree(GetProcessHeap(), 0, This
->displayName
);
1170 HeapFree(GetProcessHeap(), 0, This
);
1173 *job_id
= This
->jobId
;
1175 list_init(&This
->files
);
1176 This
->jobProgress
.BytesTotal
= 0;
1177 This
->jobProgress
.BytesTransferred
= 0;
1178 This
->jobProgress
.FilesTotal
= 0;
1179 This
->jobProgress
.FilesTransferred
= 0;
1181 This
->state
= BG_JOB_STATE_SUSPENDED
;
1182 This
->description
= NULL
;
1183 This
->notify_flags
= BG_NOTIFY_JOB_ERROR
| BG_NOTIFY_JOB_TRANSFERRED
;
1184 This
->callback
= NULL
;
1185 This
->callback2
= FALSE
;
1187 This
->error
.context
= 0;
1188 This
->error
.code
= S_OK
;
1189 This
->error
.file
= NULL
;
1191 memset(&This
->http_options
, 0, sizeof(This
->http_options
));
1193 This
->wait
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
1194 This
->cancel
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
1195 This
->done
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
1199 TRACE("created job %s:%p\n", debugstr_guid(&This
->jobId
), This
);
1204 void processJob(BackgroundCopyJobImpl
*job
)
1208 BackgroundCopyFileImpl
*file
;
1211 EnterCriticalSection(&job
->cs
);
1212 LIST_FOR_EACH_ENTRY(file
, &job
->files
, BackgroundCopyFileImpl
, entryFromJob
)
1213 if (!file
->fileProgress
.Completed
)
1218 LeaveCriticalSection(&job
->cs
);
1221 transitionJobState(job
, BG_JOB_STATE_QUEUED
, BG_JOB_STATE_TRANSFERRED
);
1222 if (job
->callback
&& (job
->notify_flags
& BG_NOTIFY_JOB_TRANSFERRED
))
1224 TRACE("Calling JobTransferred -->\n");
1225 IBackgroundCopyCallback2_JobTransferred(job
->callback
, (IBackgroundCopyJob
*)&job
->IBackgroundCopyJob4_iface
);
1226 TRACE("Called JobTransferred <--\n");
1231 if (!processFile(file
, job
))