wininet: Support the Cache-Control max-age directive for setting url cache entry...
[wine/testsucceed.git] / dlls / qmgr / job.c
blob09693a3bd53e96f66c755b644da212da2a6896f3
1 /*
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
21 #include <stdarg.h>
23 #include "windef.h"
24 #include "winbase.h"
26 #include "qmgr.h"
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(IBackgroundCopyJob2 *iface)
40 BackgroundCopyJobImpl *This = (BackgroundCopyJobImpl *) iface;
41 return InterlockedIncrement(&This->ref);
44 static HRESULT WINAPI BITS_IBackgroundCopyJob_QueryInterface(
45 IBackgroundCopyJob2 *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)
52 || IsEqualGUID(riid, &IID_IBackgroundCopyJob2))
54 *ppvObject = &This->lpVtbl;
55 BITS_IBackgroundCopyJob_AddRef(iface);
56 return S_OK;
59 *ppvObject = NULL;
60 return E_NOINTERFACE;
63 static ULONG WINAPI BITS_IBackgroundCopyJob_Release(IBackgroundCopyJob2 *iface)
65 BackgroundCopyJobImpl *This = (BackgroundCopyJobImpl *) iface;
66 ULONG ref = InterlockedDecrement(&This->ref);
68 if (ref == 0)
69 BackgroundCopyJobDestructor(This);
71 return ref;
74 /*** IBackgroundCopyJob methods ***/
76 static HRESULT WINAPI BITS_IBackgroundCopyJob_AddFileSet(
77 IBackgroundCopyJob2 *iface,
78 ULONG cFileCount,
79 BG_FILE_INFO *pFileSet)
81 ULONG i;
82 for (i = 0; i < cFileCount; ++i)
84 HRESULT hr = IBackgroundCopyJob_AddFile(iface, pFileSet[i].RemoteName,
85 pFileSet[i].LocalName);
86 if (FAILED(hr))
87 return hr;
89 return S_OK;
92 static HRESULT WINAPI BITS_IBackgroundCopyJob_AddFile(
93 IBackgroundCopyJob2 *iface,
94 LPCWSTR RemoteUrl,
95 LPCWSTR LocalName)
97 BackgroundCopyJobImpl *This = (BackgroundCopyJobImpl *) iface;
98 IBackgroundCopyFile *pFile;
99 BackgroundCopyFileImpl *file;
100 HRESULT res;
102 /* We should return E_INVALIDARG in these cases. */
103 FIXME("Check for valid filenames and supported protocols\n");
105 res = BackgroundCopyFileConstructor(This, RemoteUrl, LocalName, (LPVOID *) &pFile);
106 if (res != S_OK)
107 return res;
109 /* Add a reference to the file to file list */
110 IBackgroundCopyFile_AddRef(pFile);
111 file = (BackgroundCopyFileImpl *) pFile;
112 EnterCriticalSection(&This->cs);
113 list_add_head(&This->files, &file->entryFromJob);
114 This->jobProgress.BytesTotal = BG_SIZE_UNKNOWN;
115 ++This->jobProgress.FilesTotal;
116 LeaveCriticalSection(&This->cs);
118 return S_OK;
121 static HRESULT WINAPI BITS_IBackgroundCopyJob_EnumFiles(
122 IBackgroundCopyJob2 *iface,
123 IEnumBackgroundCopyFiles **ppEnum)
125 TRACE("\n");
126 return EnumBackgroundCopyFilesConstructor((LPVOID *) ppEnum, iface);
129 static HRESULT WINAPI BITS_IBackgroundCopyJob_Suspend(
130 IBackgroundCopyJob2 *iface)
132 FIXME("Not implemented\n");
133 return E_NOTIMPL;
136 static HRESULT WINAPI BITS_IBackgroundCopyJob_Resume(
137 IBackgroundCopyJob2 *iface)
139 BackgroundCopyJobImpl *This = (BackgroundCopyJobImpl *) iface;
140 HRESULT rv = S_OK;
142 EnterCriticalSection(&globalMgr.cs);
143 if (This->state == BG_JOB_STATE_CANCELLED
144 || This->state == BG_JOB_STATE_ACKNOWLEDGED)
146 rv = BG_E_INVALID_STATE;
148 else if (This->jobProgress.FilesTransferred == This->jobProgress.FilesTotal)
150 rv = BG_E_EMPTY;
152 else if (This->state != BG_JOB_STATE_CONNECTING
153 && This->state != BG_JOB_STATE_TRANSFERRING)
155 This->state = BG_JOB_STATE_QUEUED;
156 SetEvent(globalMgr.jobEvent);
158 LeaveCriticalSection(&globalMgr.cs);
160 return rv;
163 static HRESULT WINAPI BITS_IBackgroundCopyJob_Cancel(
164 IBackgroundCopyJob2 *iface)
166 FIXME("Not implemented\n");
167 return E_NOTIMPL;
170 static HRESULT WINAPI BITS_IBackgroundCopyJob_Complete(
171 IBackgroundCopyJob2 *iface)
173 BackgroundCopyJobImpl *This = (BackgroundCopyJobImpl *) iface;
174 HRESULT rv = S_OK;
176 EnterCriticalSection(&This->cs);
178 if (This->state == BG_JOB_STATE_CANCELLED
179 || This->state == BG_JOB_STATE_ACKNOWLEDGED)
181 rv = BG_E_INVALID_STATE;
183 else
185 BackgroundCopyFileImpl *file;
186 LIST_FOR_EACH_ENTRY(file, &This->files, BackgroundCopyFileImpl, entryFromJob)
188 if (file->fileProgress.Completed)
190 if (!MoveFileExW(file->tempFileName, file->info.LocalName,
191 (MOVEFILE_COPY_ALLOWED
192 | MOVEFILE_REPLACE_EXISTING
193 | MOVEFILE_WRITE_THROUGH)))
195 ERR("Couldn't rename file %s -> %s\n",
196 debugstr_w(file->tempFileName),
197 debugstr_w(file->info.LocalName));
198 rv = BG_S_PARTIAL_COMPLETE;
201 else
202 rv = BG_S_PARTIAL_COMPLETE;
206 This->state = BG_JOB_STATE_ACKNOWLEDGED;
207 LeaveCriticalSection(&This->cs);
209 return rv;
212 static HRESULT WINAPI BITS_IBackgroundCopyJob_GetId(
213 IBackgroundCopyJob2 *iface,
214 GUID *pVal)
216 BackgroundCopyJobImpl *This = (BackgroundCopyJobImpl *) iface;
217 *pVal = This->jobId;
218 return S_OK;
221 static HRESULT WINAPI BITS_IBackgroundCopyJob_GetType(
222 IBackgroundCopyJob2 *iface,
223 BG_JOB_TYPE *pVal)
225 BackgroundCopyJobImpl *This = (BackgroundCopyJobImpl *) iface;
227 if (!pVal)
228 return E_INVALIDARG;
230 *pVal = This->type;
231 return S_OK;
234 static HRESULT WINAPI BITS_IBackgroundCopyJob_GetProgress(
235 IBackgroundCopyJob2 *iface,
236 BG_JOB_PROGRESS *pVal)
238 BackgroundCopyJobImpl *This = (BackgroundCopyJobImpl *) iface;
240 if (!pVal)
241 return E_INVALIDARG;
243 EnterCriticalSection(&This->cs);
244 pVal->BytesTotal = This->jobProgress.BytesTotal;
245 pVal->BytesTransferred = This->jobProgress.BytesTransferred;
246 pVal->FilesTotal = This->jobProgress.FilesTotal;
247 pVal->FilesTransferred = This->jobProgress.FilesTransferred;
248 LeaveCriticalSection(&This->cs);
250 return S_OK;
253 static HRESULT WINAPI BITS_IBackgroundCopyJob_GetTimes(
254 IBackgroundCopyJob2 *iface,
255 BG_JOB_TIMES *pVal)
257 FIXME("Not implemented\n");
258 return E_NOTIMPL;
261 static HRESULT WINAPI BITS_IBackgroundCopyJob_GetState(
262 IBackgroundCopyJob2 *iface,
263 BG_JOB_STATE *pVal)
265 BackgroundCopyJobImpl *This = (BackgroundCopyJobImpl *) iface;
267 if (!pVal)
268 return E_INVALIDARG;
270 /* Don't think we need a critical section for this */
271 *pVal = This->state;
272 return S_OK;
275 static HRESULT WINAPI BITS_IBackgroundCopyJob_GetError(
276 IBackgroundCopyJob2 *iface,
277 IBackgroundCopyError **ppError)
279 FIXME("Not implemented\n");
280 return E_NOTIMPL;
283 static HRESULT WINAPI BITS_IBackgroundCopyJob_GetOwner(
284 IBackgroundCopyJob2 *iface,
285 LPWSTR *pVal)
287 FIXME("Not implemented\n");
288 return E_NOTIMPL;
291 static HRESULT WINAPI BITS_IBackgroundCopyJob_SetDisplayName(
292 IBackgroundCopyJob2 *iface,
293 LPCWSTR Val)
295 FIXME("Not implemented\n");
296 return E_NOTIMPL;
299 static HRESULT WINAPI BITS_IBackgroundCopyJob_GetDisplayName(
300 IBackgroundCopyJob2 *iface,
301 LPWSTR *pVal)
303 BackgroundCopyJobImpl *This = (BackgroundCopyJobImpl *) iface;
304 int n;
306 if (!pVal)
307 return E_INVALIDARG;
309 n = (lstrlenW(This->displayName) + 1) * sizeof **pVal;
310 *pVal = CoTaskMemAlloc(n);
311 if (*pVal == NULL)
312 return E_OUTOFMEMORY;
313 memcpy(*pVal, This->displayName, n);
314 return S_OK;
317 static HRESULT WINAPI BITS_IBackgroundCopyJob_SetDescription(
318 IBackgroundCopyJob2 *iface,
319 LPCWSTR Val)
321 FIXME("Not implemented\n");
322 return E_NOTIMPL;
325 static HRESULT WINAPI BITS_IBackgroundCopyJob_GetDescription(
326 IBackgroundCopyJob2 *iface,
327 LPWSTR *pVal)
329 FIXME("Not implemented\n");
330 return E_NOTIMPL;
333 static HRESULT WINAPI BITS_IBackgroundCopyJob_SetPriority(
334 IBackgroundCopyJob2 *iface,
335 BG_JOB_PRIORITY Val)
337 FIXME("(%p,0x%08x) stub\n", iface, Val);
338 return S_OK;
341 static HRESULT WINAPI BITS_IBackgroundCopyJob_GetPriority(
342 IBackgroundCopyJob2 *iface,
343 BG_JOB_PRIORITY *pVal)
345 FIXME("Not implemented\n");
346 return E_NOTIMPL;
349 static HRESULT WINAPI BITS_IBackgroundCopyJob_SetNotifyFlags(
350 IBackgroundCopyJob2 *iface,
351 ULONG Val)
353 FIXME("Not implemented\n");
354 return E_NOTIMPL;
357 static HRESULT WINAPI BITS_IBackgroundCopyJob_GetNotifyFlags(
358 IBackgroundCopyJob2 *iface,
359 ULONG *pVal)
361 FIXME("Not implemented\n");
362 return E_NOTIMPL;
365 static HRESULT WINAPI BITS_IBackgroundCopyJob_SetNotifyInterface(
366 IBackgroundCopyJob2 *iface,
367 IUnknown *Val)
369 FIXME("Not implemented\n");
370 return E_NOTIMPL;
373 static HRESULT WINAPI BITS_IBackgroundCopyJob_GetNotifyInterface(
374 IBackgroundCopyJob2 *iface,
375 IUnknown **pVal)
377 FIXME("Not implemented\n");
378 return E_NOTIMPL;
381 static HRESULT WINAPI BITS_IBackgroundCopyJob_SetMinimumRetryDelay(
382 IBackgroundCopyJob2 *iface,
383 ULONG Seconds)
385 FIXME("%u\n", Seconds);
386 return S_OK;
389 static HRESULT WINAPI BITS_IBackgroundCopyJob_GetMinimumRetryDelay(
390 IBackgroundCopyJob2 *iface,
391 ULONG *Seconds)
393 FIXME("%p\n", Seconds);
394 *Seconds = 30;
395 return S_OK;
398 static HRESULT WINAPI BITS_IBackgroundCopyJob_SetNoProgressTimeout(
399 IBackgroundCopyJob2 *iface,
400 ULONG Seconds)
402 FIXME("%u\n", Seconds);
403 return S_OK;
406 static HRESULT WINAPI BITS_IBackgroundCopyJob_GetNoProgressTimeout(
407 IBackgroundCopyJob2 *iface,
408 ULONG *Seconds)
410 FIXME("%p\n", Seconds);
411 *Seconds = 900;
412 return S_OK;
415 static HRESULT WINAPI BITS_IBackgroundCopyJob_GetErrorCount(
416 IBackgroundCopyJob2 *iface,
417 ULONG *Errors)
419 FIXME("Not implemented\n");
420 return E_NOTIMPL;
423 static HRESULT WINAPI BITS_IBackgroundCopyJob_SetProxySettings(
424 IBackgroundCopyJob2 *iface,
425 BG_JOB_PROXY_USAGE ProxyUsage,
426 const WCHAR *ProxyList,
427 const WCHAR *ProxyBypassList)
429 FIXME("Not implemented\n");
430 return E_NOTIMPL;
433 static HRESULT WINAPI BITS_IBackgroundCopyJob_GetProxySettings(
434 IBackgroundCopyJob2 *iface,
435 BG_JOB_PROXY_USAGE *pProxyUsage,
436 LPWSTR *pProxyList,
437 LPWSTR *pProxyBypassList)
439 FIXME("Not implemented\n");
440 return E_NOTIMPL;
443 static HRESULT WINAPI BITS_IBackgroundCopyJob_TakeOwnership(
444 IBackgroundCopyJob2 *iface)
446 FIXME("Not implemented\n");
447 return E_NOTIMPL;
450 static HRESULT WINAPI BITS_IBackgroundCopyJob_SetNotifyCmdLine(
451 IBackgroundCopyJob2 *iface,
452 LPCWSTR prog,
453 LPCWSTR params)
455 FIXME("Not implemented\n");
456 return E_NOTIMPL;
459 static HRESULT WINAPI BITS_IBackgroundCopyJob_GetNotifyCmdLine(
460 IBackgroundCopyJob2 *iface,
461 LPWSTR *prog,
462 LPWSTR *params)
464 FIXME("Not implemented\n");
465 return E_NOTIMPL;
468 static HRESULT WINAPI BITS_IBackgroundCopyJob_GetReplyProgress(
469 IBackgroundCopyJob2 *iface,
470 BG_JOB_REPLY_PROGRESS *progress)
472 FIXME("Not implemented\n");
473 return E_NOTIMPL;
476 static HRESULT WINAPI BITS_IBackgroundCopyJob_GetReplyData(
477 IBackgroundCopyJob2 *iface,
478 byte **pBuffer,
479 UINT64 *pLength)
481 FIXME("Not implemented\n");
482 return E_NOTIMPL;
485 static HRESULT WINAPI BITS_IBackgroundCopyJob_SetReplyFileName(
486 IBackgroundCopyJob2 *iface,
487 LPCWSTR filename)
489 FIXME("Not implemented\n");
490 return E_NOTIMPL;
493 static HRESULT WINAPI BITS_IBackgroundCopyJob_GetReplyFileName(
494 IBackgroundCopyJob2 *iface,
495 LPWSTR *pFilename)
497 FIXME("Not implemented\n");
498 return E_NOTIMPL;
501 static HRESULT WINAPI BITS_IBackgroundCopyJob_SetCredentials(
502 IBackgroundCopyJob2 *iface,
503 BG_AUTH_CREDENTIALS *cred)
505 FIXME("Not implemented\n");
506 return S_OK;
509 static HRESULT WINAPI BITS_IBackgroundCopyJob_RemoveCredentials(
510 IBackgroundCopyJob2 *iface,
511 BG_AUTH_TARGET target,
512 BG_AUTH_SCHEME scheme)
514 FIXME("Not implemented\n");
515 return S_OK;
518 static const IBackgroundCopyJob2Vtbl BITS_IBackgroundCopyJob_Vtbl =
520 BITS_IBackgroundCopyJob_QueryInterface,
521 BITS_IBackgroundCopyJob_AddRef,
522 BITS_IBackgroundCopyJob_Release,
523 BITS_IBackgroundCopyJob_AddFileSet,
524 BITS_IBackgroundCopyJob_AddFile,
525 BITS_IBackgroundCopyJob_EnumFiles,
526 BITS_IBackgroundCopyJob_Suspend,
527 BITS_IBackgroundCopyJob_Resume,
528 BITS_IBackgroundCopyJob_Cancel,
529 BITS_IBackgroundCopyJob_Complete,
530 BITS_IBackgroundCopyJob_GetId,
531 BITS_IBackgroundCopyJob_GetType,
532 BITS_IBackgroundCopyJob_GetProgress,
533 BITS_IBackgroundCopyJob_GetTimes,
534 BITS_IBackgroundCopyJob_GetState,
535 BITS_IBackgroundCopyJob_GetError,
536 BITS_IBackgroundCopyJob_GetOwner,
537 BITS_IBackgroundCopyJob_SetDisplayName,
538 BITS_IBackgroundCopyJob_GetDisplayName,
539 BITS_IBackgroundCopyJob_SetDescription,
540 BITS_IBackgroundCopyJob_GetDescription,
541 BITS_IBackgroundCopyJob_SetPriority,
542 BITS_IBackgroundCopyJob_GetPriority,
543 BITS_IBackgroundCopyJob_SetNotifyFlags,
544 BITS_IBackgroundCopyJob_GetNotifyFlags,
545 BITS_IBackgroundCopyJob_SetNotifyInterface,
546 BITS_IBackgroundCopyJob_GetNotifyInterface,
547 BITS_IBackgroundCopyJob_SetMinimumRetryDelay,
548 BITS_IBackgroundCopyJob_GetMinimumRetryDelay,
549 BITS_IBackgroundCopyJob_SetNoProgressTimeout,
550 BITS_IBackgroundCopyJob_GetNoProgressTimeout,
551 BITS_IBackgroundCopyJob_GetErrorCount,
552 BITS_IBackgroundCopyJob_SetProxySettings,
553 BITS_IBackgroundCopyJob_GetProxySettings,
554 BITS_IBackgroundCopyJob_TakeOwnership,
555 BITS_IBackgroundCopyJob_SetNotifyCmdLine,
556 BITS_IBackgroundCopyJob_GetNotifyCmdLine,
557 BITS_IBackgroundCopyJob_GetReplyProgress,
558 BITS_IBackgroundCopyJob_GetReplyData,
559 BITS_IBackgroundCopyJob_SetReplyFileName,
560 BITS_IBackgroundCopyJob_GetReplyFileName,
561 BITS_IBackgroundCopyJob_SetCredentials,
562 BITS_IBackgroundCopyJob_RemoveCredentials
565 HRESULT BackgroundCopyJobConstructor(LPCWSTR displayName, BG_JOB_TYPE type,
566 GUID *pJobId, LPVOID *ppObj)
568 HRESULT hr;
569 BackgroundCopyJobImpl *This;
570 int n;
572 TRACE("(%s,%d,%p)\n", debugstr_w(displayName), type, ppObj);
574 This = HeapAlloc(GetProcessHeap(), 0, sizeof *This);
575 if (!This)
576 return E_OUTOFMEMORY;
578 This->lpVtbl = &BITS_IBackgroundCopyJob_Vtbl;
579 InitializeCriticalSection(&This->cs);
580 This->ref = 1;
581 This->type = type;
583 n = (lstrlenW(displayName) + 1) * sizeof *displayName;
584 This->displayName = HeapAlloc(GetProcessHeap(), 0, n);
585 if (!This->displayName)
587 DeleteCriticalSection(&This->cs);
588 HeapFree(GetProcessHeap(), 0, This);
589 return E_OUTOFMEMORY;
591 memcpy(This->displayName, displayName, n);
593 hr = CoCreateGuid(&This->jobId);
594 if (FAILED(hr))
596 DeleteCriticalSection(&This->cs);
597 HeapFree(GetProcessHeap(), 0, This->displayName);
598 HeapFree(GetProcessHeap(), 0, This);
599 return hr;
601 *pJobId = This->jobId;
603 list_init(&This->files);
604 This->jobProgress.BytesTotal = 0;
605 This->jobProgress.BytesTransferred = 0;
606 This->jobProgress.FilesTotal = 0;
607 This->jobProgress.FilesTransferred = 0;
609 This->state = BG_JOB_STATE_SUSPENDED;
611 *ppObj = &This->lpVtbl;
612 return S_OK;
615 void processJob(BackgroundCopyJobImpl *job)
617 for (;;)
619 BackgroundCopyFileImpl *file;
620 BOOL done = TRUE;
622 EnterCriticalSection(&job->cs);
623 LIST_FOR_EACH_ENTRY(file, &job->files, BackgroundCopyFileImpl, entryFromJob)
624 if (!file->fileProgress.Completed)
626 done = FALSE;
627 break;
629 LeaveCriticalSection(&job->cs);
630 if (done)
632 transitionJobState(job, BG_JOB_STATE_QUEUED, BG_JOB_STATE_TRANSFERRED);
633 return;
636 if (!processFile(file, job))
637 return;