mirror of
https://github.com/reactos/reactos.git
synced 2025-02-22 16:36:33 +00:00
[QMGR] Sync with Wine Staging 1.7.47. CORE-9924
svn path=/trunk/; revision=68490
This commit is contained in:
parent
ba989e1c40
commit
c22de4d293
9 changed files with 1022 additions and 401 deletions
|
@ -25,7 +25,7 @@ set_source_files_properties(rsrc.rc PROPERTIES OBJECT_DEPENDS ${CMAKE_CURRENT_SO
|
||||||
add_idl_headers(qmgr_idlheader qmgr_local.idl)
|
add_idl_headers(qmgr_idlheader qmgr_local.idl)
|
||||||
set_module_type(qmgr win32dll)
|
set_module_type(qmgr win32dll)
|
||||||
target_link_libraries(qmgr uuid wine)
|
target_link_libraries(qmgr uuid wine)
|
||||||
add_importlibs(qmgr ole32 wininet urlmon advapi32 msvcrt kernel32 ntdll)
|
add_importlibs(qmgr winhttp ole32 advapi32 msvcrt kernel32 ntdll)
|
||||||
add_pch(qmgr qmgr.h SOURCE)
|
add_pch(qmgr qmgr.h SOURCE)
|
||||||
add_cd_file(TARGET qmgr DESTINATION reactos/system32 FOR all)
|
add_cd_file(TARGET qmgr DESTINATION reactos/system32 FOR all)
|
||||||
add_dependencies(qmgr qmgr_idlheader)
|
add_dependencies(qmgr qmgr_idlheader)
|
||||||
|
|
|
@ -24,7 +24,7 @@ typedef struct
|
||||||
{
|
{
|
||||||
IEnumBackgroundCopyFiles IEnumBackgroundCopyFiles_iface;
|
IEnumBackgroundCopyFiles IEnumBackgroundCopyFiles_iface;
|
||||||
LONG ref;
|
LONG ref;
|
||||||
IBackgroundCopyFile **files;
|
IBackgroundCopyFile2 **files;
|
||||||
ULONG numFiles;
|
ULONG numFiles;
|
||||||
ULONG indexFiles;
|
ULONG indexFiles;
|
||||||
} EnumBackgroundCopyFilesImpl;
|
} EnumBackgroundCopyFilesImpl;
|
||||||
|
@ -72,7 +72,7 @@ static ULONG WINAPI EnumBackgroundCopyFiles_Release(IEnumBackgroundCopyFiles *if
|
||||||
if (ref == 0)
|
if (ref == 0)
|
||||||
{
|
{
|
||||||
for(i = 0; i < This->numFiles; i++)
|
for(i = 0; i < This->numFiles; i++)
|
||||||
IBackgroundCopyFile_Release(This->files[i]);
|
IBackgroundCopyFile2_Release(This->files[i]);
|
||||||
HeapFree(GetProcessHeap(), 0, This->files);
|
HeapFree(GetProcessHeap(), 0, This->files);
|
||||||
HeapFree(GetProcessHeap(), 0, This);
|
HeapFree(GetProcessHeap(), 0, This);
|
||||||
}
|
}
|
||||||
|
@ -87,7 +87,7 @@ static HRESULT WINAPI EnumBackgroundCopyFiles_Next(IEnumBackgroundCopyFiles *ifa
|
||||||
EnumBackgroundCopyFilesImpl *This = impl_from_IEnumBackgroundCopyFiles(iface);
|
EnumBackgroundCopyFilesImpl *This = impl_from_IEnumBackgroundCopyFiles(iface);
|
||||||
ULONG fetched;
|
ULONG fetched;
|
||||||
ULONG i;
|
ULONG i;
|
||||||
IBackgroundCopyFile *file;
|
IBackgroundCopyFile2 *file;
|
||||||
|
|
||||||
TRACE("(%p)->(%d %p %p)\n", This, celt, rgelt, pceltFetched);
|
TRACE("(%p)->(%d %p %p)\n", This, celt, rgelt, pceltFetched);
|
||||||
|
|
||||||
|
@ -113,8 +113,8 @@ static HRESULT WINAPI EnumBackgroundCopyFiles_Next(IEnumBackgroundCopyFiles *ifa
|
||||||
for (i = 0; i < fetched; i++)
|
for (i = 0; i < fetched; i++)
|
||||||
{
|
{
|
||||||
file = This->files[This->indexFiles++];
|
file = This->files[This->indexFiles++];
|
||||||
IBackgroundCopyFile_AddRef(file);
|
IBackgroundCopyFile2_AddRef(file);
|
||||||
rgelt[i] = file;
|
rgelt[i] = (IBackgroundCopyFile *)file;
|
||||||
}
|
}
|
||||||
|
|
||||||
return fetched == celt ? S_OK : S_FALSE;
|
return fetched == celt ? S_OK : S_FALSE;
|
||||||
|
@ -212,8 +212,8 @@ HRESULT EnumBackgroundCopyFilesConstructor(BackgroundCopyJobImpl *job, IEnumBack
|
||||||
i = 0;
|
i = 0;
|
||||||
LIST_FOR_EACH_ENTRY(file, &job->files, BackgroundCopyFileImpl, entryFromJob)
|
LIST_FOR_EACH_ENTRY(file, &job->files, BackgroundCopyFileImpl, entryFromJob)
|
||||||
{
|
{
|
||||||
IBackgroundCopyFile_AddRef(&file->IBackgroundCopyFile_iface);
|
IBackgroundCopyFile2_AddRef(&file->IBackgroundCopyFile2_iface);
|
||||||
This->files[i] = &file->IBackgroundCopyFile_iface;
|
This->files[i] = &file->IBackgroundCopyFile2_iface;
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
LeaveCriticalSection(&job->cs);
|
LeaveCriticalSection(&job->cs);
|
||||||
|
|
|
@ -24,7 +24,7 @@ typedef struct
|
||||||
{
|
{
|
||||||
IEnumBackgroundCopyJobs IEnumBackgroundCopyJobs_iface;
|
IEnumBackgroundCopyJobs IEnumBackgroundCopyJobs_iface;
|
||||||
LONG ref;
|
LONG ref;
|
||||||
IBackgroundCopyJob **jobs;
|
IBackgroundCopyJob3 **jobs;
|
||||||
ULONG numJobs;
|
ULONG numJobs;
|
||||||
ULONG indexJobs;
|
ULONG indexJobs;
|
||||||
} EnumBackgroundCopyJobsImpl;
|
} EnumBackgroundCopyJobsImpl;
|
||||||
|
@ -72,7 +72,7 @@ static ULONG WINAPI EnumBackgroundCopyJobs_Release(IEnumBackgroundCopyJobs *ifac
|
||||||
|
|
||||||
if (ref == 0) {
|
if (ref == 0) {
|
||||||
for(i = 0; i < This->numJobs; i++)
|
for(i = 0; i < This->numJobs; i++)
|
||||||
IBackgroundCopyJob_Release(This->jobs[i]);
|
IBackgroundCopyJob3_Release(This->jobs[i]);
|
||||||
HeapFree(GetProcessHeap(), 0, This->jobs);
|
HeapFree(GetProcessHeap(), 0, This->jobs);
|
||||||
HeapFree(GetProcessHeap(), 0, This);
|
HeapFree(GetProcessHeap(), 0, This);
|
||||||
}
|
}
|
||||||
|
@ -86,7 +86,7 @@ static HRESULT WINAPI EnumBackgroundCopyJobs_Next(IEnumBackgroundCopyJobs *iface
|
||||||
EnumBackgroundCopyJobsImpl *This = impl_from_IEnumBackgroundCopyJobs(iface);
|
EnumBackgroundCopyJobsImpl *This = impl_from_IEnumBackgroundCopyJobs(iface);
|
||||||
ULONG fetched;
|
ULONG fetched;
|
||||||
ULONG i;
|
ULONG i;
|
||||||
IBackgroundCopyJob *job;
|
IBackgroundCopyJob3 *job;
|
||||||
|
|
||||||
TRACE("(%p)->(%d %p %p)\n", This, celt, rgelt, pceltFetched);
|
TRACE("(%p)->(%d %p %p)\n", This, celt, rgelt, pceltFetched);
|
||||||
|
|
||||||
|
@ -109,8 +109,8 @@ static HRESULT WINAPI EnumBackgroundCopyJobs_Next(IEnumBackgroundCopyJobs *iface
|
||||||
for (i = 0; i < fetched; ++i)
|
for (i = 0; i < fetched; ++i)
|
||||||
{
|
{
|
||||||
job = This->jobs[This->indexJobs++];
|
job = This->jobs[This->indexJobs++];
|
||||||
IBackgroundCopyJob_AddRef(job);
|
IBackgroundCopyJob3_AddRef(job);
|
||||||
rgelt[i] = job;
|
rgelt[i] = (IBackgroundCopyJob *)job;
|
||||||
}
|
}
|
||||||
|
|
||||||
return fetched == celt ? S_OK : S_FALSE;
|
return fetched == celt ? S_OK : S_FALSE;
|
||||||
|
@ -210,9 +210,8 @@ HRESULT enum_copy_job_create(BackgroundCopyManagerImpl *qmgr, IEnumBackgroundCop
|
||||||
i = 0;
|
i = 0;
|
||||||
LIST_FOR_EACH_ENTRY(job, &qmgr->jobs, BackgroundCopyJobImpl, entryFromQmgr)
|
LIST_FOR_EACH_ENTRY(job, &qmgr->jobs, BackgroundCopyJobImpl, entryFromQmgr)
|
||||||
{
|
{
|
||||||
IBackgroundCopyJob *job_iface = (IBackgroundCopyJob*)&job->IBackgroundCopyJob2_iface;
|
IBackgroundCopyJob3_AddRef(&job->IBackgroundCopyJob3_iface);
|
||||||
IBackgroundCopyJob_AddRef(job_iface);
|
This->jobs[i++] = &job->IBackgroundCopyJob3_iface;
|
||||||
This->jobs[i++] = job_iface;
|
|
||||||
}
|
}
|
||||||
LeaveCriticalSection(&qmgr->cs);
|
LeaveCriticalSection(&qmgr->cs);
|
||||||
|
|
||||||
|
|
|
@ -21,56 +21,62 @@
|
||||||
#include "qmgr.h"
|
#include "qmgr.h"
|
||||||
|
|
||||||
#include <urlmon.h>
|
#include <urlmon.h>
|
||||||
#include <wininet.h>
|
#include <winhttp.h>
|
||||||
|
|
||||||
static inline BackgroundCopyFileImpl *impl_from_IBackgroundCopyFile(IBackgroundCopyFile *iface)
|
static inline BackgroundCopyFileImpl *impl_from_IBackgroundCopyFile2(
|
||||||
|
IBackgroundCopyFile2 *iface)
|
||||||
{
|
{
|
||||||
return CONTAINING_RECORD(iface, BackgroundCopyFileImpl, IBackgroundCopyFile_iface);
|
return CONTAINING_RECORD(iface, BackgroundCopyFileImpl, IBackgroundCopyFile2_iface);
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI BackgroundCopyFile_QueryInterface(
|
static HRESULT WINAPI BackgroundCopyFile_QueryInterface(
|
||||||
IBackgroundCopyFile* iface,
|
IBackgroundCopyFile2 *iface,
|
||||||
REFIID riid,
|
REFIID riid,
|
||||||
void **obj)
|
void **obj)
|
||||||
{
|
{
|
||||||
BackgroundCopyFileImpl *This = impl_from_IBackgroundCopyFile(iface);
|
BackgroundCopyFileImpl *file = impl_from_IBackgroundCopyFile2(iface);
|
||||||
|
|
||||||
TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), obj);
|
TRACE("(%p)->(%s %p)\n", file, debugstr_guid(riid), obj);
|
||||||
|
|
||||||
if (IsEqualGUID(riid, &IID_IUnknown)
|
if (IsEqualGUID(riid, &IID_IUnknown) ||
|
||||||
|| IsEqualGUID(riid, &IID_IBackgroundCopyFile))
|
IsEqualGUID(riid, &IID_IBackgroundCopyFile) ||
|
||||||
|
IsEqualGUID(riid, &IID_IBackgroundCopyFile2))
|
||||||
{
|
{
|
||||||
*obj = iface;
|
*obj = iface;
|
||||||
IBackgroundCopyFile_AddRef(iface);
|
}
|
||||||
return S_OK;
|
else
|
||||||
|
{
|
||||||
|
*obj = NULL;
|
||||||
|
return E_NOINTERFACE;
|
||||||
}
|
}
|
||||||
|
|
||||||
*obj = NULL;
|
IBackgroundCopyFile2_AddRef(iface);
|
||||||
return E_NOINTERFACE;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ULONG WINAPI BackgroundCopyFile_AddRef(IBackgroundCopyFile* iface)
|
static ULONG WINAPI BackgroundCopyFile_AddRef(
|
||||||
|
IBackgroundCopyFile2 *iface)
|
||||||
{
|
{
|
||||||
BackgroundCopyFileImpl *This = impl_from_IBackgroundCopyFile(iface);
|
BackgroundCopyFileImpl *file = impl_from_IBackgroundCopyFile2(iface);
|
||||||
ULONG ref = InterlockedIncrement(&This->ref);
|
ULONG ref = InterlockedIncrement(&file->ref);
|
||||||
TRACE("(%p)->(%d)\n", This, ref);
|
TRACE("(%p)->(%d)\n", file, ref);
|
||||||
return ref;
|
return ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ULONG WINAPI BackgroundCopyFile_Release(
|
static ULONG WINAPI BackgroundCopyFile_Release(
|
||||||
IBackgroundCopyFile* iface)
|
IBackgroundCopyFile2 *iface)
|
||||||
{
|
{
|
||||||
BackgroundCopyFileImpl *This = impl_from_IBackgroundCopyFile(iface);
|
BackgroundCopyFileImpl *file = impl_from_IBackgroundCopyFile2(iface);
|
||||||
ULONG ref = InterlockedDecrement(&This->ref);
|
ULONG ref = InterlockedDecrement(&file->ref);
|
||||||
|
|
||||||
TRACE("(%p)->(%d)\n", This, ref);
|
TRACE("(%p)->(%d)\n", file, ref);
|
||||||
|
|
||||||
if (ref == 0)
|
if (ref == 0)
|
||||||
{
|
{
|
||||||
IBackgroundCopyJob2_Release(&This->owner->IBackgroundCopyJob2_iface);
|
IBackgroundCopyJob3_Release(&file->owner->IBackgroundCopyJob3_iface);
|
||||||
HeapFree(GetProcessHeap(), 0, This->info.LocalName);
|
HeapFree(GetProcessHeap(), 0, file->info.LocalName);
|
||||||
HeapFree(GetProcessHeap(), 0, This->info.RemoteName);
|
HeapFree(GetProcessHeap(), 0, file->info.RemoteName);
|
||||||
HeapFree(GetProcessHeap(), 0, This);
|
HeapFree(GetProcessHeap(), 0, file);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ref;
|
return ref;
|
||||||
|
@ -78,52 +84,71 @@ static ULONG WINAPI BackgroundCopyFile_Release(
|
||||||
|
|
||||||
/* Get the remote name of a background copy file */
|
/* Get the remote name of a background copy file */
|
||||||
static HRESULT WINAPI BackgroundCopyFile_GetRemoteName(
|
static HRESULT WINAPI BackgroundCopyFile_GetRemoteName(
|
||||||
IBackgroundCopyFile* iface,
|
IBackgroundCopyFile2 *iface,
|
||||||
LPWSTR *pVal)
|
LPWSTR *pVal)
|
||||||
{
|
{
|
||||||
BackgroundCopyFileImpl *This = impl_from_IBackgroundCopyFile(iface);
|
BackgroundCopyFileImpl *file = impl_from_IBackgroundCopyFile2(iface);
|
||||||
|
|
||||||
TRACE("(%p)->(%p)\n", This, pVal);
|
TRACE("(%p)->(%p)\n", file, pVal);
|
||||||
|
|
||||||
return return_strval(This->info.RemoteName, pVal);
|
return return_strval(file->info.RemoteName, pVal);
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI BackgroundCopyFile_GetLocalName(
|
static HRESULT WINAPI BackgroundCopyFile_GetLocalName(
|
||||||
IBackgroundCopyFile* iface,
|
IBackgroundCopyFile2 *iface,
|
||||||
LPWSTR *pVal)
|
LPWSTR *pVal)
|
||||||
{
|
{
|
||||||
BackgroundCopyFileImpl *This = impl_from_IBackgroundCopyFile(iface);
|
BackgroundCopyFileImpl *file = impl_from_IBackgroundCopyFile2(iface);
|
||||||
|
|
||||||
TRACE("(%p)->(%p)\n", This, pVal);
|
TRACE("(%p)->(%p)\n", file, pVal);
|
||||||
|
|
||||||
return return_strval(This->info.LocalName, pVal);
|
return return_strval(file->info.LocalName, pVal);
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI BackgroundCopyFile_GetProgress(
|
static HRESULT WINAPI BackgroundCopyFile_GetProgress(
|
||||||
IBackgroundCopyFile* iface,
|
IBackgroundCopyFile2 *iface,
|
||||||
BG_FILE_PROGRESS *pVal)
|
BG_FILE_PROGRESS *pVal)
|
||||||
{
|
{
|
||||||
BackgroundCopyFileImpl *This = impl_from_IBackgroundCopyFile(iface);
|
BackgroundCopyFileImpl *file = impl_from_IBackgroundCopyFile2(iface);
|
||||||
|
|
||||||
TRACE("(%p)->(%p)\n", This, pVal);
|
TRACE("(%p)->(%p)\n", file, pVal);
|
||||||
|
|
||||||
EnterCriticalSection(&This->owner->cs);
|
EnterCriticalSection(&file->owner->cs);
|
||||||
pVal->BytesTotal = This->fileProgress.BytesTotal;
|
*pVal = file->fileProgress;
|
||||||
pVal->BytesTransferred = This->fileProgress.BytesTransferred;
|
LeaveCriticalSection(&file->owner->cs);
|
||||||
pVal->Completed = This->fileProgress.Completed;
|
|
||||||
LeaveCriticalSection(&This->owner->cs);
|
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const IBackgroundCopyFileVtbl BackgroundCopyFileVtbl =
|
static HRESULT WINAPI BackgroundCopyFile_GetFileRanges(
|
||||||
|
IBackgroundCopyFile2 *iface,
|
||||||
|
DWORD *RangeCount,
|
||||||
|
BG_FILE_RANGE **Ranges)
|
||||||
|
{
|
||||||
|
BackgroundCopyFileImpl *file = impl_from_IBackgroundCopyFile2(iface);
|
||||||
|
FIXME("(%p)->(%p %p)\n", file, RangeCount, Ranges);
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI BackgroundCopyFile_SetRemoteName(
|
||||||
|
IBackgroundCopyFile2 *iface,
|
||||||
|
LPCWSTR Val)
|
||||||
|
{
|
||||||
|
BackgroundCopyFileImpl *file = impl_from_IBackgroundCopyFile2(iface);
|
||||||
|
FIXME("(%p)->(%s)\n", file, debugstr_w(Val));
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const IBackgroundCopyFile2Vtbl BackgroundCopyFile2Vtbl =
|
||||||
{
|
{
|
||||||
BackgroundCopyFile_QueryInterface,
|
BackgroundCopyFile_QueryInterface,
|
||||||
BackgroundCopyFile_AddRef,
|
BackgroundCopyFile_AddRef,
|
||||||
BackgroundCopyFile_Release,
|
BackgroundCopyFile_Release,
|
||||||
BackgroundCopyFile_GetRemoteName,
|
BackgroundCopyFile_GetRemoteName,
|
||||||
BackgroundCopyFile_GetLocalName,
|
BackgroundCopyFile_GetLocalName,
|
||||||
BackgroundCopyFile_GetProgress
|
BackgroundCopyFile_GetProgress,
|
||||||
|
BackgroundCopyFile_GetFileRanges,
|
||||||
|
BackgroundCopyFile_SetRemoteName
|
||||||
};
|
};
|
||||||
|
|
||||||
HRESULT BackgroundCopyFileConstructor(BackgroundCopyJobImpl *owner,
|
HRESULT BackgroundCopyFileConstructor(BackgroundCopyJobImpl *owner,
|
||||||
|
@ -131,7 +156,6 @@ HRESULT BackgroundCopyFileConstructor(BackgroundCopyJobImpl *owner,
|
||||||
BackgroundCopyFileImpl **file)
|
BackgroundCopyFileImpl **file)
|
||||||
{
|
{
|
||||||
BackgroundCopyFileImpl *This;
|
BackgroundCopyFileImpl *This;
|
||||||
int n;
|
|
||||||
|
|
||||||
TRACE("(%s, %s, %p)\n", debugstr_w(remoteName), debugstr_w(localName), file);
|
TRACE("(%s, %s, %p)\n", debugstr_w(remoteName), debugstr_w(localName), file);
|
||||||
|
|
||||||
|
@ -139,47 +163,264 @@ HRESULT BackgroundCopyFileConstructor(BackgroundCopyJobImpl *owner,
|
||||||
if (!This)
|
if (!This)
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
n = (lstrlenW(remoteName) + 1) * sizeof(WCHAR);
|
This->info.RemoteName = strdupW(remoteName);
|
||||||
This->info.RemoteName = HeapAlloc(GetProcessHeap(), 0, n);
|
|
||||||
if (!This->info.RemoteName)
|
if (!This->info.RemoteName)
|
||||||
{
|
{
|
||||||
HeapFree(GetProcessHeap(), 0, This);
|
HeapFree(GetProcessHeap(), 0, This);
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
}
|
}
|
||||||
memcpy(This->info.RemoteName, remoteName, n);
|
|
||||||
|
|
||||||
n = (lstrlenW(localName) + 1) * sizeof(WCHAR);
|
This->info.LocalName = strdupW(localName);
|
||||||
This->info.LocalName = HeapAlloc(GetProcessHeap(), 0, n);
|
|
||||||
if (!This->info.LocalName)
|
if (!This->info.LocalName)
|
||||||
{
|
{
|
||||||
HeapFree(GetProcessHeap(), 0, This->info.RemoteName);
|
HeapFree(GetProcessHeap(), 0, This->info.RemoteName);
|
||||||
HeapFree(GetProcessHeap(), 0, This);
|
HeapFree(GetProcessHeap(), 0, This);
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
}
|
}
|
||||||
memcpy(This->info.LocalName, localName, n);
|
|
||||||
|
|
||||||
This->IBackgroundCopyFile_iface.lpVtbl = &BackgroundCopyFileVtbl;
|
This->IBackgroundCopyFile2_iface.lpVtbl = &BackgroundCopyFile2Vtbl;
|
||||||
This->ref = 1;
|
This->ref = 1;
|
||||||
|
|
||||||
This->fileProgress.BytesTotal = BG_SIZE_UNKNOWN;
|
This->fileProgress.BytesTotal = BG_SIZE_UNKNOWN;
|
||||||
This->fileProgress.BytesTransferred = 0;
|
This->fileProgress.BytesTransferred = 0;
|
||||||
This->fileProgress.Completed = FALSE;
|
This->fileProgress.Completed = FALSE;
|
||||||
This->owner = owner;
|
This->owner = owner;
|
||||||
IBackgroundCopyJob2_AddRef(&owner->IBackgroundCopyJob2_iface);
|
This->read_size = 0;
|
||||||
|
This->tempFileName[0] = 0;
|
||||||
|
IBackgroundCopyJob3_AddRef(&owner->IBackgroundCopyJob3_iface);
|
||||||
|
|
||||||
*file = This;
|
*file = This;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static DWORD CALLBACK copyProgressCallback(LARGE_INTEGER totalSize,
|
static HRESULT error_from_http_response(DWORD code)
|
||||||
LARGE_INTEGER totalTransferred,
|
{
|
||||||
LARGE_INTEGER streamSize,
|
switch (code)
|
||||||
LARGE_INTEGER streamTransferred,
|
{
|
||||||
DWORD streamNum,
|
case 200: return S_OK;
|
||||||
DWORD reason,
|
case 400: return BG_E_HTTP_ERROR_400;
|
||||||
HANDLE srcFile,
|
case 401: return BG_E_HTTP_ERROR_401;
|
||||||
HANDLE dstFile,
|
case 404: return BG_E_HTTP_ERROR_404;
|
||||||
LPVOID obj)
|
case 407: return BG_E_HTTP_ERROR_407;
|
||||||
|
case 414: return BG_E_HTTP_ERROR_414;
|
||||||
|
case 501: return BG_E_HTTP_ERROR_501;
|
||||||
|
case 503: return BG_E_HTTP_ERROR_503;
|
||||||
|
case 504: return BG_E_HTTP_ERROR_504;
|
||||||
|
case 505: return BG_E_HTTP_ERROR_505;
|
||||||
|
default:
|
||||||
|
FIXME("unhandled response code %u\n", code);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void CALLBACK progress_callback_http(HINTERNET handle, DWORD_PTR context, DWORD status,
|
||||||
|
LPVOID buf, DWORD buflen)
|
||||||
|
{
|
||||||
|
BackgroundCopyFileImpl *file = (BackgroundCopyFileImpl *)context;
|
||||||
|
BackgroundCopyJobImpl *job = file->owner;
|
||||||
|
|
||||||
|
TRACE("%p, %p, %x, %p, %u\n", handle, file, status, buf, buflen);
|
||||||
|
|
||||||
|
switch (status)
|
||||||
|
{
|
||||||
|
case WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE:
|
||||||
|
{
|
||||||
|
DWORD code, len, size;
|
||||||
|
|
||||||
|
size = sizeof(code);
|
||||||
|
if (WinHttpQueryHeaders(handle, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER,
|
||||||
|
NULL, &code, &size, NULL))
|
||||||
|
{
|
||||||
|
if ((job->error.code = error_from_http_response(code)))
|
||||||
|
{
|
||||||
|
EnterCriticalSection(&job->cs);
|
||||||
|
|
||||||
|
job->error.context = BG_ERROR_CONTEXT_REMOTE_FILE;
|
||||||
|
if (job->error.file) IBackgroundCopyFile2_Release(job->error.file);
|
||||||
|
job->error.file = &file->IBackgroundCopyFile2_iface;
|
||||||
|
IBackgroundCopyFile2_AddRef(job->error.file);
|
||||||
|
|
||||||
|
LeaveCriticalSection(&job->cs);
|
||||||
|
transitionJobState(job, BG_JOB_STATE_TRANSFERRING, BG_JOB_STATE_ERROR);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
EnterCriticalSection(&job->cs);
|
||||||
|
|
||||||
|
job->error.context = 0;
|
||||||
|
if (job->error.file)
|
||||||
|
{
|
||||||
|
IBackgroundCopyFile2_Release(job->error.file);
|
||||||
|
job->error.file = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
LeaveCriticalSection(&job->cs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
size = sizeof(len);
|
||||||
|
if (WinHttpQueryHeaders(handle, WINHTTP_QUERY_CONTENT_LENGTH|WINHTTP_QUERY_FLAG_NUMBER,
|
||||||
|
NULL, &len, &size, NULL))
|
||||||
|
{
|
||||||
|
file->fileProgress.BytesTotal = len;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case WINHTTP_CALLBACK_STATUS_READ_COMPLETE:
|
||||||
|
{
|
||||||
|
file->read_size = buflen;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case WINHTTP_CALLBACK_STATUS_REQUEST_ERROR:
|
||||||
|
{
|
||||||
|
WINHTTP_ASYNC_RESULT *result = (WINHTTP_ASYNC_RESULT *)buf;
|
||||||
|
job->error.code = result->dwError;
|
||||||
|
transitionJobState(job, BG_JOB_STATE_TRANSFERRING, BG_JOB_STATE_ERROR);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetEvent(job->wait);
|
||||||
|
}
|
||||||
|
|
||||||
|
static DWORD wait_for_completion(BackgroundCopyJobImpl *job)
|
||||||
|
{
|
||||||
|
HANDLE handles[2] = {job->wait, job->cancel};
|
||||||
|
DWORD error = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
switch (WaitForMultipleObjects(2, handles, FALSE, INFINITE))
|
||||||
|
{
|
||||||
|
case WAIT_OBJECT_0:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WAIT_OBJECT_0 + 1:
|
||||||
|
error = ERROR_CANCELLED;
|
||||||
|
transitionJobState(job, BG_JOB_STATE_TRANSFERRING, BG_JOB_STATE_CANCELLED);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
error = GetLastError();
|
||||||
|
transitionJobState(job, BG_JOB_STATE_TRANSFERRING, BG_JOB_STATE_ERROR);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
static UINT target_from_index(UINT index)
|
||||||
|
{
|
||||||
|
switch (index)
|
||||||
|
{
|
||||||
|
case 0: return WINHTTP_AUTH_TARGET_SERVER;
|
||||||
|
case 1: return WINHTTP_AUTH_TARGET_PROXY;
|
||||||
|
default:
|
||||||
|
ERR("unhandled index %u\n", index);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static UINT scheme_from_index(UINT index)
|
||||||
|
{
|
||||||
|
switch (index)
|
||||||
|
{
|
||||||
|
case 0: return WINHTTP_AUTH_SCHEME_BASIC;
|
||||||
|
case 1: return WINHTTP_AUTH_SCHEME_NTLM;
|
||||||
|
case 2: return WINHTTP_AUTH_SCHEME_PASSPORT;
|
||||||
|
case 3: return WINHTTP_AUTH_SCHEME_DIGEST;
|
||||||
|
case 4: return WINHTTP_AUTH_SCHEME_NEGOTIATE;
|
||||||
|
default:
|
||||||
|
ERR("unhandled index %u\n", index);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL set_request_credentials(HINTERNET req, BackgroundCopyJobImpl *job)
|
||||||
|
{
|
||||||
|
UINT i, j;
|
||||||
|
|
||||||
|
for (i = 0; i < BG_AUTH_TARGET_PROXY; i++)
|
||||||
|
{
|
||||||
|
UINT target = target_from_index(i);
|
||||||
|
for (j = 0; j < BG_AUTH_SCHEME_PASSPORT; j++)
|
||||||
|
{
|
||||||
|
UINT scheme = scheme_from_index(j);
|
||||||
|
const WCHAR *username = job->http_options.creds[i][j].Credentials.Basic.UserName;
|
||||||
|
const WCHAR *password = job->http_options.creds[i][j].Credentials.Basic.Password;
|
||||||
|
|
||||||
|
if (!username) continue;
|
||||||
|
if (!WinHttpSetCredentials(req, target, scheme, username, password, NULL)) return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL transfer_file_http(BackgroundCopyFileImpl *file, URL_COMPONENTSW *uc,
|
||||||
|
const WCHAR *tmpfile)
|
||||||
|
{
|
||||||
|
BackgroundCopyJobImpl *job = file->owner;
|
||||||
|
HANDLE handle;
|
||||||
|
HINTERNET ses, con = NULL, req = NULL;
|
||||||
|
DWORD flags = (uc->nScheme == INTERNET_SCHEME_HTTPS) ? WINHTTP_FLAG_SECURE : 0;
|
||||||
|
char buf[4096];
|
||||||
|
BOOL ret = FALSE;
|
||||||
|
|
||||||
|
transitionJobState(job, BG_JOB_STATE_QUEUED, BG_JOB_STATE_CONNECTING);
|
||||||
|
|
||||||
|
if (!(ses = WinHttpOpen(NULL, 0, NULL, NULL, WINHTTP_FLAG_ASYNC))) return FALSE;
|
||||||
|
WinHttpSetStatusCallback(ses, progress_callback_http, WINHTTP_CALLBACK_FLAG_ALL_COMPLETIONS, 0);
|
||||||
|
if (!WinHttpSetOption(ses, WINHTTP_OPTION_CONTEXT_VALUE, &file, sizeof(file))) goto done;
|
||||||
|
|
||||||
|
if (!(con = WinHttpConnect(ses, uc->lpszHostName, uc->nPort, 0))) goto done;
|
||||||
|
if (!(req = WinHttpOpenRequest(con, NULL, uc->lpszUrlPath, NULL, NULL, NULL, flags))) goto done;
|
||||||
|
if (!set_request_credentials(req, job)) goto done;
|
||||||
|
|
||||||
|
if (!(WinHttpSendRequest(req, job->http_options.headers, ~0u, NULL, 0, 0, (DWORD_PTR)file))) goto done;
|
||||||
|
if (wait_for_completion(job) || job->error.code) goto done;
|
||||||
|
|
||||||
|
if (!(WinHttpReceiveResponse(req, NULL))) goto done;
|
||||||
|
if (wait_for_completion(job) || job->error.code) goto done;
|
||||||
|
|
||||||
|
transitionJobState(job, BG_JOB_STATE_CONNECTING, BG_JOB_STATE_TRANSFERRING);
|
||||||
|
|
||||||
|
handle = CreateFileW(tmpfile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||||
|
if (handle == INVALID_HANDLE_VALUE) goto done;
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
file->read_size = 0;
|
||||||
|
if (!(ret = WinHttpReadData(req, buf, sizeof(buf), NULL))) break;
|
||||||
|
if (wait_for_completion(job) || job->error.code)
|
||||||
|
{
|
||||||
|
ret = FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!file->read_size) break;
|
||||||
|
if (!(ret = WriteFile(handle, buf, file->read_size, NULL, NULL))) break;
|
||||||
|
|
||||||
|
EnterCriticalSection(&job->cs);
|
||||||
|
file->fileProgress.BytesTransferred += file->read_size;
|
||||||
|
job->jobProgress.BytesTransferred += file->read_size;
|
||||||
|
LeaveCriticalSection(&job->cs);
|
||||||
|
}
|
||||||
|
|
||||||
|
CloseHandle(handle);
|
||||||
|
|
||||||
|
done:
|
||||||
|
WinHttpCloseHandle(req);
|
||||||
|
WinHttpCloseHandle(con);
|
||||||
|
WinHttpCloseHandle(ses);
|
||||||
|
if (!ret) DeleteFileW(tmpfile);
|
||||||
|
|
||||||
|
SetEvent(job->done);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DWORD CALLBACK progress_callback_local(LARGE_INTEGER totalSize, LARGE_INTEGER totalTransferred,
|
||||||
|
LARGE_INTEGER streamSize, LARGE_INTEGER streamTransferred,
|
||||||
|
DWORD streamNum, DWORD reason, HANDLE srcFile,
|
||||||
|
HANDLE dstFile, LPVOID obj)
|
||||||
{
|
{
|
||||||
BackgroundCopyFileImpl *file = obj;
|
BackgroundCopyFileImpl *file = obj;
|
||||||
BackgroundCopyJobImpl *job = file->owner;
|
BackgroundCopyJobImpl *job = file->owner;
|
||||||
|
@ -199,173 +440,37 @@ static DWORD CALLBACK copyProgressCallback(LARGE_INTEGER totalSize,
|
||||||
: PROGRESS_CANCEL);
|
: PROGRESS_CANCEL);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct
|
static BOOL transfer_file_local(BackgroundCopyFileImpl *file, const WCHAR *tmpname)
|
||||||
{
|
{
|
||||||
IBindStatusCallback IBindStatusCallback_iface;
|
static const WCHAR fileW[] = {'f','i','l','e',':','/','/',0};
|
||||||
BackgroundCopyFileImpl *file;
|
|
||||||
LONG ref;
|
|
||||||
} DLBindStatusCallback;
|
|
||||||
|
|
||||||
static inline DLBindStatusCallback *impl_from_IBindStatusCallback(IBindStatusCallback *iface)
|
|
||||||
{
|
|
||||||
return CONTAINING_RECORD(iface, DLBindStatusCallback, IBindStatusCallback_iface);
|
|
||||||
}
|
|
||||||
|
|
||||||
static HRESULT WINAPI DLBindStatusCallback_QueryInterface(
|
|
||||||
IBindStatusCallback *iface,
|
|
||||||
REFIID riid,
|
|
||||||
void **ppvObject)
|
|
||||||
{
|
|
||||||
DLBindStatusCallback *This = impl_from_IBindStatusCallback(iface);
|
|
||||||
|
|
||||||
if (IsEqualGUID(riid, &IID_IUnknown)
|
|
||||||
|| IsEqualGUID(riid, &IID_IBindStatusCallback))
|
|
||||||
{
|
|
||||||
*ppvObject = &This->IBindStatusCallback_iface;
|
|
||||||
IBindStatusCallback_AddRef(iface);
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
*ppvObject = NULL;
|
|
||||||
return E_NOINTERFACE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ULONG WINAPI DLBindStatusCallback_AddRef(IBindStatusCallback *iface)
|
|
||||||
{
|
|
||||||
DLBindStatusCallback *This = impl_from_IBindStatusCallback(iface);
|
|
||||||
return InterlockedIncrement(&This->ref);
|
|
||||||
}
|
|
||||||
|
|
||||||
static ULONG WINAPI DLBindStatusCallback_Release(IBindStatusCallback *iface)
|
|
||||||
{
|
|
||||||
DLBindStatusCallback *This = impl_from_IBindStatusCallback(iface);
|
|
||||||
ULONG ref = InterlockedDecrement(&This->ref);
|
|
||||||
|
|
||||||
if (ref == 0)
|
|
||||||
{
|
|
||||||
IBackgroundCopyFile_Release(&This->file->IBackgroundCopyFile_iface);
|
|
||||||
HeapFree(GetProcessHeap(), 0, This);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ref;
|
|
||||||
}
|
|
||||||
|
|
||||||
static HRESULT WINAPI DLBindStatusCallback_GetBindInfo(
|
|
||||||
IBindStatusCallback *iface,
|
|
||||||
DWORD *grfBINDF,
|
|
||||||
BINDINFO *pbindinfo)
|
|
||||||
{
|
|
||||||
return E_NOTIMPL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static HRESULT WINAPI DLBindStatusCallback_GetPriority(
|
|
||||||
IBindStatusCallback *iface,
|
|
||||||
LONG *pnPriority)
|
|
||||||
{
|
|
||||||
return E_NOTIMPL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static HRESULT WINAPI DLBindStatusCallback_OnDataAvailable(
|
|
||||||
IBindStatusCallback *iface,
|
|
||||||
DWORD grfBSCF,
|
|
||||||
DWORD dwSize,
|
|
||||||
FORMATETC *pformatetc,
|
|
||||||
STGMEDIUM *pstgmed)
|
|
||||||
{
|
|
||||||
return E_NOTIMPL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static HRESULT WINAPI DLBindStatusCallback_OnLowResource(
|
|
||||||
IBindStatusCallback *iface,
|
|
||||||
DWORD reserved)
|
|
||||||
{
|
|
||||||
return E_NOTIMPL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static HRESULT WINAPI DLBindStatusCallback_OnObjectAvailable(
|
|
||||||
IBindStatusCallback *iface,
|
|
||||||
REFIID riid,
|
|
||||||
IUnknown *punk)
|
|
||||||
{
|
|
||||||
return E_NOTIMPL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static HRESULT WINAPI DLBindStatusCallback_OnProgress(
|
|
||||||
IBindStatusCallback *iface,
|
|
||||||
ULONG progress,
|
|
||||||
ULONG progressMax,
|
|
||||||
ULONG statusCode,
|
|
||||||
LPCWSTR statusText)
|
|
||||||
{
|
|
||||||
DLBindStatusCallback *This = impl_from_IBindStatusCallback(iface);
|
|
||||||
BackgroundCopyFileImpl *file = This->file;
|
|
||||||
BackgroundCopyJobImpl *job = file->owner;
|
BackgroundCopyJobImpl *job = file->owner;
|
||||||
ULONG64 diff;
|
const WCHAR *ptr;
|
||||||
|
BOOL ret;
|
||||||
|
|
||||||
EnterCriticalSection(&job->cs);
|
transitionJobState(job, BG_JOB_STATE_QUEUED, BG_JOB_STATE_TRANSFERRING);
|
||||||
diff = (file->fileProgress.BytesTotal == BG_SIZE_UNKNOWN
|
|
||||||
? progress
|
|
||||||
: progress - file->fileProgress.BytesTransferred);
|
|
||||||
file->fileProgress.BytesTotal = progressMax ? progressMax : BG_SIZE_UNKNOWN;
|
|
||||||
file->fileProgress.BytesTransferred = progress;
|
|
||||||
job->jobProgress.BytesTransferred += diff;
|
|
||||||
LeaveCriticalSection(&job->cs);
|
|
||||||
|
|
||||||
return S_OK;
|
if (strlenW(file->info.RemoteName) > 7 && !memicmpW(file->info.RemoteName, fileW, 7))
|
||||||
}
|
ptr = file->info.RemoteName + 7;
|
||||||
|
else
|
||||||
|
ptr = file->info.RemoteName;
|
||||||
|
|
||||||
static HRESULT WINAPI DLBindStatusCallback_OnStartBinding(
|
if (!(ret = CopyFileExW(ptr, tmpname, progress_callback_local, file, NULL, 0)))
|
||||||
IBindStatusCallback *iface,
|
{
|
||||||
DWORD dwReserved,
|
WARN("Local file copy failed: error %u\n", GetLastError());
|
||||||
IBinding *pib)
|
transitionJobState(job, BG_JOB_STATE_TRANSFERRING, BG_JOB_STATE_ERROR);
|
||||||
{
|
}
|
||||||
return E_NOTIMPL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static HRESULT WINAPI DLBindStatusCallback_OnStopBinding(
|
SetEvent(job->done);
|
||||||
IBindStatusCallback *iface,
|
return ret;
|
||||||
HRESULT hresult,
|
|
||||||
LPCWSTR szError)
|
|
||||||
{
|
|
||||||
return E_NOTIMPL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const IBindStatusCallbackVtbl DLBindStatusCallback_Vtbl =
|
|
||||||
{
|
|
||||||
DLBindStatusCallback_QueryInterface,
|
|
||||||
DLBindStatusCallback_AddRef,
|
|
||||||
DLBindStatusCallback_Release,
|
|
||||||
DLBindStatusCallback_OnStartBinding,
|
|
||||||
DLBindStatusCallback_GetPriority,
|
|
||||||
DLBindStatusCallback_OnLowResource,
|
|
||||||
DLBindStatusCallback_OnProgress,
|
|
||||||
DLBindStatusCallback_OnStopBinding,
|
|
||||||
DLBindStatusCallback_GetBindInfo,
|
|
||||||
DLBindStatusCallback_OnDataAvailable,
|
|
||||||
DLBindStatusCallback_OnObjectAvailable
|
|
||||||
};
|
|
||||||
|
|
||||||
static DLBindStatusCallback *DLBindStatusCallbackConstructor(
|
|
||||||
BackgroundCopyFileImpl *file)
|
|
||||||
{
|
|
||||||
DLBindStatusCallback *This = HeapAlloc(GetProcessHeap(), 0, sizeof *This);
|
|
||||||
if (!This)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
This->IBindStatusCallback_iface.lpVtbl = &DLBindStatusCallback_Vtbl;
|
|
||||||
IBackgroundCopyFile_AddRef(&file->IBackgroundCopyFile_iface);
|
|
||||||
This->file = file;
|
|
||||||
This->ref = 1;
|
|
||||||
return This;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL processFile(BackgroundCopyFileImpl *file, BackgroundCopyJobImpl *job)
|
BOOL processFile(BackgroundCopyFileImpl *file, BackgroundCopyJobImpl *job)
|
||||||
{
|
{
|
||||||
static const WCHAR prefix[] = {'B','I','T', 0};
|
static const WCHAR prefix[] = {'B','I','T', 0};
|
||||||
DLBindStatusCallback *callbackObj;
|
WCHAR tmpDir[MAX_PATH], tmpName[MAX_PATH];
|
||||||
WCHAR tmpDir[MAX_PATH];
|
WCHAR host[MAX_PATH], path[MAX_PATH];
|
||||||
WCHAR tmpName[MAX_PATH];
|
URL_COMPONENTSW uc;
|
||||||
HRESULT hr;
|
BOOL ret;
|
||||||
|
|
||||||
if (!GetTempPathW(MAX_PATH, tmpDir))
|
if (!GetTempPathW(MAX_PATH, tmpDir))
|
||||||
{
|
{
|
||||||
|
@ -383,14 +488,6 @@ BOOL processFile(BackgroundCopyFileImpl *file, BackgroundCopyJobImpl *job)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
callbackObj = DLBindStatusCallbackConstructor(file);
|
|
||||||
if (!callbackObj)
|
|
||||||
{
|
|
||||||
ERR("Out of memory\n");
|
|
||||||
transitionJobState(job, BG_JOB_STATE_QUEUED, BG_JOB_STATE_TRANSIENT_ERROR);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
EnterCriticalSection(&job->cs);
|
EnterCriticalSection(&job->cs);
|
||||||
file->fileProgress.BytesTotal = BG_SIZE_UNKNOWN;
|
file->fileProgress.BytesTotal = BG_SIZE_UNKNOWN;
|
||||||
file->fileProgress.BytesTransferred = 0;
|
file->fileProgress.BytesTransferred = 0;
|
||||||
|
@ -402,31 +499,35 @@ BOOL processFile(BackgroundCopyFileImpl *file, BackgroundCopyJobImpl *job)
|
||||||
debugstr_w(tmpName),
|
debugstr_w(tmpName),
|
||||||
debugstr_w(file->info.LocalName));
|
debugstr_w(file->info.LocalName));
|
||||||
|
|
||||||
transitionJobState(job, BG_JOB_STATE_QUEUED, BG_JOB_STATE_TRANSFERRING);
|
uc.dwStructSize = sizeof(uc);
|
||||||
|
uc.nScheme = 0;
|
||||||
DeleteUrlCacheEntryW(file->info.RemoteName);
|
uc.lpszScheme = NULL;
|
||||||
hr = URLDownloadToFileW(NULL, file->info.RemoteName, tmpName, 0,
|
uc.dwSchemeLength = 0;
|
||||||
&callbackObj->IBindStatusCallback_iface);
|
uc.lpszUserName = NULL;
|
||||||
IBindStatusCallback_Release(&callbackObj->IBindStatusCallback_iface);
|
uc.dwUserNameLength = 0;
|
||||||
if (hr == INET_E_DOWNLOAD_FAILURE)
|
uc.lpszPassword = NULL;
|
||||||
|
uc.dwPasswordLength = 0;
|
||||||
|
uc.lpszHostName = host;
|
||||||
|
uc.dwHostNameLength = sizeof(host)/sizeof(host[0]);
|
||||||
|
uc.nPort = 0;
|
||||||
|
uc.lpszUrlPath = path;
|
||||||
|
uc.dwUrlPathLength = sizeof(path)/sizeof(path[0]);
|
||||||
|
uc.lpszExtraInfo = NULL;
|
||||||
|
uc.dwExtraInfoLength = 0;
|
||||||
|
ret = WinHttpCrackUrl(file->info.RemoteName, 0, 0, &uc);
|
||||||
|
if (!ret)
|
||||||
{
|
{
|
||||||
TRACE("URLDownload failed, trying local file copy\n");
|
TRACE("WinHttpCrackUrl failed, trying local file copy\n");
|
||||||
if (!CopyFileExW(file->info.RemoteName, tmpName, copyProgressCallback,
|
if (!transfer_file_local(file, tmpName)) return FALSE;
|
||||||
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 if (FAILED(hr))
|
else if (!transfer_file_http(file, &uc, tmpName))
|
||||||
{
|
{
|
||||||
ERR("URLDownload failed: eh 0x%08x\n", hr);
|
WARN("HTTP transfer failed\n");
|
||||||
transitionJobState(job, BG_JOB_STATE_TRANSFERRING, BG_JOB_STATE_ERROR);
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (transitionJobState(job, BG_JOB_STATE_TRANSFERRING, BG_JOB_STATE_QUEUED))
|
if (transitionJobState(job, BG_JOB_STATE_CONNECTING, BG_JOB_STATE_QUEUED) ||
|
||||||
|
transitionJobState(job, BG_JOB_STATE_TRANSFERRING, BG_JOB_STATE_QUEUED))
|
||||||
{
|
{
|
||||||
lstrcpyW(file->tempFileName, tmpName);
|
lstrcpyW(file->tempFileName, tmpName);
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -63,7 +63,7 @@ static HRESULT WINAPI BackgroundCopyManager_CreateJob(IBackgroundCopyManager *if
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
/* Add a reference to the job to job list */
|
/* Add a reference to the job to job list */
|
||||||
*ppJob = (IBackgroundCopyJob*)&job->IBackgroundCopyJob2_iface;
|
*ppJob = (IBackgroundCopyJob *)&job->IBackgroundCopyJob3_iface;
|
||||||
IBackgroundCopyJob_AddRef(*ppJob);
|
IBackgroundCopyJob_AddRef(*ppJob);
|
||||||
EnterCriticalSection(&globalMgr.cs);
|
EnterCriticalSection(&globalMgr.cs);
|
||||||
list_add_head(&globalMgr.jobs, &job->entryFromQmgr);
|
list_add_head(&globalMgr.jobs, &job->entryFromQmgr);
|
||||||
|
@ -90,8 +90,8 @@ static HRESULT WINAPI BackgroundCopyManager_GetJob(IBackgroundCopyManager *iface
|
||||||
{
|
{
|
||||||
if (IsEqualGUID(&cur->jobId, jobID))
|
if (IsEqualGUID(&cur->jobId, jobID))
|
||||||
{
|
{
|
||||||
*job = (IBackgroundCopyJob*)&cur->IBackgroundCopyJob2_iface;
|
*job = (IBackgroundCopyJob *)&cur->IBackgroundCopyJob3_iface;
|
||||||
IBackgroundCopyJob2_AddRef(&cur->IBackgroundCopyJob2_iface);
|
IBackgroundCopyJob3_AddRef(&cur->IBackgroundCopyJob3_iface);
|
||||||
hr = S_OK;
|
hr = S_OK;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -161,7 +161,7 @@ DWORD WINAPI fileTransfer(void *param)
|
||||||
LIST_FOR_EACH_ENTRY_SAFE(job, jobCur, &qmgr->jobs, BackgroundCopyJobImpl, entryFromQmgr)
|
LIST_FOR_EACH_ENTRY_SAFE(job, jobCur, &qmgr->jobs, BackgroundCopyJobImpl, entryFromQmgr)
|
||||||
{
|
{
|
||||||
list_remove(&job->entryFromQmgr);
|
list_remove(&job->entryFromQmgr);
|
||||||
IBackgroundCopyJob2_Release(&job->IBackgroundCopyJob2_iface);
|
IBackgroundCopyJob3_Release(&job->IBackgroundCopyJob3_iface);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -176,7 +176,7 @@ DWORD WINAPI fileTransfer(void *param)
|
||||||
if (job->state == BG_JOB_STATE_ACKNOWLEDGED || job->state == BG_JOB_STATE_CANCELLED)
|
if (job->state == BG_JOB_STATE_ACKNOWLEDGED || job->state == BG_JOB_STATE_CANCELLED)
|
||||||
{
|
{
|
||||||
list_remove(&job->entryFromQmgr);
|
list_remove(&job->entryFromQmgr);
|
||||||
IBackgroundCopyJob2_Release(&job->IBackgroundCopyJob2_iface);
|
IBackgroundCopyJob3_Release(&job->IBackgroundCopyJob3_iface);
|
||||||
}
|
}
|
||||||
else if (job->state == BG_JOB_STATE_QUEUED)
|
else if (job->state == BG_JOB_STATE_QUEUED)
|
||||||
{
|
{
|
||||||
|
|
|
@ -34,6 +34,8 @@
|
||||||
#include <winsvc.h>
|
#include <winsvc.h>
|
||||||
#include <objbase.h>
|
#include <objbase.h>
|
||||||
#include <bits1_5.h>
|
#include <bits1_5.h>
|
||||||
|
#include <bits2_0.h>
|
||||||
|
#include <bits2_5.h>
|
||||||
#include <bits3_0.h>
|
#include <bits3_0.h>
|
||||||
|
|
||||||
#include <wine/list.h>
|
#include <wine/list.h>
|
||||||
|
@ -45,7 +47,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(qmgr);
|
||||||
/* Background copy job vtbl and related data */
|
/* Background copy job vtbl and related data */
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
IBackgroundCopyJob2 IBackgroundCopyJob2_iface;
|
IBackgroundCopyJob3 IBackgroundCopyJob3_iface;
|
||||||
|
IBackgroundCopyJobHttpOptions IBackgroundCopyJobHttpOptions_iface;
|
||||||
LONG ref;
|
LONG ref;
|
||||||
LPWSTR displayName;
|
LPWSTR displayName;
|
||||||
LPWSTR description;
|
LPWSTR description;
|
||||||
|
@ -60,18 +63,34 @@ typedef struct
|
||||||
/* Protects file list, and progress */
|
/* Protects file list, and progress */
|
||||||
CRITICAL_SECTION cs;
|
CRITICAL_SECTION cs;
|
||||||
struct list entryFromQmgr;
|
struct list entryFromQmgr;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
WCHAR *headers;
|
||||||
|
ULONG flags;
|
||||||
|
BG_AUTH_CREDENTIALS creds[BG_AUTH_TARGET_PROXY][BG_AUTH_SCHEME_PASSPORT];
|
||||||
|
} http_options;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
BG_ERROR_CONTEXT context;
|
||||||
|
HRESULT code;
|
||||||
|
IBackgroundCopyFile2 *file;
|
||||||
|
} error;
|
||||||
|
HANDLE wait;
|
||||||
|
HANDLE cancel;
|
||||||
|
HANDLE done;
|
||||||
} BackgroundCopyJobImpl;
|
} BackgroundCopyJobImpl;
|
||||||
|
|
||||||
/* Background copy file vtbl and related data */
|
/* Background copy file vtbl and related data */
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
IBackgroundCopyFile IBackgroundCopyFile_iface;
|
IBackgroundCopyFile2 IBackgroundCopyFile2_iface;
|
||||||
LONG ref;
|
LONG ref;
|
||||||
BG_FILE_INFO info;
|
BG_FILE_INFO info;
|
||||||
BG_FILE_PROGRESS fileProgress;
|
BG_FILE_PROGRESS fileProgress;
|
||||||
WCHAR tempFileName[MAX_PATH];
|
WCHAR tempFileName[MAX_PATH];
|
||||||
struct list entryFromJob;
|
struct list entryFromJob;
|
||||||
BackgroundCopyJobImpl *owner;
|
BackgroundCopyJobImpl *owner;
|
||||||
|
DWORD read_size;
|
||||||
} BackgroundCopyFileImpl;
|
} BackgroundCopyFileImpl;
|
||||||
|
|
||||||
/* Background copy manager vtbl and related data */
|
/* Background copy manager vtbl and related data */
|
||||||
|
@ -105,14 +124,21 @@ HRESULT EnumBackgroundCopyFilesConstructor(BackgroundCopyJobImpl*, IEnumBackgrou
|
||||||
DWORD WINAPI fileTransfer(void *param) DECLSPEC_HIDDEN;
|
DWORD WINAPI fileTransfer(void *param) DECLSPEC_HIDDEN;
|
||||||
void processJob(BackgroundCopyJobImpl *job) DECLSPEC_HIDDEN;
|
void processJob(BackgroundCopyJobImpl *job) DECLSPEC_HIDDEN;
|
||||||
BOOL processFile(BackgroundCopyFileImpl *file, BackgroundCopyJobImpl *job) DECLSPEC_HIDDEN;
|
BOOL processFile(BackgroundCopyFileImpl *file, BackgroundCopyJobImpl *job) DECLSPEC_HIDDEN;
|
||||||
|
BOOL transitionJobState(BackgroundCopyJobImpl *job, BG_JOB_STATE from, BG_JOB_STATE to) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
/* Little helper functions */
|
/* Little helper functions */
|
||||||
static inline char *
|
static inline WCHAR *strdupW(const WCHAR *src)
|
||||||
qmgr_strdup(const char *s)
|
|
||||||
{
|
{
|
||||||
size_t n = strlen(s) + 1;
|
WCHAR *dst = HeapAlloc(GetProcessHeap(), 0, (strlenW(src) + 1) * sizeof(WCHAR));
|
||||||
char *d = HeapAlloc(GetProcessHeap(), 0, n);
|
if (dst) strcpyW(dst, src);
|
||||||
return d ? memcpy(d, s, n) : NULL;
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline WCHAR *co_strdupW(const WCHAR *src)
|
||||||
|
{
|
||||||
|
WCHAR *dst = CoTaskMemAlloc((strlenW(src) + 1) * sizeof(WCHAR));
|
||||||
|
if (dst) strcpyW(dst, src);
|
||||||
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline HRESULT return_strval(const WCHAR *str, WCHAR **ret)
|
static inline HRESULT return_strval(const WCHAR *str, WCHAR **ret)
|
||||||
|
@ -128,19 +154,4 @@ static inline HRESULT return_strval(const WCHAR *str, WCHAR **ret)
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
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__ */
|
#endif /* __QMGR_H__ */
|
||||||
|
|
|
@ -22,4 +22,6 @@
|
||||||
|
|
||||||
#define DO_NO_IMPORTS
|
#define DO_NO_IMPORTS
|
||||||
#include "bits1_5.idl"
|
#include "bits1_5.idl"
|
||||||
|
#include "bits2_0.idl"
|
||||||
|
#include "bits2_5.idl"
|
||||||
#include "bits3_0.idl"
|
#include "bits3_0.idl"
|
||||||
|
|
|
@ -159,7 +159,7 @@ reactos/dll/win32/powrprof # Forked at Wine-1.0rc5
|
||||||
reactos/dll/win32/printui # Synced to WineStaging-1.7.37
|
reactos/dll/win32/printui # Synced to WineStaging-1.7.37
|
||||||
reactos/dll/win32/propsys # Synced to WineStaging-1.7.37
|
reactos/dll/win32/propsys # Synced to WineStaging-1.7.37
|
||||||
reactos/dll/win32/pstorec # Synced to WineStaging-1.7.37
|
reactos/dll/win32/pstorec # Synced to WineStaging-1.7.37
|
||||||
reactos/dll/win32/qmgr # Synced to WineStaging-1.7.37
|
reactos/dll/win32/qmgr # Synced to WineStaging-1.7.47
|
||||||
reactos/dll/win32/qmgrprxy # Synced to WineStaging-1.7.37
|
reactos/dll/win32/qmgrprxy # Synced to WineStaging-1.7.37
|
||||||
reactos/dll/win32/query # Synced to WineStaging-1.7.37
|
reactos/dll/win32/query # Synced to WineStaging-1.7.37
|
||||||
reactos/dll/win32/rasapi32 # Synced to WineStaging-1.7.37
|
reactos/dll/win32/rasapi32 # Synced to WineStaging-1.7.37
|
||||||
|
|
Loading…
Reference in a new issue