mirror of
git://source.winehq.org/git/wine.git
synced 2024-11-05 18:01:34 +00:00
644 lines
17 KiB
C
644 lines
17 KiB
C
/*
|
|
* Background Copy Job Interface for BITS
|
|
*
|
|
* Copyright 2007 Google (Roy Shea)
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
|
*/
|
|
|
|
#include <stdarg.h>
|
|
|
|
#include "windef.h"
|
|
#include "winbase.h"
|
|
|
|
#include "qmgr.h"
|
|
#include "wine/debug.h"
|
|
|
|
WINE_DEFAULT_DEBUG_CHANNEL(qmgr);
|
|
|
|
static void BackgroundCopyJobDestructor(BackgroundCopyJobImpl *This)
|
|
{
|
|
This->cs.DebugInfo->Spare[0] = 0;
|
|
DeleteCriticalSection(&This->cs);
|
|
HeapFree(GetProcessHeap(), 0, This->displayName);
|
|
HeapFree(GetProcessHeap(), 0, This);
|
|
}
|
|
|
|
static ULONG WINAPI BITS_IBackgroundCopyJob_AddRef(IBackgroundCopyJob2 *iface)
|
|
{
|
|
BackgroundCopyJobImpl *This = (BackgroundCopyJobImpl *) iface;
|
|
return InterlockedIncrement(&This->ref);
|
|
}
|
|
|
|
static HRESULT WINAPI BITS_IBackgroundCopyJob_QueryInterface(
|
|
IBackgroundCopyJob2 *iface, REFIID riid, LPVOID *ppvObject)
|
|
{
|
|
BackgroundCopyJobImpl *This = (BackgroundCopyJobImpl *) iface;
|
|
TRACE("IID: %s\n", debugstr_guid(riid));
|
|
|
|
if (IsEqualGUID(riid, &IID_IUnknown)
|
|
|| IsEqualGUID(riid, &IID_IBackgroundCopyJob)
|
|
|| IsEqualGUID(riid, &IID_IBackgroundCopyJob2))
|
|
{
|
|
*ppvObject = &This->lpVtbl;
|
|
BITS_IBackgroundCopyJob_AddRef(iface);
|
|
return S_OK;
|
|
}
|
|
|
|
*ppvObject = NULL;
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
static ULONG WINAPI BITS_IBackgroundCopyJob_Release(IBackgroundCopyJob2 *iface)
|
|
{
|
|
BackgroundCopyJobImpl *This = (BackgroundCopyJobImpl *) iface;
|
|
ULONG ref = InterlockedDecrement(&This->ref);
|
|
|
|
if (ref == 0)
|
|
BackgroundCopyJobDestructor(This);
|
|
|
|
return ref;
|
|
}
|
|
|
|
/*** IBackgroundCopyJob methods ***/
|
|
|
|
static HRESULT WINAPI BITS_IBackgroundCopyJob_AddFileSet(
|
|
IBackgroundCopyJob2 *iface,
|
|
ULONG cFileCount,
|
|
BG_FILE_INFO *pFileSet)
|
|
{
|
|
ULONG i;
|
|
for (i = 0; i < cFileCount; ++i)
|
|
{
|
|
HRESULT hr = IBackgroundCopyJob_AddFile(iface, pFileSet[i].RemoteName,
|
|
pFileSet[i].LocalName);
|
|
if (FAILED(hr))
|
|
return hr;
|
|
}
|
|
return S_OK;
|
|
}
|
|
|
|
static HRESULT WINAPI BITS_IBackgroundCopyJob_AddFile(
|
|
IBackgroundCopyJob2 *iface,
|
|
LPCWSTR RemoteUrl,
|
|
LPCWSTR LocalName)
|
|
{
|
|
BackgroundCopyJobImpl *This = (BackgroundCopyJobImpl *) iface;
|
|
IBackgroundCopyFile *pFile;
|
|
BackgroundCopyFileImpl *file;
|
|
HRESULT res;
|
|
|
|
/* We should return E_INVALIDARG in these cases. */
|
|
FIXME("Check for valid filenames and supported protocols\n");
|
|
|
|
res = BackgroundCopyFileConstructor(This, RemoteUrl, LocalName, (LPVOID *) &pFile);
|
|
if (res != S_OK)
|
|
return res;
|
|
|
|
/* Add a reference to the file to file list */
|
|
IBackgroundCopyFile_AddRef(pFile);
|
|
file = (BackgroundCopyFileImpl *) pFile;
|
|
EnterCriticalSection(&This->cs);
|
|
list_add_head(&This->files, &file->entryFromJob);
|
|
This->jobProgress.BytesTotal = BG_SIZE_UNKNOWN;
|
|
++This->jobProgress.FilesTotal;
|
|
LeaveCriticalSection(&This->cs);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
static HRESULT WINAPI BITS_IBackgroundCopyJob_EnumFiles(
|
|
IBackgroundCopyJob2 *iface,
|
|
IEnumBackgroundCopyFiles **ppEnum)
|
|
{
|
|
TRACE("\n");
|
|
return EnumBackgroundCopyFilesConstructor((LPVOID *) ppEnum, iface);
|
|
}
|
|
|
|
static HRESULT WINAPI BITS_IBackgroundCopyJob_Suspend(
|
|
IBackgroundCopyJob2 *iface)
|
|
{
|
|
FIXME("Not implemented\n");
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI BITS_IBackgroundCopyJob_Resume(
|
|
IBackgroundCopyJob2 *iface)
|
|
{
|
|
BackgroundCopyJobImpl *This = (BackgroundCopyJobImpl *) iface;
|
|
HRESULT rv = S_OK;
|
|
|
|
EnterCriticalSection(&globalMgr.cs);
|
|
if (This->state == BG_JOB_STATE_CANCELLED
|
|
|| This->state == BG_JOB_STATE_ACKNOWLEDGED)
|
|
{
|
|
rv = BG_E_INVALID_STATE;
|
|
}
|
|
else if (This->jobProgress.FilesTransferred == This->jobProgress.FilesTotal)
|
|
{
|
|
rv = BG_E_EMPTY;
|
|
}
|
|
else if (This->state != BG_JOB_STATE_CONNECTING
|
|
&& This->state != BG_JOB_STATE_TRANSFERRING)
|
|
{
|
|
This->state = BG_JOB_STATE_QUEUED;
|
|
SetEvent(globalMgr.jobEvent);
|
|
}
|
|
LeaveCriticalSection(&globalMgr.cs);
|
|
|
|
return rv;
|
|
}
|
|
|
|
static HRESULT WINAPI BITS_IBackgroundCopyJob_Cancel(
|
|
IBackgroundCopyJob2 *iface)
|
|
{
|
|
FIXME("Not implemented\n");
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI BITS_IBackgroundCopyJob_Complete(
|
|
IBackgroundCopyJob2 *iface)
|
|
{
|
|
BackgroundCopyJobImpl *This = (BackgroundCopyJobImpl *) iface;
|
|
HRESULT rv = S_OK;
|
|
|
|
EnterCriticalSection(&This->cs);
|
|
|
|
if (This->state == BG_JOB_STATE_CANCELLED
|
|
|| This->state == BG_JOB_STATE_ACKNOWLEDGED)
|
|
{
|
|
rv = BG_E_INVALID_STATE;
|
|
}
|
|
else
|
|
{
|
|
BackgroundCopyFileImpl *file;
|
|
LIST_FOR_EACH_ENTRY(file, &This->files, BackgroundCopyFileImpl, entryFromJob)
|
|
{
|
|
if (file->fileProgress.Completed)
|
|
{
|
|
if (!MoveFileExW(file->tempFileName, file->info.LocalName,
|
|
(MOVEFILE_COPY_ALLOWED
|
|
| MOVEFILE_REPLACE_EXISTING
|
|
| MOVEFILE_WRITE_THROUGH)))
|
|
{
|
|
ERR("Couldn't rename file %s -> %s\n",
|
|
debugstr_w(file->tempFileName),
|
|
debugstr_w(file->info.LocalName));
|
|
rv = BG_S_PARTIAL_COMPLETE;
|
|
}
|
|
}
|
|
else
|
|
rv = BG_S_PARTIAL_COMPLETE;
|
|
}
|
|
}
|
|
|
|
This->state = BG_JOB_STATE_ACKNOWLEDGED;
|
|
LeaveCriticalSection(&This->cs);
|
|
|
|
return rv;
|
|
}
|
|
|
|
static HRESULT WINAPI BITS_IBackgroundCopyJob_GetId(
|
|
IBackgroundCopyJob2 *iface,
|
|
GUID *pVal)
|
|
{
|
|
BackgroundCopyJobImpl *This = (BackgroundCopyJobImpl *) iface;
|
|
*pVal = This->jobId;
|
|
return S_OK;
|
|
}
|
|
|
|
static HRESULT WINAPI BITS_IBackgroundCopyJob_GetType(
|
|
IBackgroundCopyJob2 *iface,
|
|
BG_JOB_TYPE *pVal)
|
|
{
|
|
BackgroundCopyJobImpl *This = (BackgroundCopyJobImpl *) iface;
|
|
|
|
if (!pVal)
|
|
return E_INVALIDARG;
|
|
|
|
*pVal = This->type;
|
|
return S_OK;
|
|
}
|
|
|
|
static HRESULT WINAPI BITS_IBackgroundCopyJob_GetProgress(
|
|
IBackgroundCopyJob2 *iface,
|
|
BG_JOB_PROGRESS *pVal)
|
|
{
|
|
BackgroundCopyJobImpl *This = (BackgroundCopyJobImpl *) iface;
|
|
|
|
if (!pVal)
|
|
return E_INVALIDARG;
|
|
|
|
EnterCriticalSection(&This->cs);
|
|
pVal->BytesTotal = This->jobProgress.BytesTotal;
|
|
pVal->BytesTransferred = This->jobProgress.BytesTransferred;
|
|
pVal->FilesTotal = This->jobProgress.FilesTotal;
|
|
pVal->FilesTransferred = This->jobProgress.FilesTransferred;
|
|
LeaveCriticalSection(&This->cs);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
static HRESULT WINAPI BITS_IBackgroundCopyJob_GetTimes(
|
|
IBackgroundCopyJob2 *iface,
|
|
BG_JOB_TIMES *pVal)
|
|
{
|
|
FIXME("Not implemented\n");
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI BITS_IBackgroundCopyJob_GetState(
|
|
IBackgroundCopyJob2 *iface,
|
|
BG_JOB_STATE *pVal)
|
|
{
|
|
BackgroundCopyJobImpl *This = (BackgroundCopyJobImpl *) iface;
|
|
|
|
if (!pVal)
|
|
return E_INVALIDARG;
|
|
|
|
/* Don't think we need a critical section for this */
|
|
*pVal = This->state;
|
|
return S_OK;
|
|
}
|
|
|
|
static HRESULT WINAPI BITS_IBackgroundCopyJob_GetError(
|
|
IBackgroundCopyJob2 *iface,
|
|
IBackgroundCopyError **ppError)
|
|
{
|
|
FIXME("Not implemented\n");
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI BITS_IBackgroundCopyJob_GetOwner(
|
|
IBackgroundCopyJob2 *iface,
|
|
LPWSTR *pVal)
|
|
{
|
|
FIXME("Not implemented\n");
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI BITS_IBackgroundCopyJob_SetDisplayName(
|
|
IBackgroundCopyJob2 *iface,
|
|
LPCWSTR Val)
|
|
{
|
|
FIXME("Not implemented\n");
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI BITS_IBackgroundCopyJob_GetDisplayName(
|
|
IBackgroundCopyJob2 *iface,
|
|
LPWSTR *pVal)
|
|
{
|
|
BackgroundCopyJobImpl *This = (BackgroundCopyJobImpl *) iface;
|
|
int n;
|
|
|
|
if (!pVal)
|
|
return E_INVALIDARG;
|
|
|
|
n = (lstrlenW(This->displayName) + 1) * sizeof **pVal;
|
|
*pVal = CoTaskMemAlloc(n);
|
|
if (*pVal == NULL)
|
|
return E_OUTOFMEMORY;
|
|
memcpy(*pVal, This->displayName, n);
|
|
return S_OK;
|
|
}
|
|
|
|
static HRESULT WINAPI BITS_IBackgroundCopyJob_SetDescription(
|
|
IBackgroundCopyJob2 *iface,
|
|
LPCWSTR Val)
|
|
{
|
|
FIXME("Not implemented\n");
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI BITS_IBackgroundCopyJob_GetDescription(
|
|
IBackgroundCopyJob2 *iface,
|
|
LPWSTR *pVal)
|
|
{
|
|
FIXME("Not implemented\n");
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI BITS_IBackgroundCopyJob_SetPriority(
|
|
IBackgroundCopyJob2 *iface,
|
|
BG_JOB_PRIORITY Val)
|
|
{
|
|
FIXME("(%p,0x%08x) stub\n", iface, Val);
|
|
return S_OK;
|
|
}
|
|
|
|
static HRESULT WINAPI BITS_IBackgroundCopyJob_GetPriority(
|
|
IBackgroundCopyJob2 *iface,
|
|
BG_JOB_PRIORITY *pVal)
|
|
{
|
|
FIXME("Not implemented\n");
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI BITS_IBackgroundCopyJob_SetNotifyFlags(
|
|
IBackgroundCopyJob2 *iface,
|
|
ULONG Val)
|
|
{
|
|
FIXME("Not implemented\n");
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI BITS_IBackgroundCopyJob_GetNotifyFlags(
|
|
IBackgroundCopyJob2 *iface,
|
|
ULONG *pVal)
|
|
{
|
|
FIXME("Not implemented\n");
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI BITS_IBackgroundCopyJob_SetNotifyInterface(
|
|
IBackgroundCopyJob2 *iface,
|
|
IUnknown *Val)
|
|
{
|
|
FIXME("Not implemented\n");
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI BITS_IBackgroundCopyJob_GetNotifyInterface(
|
|
IBackgroundCopyJob2 *iface,
|
|
IUnknown **pVal)
|
|
{
|
|
FIXME("Not implemented\n");
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI BITS_IBackgroundCopyJob_SetMinimumRetryDelay(
|
|
IBackgroundCopyJob2 *iface,
|
|
ULONG Seconds)
|
|
{
|
|
FIXME("%u\n", Seconds);
|
|
return S_OK;
|
|
}
|
|
|
|
static HRESULT WINAPI BITS_IBackgroundCopyJob_GetMinimumRetryDelay(
|
|
IBackgroundCopyJob2 *iface,
|
|
ULONG *Seconds)
|
|
{
|
|
FIXME("%p\n", Seconds);
|
|
*Seconds = 30;
|
|
return S_OK;
|
|
}
|
|
|
|
static HRESULT WINAPI BITS_IBackgroundCopyJob_SetNoProgressTimeout(
|
|
IBackgroundCopyJob2 *iface,
|
|
ULONG Seconds)
|
|
{
|
|
FIXME("%u\n", Seconds);
|
|
return S_OK;
|
|
}
|
|
|
|
static HRESULT WINAPI BITS_IBackgroundCopyJob_GetNoProgressTimeout(
|
|
IBackgroundCopyJob2 *iface,
|
|
ULONG *Seconds)
|
|
{
|
|
FIXME("%p\n", Seconds);
|
|
*Seconds = 900;
|
|
return S_OK;
|
|
}
|
|
|
|
static HRESULT WINAPI BITS_IBackgroundCopyJob_GetErrorCount(
|
|
IBackgroundCopyJob2 *iface,
|
|
ULONG *Errors)
|
|
{
|
|
FIXME("Not implemented\n");
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI BITS_IBackgroundCopyJob_SetProxySettings(
|
|
IBackgroundCopyJob2 *iface,
|
|
BG_JOB_PROXY_USAGE ProxyUsage,
|
|
const WCHAR *ProxyList,
|
|
const WCHAR *ProxyBypassList)
|
|
{
|
|
FIXME("Not implemented\n");
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI BITS_IBackgroundCopyJob_GetProxySettings(
|
|
IBackgroundCopyJob2 *iface,
|
|
BG_JOB_PROXY_USAGE *pProxyUsage,
|
|
LPWSTR *pProxyList,
|
|
LPWSTR *pProxyBypassList)
|
|
{
|
|
FIXME("Not implemented\n");
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI BITS_IBackgroundCopyJob_TakeOwnership(
|
|
IBackgroundCopyJob2 *iface)
|
|
{
|
|
FIXME("Not implemented\n");
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI BITS_IBackgroundCopyJob_SetNotifyCmdLine(
|
|
IBackgroundCopyJob2 *iface,
|
|
LPCWSTR prog,
|
|
LPCWSTR params)
|
|
{
|
|
FIXME("Not implemented\n");
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI BITS_IBackgroundCopyJob_GetNotifyCmdLine(
|
|
IBackgroundCopyJob2 *iface,
|
|
LPWSTR *prog,
|
|
LPWSTR *params)
|
|
{
|
|
FIXME("Not implemented\n");
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI BITS_IBackgroundCopyJob_GetReplyProgress(
|
|
IBackgroundCopyJob2 *iface,
|
|
BG_JOB_REPLY_PROGRESS *progress)
|
|
{
|
|
FIXME("Not implemented\n");
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI BITS_IBackgroundCopyJob_GetReplyData(
|
|
IBackgroundCopyJob2 *iface,
|
|
byte **pBuffer,
|
|
UINT64 *pLength)
|
|
{
|
|
FIXME("Not implemented\n");
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI BITS_IBackgroundCopyJob_SetReplyFileName(
|
|
IBackgroundCopyJob2 *iface,
|
|
LPCWSTR filename)
|
|
{
|
|
FIXME("Not implemented\n");
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI BITS_IBackgroundCopyJob_GetReplyFileName(
|
|
IBackgroundCopyJob2 *iface,
|
|
LPWSTR *pFilename)
|
|
{
|
|
FIXME("Not implemented\n");
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI BITS_IBackgroundCopyJob_SetCredentials(
|
|
IBackgroundCopyJob2 *iface,
|
|
BG_AUTH_CREDENTIALS *cred)
|
|
{
|
|
FIXME("Not implemented\n");
|
|
return S_OK;
|
|
}
|
|
|
|
static HRESULT WINAPI BITS_IBackgroundCopyJob_RemoveCredentials(
|
|
IBackgroundCopyJob2 *iface,
|
|
BG_AUTH_TARGET target,
|
|
BG_AUTH_SCHEME scheme)
|
|
{
|
|
FIXME("Not implemented\n");
|
|
return S_OK;
|
|
}
|
|
|
|
static const IBackgroundCopyJob2Vtbl BITS_IBackgroundCopyJob_Vtbl =
|
|
{
|
|
BITS_IBackgroundCopyJob_QueryInterface,
|
|
BITS_IBackgroundCopyJob_AddRef,
|
|
BITS_IBackgroundCopyJob_Release,
|
|
BITS_IBackgroundCopyJob_AddFileSet,
|
|
BITS_IBackgroundCopyJob_AddFile,
|
|
BITS_IBackgroundCopyJob_EnumFiles,
|
|
BITS_IBackgroundCopyJob_Suspend,
|
|
BITS_IBackgroundCopyJob_Resume,
|
|
BITS_IBackgroundCopyJob_Cancel,
|
|
BITS_IBackgroundCopyJob_Complete,
|
|
BITS_IBackgroundCopyJob_GetId,
|
|
BITS_IBackgroundCopyJob_GetType,
|
|
BITS_IBackgroundCopyJob_GetProgress,
|
|
BITS_IBackgroundCopyJob_GetTimes,
|
|
BITS_IBackgroundCopyJob_GetState,
|
|
BITS_IBackgroundCopyJob_GetError,
|
|
BITS_IBackgroundCopyJob_GetOwner,
|
|
BITS_IBackgroundCopyJob_SetDisplayName,
|
|
BITS_IBackgroundCopyJob_GetDisplayName,
|
|
BITS_IBackgroundCopyJob_SetDescription,
|
|
BITS_IBackgroundCopyJob_GetDescription,
|
|
BITS_IBackgroundCopyJob_SetPriority,
|
|
BITS_IBackgroundCopyJob_GetPriority,
|
|
BITS_IBackgroundCopyJob_SetNotifyFlags,
|
|
BITS_IBackgroundCopyJob_GetNotifyFlags,
|
|
BITS_IBackgroundCopyJob_SetNotifyInterface,
|
|
BITS_IBackgroundCopyJob_GetNotifyInterface,
|
|
BITS_IBackgroundCopyJob_SetMinimumRetryDelay,
|
|
BITS_IBackgroundCopyJob_GetMinimumRetryDelay,
|
|
BITS_IBackgroundCopyJob_SetNoProgressTimeout,
|
|
BITS_IBackgroundCopyJob_GetNoProgressTimeout,
|
|
BITS_IBackgroundCopyJob_GetErrorCount,
|
|
BITS_IBackgroundCopyJob_SetProxySettings,
|
|
BITS_IBackgroundCopyJob_GetProxySettings,
|
|
BITS_IBackgroundCopyJob_TakeOwnership,
|
|
BITS_IBackgroundCopyJob_SetNotifyCmdLine,
|
|
BITS_IBackgroundCopyJob_GetNotifyCmdLine,
|
|
BITS_IBackgroundCopyJob_GetReplyProgress,
|
|
BITS_IBackgroundCopyJob_GetReplyData,
|
|
BITS_IBackgroundCopyJob_SetReplyFileName,
|
|
BITS_IBackgroundCopyJob_GetReplyFileName,
|
|
BITS_IBackgroundCopyJob_SetCredentials,
|
|
BITS_IBackgroundCopyJob_RemoveCredentials
|
|
};
|
|
|
|
HRESULT BackgroundCopyJobConstructor(LPCWSTR displayName, BG_JOB_TYPE type,
|
|
GUID *pJobId, LPVOID *ppObj)
|
|
{
|
|
HRESULT hr;
|
|
BackgroundCopyJobImpl *This;
|
|
int n;
|
|
|
|
TRACE("(%s,%d,%p)\n", debugstr_w(displayName), type, ppObj);
|
|
|
|
This = HeapAlloc(GetProcessHeap(), 0, sizeof *This);
|
|
if (!This)
|
|
return E_OUTOFMEMORY;
|
|
|
|
This->lpVtbl = &BITS_IBackgroundCopyJob_Vtbl;
|
|
InitializeCriticalSection(&This->cs);
|
|
This->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": BackgroundCopyJobImpl.cs");
|
|
|
|
This->ref = 1;
|
|
This->type = type;
|
|
|
|
n = (lstrlenW(displayName) + 1) * sizeof *displayName;
|
|
This->displayName = HeapAlloc(GetProcessHeap(), 0, n);
|
|
if (!This->displayName)
|
|
{
|
|
This->cs.DebugInfo->Spare[0] = 0;
|
|
DeleteCriticalSection(&This->cs);
|
|
HeapFree(GetProcessHeap(), 0, This);
|
|
return E_OUTOFMEMORY;
|
|
}
|
|
memcpy(This->displayName, displayName, n);
|
|
|
|
hr = CoCreateGuid(&This->jobId);
|
|
if (FAILED(hr))
|
|
{
|
|
This->cs.DebugInfo->Spare[0] = 0;
|
|
DeleteCriticalSection(&This->cs);
|
|
HeapFree(GetProcessHeap(), 0, This->displayName);
|
|
HeapFree(GetProcessHeap(), 0, This);
|
|
return hr;
|
|
}
|
|
*pJobId = This->jobId;
|
|
|
|
list_init(&This->files);
|
|
This->jobProgress.BytesTotal = 0;
|
|
This->jobProgress.BytesTransferred = 0;
|
|
This->jobProgress.FilesTotal = 0;
|
|
This->jobProgress.FilesTransferred = 0;
|
|
|
|
This->state = BG_JOB_STATE_SUSPENDED;
|
|
|
|
*ppObj = &This->lpVtbl;
|
|
return S_OK;
|
|
}
|
|
|
|
void processJob(BackgroundCopyJobImpl *job)
|
|
{
|
|
for (;;)
|
|
{
|
|
BackgroundCopyFileImpl *file;
|
|
BOOL done = TRUE;
|
|
|
|
EnterCriticalSection(&job->cs);
|
|
LIST_FOR_EACH_ENTRY(file, &job->files, BackgroundCopyFileImpl, entryFromJob)
|
|
if (!file->fileProgress.Completed)
|
|
{
|
|
done = FALSE;
|
|
break;
|
|
}
|
|
LeaveCriticalSection(&job->cs);
|
|
if (done)
|
|
{
|
|
transitionJobState(job, BG_JOB_STATE_QUEUED, BG_JOB_STATE_TRANSFERRED);
|
|
return;
|
|
}
|
|
|
|
if (!processFile(file, job))
|
|
return;
|
|
}
|
|
}
|