Dan Hipschman : qmgr: Implement local file background "downloads."
Alexandre Julliard
julliard at winehq.org
Fri Mar 14 08:29:23 CDT 2008
Module: wine
Branch: master
Commit: b329a2ef3cdb17f4b301adcbe5beddf57506ace6
URL: http://source.winehq.org/git/wine.git/?a=commit;h=b329a2ef3cdb17f4b301adcbe5beddf57506ace6
Author: Dan Hipschman <dsh at linux.ucla.edu>
Date: Thu Mar 13 15:54:35 2008 -0700
qmgr: Implement local file background "downloads."
---
dlls/qmgr/file.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
dlls/qmgr/job.c | 27 ++++++++++++++++
dlls/qmgr/qmgr.c | 7 +----
dlls/qmgr/qmgr.h | 18 +++++++++++
4 files changed, 134 insertions(+), 6 deletions(-)
diff --git a/dlls/qmgr/file.c b/dlls/qmgr/file.c
index f1ae06a..a874062 100644
--- a/dlls/qmgr/file.c
+++ b/dlls/qmgr/file.c
@@ -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;
+ }
+}
diff --git a/dlls/qmgr/job.c b/dlls/qmgr/job.c
index 2fbf1bc..3b94a79 100644
--- a/dlls/qmgr/job.c
+++ b/dlls/qmgr/job.c
@@ -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;
+ }
+}
diff --git a/dlls/qmgr/qmgr.c b/dlls/qmgr/qmgr.c
index 608e01a..4e3d259 100644
--- a/dlls/qmgr/qmgr.c
+++ b/dlls/qmgr/qmgr.c
@@ -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);
}
}
diff --git a/dlls/qmgr/qmgr.h b/dlls/qmgr/qmgr.h
index fce84d9..9530b97 100644
--- a/dlls/qmgr/qmgr.h
+++ b/dlls/qmgr/qmgr.h
@@ -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__ */
More information about the wine-cvs
mailing list