winemac: Return 0 from ToUnicodeEx() for a key release.
[wine.git] / dlls / qmgr / job.c
blob4abf22055565c67851d03da152a769d3122be9cc
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 inline BackgroundCopyJobImpl *impl_from_IBackgroundCopyJob2(IBackgroundCopyJob2 *iface)
33 return CONTAINING_RECORD(iface, BackgroundCopyJobImpl, IBackgroundCopyJob2_iface);
36 static HRESULT WINAPI BITS_IBackgroundCopyJob_QueryInterface(
37 IBackgroundCopyJob2 *iface, REFIID riid, void **obj)
39 BackgroundCopyJobImpl *This = impl_from_IBackgroundCopyJob2(iface);
41 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), obj);
43 if (IsEqualGUID(riid, &IID_IUnknown)
44 || IsEqualGUID(riid, &IID_IBackgroundCopyJob)
45 || IsEqualGUID(riid, &IID_IBackgroundCopyJob2))
47 *obj = iface;
48 IBackgroundCopyJob2_AddRef(iface);
49 return S_OK;
52 *obj = NULL;
53 return E_NOINTERFACE;
56 static ULONG WINAPI BITS_IBackgroundCopyJob_AddRef(IBackgroundCopyJob2 *iface)
58 BackgroundCopyJobImpl *This = impl_from_IBackgroundCopyJob2(iface);
59 ULONG ref = InterlockedIncrement(&This->ref);
60 TRACE("(%p)->(%d)\n", This, ref);
61 return ref;
64 static ULONG WINAPI BITS_IBackgroundCopyJob_Release(IBackgroundCopyJob2 *iface)
66 BackgroundCopyJobImpl *This = impl_from_IBackgroundCopyJob2(iface);
67 ULONG ref = InterlockedDecrement(&This->ref);
69 TRACE("(%p)->(%d)\n", This, ref);
71 if (ref == 0)
73 This->cs.DebugInfo->Spare[0] = 0;
74 DeleteCriticalSection(&This->cs);
75 HeapFree(GetProcessHeap(), 0, This->displayName);
76 HeapFree(GetProcessHeap(), 0, This);
79 return ref;
82 /*** IBackgroundCopyJob methods ***/
84 static HRESULT WINAPI BITS_IBackgroundCopyJob_AddFileSet(
85 IBackgroundCopyJob2 *iface,
86 ULONG cFileCount,
87 BG_FILE_INFO *pFileSet)
89 ULONG i;
90 for (i = 0; i < cFileCount; ++i)
92 HRESULT hr = IBackgroundCopyJob2_AddFile(iface, pFileSet[i].RemoteName,
93 pFileSet[i].LocalName);
94 if (FAILED(hr))
95 return hr;
97 return S_OK;
100 static HRESULT WINAPI BITS_IBackgroundCopyJob_AddFile(
101 IBackgroundCopyJob2 *iface,
102 LPCWSTR RemoteUrl,
103 LPCWSTR LocalName)
105 BackgroundCopyJobImpl *This = impl_from_IBackgroundCopyJob2(iface);
106 BackgroundCopyFileImpl *file;
107 HRESULT res;
109 /* We should return E_INVALIDARG in these cases. */
110 FIXME("Check for valid filenames and supported protocols\n");
112 res = BackgroundCopyFileConstructor(This, RemoteUrl, LocalName, &file);
113 if (res != S_OK)
114 return res;
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);
124 return S_OK;
127 static HRESULT WINAPI BITS_IBackgroundCopyJob_EnumFiles(
128 IBackgroundCopyJob2 *iface,
129 IEnumBackgroundCopyFiles **enum_files)
131 BackgroundCopyJobImpl *This = impl_from_IBackgroundCopyJob2(iface);
132 TRACE("(%p)->(%p)\n", This, enum_files);
133 return EnumBackgroundCopyFilesConstructor(This, enum_files);
136 static HRESULT WINAPI BITS_IBackgroundCopyJob_Suspend(
137 IBackgroundCopyJob2 *iface)
139 FIXME("Not implemented\n");
140 return E_NOTIMPL;
143 static HRESULT WINAPI BITS_IBackgroundCopyJob_Resume(
144 IBackgroundCopyJob2 *iface)
146 BackgroundCopyJobImpl *This = impl_from_IBackgroundCopyJob2(iface);
147 HRESULT rv = S_OK;
149 EnterCriticalSection(&globalMgr.cs);
150 if (This->state == BG_JOB_STATE_CANCELLED
151 || This->state == BG_JOB_STATE_ACKNOWLEDGED)
153 rv = BG_E_INVALID_STATE;
155 else if (This->jobProgress.FilesTransferred == This->jobProgress.FilesTotal)
157 rv = BG_E_EMPTY;
159 else if (This->state != BG_JOB_STATE_CONNECTING
160 && This->state != BG_JOB_STATE_TRANSFERRING)
162 This->state = BG_JOB_STATE_QUEUED;
163 SetEvent(globalMgr.jobEvent);
165 LeaveCriticalSection(&globalMgr.cs);
167 return rv;
170 static HRESULT WINAPI BITS_IBackgroundCopyJob_Cancel(
171 IBackgroundCopyJob2 *iface)
173 FIXME("Not implemented\n");
174 return E_NOTIMPL;
177 static HRESULT WINAPI BITS_IBackgroundCopyJob_Complete(
178 IBackgroundCopyJob2 *iface)
180 BackgroundCopyJobImpl *This = impl_from_IBackgroundCopyJob2(iface);
181 HRESULT rv = S_OK;
183 EnterCriticalSection(&This->cs);
185 if (This->state == BG_JOB_STATE_CANCELLED
186 || This->state == BG_JOB_STATE_ACKNOWLEDGED)
188 rv = BG_E_INVALID_STATE;
190 else
192 BackgroundCopyFileImpl *file;
193 LIST_FOR_EACH_ENTRY(file, &This->files, BackgroundCopyFileImpl, entryFromJob)
195 if (file->fileProgress.Completed)
197 if (!MoveFileExW(file->tempFileName, file->info.LocalName,
198 (MOVEFILE_COPY_ALLOWED
199 | MOVEFILE_REPLACE_EXISTING
200 | MOVEFILE_WRITE_THROUGH)))
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;
208 else
209 rv = BG_S_PARTIAL_COMPLETE;
213 This->state = BG_JOB_STATE_ACKNOWLEDGED;
214 LeaveCriticalSection(&This->cs);
216 return rv;
219 static HRESULT WINAPI BITS_IBackgroundCopyJob_GetId(
220 IBackgroundCopyJob2 *iface,
221 GUID *pVal)
223 BackgroundCopyJobImpl *This = impl_from_IBackgroundCopyJob2(iface);
224 *pVal = This->jobId;
225 return S_OK;
228 static HRESULT WINAPI BITS_IBackgroundCopyJob_GetType(
229 IBackgroundCopyJob2 *iface,
230 BG_JOB_TYPE *pVal)
232 BackgroundCopyJobImpl *This = impl_from_IBackgroundCopyJob2(iface);
234 if (!pVal)
235 return E_INVALIDARG;
237 *pVal = This->type;
238 return S_OK;
241 static HRESULT WINAPI BITS_IBackgroundCopyJob_GetProgress(
242 IBackgroundCopyJob2 *iface,
243 BG_JOB_PROGRESS *pVal)
245 BackgroundCopyJobImpl *This = impl_from_IBackgroundCopyJob2(iface);
247 if (!pVal)
248 return E_INVALIDARG;
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);
257 return S_OK;
260 static HRESULT WINAPI BITS_IBackgroundCopyJob_GetTimes(
261 IBackgroundCopyJob2 *iface,
262 BG_JOB_TIMES *pVal)
264 FIXME("Not implemented\n");
265 return E_NOTIMPL;
268 static HRESULT WINAPI BITS_IBackgroundCopyJob_GetState(
269 IBackgroundCopyJob2 *iface,
270 BG_JOB_STATE *pVal)
272 BackgroundCopyJobImpl *This = impl_from_IBackgroundCopyJob2(iface);
274 if (!pVal)
275 return E_INVALIDARG;
277 /* Don't think we need a critical section for this */
278 *pVal = This->state;
279 return S_OK;
282 static HRESULT WINAPI BITS_IBackgroundCopyJob_GetError(
283 IBackgroundCopyJob2 *iface,
284 IBackgroundCopyError **ppError)
286 FIXME("Not implemented\n");
287 return E_NOTIMPL;
290 static HRESULT WINAPI BITS_IBackgroundCopyJob_GetOwner(
291 IBackgroundCopyJob2 *iface,
292 LPWSTR *pVal)
294 FIXME("Not implemented\n");
295 return E_NOTIMPL;
298 static HRESULT WINAPI BITS_IBackgroundCopyJob_SetDisplayName(
299 IBackgroundCopyJob2 *iface,
300 LPCWSTR Val)
302 FIXME("Not implemented\n");
303 return E_NOTIMPL;
306 static HRESULT WINAPI BITS_IBackgroundCopyJob_GetDisplayName(
307 IBackgroundCopyJob2 *iface,
308 LPWSTR *pVal)
310 BackgroundCopyJobImpl *This = impl_from_IBackgroundCopyJob2(iface);
311 int n;
313 if (!pVal)
314 return E_INVALIDARG;
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;
324 static HRESULT WINAPI BITS_IBackgroundCopyJob_SetDescription(
325 IBackgroundCopyJob2 *iface,
326 LPCWSTR Val)
328 FIXME("Not implemented\n");
329 return E_NOTIMPL;
332 static HRESULT WINAPI BITS_IBackgroundCopyJob_GetDescription(
333 IBackgroundCopyJob2 *iface,
334 LPWSTR *pVal)
336 FIXME("Not implemented\n");
337 return E_NOTIMPL;
340 static HRESULT WINAPI BITS_IBackgroundCopyJob_SetPriority(
341 IBackgroundCopyJob2 *iface,
342 BG_JOB_PRIORITY Val)
344 FIXME("(%p,0x%08x) stub\n", iface, Val);
345 return S_OK;
348 static HRESULT WINAPI BITS_IBackgroundCopyJob_GetPriority(
349 IBackgroundCopyJob2 *iface,
350 BG_JOB_PRIORITY *pVal)
352 FIXME("Not implemented\n");
353 return E_NOTIMPL;
356 static HRESULT WINAPI BITS_IBackgroundCopyJob_SetNotifyFlags(
357 IBackgroundCopyJob2 *iface,
358 ULONG Val)
360 FIXME("Not implemented\n");
361 return E_NOTIMPL;
364 static HRESULT WINAPI BITS_IBackgroundCopyJob_GetNotifyFlags(
365 IBackgroundCopyJob2 *iface,
366 ULONG *pVal)
368 FIXME("Not implemented\n");
369 return E_NOTIMPL;
372 static HRESULT WINAPI BITS_IBackgroundCopyJob_SetNotifyInterface(
373 IBackgroundCopyJob2 *iface,
374 IUnknown *Val)
376 FIXME("Not implemented\n");
377 return E_NOTIMPL;
380 static HRESULT WINAPI BITS_IBackgroundCopyJob_GetNotifyInterface(
381 IBackgroundCopyJob2 *iface,
382 IUnknown **pVal)
384 FIXME("Not implemented\n");
385 return E_NOTIMPL;
388 static HRESULT WINAPI BITS_IBackgroundCopyJob_SetMinimumRetryDelay(
389 IBackgroundCopyJob2 *iface,
390 ULONG Seconds)
392 FIXME("%u\n", Seconds);
393 return S_OK;
396 static HRESULT WINAPI BITS_IBackgroundCopyJob_GetMinimumRetryDelay(
397 IBackgroundCopyJob2 *iface,
398 ULONG *Seconds)
400 FIXME("%p\n", Seconds);
401 *Seconds = 30;
402 return S_OK;
405 static HRESULT WINAPI BITS_IBackgroundCopyJob_SetNoProgressTimeout(
406 IBackgroundCopyJob2 *iface,
407 ULONG Seconds)
409 FIXME("%u\n", Seconds);
410 return S_OK;
413 static HRESULT WINAPI BITS_IBackgroundCopyJob_GetNoProgressTimeout(
414 IBackgroundCopyJob2 *iface,
415 ULONG *Seconds)
417 FIXME("%p\n", Seconds);
418 *Seconds = 900;
419 return S_OK;
422 static HRESULT WINAPI BITS_IBackgroundCopyJob_GetErrorCount(
423 IBackgroundCopyJob2 *iface,
424 ULONG *Errors)
426 FIXME("Not implemented\n");
427 return E_NOTIMPL;
430 static HRESULT WINAPI BITS_IBackgroundCopyJob_SetProxySettings(
431 IBackgroundCopyJob2 *iface,
432 BG_JOB_PROXY_USAGE ProxyUsage,
433 const WCHAR *ProxyList,
434 const WCHAR *ProxyBypassList)
436 FIXME("Not implemented\n");
437 return E_NOTIMPL;
440 static HRESULT WINAPI BITS_IBackgroundCopyJob_GetProxySettings(
441 IBackgroundCopyJob2 *iface,
442 BG_JOB_PROXY_USAGE *pProxyUsage,
443 LPWSTR *pProxyList,
444 LPWSTR *pProxyBypassList)
446 FIXME("Not implemented\n");
447 return E_NOTIMPL;
450 static HRESULT WINAPI BITS_IBackgroundCopyJob_TakeOwnership(
451 IBackgroundCopyJob2 *iface)
453 FIXME("Not implemented\n");
454 return E_NOTIMPL;
457 static HRESULT WINAPI BITS_IBackgroundCopyJob_SetNotifyCmdLine(
458 IBackgroundCopyJob2 *iface,
459 LPCWSTR prog,
460 LPCWSTR params)
462 FIXME("Not implemented\n");
463 return E_NOTIMPL;
466 static HRESULT WINAPI BITS_IBackgroundCopyJob_GetNotifyCmdLine(
467 IBackgroundCopyJob2 *iface,
468 LPWSTR *prog,
469 LPWSTR *params)
471 FIXME("Not implemented\n");
472 return E_NOTIMPL;
475 static HRESULT WINAPI BITS_IBackgroundCopyJob_GetReplyProgress(
476 IBackgroundCopyJob2 *iface,
477 BG_JOB_REPLY_PROGRESS *progress)
479 FIXME("Not implemented\n");
480 return E_NOTIMPL;
483 static HRESULT WINAPI BITS_IBackgroundCopyJob_GetReplyData(
484 IBackgroundCopyJob2 *iface,
485 byte **pBuffer,
486 UINT64 *pLength)
488 FIXME("Not implemented\n");
489 return E_NOTIMPL;
492 static HRESULT WINAPI BITS_IBackgroundCopyJob_SetReplyFileName(
493 IBackgroundCopyJob2 *iface,
494 LPCWSTR filename)
496 FIXME("Not implemented\n");
497 return E_NOTIMPL;
500 static HRESULT WINAPI BITS_IBackgroundCopyJob_GetReplyFileName(
501 IBackgroundCopyJob2 *iface,
502 LPWSTR *pFilename)
504 FIXME("Not implemented\n");
505 return E_NOTIMPL;
508 static HRESULT WINAPI BITS_IBackgroundCopyJob_SetCredentials(
509 IBackgroundCopyJob2 *iface,
510 BG_AUTH_CREDENTIALS *cred)
512 FIXME("Not implemented\n");
513 return S_OK;
516 static HRESULT WINAPI BITS_IBackgroundCopyJob_RemoveCredentials(
517 IBackgroundCopyJob2 *iface,
518 BG_AUTH_TARGET target,
519 BG_AUTH_SCHEME scheme)
521 FIXME("Not implemented\n");
522 return S_OK;
525 static const IBackgroundCopyJob2Vtbl BITS_IBackgroundCopyJob_Vtbl =
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
572 HRESULT BackgroundCopyJobConstructor(LPCWSTR displayName, BG_JOB_TYPE type, GUID *job_id, BackgroundCopyJobImpl **job)
574 HRESULT hr;
575 BackgroundCopyJobImpl *This;
576 int n;
578 TRACE("(%s,%d,%p)\n", debugstr_w(displayName), type, job);
580 This = HeapAlloc(GetProcessHeap(), 0, sizeof *This);
581 if (!This)
582 return E_OUTOFMEMORY;
584 This->IBackgroundCopyJob2_iface.lpVtbl = &BITS_IBackgroundCopyJob_Vtbl;
585 InitializeCriticalSection(&This->cs);
586 This->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": BackgroundCopyJobImpl.cs");
588 This->ref = 1;
589 This->type = type;
591 n = (lstrlenW(displayName) + 1) * sizeof *displayName;
592 This->displayName = HeapAlloc(GetProcessHeap(), 0, n);
593 if (!This->displayName)
595 This->cs.DebugInfo->Spare[0] = 0;
596 DeleteCriticalSection(&This->cs);
597 HeapFree(GetProcessHeap(), 0, This);
598 return E_OUTOFMEMORY;
600 memcpy(This->displayName, displayName, n);
602 hr = CoCreateGuid(&This->jobId);
603 if (FAILED(hr))
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;
611 *job_id = This->jobId;
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;
619 This->state = BG_JOB_STATE_SUSPENDED;
621 *job = This;
622 return S_OK;
625 void processJob(BackgroundCopyJobImpl *job)
627 for (;;)
629 BackgroundCopyFileImpl *file;
630 BOOL done = TRUE;
632 EnterCriticalSection(&job->cs);
633 LIST_FOR_EACH_ENTRY(file, &job->files, BackgroundCopyFileImpl, entryFromJob)
634 if (!file->fileProgress.Completed)
636 done = FALSE;
637 break;
639 LeaveCriticalSection(&job->cs);
640 if (done)
642 transitionJobState(job, BG_JOB_STATE_QUEUED, BG_JOB_STATE_TRANSFERRED);
643 return;
646 if (!processFile(file, job))
647 return;