qmgr: Transfer files given by URL (including HTTP, etc).
This commit is contained in:
parent
1c93ee77e5
commit
2f2b3303d7
|
@ -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 = \
|
||||||
|
|
|
@ -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,10 +244,30 @@ 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);
|
||||||
if (!CopyFileExW(file->info.RemoteName, tmpName, copyProgressCallback,
|
|
||||||
file, NULL, 0))
|
DeleteUrlCacheEntryW(file->info.RemoteName);
|
||||||
|
hr = URLDownloadToFileW(NULL, file->info.RemoteName, tmpName, 0, NULL);
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
ERR("Local file copy failed: error %d\n", GetLastError());
|
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,
|
||||||
|
file, NULL, 0))
|
||||||
|
{
|
||||||
|
ERR("Local file copy failed: error %d\n", GetLastError());
|
||||||
|
transitionJobState(job, BG_JOB_STATE_TRANSFERRING, BG_JOB_STATE_ERROR);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ERR("URLDownload failed: eh 0x%08x\n", hr);
|
||||||
transitionJobState(job, BG_JOB_STATE_TRANSFERRING, BG_JOB_STATE_ERROR);
|
transitionJobState(job, BG_JOB_STATE_TRANSFERRING, BG_JOB_STATE_ERROR);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue