2 * Background Copy Job Interface for BITS
4 * Copyright 2007 Google (Roy Shea)
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
27 #include "wine/debug.h"
29 WINE_DEFAULT_DEBUG_CHANNEL(qmgr
);
31 static void BackgroundCopyJobDestructor(BackgroundCopyJobImpl
*This
)
33 DeleteCriticalSection(&This
->cs
);
34 HeapFree(GetProcessHeap(), 0, This
->displayName
);
35 HeapFree(GetProcessHeap(), 0, This
);
38 static ULONG WINAPI
BITS_IBackgroundCopyJob_AddRef(IBackgroundCopyJob
* iface
)
40 BackgroundCopyJobImpl
*This
= (BackgroundCopyJobImpl
*) iface
;
41 return InterlockedIncrement(&This
->ref
);
44 static HRESULT WINAPI
BITS_IBackgroundCopyJob_QueryInterface(
45 IBackgroundCopyJob
* iface
, REFIID riid
, LPVOID
*ppvObject
)
47 BackgroundCopyJobImpl
*This
= (BackgroundCopyJobImpl
*) iface
;
48 TRACE("IID: %s\n", debugstr_guid(riid
));
50 if (IsEqualGUID(riid
, &IID_IUnknown
)
51 || IsEqualGUID(riid
, &IID_IBackgroundCopyJob
))
53 *ppvObject
= &This
->lpVtbl
;
54 BITS_IBackgroundCopyJob_AddRef(iface
);
62 static ULONG WINAPI
BITS_IBackgroundCopyJob_Release(IBackgroundCopyJob
* iface
)
64 BackgroundCopyJobImpl
*This
= (BackgroundCopyJobImpl
*) iface
;
65 ULONG ref
= InterlockedDecrement(&This
->ref
);
68 BackgroundCopyJobDestructor(This
);
73 /*** IBackgroundCopyJob methods ***/
75 static HRESULT WINAPI
BITS_IBackgroundCopyJob_AddFileSet(
76 IBackgroundCopyJob
* iface
,
78 BG_FILE_INFO
*pFileSet
)
81 for (i
= 0; i
< cFileCount
; ++i
)
83 HRESULT hr
= IBackgroundCopyJob_AddFile(iface
, pFileSet
[i
].RemoteName
,
84 pFileSet
[i
].LocalName
);
91 static HRESULT WINAPI
BITS_IBackgroundCopyJob_AddFile(
92 IBackgroundCopyJob
* iface
,
96 BackgroundCopyJobImpl
*This
= (BackgroundCopyJobImpl
*) iface
;
97 IBackgroundCopyFile
*pFile
;
98 BackgroundCopyFileImpl
*file
;
101 /* We should return E_INVALIDARG in these cases. */
102 FIXME("Check for valid filenames and supported protocols\n");
104 res
= BackgroundCopyFileConstructor(This
, RemoteUrl
, LocalName
, (LPVOID
*) &pFile
);
108 /* Add a reference to the file to file list */
109 IBackgroundCopyFile_AddRef(pFile
);
110 file
= (BackgroundCopyFileImpl
*) pFile
;
111 EnterCriticalSection(&This
->cs
);
112 list_add_head(&This
->files
, &file
->entryFromJob
);
113 This
->jobProgress
.BytesTotal
= BG_SIZE_UNKNOWN
;
114 ++This
->jobProgress
.FilesTotal
;
115 LeaveCriticalSection(&This
->cs
);
120 static HRESULT WINAPI
BITS_IBackgroundCopyJob_EnumFiles(
121 IBackgroundCopyJob
* iface
,
122 IEnumBackgroundCopyFiles
**ppEnum
)
125 return EnumBackgroundCopyFilesConstructor((LPVOID
*) ppEnum
, iface
);
128 static HRESULT WINAPI
BITS_IBackgroundCopyJob_Suspend(
129 IBackgroundCopyJob
* iface
)
131 FIXME("Not implemented\n");
135 static HRESULT WINAPI
BITS_IBackgroundCopyJob_Resume(
136 IBackgroundCopyJob
* iface
)
138 BackgroundCopyJobImpl
*This
= (BackgroundCopyJobImpl
*) iface
;
141 EnterCriticalSection(&globalMgr
.cs
);
142 if (This
->state
== BG_JOB_STATE_CANCELLED
143 || This
->state
== BG_JOB_STATE_ACKNOWLEDGED
)
145 rv
= BG_E_INVALID_STATE
;
147 else if (This
->jobProgress
.FilesTransferred
== This
->jobProgress
.FilesTotal
)
151 else if (This
->state
!= BG_JOB_STATE_CONNECTING
152 && This
->state
!= BG_JOB_STATE_TRANSFERRING
)
154 This
->state
= BG_JOB_STATE_QUEUED
;
155 SetEvent(globalMgr
.jobEvent
);
157 LeaveCriticalSection(&globalMgr
.cs
);
162 static HRESULT WINAPI
BITS_IBackgroundCopyJob_Cancel(
163 IBackgroundCopyJob
* iface
)
165 FIXME("Not implemented\n");
169 static HRESULT WINAPI
BITS_IBackgroundCopyJob_Complete(
170 IBackgroundCopyJob
* iface
)
172 BackgroundCopyJobImpl
*This
= (BackgroundCopyJobImpl
*) iface
;
175 EnterCriticalSection(&This
->cs
);
177 if (This
->state
== BG_JOB_STATE_CANCELLED
178 || This
->state
== BG_JOB_STATE_ACKNOWLEDGED
)
180 rv
= BG_E_INVALID_STATE
;
184 BackgroundCopyFileImpl
*file
;
185 LIST_FOR_EACH_ENTRY(file
, &This
->files
, BackgroundCopyFileImpl
, entryFromJob
)
187 if (file
->fileProgress
.Completed
)
189 if (!MoveFileExW(file
->tempFileName
, file
->info
.LocalName
,
190 (MOVEFILE_COPY_ALLOWED
191 | MOVEFILE_REPLACE_EXISTING
192 | MOVEFILE_WRITE_THROUGH
)))
194 ERR("Couldn't rename file %s -> %s\n",
195 debugstr_w(file
->tempFileName
),
196 debugstr_w(file
->info
.LocalName
));
197 rv
= BG_S_PARTIAL_COMPLETE
;
201 rv
= BG_S_PARTIAL_COMPLETE
;
205 This
->state
= BG_JOB_STATE_ACKNOWLEDGED
;
206 LeaveCriticalSection(&This
->cs
);
211 static HRESULT WINAPI
BITS_IBackgroundCopyJob_GetId(
212 IBackgroundCopyJob
* iface
,
215 BackgroundCopyJobImpl
*This
= (BackgroundCopyJobImpl
*) iface
;
220 static HRESULT WINAPI
BITS_IBackgroundCopyJob_GetType(
221 IBackgroundCopyJob
* iface
,
224 BackgroundCopyJobImpl
*This
= (BackgroundCopyJobImpl
*) iface
;
233 static HRESULT WINAPI
BITS_IBackgroundCopyJob_GetProgress(
234 IBackgroundCopyJob
* iface
,
235 BG_JOB_PROGRESS
*pVal
)
237 BackgroundCopyJobImpl
*This
= (BackgroundCopyJobImpl
*) iface
;
242 EnterCriticalSection(&This
->cs
);
243 pVal
->BytesTotal
= This
->jobProgress
.BytesTotal
;
244 pVal
->BytesTransferred
= This
->jobProgress
.BytesTransferred
;
245 pVal
->FilesTotal
= This
->jobProgress
.FilesTotal
;
246 pVal
->FilesTransferred
= This
->jobProgress
.FilesTransferred
;
247 LeaveCriticalSection(&This
->cs
);
252 static HRESULT WINAPI
BITS_IBackgroundCopyJob_GetTimes(
253 IBackgroundCopyJob
* iface
,
256 FIXME("Not implemented\n");
260 static HRESULT WINAPI
BITS_IBackgroundCopyJob_GetState(
261 IBackgroundCopyJob
* iface
,
264 BackgroundCopyJobImpl
*This
= (BackgroundCopyJobImpl
*) iface
;
269 /* Don't think we need a critical section for this */
274 static HRESULT WINAPI
BITS_IBackgroundCopyJob_GetError(
275 IBackgroundCopyJob
* iface
,
276 IBackgroundCopyError
**ppError
)
278 FIXME("Not implemented\n");
282 static HRESULT WINAPI
BITS_IBackgroundCopyJob_GetOwner(
283 IBackgroundCopyJob
* iface
,
286 FIXME("Not implemented\n");
290 static HRESULT WINAPI
BITS_IBackgroundCopyJob_SetDisplayName(
291 IBackgroundCopyJob
* iface
,
294 FIXME("Not implemented\n");
298 static HRESULT WINAPI
BITS_IBackgroundCopyJob_GetDisplayName(
299 IBackgroundCopyJob
* iface
,
302 BackgroundCopyJobImpl
*This
= (BackgroundCopyJobImpl
*) iface
;
308 n
= (lstrlenW(This
->displayName
) + 1) * sizeof **pVal
;
309 *pVal
= CoTaskMemAlloc(n
);
311 return E_OUTOFMEMORY
;
312 memcpy(*pVal
, This
->displayName
, n
);
316 static HRESULT WINAPI
BITS_IBackgroundCopyJob_SetDescription(
317 IBackgroundCopyJob
* iface
,
320 FIXME("Not implemented\n");
324 static HRESULT WINAPI
BITS_IBackgroundCopyJob_GetDescription(
325 IBackgroundCopyJob
* iface
,
328 FIXME("Not implemented\n");
332 static HRESULT WINAPI
BITS_IBackgroundCopyJob_SetPriority(
333 IBackgroundCopyJob
* iface
,
336 FIXME("Not implemented\n");
340 static HRESULT WINAPI
BITS_IBackgroundCopyJob_GetPriority(
341 IBackgroundCopyJob
* iface
,
342 BG_JOB_PRIORITY
*pVal
)
344 FIXME("Not implemented\n");
348 static HRESULT WINAPI
BITS_IBackgroundCopyJob_SetNotifyFlags(
349 IBackgroundCopyJob
* iface
,
352 FIXME("Not implemented\n");
356 static HRESULT WINAPI
BITS_IBackgroundCopyJob_GetNotifyFlags(
357 IBackgroundCopyJob
* iface
,
360 FIXME("Not implemented\n");
364 static HRESULT WINAPI
BITS_IBackgroundCopyJob_SetNotifyInterface(
365 IBackgroundCopyJob
* iface
,
368 FIXME("Not implemented\n");
372 static HRESULT WINAPI
BITS_IBackgroundCopyJob_GetNotifyInterface(
373 IBackgroundCopyJob
* iface
,
376 FIXME("Not implemented\n");
380 static HRESULT WINAPI
BITS_IBackgroundCopyJob_SetMinimumRetryDelay(
381 IBackgroundCopyJob
* iface
,
384 FIXME("Not implemented\n");
388 static HRESULT WINAPI
BITS_IBackgroundCopyJob_GetMinimumRetryDelay(
389 IBackgroundCopyJob
* iface
,
392 FIXME("Not implemented\n");
396 static HRESULT WINAPI
BITS_IBackgroundCopyJob_SetNoProgressTimeout(
397 IBackgroundCopyJob
* iface
,
400 FIXME("Not implemented\n");
404 static HRESULT WINAPI
BITS_IBackgroundCopyJob_GetNoProgressTimeout(
405 IBackgroundCopyJob
* iface
,
408 FIXME("Not implemented\n");
412 static HRESULT WINAPI
BITS_IBackgroundCopyJob_GetErrorCount(
413 IBackgroundCopyJob
* iface
,
416 FIXME("Not implemented\n");
420 static HRESULT WINAPI
BITS_IBackgroundCopyJob_SetProxySettings(
421 IBackgroundCopyJob
* iface
,
422 BG_JOB_PROXY_USAGE ProxyUsage
,
423 const WCHAR
*ProxyList
,
424 const WCHAR
*ProxyBypassList
)
426 FIXME("Not implemented\n");
430 static HRESULT WINAPI
BITS_IBackgroundCopyJob_GetProxySettings(
431 IBackgroundCopyJob
* iface
,
432 BG_JOB_PROXY_USAGE
*pProxyUsage
,
434 LPWSTR
*pProxyBypassList
)
436 FIXME("Not implemented\n");
440 static HRESULT WINAPI
BITS_IBackgroundCopyJob_TakeOwnership(
441 IBackgroundCopyJob
* iface
)
443 FIXME("Not implemented\n");
448 static const IBackgroundCopyJobVtbl BITS_IBackgroundCopyJob_Vtbl
=
450 BITS_IBackgroundCopyJob_QueryInterface
,
451 BITS_IBackgroundCopyJob_AddRef
,
452 BITS_IBackgroundCopyJob_Release
,
453 BITS_IBackgroundCopyJob_AddFileSet
,
454 BITS_IBackgroundCopyJob_AddFile
,
455 BITS_IBackgroundCopyJob_EnumFiles
,
456 BITS_IBackgroundCopyJob_Suspend
,
457 BITS_IBackgroundCopyJob_Resume
,
458 BITS_IBackgroundCopyJob_Cancel
,
459 BITS_IBackgroundCopyJob_Complete
,
460 BITS_IBackgroundCopyJob_GetId
,
461 BITS_IBackgroundCopyJob_GetType
,
462 BITS_IBackgroundCopyJob_GetProgress
,
463 BITS_IBackgroundCopyJob_GetTimes
,
464 BITS_IBackgroundCopyJob_GetState
,
465 BITS_IBackgroundCopyJob_GetError
,
466 BITS_IBackgroundCopyJob_GetOwner
,
467 BITS_IBackgroundCopyJob_SetDisplayName
,
468 BITS_IBackgroundCopyJob_GetDisplayName
,
469 BITS_IBackgroundCopyJob_SetDescription
,
470 BITS_IBackgroundCopyJob_GetDescription
,
471 BITS_IBackgroundCopyJob_SetPriority
,
472 BITS_IBackgroundCopyJob_GetPriority
,
473 BITS_IBackgroundCopyJob_SetNotifyFlags
,
474 BITS_IBackgroundCopyJob_GetNotifyFlags
,
475 BITS_IBackgroundCopyJob_SetNotifyInterface
,
476 BITS_IBackgroundCopyJob_GetNotifyInterface
,
477 BITS_IBackgroundCopyJob_SetMinimumRetryDelay
,
478 BITS_IBackgroundCopyJob_GetMinimumRetryDelay
,
479 BITS_IBackgroundCopyJob_SetNoProgressTimeout
,
480 BITS_IBackgroundCopyJob_GetNoProgressTimeout
,
481 BITS_IBackgroundCopyJob_GetErrorCount
,
482 BITS_IBackgroundCopyJob_SetProxySettings
,
483 BITS_IBackgroundCopyJob_GetProxySettings
,
484 BITS_IBackgroundCopyJob_TakeOwnership
,
487 HRESULT
BackgroundCopyJobConstructor(LPCWSTR displayName
, BG_JOB_TYPE type
,
488 GUID
*pJobId
, LPVOID
*ppObj
)
491 BackgroundCopyJobImpl
*This
;
494 TRACE("(%s,%d,%p)\n", debugstr_w(displayName
), type
, ppObj
);
496 This
= HeapAlloc(GetProcessHeap(), 0, sizeof *This
);
498 return E_OUTOFMEMORY
;
500 This
->lpVtbl
= &BITS_IBackgroundCopyJob_Vtbl
;
501 InitializeCriticalSection(&This
->cs
);
505 n
= (lstrlenW(displayName
) + 1) * sizeof *displayName
;
506 This
->displayName
= HeapAlloc(GetProcessHeap(), 0, n
);
507 if (!This
->displayName
)
509 DeleteCriticalSection(&This
->cs
);
510 HeapFree(GetProcessHeap(), 0, This
);
511 return E_OUTOFMEMORY
;
513 memcpy(This
->displayName
, displayName
, n
);
515 hr
= CoCreateGuid(&This
->jobId
);
518 DeleteCriticalSection(&This
->cs
);
519 HeapFree(GetProcessHeap(), 0, This
->displayName
);
520 HeapFree(GetProcessHeap(), 0, This
);
523 *pJobId
= This
->jobId
;
525 list_init(&This
->files
);
526 This
->jobProgress
.BytesTotal
= 0;
527 This
->jobProgress
.BytesTransferred
= 0;
528 This
->jobProgress
.FilesTotal
= 0;
529 This
->jobProgress
.FilesTransferred
= 0;
531 This
->state
= BG_JOB_STATE_SUSPENDED
;
533 *ppObj
= &This
->lpVtbl
;
537 void processJob(BackgroundCopyJobImpl
*job
)
541 BackgroundCopyFileImpl
*file
;
544 EnterCriticalSection(&job
->cs
);
545 LIST_FOR_EACH_ENTRY(file
, &job
->files
, BackgroundCopyFileImpl
, entryFromJob
)
546 if (!file
->fileProgress
.Completed
)
551 LeaveCriticalSection(&job
->cs
);
554 transitionJobState(job
, BG_JOB_STATE_QUEUED
, BG_JOB_STATE_TRANSFERRED
);
558 if (!processFile(file
, job
))