Release 1.5.29.
[wine] / dlls / qmgr / job.c
1 /*
2  * Background Copy Job Interface for BITS
3  *
4  * Copyright 2007 Google (Roy Shea)
5  *
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.
10  *
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.
15  *
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
19  */
20
21 #include <stdarg.h>
22
23 #include "windef.h"
24 #include "winbase.h"
25
26 #include "qmgr.h"
27 #include "wine/debug.h"
28
29 WINE_DEFAULT_DEBUG_CHANNEL(qmgr);
30
31 static inline BackgroundCopyJobImpl *impl_from_IBackgroundCopyJob2(IBackgroundCopyJob2 *iface)
32 {
33     return CONTAINING_RECORD(iface, BackgroundCopyJobImpl, IBackgroundCopyJob2_iface);
34 }
35
36 static HRESULT WINAPI BITS_IBackgroundCopyJob_QueryInterface(
37     IBackgroundCopyJob2 *iface, REFIID riid, void **obj)
38 {
39     BackgroundCopyJobImpl *This = impl_from_IBackgroundCopyJob2(iface);
40
41     TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), obj);
42
43     if (IsEqualGUID(riid, &IID_IUnknown)
44         || IsEqualGUID(riid, &IID_IBackgroundCopyJob)
45         || IsEqualGUID(riid, &IID_IBackgroundCopyJob2))
46     {
47         *obj = iface;
48         IBackgroundCopyJob2_AddRef(iface);
49         return S_OK;
50     }
51
52     *obj = NULL;
53     return E_NOINTERFACE;
54 }
55
56 static ULONG WINAPI BITS_IBackgroundCopyJob_AddRef(IBackgroundCopyJob2 *iface)
57 {
58     BackgroundCopyJobImpl *This = impl_from_IBackgroundCopyJob2(iface);
59     ULONG ref = InterlockedIncrement(&This->ref);
60     TRACE("(%p)->(%d)\n", This, ref);
61     return ref;
62 }
63
64 static ULONG WINAPI BITS_IBackgroundCopyJob_Release(IBackgroundCopyJob2 *iface)
65 {
66     BackgroundCopyJobImpl *This = impl_from_IBackgroundCopyJob2(iface);
67     ULONG ref = InterlockedDecrement(&This->ref);
68
69     TRACE("(%p)->(%d)\n", This, ref);
70
71     if (ref == 0)
72     {
73         This->cs.DebugInfo->Spare[0] = 0;
74         DeleteCriticalSection(&This->cs);
75         HeapFree(GetProcessHeap(), 0, This->displayName);
76         HeapFree(GetProcessHeap(), 0, This);
77     }
78
79     return ref;
80 }
81
82 /*** IBackgroundCopyJob methods ***/
83
84 static HRESULT WINAPI BITS_IBackgroundCopyJob_AddFileSet(
85     IBackgroundCopyJob2 *iface,
86     ULONG cFileCount,
87     BG_FILE_INFO *pFileSet)
88 {
89     ULONG i;
90     for (i = 0; i < cFileCount; ++i)
91     {
92         HRESULT hr = IBackgroundCopyJob2_AddFile(iface, pFileSet[i].RemoteName,
93                                                 pFileSet[i].LocalName);
94         if (FAILED(hr))
95             return hr;
96     }
97     return S_OK;
98 }
99
100 static HRESULT WINAPI BITS_IBackgroundCopyJob_AddFile(
101     IBackgroundCopyJob2 *iface,
102     LPCWSTR RemoteUrl,
103     LPCWSTR LocalName)
104 {
105     BackgroundCopyJobImpl *This = impl_from_IBackgroundCopyJob2(iface);
106     BackgroundCopyFileImpl *file;
107     HRESULT res;
108
109     /* We should return E_INVALIDARG in these cases.  */
110     FIXME("Check for valid filenames and supported protocols\n");
111
112     res = BackgroundCopyFileConstructor(This, RemoteUrl, LocalName, &file);
113     if (res != S_OK)
114         return res;
115
116     /* Add a reference to the file to file list */
117     IBackgroundCopyFile_AddRef(&file->IBackgroundCopyFile_iface);
118     EnterCriticalSection(&This->cs);
119     list_add_head(&This->files, &file->entryFromJob);
120     This->jobProgress.BytesTotal = BG_SIZE_UNKNOWN;
121     ++This->jobProgress.FilesTotal;
122     LeaveCriticalSection(&This->cs);
123
124     return S_OK;
125 }
126
127 static HRESULT WINAPI BITS_IBackgroundCopyJob_EnumFiles(
128     IBackgroundCopyJob2 *iface,
129     IEnumBackgroundCopyFiles **enum_files)
130 {
131     BackgroundCopyJobImpl *This = impl_from_IBackgroundCopyJob2(iface);
132     TRACE("(%p)->(%p)\n", This, enum_files);
133     return EnumBackgroundCopyFilesConstructor(This, enum_files);
134 }
135
136 static HRESULT WINAPI BITS_IBackgroundCopyJob_Suspend(
137     IBackgroundCopyJob2 *iface)
138 {
139     FIXME("Not implemented\n");
140     return E_NOTIMPL;
141 }
142
143 static HRESULT WINAPI BITS_IBackgroundCopyJob_Resume(
144     IBackgroundCopyJob2 *iface)
145 {
146     BackgroundCopyJobImpl *This = impl_from_IBackgroundCopyJob2(iface);
147     HRESULT rv = S_OK;
148
149     EnterCriticalSection(&globalMgr.cs);
150     if (This->state == BG_JOB_STATE_CANCELLED
151         || This->state == BG_JOB_STATE_ACKNOWLEDGED)
152     {
153         rv = BG_E_INVALID_STATE;
154     }
155     else if (This->jobProgress.FilesTransferred == This->jobProgress.FilesTotal)
156     {
157         rv = BG_E_EMPTY;
158     }
159     else if (This->state != BG_JOB_STATE_CONNECTING
160              && This->state != BG_JOB_STATE_TRANSFERRING)
161     {
162         This->state = BG_JOB_STATE_QUEUED;
163         SetEvent(globalMgr.jobEvent);
164     }
165     LeaveCriticalSection(&globalMgr.cs);
166
167     return rv;
168 }
169
170 static HRESULT WINAPI BITS_IBackgroundCopyJob_Cancel(
171     IBackgroundCopyJob2 *iface)
172 {
173     FIXME("Not implemented\n");
174     return E_NOTIMPL;
175 }
176
177 static HRESULT WINAPI BITS_IBackgroundCopyJob_Complete(
178     IBackgroundCopyJob2 *iface)
179 {
180     BackgroundCopyJobImpl *This = impl_from_IBackgroundCopyJob2(iface);
181     HRESULT rv = S_OK;
182
183     EnterCriticalSection(&This->cs);
184
185     if (This->state == BG_JOB_STATE_CANCELLED
186         || This->state == BG_JOB_STATE_ACKNOWLEDGED)
187     {
188         rv = BG_E_INVALID_STATE;
189     }
190     else
191     {
192         BackgroundCopyFileImpl *file;
193         LIST_FOR_EACH_ENTRY(file, &This->files, BackgroundCopyFileImpl, entryFromJob)
194         {
195             if (file->fileProgress.Completed)
196             {
197                 if (!MoveFileExW(file->tempFileName, file->info.LocalName,
198                                  (MOVEFILE_COPY_ALLOWED
199                                   | MOVEFILE_REPLACE_EXISTING
200                                   | MOVEFILE_WRITE_THROUGH)))
201                 {
202                     ERR("Couldn't rename file %s -> %s\n",
203                         debugstr_w(file->tempFileName),
204                         debugstr_w(file->info.LocalName));
205                     rv = BG_S_PARTIAL_COMPLETE;
206                 }
207             }
208             else
209                 rv = BG_S_PARTIAL_COMPLETE;
210         }
211     }
212
213     This->state = BG_JOB_STATE_ACKNOWLEDGED;
214     LeaveCriticalSection(&This->cs);
215
216     return rv;
217 }
218
219 static HRESULT WINAPI BITS_IBackgroundCopyJob_GetId(
220     IBackgroundCopyJob2 *iface,
221     GUID *pVal)
222 {
223     BackgroundCopyJobImpl *This = impl_from_IBackgroundCopyJob2(iface);
224     *pVal = This->jobId;
225     return S_OK;
226 }
227
228 static HRESULT WINAPI BITS_IBackgroundCopyJob_GetType(
229     IBackgroundCopyJob2 *iface,
230     BG_JOB_TYPE *pVal)
231 {
232     BackgroundCopyJobImpl *This = impl_from_IBackgroundCopyJob2(iface);
233
234     if (!pVal)
235         return E_INVALIDARG;
236
237     *pVal = This->type;
238     return S_OK;
239 }
240
241 static HRESULT WINAPI BITS_IBackgroundCopyJob_GetProgress(
242     IBackgroundCopyJob2 *iface,
243     BG_JOB_PROGRESS *pVal)
244 {
245     BackgroundCopyJobImpl *This = impl_from_IBackgroundCopyJob2(iface);
246
247     if (!pVal)
248         return E_INVALIDARG;
249
250     EnterCriticalSection(&This->cs);
251     pVal->BytesTotal = This->jobProgress.BytesTotal;
252     pVal->BytesTransferred = This->jobProgress.BytesTransferred;
253     pVal->FilesTotal = This->jobProgress.FilesTotal;
254     pVal->FilesTransferred = This->jobProgress.FilesTransferred;
255     LeaveCriticalSection(&This->cs);
256
257     return S_OK;
258 }
259
260 static HRESULT WINAPI BITS_IBackgroundCopyJob_GetTimes(
261     IBackgroundCopyJob2 *iface,
262     BG_JOB_TIMES *pVal)
263 {
264     FIXME("Not implemented\n");
265     return E_NOTIMPL;
266 }
267
268 static HRESULT WINAPI BITS_IBackgroundCopyJob_GetState(
269     IBackgroundCopyJob2 *iface,
270     BG_JOB_STATE *pVal)
271 {
272     BackgroundCopyJobImpl *This = impl_from_IBackgroundCopyJob2(iface);
273
274     if (!pVal)
275         return E_INVALIDARG;
276
277     /* Don't think we need a critical section for this */
278     *pVal = This->state;
279     return S_OK;
280 }
281
282 static HRESULT WINAPI BITS_IBackgroundCopyJob_GetError(
283     IBackgroundCopyJob2 *iface,
284     IBackgroundCopyError **ppError)
285 {
286     FIXME("Not implemented\n");
287     return E_NOTIMPL;
288 }
289
290 static HRESULT WINAPI BITS_IBackgroundCopyJob_GetOwner(
291     IBackgroundCopyJob2 *iface,
292     LPWSTR *pVal)
293 {
294     FIXME("Not implemented\n");
295     return E_NOTIMPL;
296 }
297
298 static HRESULT WINAPI BITS_IBackgroundCopyJob_SetDisplayName(
299     IBackgroundCopyJob2 *iface,
300     LPCWSTR Val)
301 {
302     FIXME("Not implemented\n");
303     return E_NOTIMPL;
304 }
305
306 static HRESULT WINAPI BITS_IBackgroundCopyJob_GetDisplayName(
307     IBackgroundCopyJob2 *iface,
308     LPWSTR *pVal)
309 {
310     BackgroundCopyJobImpl *This = impl_from_IBackgroundCopyJob2(iface);
311     int n;
312
313     if (!pVal)
314         return E_INVALIDARG;
315
316     n = (lstrlenW(This->displayName) + 1) * sizeof **pVal;
317     *pVal = CoTaskMemAlloc(n);
318     if (*pVal == NULL)
319         return E_OUTOFMEMORY;
320     memcpy(*pVal, This->displayName, n);
321     return S_OK;
322 }
323
324 static HRESULT WINAPI BITS_IBackgroundCopyJob_SetDescription(
325     IBackgroundCopyJob2 *iface,
326     LPCWSTR Val)
327 {
328     FIXME("Not implemented\n");
329     return E_NOTIMPL;
330 }
331
332 static HRESULT WINAPI BITS_IBackgroundCopyJob_GetDescription(
333     IBackgroundCopyJob2 *iface,
334     LPWSTR *pVal)
335 {
336     FIXME("Not implemented\n");
337     return E_NOTIMPL;
338 }
339
340 static HRESULT WINAPI BITS_IBackgroundCopyJob_SetPriority(
341     IBackgroundCopyJob2 *iface,
342     BG_JOB_PRIORITY Val)
343 {
344     FIXME("(%p,0x%08x) stub\n", iface, Val);
345     return S_OK;
346 }
347
348 static HRESULT WINAPI BITS_IBackgroundCopyJob_GetPriority(
349     IBackgroundCopyJob2 *iface,
350     BG_JOB_PRIORITY *pVal)
351 {
352     FIXME("Not implemented\n");
353     return E_NOTIMPL;
354 }
355
356 static HRESULT WINAPI BITS_IBackgroundCopyJob_SetNotifyFlags(
357     IBackgroundCopyJob2 *iface,
358     ULONG Val)
359 {
360     FIXME("Not implemented\n");
361     return E_NOTIMPL;
362 }
363
364 static HRESULT WINAPI BITS_IBackgroundCopyJob_GetNotifyFlags(
365     IBackgroundCopyJob2 *iface,
366     ULONG *pVal)
367 {
368     FIXME("Not implemented\n");
369     return E_NOTIMPL;
370 }
371
372 static HRESULT WINAPI BITS_IBackgroundCopyJob_SetNotifyInterface(
373     IBackgroundCopyJob2 *iface,
374     IUnknown *Val)
375 {
376     FIXME("Not implemented\n");
377     return E_NOTIMPL;
378 }
379
380 static HRESULT WINAPI BITS_IBackgroundCopyJob_GetNotifyInterface(
381     IBackgroundCopyJob2 *iface,
382     IUnknown **pVal)
383 {
384     FIXME("Not implemented\n");
385     return E_NOTIMPL;
386 }
387
388 static HRESULT WINAPI BITS_IBackgroundCopyJob_SetMinimumRetryDelay(
389     IBackgroundCopyJob2 *iface,
390     ULONG Seconds)
391 {
392     FIXME("%u\n", Seconds);
393     return S_OK;
394 }
395
396 static HRESULT WINAPI BITS_IBackgroundCopyJob_GetMinimumRetryDelay(
397     IBackgroundCopyJob2 *iface,
398     ULONG *Seconds)
399 {
400     FIXME("%p\n", Seconds);
401     *Seconds = 30;
402     return S_OK;
403 }
404
405 static HRESULT WINAPI BITS_IBackgroundCopyJob_SetNoProgressTimeout(
406     IBackgroundCopyJob2 *iface,
407     ULONG Seconds)
408 {
409     FIXME("%u\n", Seconds);
410     return S_OK;
411 }
412
413 static HRESULT WINAPI BITS_IBackgroundCopyJob_GetNoProgressTimeout(
414     IBackgroundCopyJob2 *iface,
415     ULONG *Seconds)
416 {
417     FIXME("%p\n", Seconds);
418     *Seconds = 900;
419     return S_OK;
420 }
421
422 static HRESULT WINAPI BITS_IBackgroundCopyJob_GetErrorCount(
423     IBackgroundCopyJob2 *iface,
424     ULONG *Errors)
425 {
426     FIXME("Not implemented\n");
427     return E_NOTIMPL;
428 }
429
430 static HRESULT WINAPI BITS_IBackgroundCopyJob_SetProxySettings(
431     IBackgroundCopyJob2 *iface,
432     BG_JOB_PROXY_USAGE ProxyUsage,
433     const WCHAR *ProxyList,
434     const WCHAR *ProxyBypassList)
435 {
436     FIXME("Not implemented\n");
437     return E_NOTIMPL;
438 }
439
440 static HRESULT WINAPI BITS_IBackgroundCopyJob_GetProxySettings(
441     IBackgroundCopyJob2 *iface,
442     BG_JOB_PROXY_USAGE *pProxyUsage,
443     LPWSTR *pProxyList,
444     LPWSTR *pProxyBypassList)
445 {
446     FIXME("Not implemented\n");
447     return E_NOTIMPL;
448 }
449
450 static HRESULT WINAPI BITS_IBackgroundCopyJob_TakeOwnership(
451     IBackgroundCopyJob2 *iface)
452 {
453     FIXME("Not implemented\n");
454     return E_NOTIMPL;
455 }
456
457 static HRESULT WINAPI BITS_IBackgroundCopyJob_SetNotifyCmdLine(
458     IBackgroundCopyJob2 *iface,
459     LPCWSTR prog,
460     LPCWSTR params)
461 {
462     FIXME("Not implemented\n");
463     return E_NOTIMPL;
464 }
465
466 static HRESULT WINAPI BITS_IBackgroundCopyJob_GetNotifyCmdLine(
467     IBackgroundCopyJob2 *iface,
468     LPWSTR *prog,
469     LPWSTR *params)
470 {
471     FIXME("Not implemented\n");
472     return E_NOTIMPL;
473 }
474
475 static HRESULT WINAPI BITS_IBackgroundCopyJob_GetReplyProgress(
476     IBackgroundCopyJob2 *iface,
477     BG_JOB_REPLY_PROGRESS *progress)
478 {
479     FIXME("Not implemented\n");
480     return E_NOTIMPL;
481 }
482
483 static HRESULT WINAPI BITS_IBackgroundCopyJob_GetReplyData(
484     IBackgroundCopyJob2 *iface,
485     byte **pBuffer,
486     UINT64 *pLength)
487 {
488     FIXME("Not implemented\n");
489     return E_NOTIMPL;
490 }
491
492 static HRESULT WINAPI BITS_IBackgroundCopyJob_SetReplyFileName(
493     IBackgroundCopyJob2 *iface,
494     LPCWSTR filename)
495 {
496     FIXME("Not implemented\n");
497     return E_NOTIMPL;
498 }
499
500 static HRESULT WINAPI BITS_IBackgroundCopyJob_GetReplyFileName(
501     IBackgroundCopyJob2 *iface,
502     LPWSTR *pFilename)
503 {
504     FIXME("Not implemented\n");
505     return E_NOTIMPL;
506 }
507
508 static HRESULT WINAPI BITS_IBackgroundCopyJob_SetCredentials(
509     IBackgroundCopyJob2 *iface,
510     BG_AUTH_CREDENTIALS *cred)
511 {
512     FIXME("Not implemented\n");
513     return S_OK;
514 }
515
516 static HRESULT WINAPI BITS_IBackgroundCopyJob_RemoveCredentials(
517     IBackgroundCopyJob2 *iface,
518     BG_AUTH_TARGET target,
519     BG_AUTH_SCHEME scheme)
520 {
521     FIXME("Not implemented\n");
522     return S_OK;
523 }
524
525 static const IBackgroundCopyJob2Vtbl BITS_IBackgroundCopyJob_Vtbl =
526 {
527     BITS_IBackgroundCopyJob_QueryInterface,
528     BITS_IBackgroundCopyJob_AddRef,
529     BITS_IBackgroundCopyJob_Release,
530     BITS_IBackgroundCopyJob_AddFileSet,
531     BITS_IBackgroundCopyJob_AddFile,
532     BITS_IBackgroundCopyJob_EnumFiles,
533     BITS_IBackgroundCopyJob_Suspend,
534     BITS_IBackgroundCopyJob_Resume,
535     BITS_IBackgroundCopyJob_Cancel,
536     BITS_IBackgroundCopyJob_Complete,
537     BITS_IBackgroundCopyJob_GetId,
538     BITS_IBackgroundCopyJob_GetType,
539     BITS_IBackgroundCopyJob_GetProgress,
540     BITS_IBackgroundCopyJob_GetTimes,
541     BITS_IBackgroundCopyJob_GetState,
542     BITS_IBackgroundCopyJob_GetError,
543     BITS_IBackgroundCopyJob_GetOwner,
544     BITS_IBackgroundCopyJob_SetDisplayName,
545     BITS_IBackgroundCopyJob_GetDisplayName,
546     BITS_IBackgroundCopyJob_SetDescription,
547     BITS_IBackgroundCopyJob_GetDescription,
548     BITS_IBackgroundCopyJob_SetPriority,
549     BITS_IBackgroundCopyJob_GetPriority,
550     BITS_IBackgroundCopyJob_SetNotifyFlags,
551     BITS_IBackgroundCopyJob_GetNotifyFlags,
552     BITS_IBackgroundCopyJob_SetNotifyInterface,
553     BITS_IBackgroundCopyJob_GetNotifyInterface,
554     BITS_IBackgroundCopyJob_SetMinimumRetryDelay,
555     BITS_IBackgroundCopyJob_GetMinimumRetryDelay,
556     BITS_IBackgroundCopyJob_SetNoProgressTimeout,
557     BITS_IBackgroundCopyJob_GetNoProgressTimeout,
558     BITS_IBackgroundCopyJob_GetErrorCount,
559     BITS_IBackgroundCopyJob_SetProxySettings,
560     BITS_IBackgroundCopyJob_GetProxySettings,
561     BITS_IBackgroundCopyJob_TakeOwnership,
562     BITS_IBackgroundCopyJob_SetNotifyCmdLine,
563     BITS_IBackgroundCopyJob_GetNotifyCmdLine,
564     BITS_IBackgroundCopyJob_GetReplyProgress,
565     BITS_IBackgroundCopyJob_GetReplyData,
566     BITS_IBackgroundCopyJob_SetReplyFileName,
567     BITS_IBackgroundCopyJob_GetReplyFileName,
568     BITS_IBackgroundCopyJob_SetCredentials,
569     BITS_IBackgroundCopyJob_RemoveCredentials
570 };
571
572 HRESULT BackgroundCopyJobConstructor(LPCWSTR displayName, BG_JOB_TYPE type, GUID *job_id, BackgroundCopyJobImpl **job)
573 {
574     HRESULT hr;
575     BackgroundCopyJobImpl *This;
576     int n;
577
578     TRACE("(%s,%d,%p)\n", debugstr_w(displayName), type, job);
579
580     This = HeapAlloc(GetProcessHeap(), 0, sizeof *This);
581     if (!This)
582         return E_OUTOFMEMORY;
583
584     This->IBackgroundCopyJob2_iface.lpVtbl = &BITS_IBackgroundCopyJob_Vtbl;
585     InitializeCriticalSection(&This->cs);
586     This->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": BackgroundCopyJobImpl.cs");
587
588     This->ref = 1;
589     This->type = type;
590
591     n = (lstrlenW(displayName) + 1) *  sizeof *displayName;
592     This->displayName = HeapAlloc(GetProcessHeap(), 0, n);
593     if (!This->displayName)
594     {
595         This->cs.DebugInfo->Spare[0] = 0;
596         DeleteCriticalSection(&This->cs);
597         HeapFree(GetProcessHeap(), 0, This);
598         return E_OUTOFMEMORY;
599     }
600     memcpy(This->displayName, displayName, n);
601
602     hr = CoCreateGuid(&This->jobId);
603     if (FAILED(hr))
604     {
605         This->cs.DebugInfo->Spare[0] = 0;
606         DeleteCriticalSection(&This->cs);
607         HeapFree(GetProcessHeap(), 0, This->displayName);
608         HeapFree(GetProcessHeap(), 0, This);
609         return hr;
610     }
611     *job_id = This->jobId;
612
613     list_init(&This->files);
614     This->jobProgress.BytesTotal = 0;
615     This->jobProgress.BytesTransferred = 0;
616     This->jobProgress.FilesTotal = 0;
617     This->jobProgress.FilesTransferred = 0;
618
619     This->state = BG_JOB_STATE_SUSPENDED;
620
621     *job = This;
622     return S_OK;
623 }
624
625 void processJob(BackgroundCopyJobImpl *job)
626 {
627     for (;;)
628     {
629         BackgroundCopyFileImpl *file;
630         BOOL done = TRUE;
631
632         EnterCriticalSection(&job->cs);
633         LIST_FOR_EACH_ENTRY(file, &job->files, BackgroundCopyFileImpl, entryFromJob)
634             if (!file->fileProgress.Completed)
635             {
636                 done = FALSE;
637                 break;
638             }
639         LeaveCriticalSection(&job->cs);
640         if (done)
641         {
642             transitionJobState(job, BG_JOB_STATE_QUEUED, BG_JOB_STATE_TRANSFERRED);
643             return;
644         }
645
646         if (!processFile(file, job))
647           return;
648     }
649 }