qmgr: Implement IBackgroundCopyError.

This commit is contained in:
Hans Leidekker 2015-06-05 10:35:09 +02:00 committed by Alexandre Julliard
parent 6aeeddbad7
commit 69175fa9e1
3 changed files with 226 additions and 5 deletions

View File

@ -424,13 +424,53 @@ static HRESULT WINAPI http_negotiate_BeginningTransaction(
return E_NOTIMPL;
}
static HRESULT error_from_http_response(DWORD code)
{
switch (code)
{
case 200: return S_OK;
case 400: return BG_E_HTTP_ERROR_400;
case 401: return BG_E_HTTP_ERROR_401;
case 404: return BG_E_HTTP_ERROR_404;
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 HRESULT WINAPI http_negotiate_OnResponse(
IHttpNegotiate *iface, DWORD code, LPCWSTR resp_headers, LPCWSTR req_headers, LPWSTR *add_reqheaders)
{
DLBindStatusCallback *callback = impl_from_IHttpNegotiate(iface);
FIXME("(%p)->(%d %s %s %p)\n", callback, code, debugstr_w(resp_headers), debugstr_w(req_headers),
BackgroundCopyJobImpl *job = callback->file->owner;
TRACE("(%p)->(%d %s %s %p)\n", callback, code, debugstr_w(resp_headers), debugstr_w(req_headers),
add_reqheaders);
return E_NOTIMPL;
if ((job->error.code = error_from_http_response(code)))
{
job->error.context = BG_ERROR_CONTEXT_REMOTE_FILE;
if (job->error.file) IBackgroundCopyFile2_Release(job->error.file);
job->error.file = &callback->file->IBackgroundCopyFile2_iface;
IBackgroundCopyFile2_AddRef(job->error.file);
}
else
{
job->error.context = 0;
if (job->error.file)
{
IBackgroundCopyFile2_Release(job->error.file);
job->error.file = NULL;
}
}
*add_reqheaders = NULL;
return S_OK;
}
static const IHttpNegotiateVtbl http_negotiate_vtbl =
@ -523,6 +563,12 @@ BOOL processFile(BackgroundCopyFileImpl *file, BackgroundCopyJobImpl *job)
transitionJobState(job, BG_JOB_STATE_TRANSFERRING, BG_JOB_STATE_ERROR);
return FALSE;
}
else if (job->error.code)
{
ERR("transfer error: 0x%08x\n", job->error.code);
transitionJobState(job, BG_JOB_STATE_TRANSFERRING, BG_JOB_STATE_ERROR);
return FALSE;
}
if (transitionJobState(job, BG_JOB_STATE_TRANSFERRING, BG_JOB_STATE_QUEUED))
{

View File

@ -27,6 +27,167 @@
WINE_DEFAULT_DEBUG_CHANNEL(qmgr);
struct copy_error
{
IBackgroundCopyError IBackgroundCopyError_iface;
LONG refs;
BG_ERROR_CONTEXT context;
HRESULT code;
IBackgroundCopyFile2 *file;
};
static inline struct copy_error *impl_from_IBackgroundCopyError(IBackgroundCopyError *iface)
{
return CONTAINING_RECORD(iface, struct copy_error, IBackgroundCopyError_iface);
}
static HRESULT WINAPI copy_error_QueryInterface(
IBackgroundCopyError *iface,
REFIID riid,
void **obj)
{
struct copy_error *error = impl_from_IBackgroundCopyError(iface);
TRACE("(%p)->(%s %p)\n", error, debugstr_guid(riid), obj);
if (IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IBackgroundCopyError))
{
*obj = &error->IBackgroundCopyError_iface;
}
else
{
*obj = NULL;
WARN("interface %s not supported\n", debugstr_guid(riid));
return E_NOINTERFACE;
}
IBackgroundCopyError_AddRef(iface);
return S_OK;
}
static ULONG WINAPI copy_error_AddRef(
IBackgroundCopyError *iface)
{
struct copy_error *error = impl_from_IBackgroundCopyError(iface);
LONG refs = InterlockedIncrement(&error->refs);
TRACE("(%p)->(%d)\n", error, refs);
return refs;
}
static ULONG WINAPI copy_error_Release(
IBackgroundCopyError *iface)
{
struct copy_error *error = impl_from_IBackgroundCopyError(iface);
LONG refs = InterlockedDecrement(&error->refs);
TRACE("(%p)->(%d)\n", error, refs);
if (!refs)
{
if (error->file) IBackgroundCopyFile2_Release(error->file);
HeapFree(GetProcessHeap(), 0, error);
}
return refs;
}
static HRESULT WINAPI copy_error_GetError(
IBackgroundCopyError *iface,
BG_ERROR_CONTEXT *pContext,
HRESULT *pCode)
{
struct copy_error *error = impl_from_IBackgroundCopyError(iface);
TRACE("(%p)->(%p %p)\n", error, pContext, pCode);
*pContext = error->context;
*pCode = error->code;
TRACE("returning context %u error code 0x%08x\n", error->context, error->code);
return S_OK;
}
static HRESULT WINAPI copy_error_GetFile(
IBackgroundCopyError *iface,
IBackgroundCopyFile **pVal)
{
struct copy_error *error = impl_from_IBackgroundCopyError(iface);
TRACE("(%p)->(%p)\n", error, pVal);
if (error->file)
{
IBackgroundCopyFile2_AddRef(error->file);
*pVal = (IBackgroundCopyFile *)error->file;
return S_OK;
}
*pVal = NULL;
return BG_E_FILE_NOT_AVAILABLE;
}
static HRESULT WINAPI copy_error_GetErrorDescription(
IBackgroundCopyError *iface,
DWORD LanguageId,
LPWSTR *pErrorDescription)
{
struct copy_error *error = impl_from_IBackgroundCopyError(iface);
FIXME("(%p)->(%p)\n", error, pErrorDescription);
return E_NOTIMPL;
}
static HRESULT WINAPI copy_error_GetErrorContextDescription(
IBackgroundCopyError *iface,
DWORD LanguageId,
LPWSTR *pContextDescription)
{
struct copy_error *error = impl_from_IBackgroundCopyError(iface);
FIXME("(%p)->(%p)\n", error, pContextDescription);
return E_NOTIMPL;
}
static HRESULT WINAPI copy_error_GetProtocol(
IBackgroundCopyError *iface,
LPWSTR *pProtocol)
{
struct copy_error *error = impl_from_IBackgroundCopyError(iface);
FIXME("(%p)->(%p)\n", error, pProtocol);
return E_NOTIMPL;
}
static const IBackgroundCopyErrorVtbl copy_error_vtbl =
{
copy_error_QueryInterface,
copy_error_AddRef,
copy_error_Release,
copy_error_GetError,
copy_error_GetFile,
copy_error_GetErrorDescription,
copy_error_GetErrorContextDescription,
copy_error_GetProtocol
};
static HRESULT create_copy_error(
BG_ERROR_CONTEXT context,
HRESULT code,
IBackgroundCopyFile2 *file,
IBackgroundCopyError **obj)
{
struct copy_error *error;
TRACE("context %u code %08x file %p\n", context, code, file);
if (!(error = HeapAlloc(GetProcessHeap(), 0, sizeof(*error) ))) return E_OUTOFMEMORY;
error->IBackgroundCopyError_iface.lpVtbl = &copy_error_vtbl;
error->refs = 1;
error->context = context;
error->code = code;
error->file = file;
if (error->file) IBackgroundCopyFile2_AddRef(error->file);
*obj = &error->IBackgroundCopyError_iface;
TRACE("returning iface %p\n", *obj);
return S_OK;
}
static inline BOOL is_job_done(const BackgroundCopyJobImpl *job)
{
return job->state == BG_JOB_STATE_CANCELLED || job->state == BG_JOB_STATE_ACKNOWLEDGED;
@ -312,9 +473,13 @@ static HRESULT WINAPI BackgroundCopyJob_GetError(
IBackgroundCopyJob3 *iface,
IBackgroundCopyError **ppError)
{
BackgroundCopyJobImpl *This = impl_from_IBackgroundCopyJob3(iface);
FIXME("(%p)->(%p): stub\n", This, ppError);
return E_NOTIMPL;
BackgroundCopyJobImpl *job = impl_from_IBackgroundCopyJob3(iface);
TRACE("(%p)->(%p)\n", job, ppError);
if (!job->error.context) return BG_E_ERROR_INFORMATION_UNAVAILABLE;
return create_copy_error(job->error.context, job->error.code, job->error.file, ppError);
}
static HRESULT WINAPI BackgroundCopyJob_GetOwner(
@ -788,6 +953,10 @@ HRESULT BackgroundCopyJobConstructor(LPCWSTR displayName, BG_JOB_TYPE type, GUID
This->callback = NULL;
This->callback2 = FALSE;
This->error.context = 0;
This->error.code = 0;
This->error.file = NULL;
*job = This;
TRACE("created job %s:%p\n", debugstr_guid(&This->jobId), This);

View File

@ -51,6 +51,12 @@ typedef struct
/* Protects file list, and progress */
CRITICAL_SECTION cs;
struct list entryFromQmgr;
struct
{
BG_ERROR_CONTEXT context;
HRESULT code;
IBackgroundCopyFile2 *file;
} error;
} BackgroundCopyJobImpl;
/* Background copy file vtbl and related data */