qmgr: Implement local file background "downloads."
This commit is contained in:
parent
374fea0a71
commit
b329a2ef3c
|
@ -170,3 +170,91 @@ HRESULT BackgroundCopyFileConstructor(BackgroundCopyJobImpl *owner,
|
|||
*ppObj = &This->lpVtbl;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static DWORD CALLBACK copyProgressCallback(LARGE_INTEGER totalSize,
|
||||
LARGE_INTEGER totalTransferred,
|
||||
LARGE_INTEGER streamSize,
|
||||
LARGE_INTEGER streamTransferred,
|
||||
DWORD streamNum,
|
||||
DWORD reason,
|
||||
HANDLE srcFile,
|
||||
HANDLE dstFile,
|
||||
LPVOID obj)
|
||||
{
|
||||
BackgroundCopyFileImpl *file = (BackgroundCopyFileImpl *) obj;
|
||||
BackgroundCopyJobImpl *job = file->owner;
|
||||
ULONG64 diff;
|
||||
|
||||
EnterCriticalSection(&job->cs);
|
||||
diff = (file->fileProgress.BytesTotal == BG_SIZE_UNKNOWN
|
||||
? totalTransferred.QuadPart
|
||||
: totalTransferred.QuadPart - file->fileProgress.BytesTransferred);
|
||||
file->fileProgress.BytesTotal = totalSize.QuadPart;
|
||||
file->fileProgress.BytesTransferred = totalTransferred.QuadPart;
|
||||
job->jobProgress.BytesTransferred += diff;
|
||||
LeaveCriticalSection(&job->cs);
|
||||
|
||||
return (job->state == BG_JOB_STATE_TRANSFERRING
|
||||
? PROGRESS_CONTINUE
|
||||
: PROGRESS_CANCEL);
|
||||
}
|
||||
|
||||
BOOL processFile(BackgroundCopyFileImpl *file, BackgroundCopyJobImpl *job)
|
||||
{
|
||||
static WCHAR prefix[] = {'B','I','T', 0};
|
||||
WCHAR tmpDir[MAX_PATH];
|
||||
WCHAR tmpName[MAX_PATH];
|
||||
|
||||
if (!GetTempPathW(MAX_PATH, tmpDir))
|
||||
{
|
||||
ERR("Couldn't create temp file name: %d\n", GetLastError());
|
||||
/* Guessing on what state this should give us */
|
||||
transitionJobState(job, BG_JOB_STATE_QUEUED, BG_JOB_STATE_TRANSIENT_ERROR);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!GetTempFileNameW(tmpDir, prefix, 0, tmpName))
|
||||
{
|
||||
ERR("Couldn't create temp file: %d\n", GetLastError());
|
||||
/* Guessing on what state this should give us */
|
||||
transitionJobState(job, BG_JOB_STATE_QUEUED, BG_JOB_STATE_TRANSIENT_ERROR);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
EnterCriticalSection(&job->cs);
|
||||
file->fileProgress.BytesTotal = BG_SIZE_UNKNOWN;
|
||||
file->fileProgress.BytesTransferred = 0;
|
||||
file->fileProgress.Completed = FALSE;
|
||||
LeaveCriticalSection(&job->cs);
|
||||
|
||||
TRACE("Transferring: %s -> %s -> %s\n",
|
||||
debugstr_w(file->info.RemoteName),
|
||||
debugstr_w(tmpName),
|
||||
debugstr_w(file->info.LocalName));
|
||||
|
||||
transitionJobState(job, BG_JOB_STATE_QUEUED, BG_JOB_STATE_TRANSFERRING);
|
||||
if (!CopyFileExW(file->info.RemoteName, tmpName, copyProgressCallback,
|
||||
file, NULL, 0))
|
||||
{
|
||||
ERR("Local file copy failed: error %d\n", GetLastError());
|
||||
transitionJobState(job, BG_JOB_STATE_TRANSFERRING, BG_JOB_STATE_ERROR);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (transitionJobState(job, BG_JOB_STATE_TRANSFERRING, BG_JOB_STATE_QUEUED))
|
||||
{
|
||||
lstrcpyW(file->tempFileName, tmpName);
|
||||
|
||||
EnterCriticalSection(&job->cs);
|
||||
file->fileProgress.Completed = TRUE;
|
||||
job->jobProgress.FilesTransferred++;
|
||||
LeaveCriticalSection(&job->cs);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
DeleteFileW(tmpName);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -98,6 +98,7 @@ static HRESULT WINAPI BITS_IBackgroundCopyJob_AddFile(
|
|||
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);
|
||||
|
||||
|
@ -485,3 +486,29 @@ HRESULT BackgroundCopyJobConstructor(LPCWSTR displayName, BG_JOB_TYPE type,
|
|||
*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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -189,11 +189,6 @@ DWORD WINAPI fileTransfer(void *param)
|
|||
LeaveCriticalSection(&qmgr->cs);
|
||||
|
||||
if (haveJob)
|
||||
{
|
||||
FIXME("Actually process job %p; setting error state\n", job);
|
||||
EnterCriticalSection(&qmgr->cs);
|
||||
job->state = BG_JOB_STATE_ERROR;
|
||||
LeaveCriticalSection(&qmgr->cs);
|
||||
}
|
||||
processJob(job);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -73,6 +73,7 @@ typedef struct
|
|||
LONG ref;
|
||||
BG_FILE_INFO info;
|
||||
BG_FILE_PROGRESS fileProgress;
|
||||
WCHAR tempFileName[MAX_PATH];
|
||||
struct list entryFromJob;
|
||||
BackgroundCopyJobImpl *owner;
|
||||
} BackgroundCopyFileImpl;
|
||||
|
@ -107,6 +108,8 @@ HRESULT BackgroundCopyFileConstructor(BackgroundCopyJobImpl *owner,
|
|||
HRESULT EnumBackgroundCopyFilesConstructor(LPVOID *ppObj,
|
||||
IBackgroundCopyJob* copyJob);
|
||||
DWORD WINAPI fileTransfer(void *param);
|
||||
void processJob(BackgroundCopyJobImpl *job);
|
||||
BOOL processFile(BackgroundCopyFileImpl *file, BackgroundCopyJobImpl *job);
|
||||
|
||||
/* Little helper functions */
|
||||
static inline char *
|
||||
|
@ -117,4 +120,19 @@ qmgr_strdup(const char *s)
|
|||
return d ? memcpy(d, s, n) : NULL;
|
||||
}
|
||||
|
||||
static inline BOOL
|
||||
transitionJobState(BackgroundCopyJobImpl *job, BG_JOB_STATE fromState,
|
||||
BG_JOB_STATE toState)
|
||||
{
|
||||
BOOL rv = FALSE;
|
||||
EnterCriticalSection(&globalMgr.cs);
|
||||
if (job->state == fromState)
|
||||
{
|
||||
job->state = toState;
|
||||
rv = TRUE;
|
||||
}
|
||||
LeaveCriticalSection(&globalMgr.cs);
|
||||
return rv;
|
||||
}
|
||||
|
||||
#endif /* __QMGR_H__ */
|
||||
|
|
Loading…
Reference in New Issue