qmgr: Transfer files given by URL (including HTTP, etc).

This commit is contained in:
Dan Hipschman 2008-03-13 15:57:19 -07:00 committed by Alexandre Julliard
parent 1c93ee77e5
commit 2f2b3303d7
3 changed files with 113 additions and 5 deletions

View File

@ -3,7 +3,7 @@ TOPOBJDIR = ../..
SRCDIR = @srcdir@ SRCDIR = @srcdir@
VPATH = @srcdir@ VPATH = @srcdir@
MODULE = qmgr.dll MODULE = qmgr.dll
IMPORTS = advpack ole32 advapi32 kernel32 IMPORTS = advpack wininet urlmon ole32 advapi32 kernel32
EXTRALIBS = -luuid EXTRALIBS = -luuid
C_SRCS = \ C_SRCS = \

View File

@ -1,7 +1,7 @@
/* /*
* Queue Manager (BITS) File * Queue Manager (BITS) File
* *
* Copyright 2007 Google (Roy Shea) * Copyright 2007, 2008 Google (Roy Shea, Dan Hipschman)
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -18,6 +18,16 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "winreg.h"
#include "ole2.h"
#include "urlmon.h"
#include "wininet.h"
#include "qmgr.h" #include "qmgr.h"
#include "wine/debug.h" #include "wine/debug.h"
@ -204,6 +214,7 @@ BOOL processFile(BackgroundCopyFileImpl *file, BackgroundCopyJobImpl *job)
static WCHAR prefix[] = {'B','I','T', 0}; static WCHAR prefix[] = {'B','I','T', 0};
WCHAR tmpDir[MAX_PATH]; WCHAR tmpDir[MAX_PATH];
WCHAR tmpName[MAX_PATH]; WCHAR tmpName[MAX_PATH];
HRESULT hr;
if (!GetTempPathW(MAX_PATH, tmpDir)) if (!GetTempPathW(MAX_PATH, tmpDir))
{ {
@ -233,6 +244,19 @@ BOOL processFile(BackgroundCopyFileImpl *file, BackgroundCopyJobImpl *job)
debugstr_w(file->info.LocalName)); debugstr_w(file->info.LocalName));
transitionJobState(job, BG_JOB_STATE_QUEUED, BG_JOB_STATE_TRANSFERRING); transitionJobState(job, BG_JOB_STATE_QUEUED, BG_JOB_STATE_TRANSFERRING);
DeleteUrlCacheEntryW(file->info.RemoteName);
hr = URLDownloadToFileW(NULL, file->info.RemoteName, tmpName, 0, NULL);
if (SUCCEEDED(hr))
{
FIXME("Do progress updates correctly with IBindStatusCallback\n");
EnterCriticalSection(&job->cs);
file->fileProgress.BytesTotal = 0;
LeaveCriticalSection(&job->cs);
}
else if (hr == INET_E_DOWNLOAD_FAILURE)
{
TRACE("URLDownload failed, trying local file copy\n");
if (!CopyFileExW(file->info.RemoteName, tmpName, copyProgressCallback, if (!CopyFileExW(file->info.RemoteName, tmpName, copyProgressCallback,
file, NULL, 0)) file, NULL, 0))
{ {
@ -240,6 +264,13 @@ BOOL processFile(BackgroundCopyFileImpl *file, BackgroundCopyJobImpl *job)
transitionJobState(job, BG_JOB_STATE_TRANSFERRING, BG_JOB_STATE_ERROR); transitionJobState(job, BG_JOB_STATE_TRANSFERRING, BG_JOB_STATE_ERROR);
return FALSE; return FALSE;
} }
}
else
{
ERR("URLDownload failed: eh 0x%08x\n", hr);
transitionJobState(job, BG_JOB_STATE_TRANSFERRING, BG_JOB_STATE_ERROR);
return FALSE;
}
if (transitionJobState(job, BG_JOB_STATE_TRANSFERRING, BG_JOB_STATE_QUEUED)) if (transitionJobState(job, BG_JOB_STATE_TRANSFERRING, BG_JOB_STATE_QUEUED))
{ {

View File

@ -377,6 +377,82 @@ static void test_CompleteLocal(void)
ok(DeleteFileW(test_remotePathB), "DeleteFile\n"); ok(DeleteFileW(test_remotePathB), "DeleteFile\n");
} }
/* Test a complete transfer for local files */
static void test_CompleteLocalURL(void)
{
static const WCHAR prot[] = {'f','i','l','e',':','/','/', 0};
static const int timeout_sec = 30;
WCHAR *urlA, *urlB;
HRESULT hres;
BG_JOB_STATE state;
int i;
DeleteFileW(test_localPathA);
DeleteFileW(test_localPathB);
makeFile(test_remotePathA, "This is a WINE test file for BITS\n");
makeFile(test_remotePathB, "This is another WINE test file for BITS\n");
urlA = HeapAlloc(GetProcessHeap(), 0,
(7 + lstrlenW(test_remotePathA) + 1) * sizeof urlA[0]);
urlB = HeapAlloc(GetProcessHeap(), 0,
(7 + lstrlenW(test_remotePathB) + 1) * sizeof urlB[0]);
if (!urlA || !urlB)
{
skip("Unable to allocate memory for URLs\n");
return;
}
lstrcpyW(urlA, prot);
lstrcatW(urlA, test_remotePathA);
lstrcpyW(urlB, prot);
lstrcatW(urlB, test_remotePathB);
hres = IBackgroundCopyJob_AddFile(test_job, urlA, test_localPathA);
if (hres != S_OK)
{
skip("Unable to add file to job\n");
return;
}
hres = IBackgroundCopyJob_AddFile(test_job, urlB, test_localPathB);
if (hres != S_OK)
{
skip("Unable to add file to job\n");
return;
}
hres = IBackgroundCopyJob_Resume(test_job);
ok(hres == S_OK, "IBackgroundCopyJob_Resume\n");
for (i = 0; i < timeout_sec; ++i)
{
hres = IBackgroundCopyJob_GetState(test_job, &state);
ok(hres == S_OK, "IBackgroundCopyJob_GetState\n");
ok(state == BG_JOB_STATE_QUEUED || state == BG_JOB_STATE_CONNECTING
|| state == BG_JOB_STATE_TRANSFERRING || state == BG_JOB_STATE_TRANSFERRED,
"Bad state: %d\n", state);
if (state == BG_JOB_STATE_TRANSFERRED)
break;
Sleep(1000);
}
ok(i < timeout_sec, "BITS jobs timed out\n");
hres = IBackgroundCopyJob_Complete(test_job);
ok(hres == S_OK, "IBackgroundCopyJob_Complete\n");
hres = IBackgroundCopyJob_GetState(test_job, &state);
ok(hres == S_OK, "IBackgroundCopyJob_GetState\n");
ok(state == BG_JOB_STATE_ACKNOWLEDGED, "Bad state: %d\n", state);
compareFiles(test_remotePathA, test_localPathA);
compareFiles(test_remotePathB, test_localPathB);
ok(DeleteFileW(test_remotePathA), "DeleteFile\n");
ok(DeleteFileW(test_remotePathB), "DeleteFile\n");
HeapFree(GetProcessHeap(), 0, urlA);
HeapFree(GetProcessHeap(), 0, urlB);
}
typedef void (*test_t)(void); typedef void (*test_t)(void);
START_TEST(job) START_TEST(job)
@ -391,6 +467,7 @@ START_TEST(job)
test_GetState, test_GetState,
test_ResumeEmpty, test_ResumeEmpty,
test_CompleteLocal, test_CompleteLocal,
test_CompleteLocalURL,
0 0
}; };
const test_t *test; const test_t *test;