1701 lines
37 KiB
C++
1701 lines
37 KiB
C++
/************************************************************************
|
|
|
|
Copyright (c) 2000 - 2000 Microsoft Corporation
|
|
|
|
Module Name :
|
|
|
|
drizcpat.cpp
|
|
|
|
Abstract :
|
|
|
|
Compatibility wrapper against the old AU bits.
|
|
|
|
Author :
|
|
|
|
Revision History :
|
|
|
|
***********************************************************************/
|
|
|
|
#include "stdafx.h"
|
|
|
|
#if !defined(BITS_V12_ON_NT4)
|
|
#include "drizcpat.tmh"
|
|
#endif
|
|
|
|
DWORD NewJobSizeToOldSize( UINT64 NewSize )
|
|
{
|
|
if ( NewSize == UINT64(-1))
|
|
return 0;
|
|
|
|
return (DWORD)NewSize;
|
|
}
|
|
|
|
DWORD MapOldNotifyToNewNotify( DWORD dwOldNotify )
|
|
{
|
|
// The mars interface has error on by default.
|
|
DWORD dwReturnVal = BG_NOTIFY_JOB_ERROR;
|
|
|
|
if ( dwOldNotify &
|
|
~( QM_NOTIFY_GROUP_DONE | QM_NOTIFY_DISABLE_NOTIFY ) )
|
|
throw ComError( E_NOTIMPL );
|
|
|
|
if ( dwOldNotify & QM_NOTIFY_GROUP_DONE )
|
|
dwReturnVal |= BG_NOTIFY_JOB_TRANSFERRED;
|
|
|
|
if ( dwOldNotify & QM_NOTIFY_DISABLE_NOTIFY )
|
|
dwReturnVal |= BG_NOTIFY_DISABLE;
|
|
|
|
return dwReturnVal;
|
|
}
|
|
|
|
DWORD MapNewNotifyToOldNotify( DWORD dwNewNotify )
|
|
{
|
|
DWORD dwReturnVal = 0;
|
|
|
|
if ( dwNewNotify & BG_NOTIFY_JOB_TRANSFERRED )
|
|
dwReturnVal |= QM_NOTIFY_GROUP_DONE;
|
|
|
|
if ( dwNewNotify & BG_NOTIFY_DISABLE )
|
|
dwReturnVal |= QM_NOTIFY_DISABLE_NOTIFY;
|
|
|
|
return dwReturnVal;
|
|
}
|
|
|
|
COldGroupInterface::COldGroupInterface(
|
|
CJob *pJob ) :
|
|
m_refs(1),
|
|
m_ServiceInstance( g_ServiceInstance ),
|
|
m_NotifyPointer( NULL ),
|
|
m_NotifyClsid( GUID_NULL ),
|
|
m_pJob(pJob),
|
|
m_pJobExternal( pJob->GetExternalInterface() )
|
|
{
|
|
m_pJobExternal->AddRef();
|
|
}
|
|
|
|
COldGroupInterface::~COldGroupInterface()
|
|
{
|
|
m_pJobExternal->Release();
|
|
}
|
|
|
|
|
|
STDMETHODIMP
|
|
COldGroupInterface::QueryInterface(
|
|
REFIID iid,
|
|
void** ppvObject
|
|
)
|
|
{
|
|
BEGIN_EXTERNAL_FUNC
|
|
|
|
LogPublicApiBegin( "iid %!guid!, ppvObject %p", &iid, ppvObject );
|
|
HRESULT Hr = S_OK;
|
|
*ppvObject = NULL;
|
|
|
|
if ((iid == _uuidof(IUnknown)) || (iid == __uuidof(IBackgroundCopyGroup)) )
|
|
{
|
|
*ppvObject = (IBackgroundCopyGroup *)this;
|
|
((IUnknown *)(*ppvObject))->AddRef();
|
|
}
|
|
else
|
|
{
|
|
Hr = E_NOINTERFACE;
|
|
}
|
|
|
|
LogPublicApiEnd( "iid %!guid!, ppvObject %p", &iid, ppvObject );
|
|
return Hr;
|
|
|
|
END_EXTERNAL_FUNC
|
|
}
|
|
|
|
ULONG _stdcall
|
|
COldGroupInterface::AddRef(void)
|
|
{
|
|
BEGIN_EXTERNAL_FUNC
|
|
|
|
ULONG newrefs = InterlockedIncrement(&m_refs);
|
|
|
|
LogRef( "job %p, refs = %d", m_pJob, newrefs );
|
|
|
|
return newrefs;
|
|
|
|
END_EXTERNAL_FUNC
|
|
}
|
|
|
|
ULONG _stdcall
|
|
COldGroupInterface::Release(void)
|
|
{
|
|
BEGIN_EXTERNAL_FUNC
|
|
|
|
ULONG newrefs = InterlockedDecrement(&m_refs);
|
|
|
|
LogRef( "job %p, refs = %d", m_pJob, newrefs );
|
|
|
|
if (newrefs == 0)
|
|
{
|
|
delete this;
|
|
}
|
|
|
|
return newrefs;
|
|
|
|
END_EXTERNAL_FUNC
|
|
}
|
|
|
|
|
|
STDMETHODIMP
|
|
COldGroupInterface::GetPropInternal(
|
|
GROUPPROP property,
|
|
VARIANT * pVal
|
|
)
|
|
{
|
|
HRESULT Hr = S_OK;
|
|
CLockedJobReadPointer LockedJob(m_pJob);
|
|
LogPublicApiBegin( "property %u, pVal %p", property, pVal );
|
|
|
|
WCHAR * pString = NULL;
|
|
|
|
try
|
|
{
|
|
ASSERT( pVal );
|
|
|
|
VariantClear( pVal );
|
|
|
|
THROW_HRESULT( LockedJob.ValidateAccess() );
|
|
|
|
switch (property)
|
|
{
|
|
case GROUPPROP_PRIORITY:
|
|
pVal->vt = VT_INT;
|
|
pVal->intVal = 1;
|
|
break;
|
|
|
|
case GROUPPROP_PROTOCOLFLAGS:
|
|
pVal->vt = VT_INT;
|
|
pVal->intVal = QM_PROTOCOL_HTTP;
|
|
break;
|
|
|
|
case GROUPPROP_NOTIFYFLAGS:
|
|
pVal->vt = VT_INT;
|
|
pVal->intVal = MapNewNotifyToOldNotify( LockedJob->GetNotifyFlags() );
|
|
break;
|
|
|
|
case GROUPPROP_NOTIFYCLSID:
|
|
{
|
|
THROW_HRESULT( StringFromIID( m_NotifyClsid, &pString ));
|
|
|
|
pVal->vt = VT_BSTR;
|
|
pVal->bstrVal = SysAllocString( pString );
|
|
|
|
if ( !pVal->bstrVal )
|
|
throw ComError( E_OUTOFMEMORY );
|
|
|
|
break;
|
|
}
|
|
|
|
case GROUPPROP_DISPLAYNAME:
|
|
{
|
|
|
|
THROW_HRESULT( LockedJob->GetDisplayName( &pString ) );
|
|
|
|
pVal->vt = VT_BSTR;
|
|
pVal->bstrVal = SysAllocString( pString );
|
|
|
|
if ( !pVal->bstrVal )
|
|
throw ComError( E_OUTOFMEMORY );
|
|
|
|
break;
|
|
}
|
|
|
|
case GROUPPROP_DESCRIPTION:
|
|
{
|
|
|
|
THROW_HRESULT( LockedJob->GetDescription( &pString ) );
|
|
|
|
pVal->vt = VT_BSTR;
|
|
pVal->bstrVal = SysAllocString( pString );
|
|
|
|
if ( !pVal->bstrVal )
|
|
throw ComError( E_OUTOFMEMORY );
|
|
|
|
break;
|
|
}
|
|
|
|
default:
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
}
|
|
catch( ComError Error )
|
|
{
|
|
Hr = Error.Error();
|
|
VariantClear( pVal );
|
|
}
|
|
|
|
CoTaskMemFree( pString );
|
|
|
|
LogPublicApiEnd( "property %u, pVal %p", property, pVal );
|
|
return Hr;
|
|
|
|
}
|
|
|
|
STDMETHODIMP
|
|
COldGroupInterface::SetPropInternal(
|
|
GROUPPROP property,
|
|
VARIANT *pvarVal
|
|
)
|
|
{
|
|
HRESULT Hr = S_OK;
|
|
CLockedJobWritePointer LockedJob(m_pJob);
|
|
LogPublicApiBegin( "property %u, Val %p", property, pvarVal );
|
|
|
|
DWORD dwValue = -1;
|
|
BSTR bstrIn = NULL;
|
|
|
|
try
|
|
{
|
|
if (!pvarVal)
|
|
throw ComError(E_INVALIDARG);
|
|
|
|
THROW_HRESULT( LockedJob.ValidateAccess() );
|
|
|
|
//
|
|
// This is how the old code did it. Unfortunate, but compatible.
|
|
//
|
|
switch (pvarVal->vt)
|
|
{
|
|
case VT_I4:
|
|
dwValue = (DWORD)(pvarVal->lVal < 0) ? -1 : pvarVal->lVal;
|
|
break;
|
|
case VT_I2:
|
|
dwValue = (DWORD)(pvarVal->iVal < 0) ? -1 : pvarVal->iVal;
|
|
break;
|
|
case VT_UI2:
|
|
dwValue = (DWORD)pvarVal->uiVal;
|
|
break;
|
|
case VT_UI4:
|
|
dwValue = (DWORD)pvarVal->ulVal;
|
|
break;
|
|
case VT_INT:
|
|
dwValue = (DWORD)(pvarVal->intVal < 0) ? -1 : pvarVal->intVal;
|
|
break;
|
|
case VT_UINT:
|
|
dwValue = (DWORD)pvarVal->uintVal;
|
|
break;
|
|
case VT_BSTR:
|
|
bstrIn = pvarVal->bstrVal;
|
|
break;
|
|
default:
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
switch (property)
|
|
{
|
|
case GROUPPROP_PRIORITY:
|
|
//
|
|
// Only one priority was supported. No need to store it.
|
|
//
|
|
if (dwValue != 1)
|
|
{
|
|
throw ComError( E_NOTIMPL );
|
|
}
|
|
break;
|
|
|
|
case GROUPPROP_PROTOCOLFLAGS:
|
|
|
|
//
|
|
// Only HTTP was supported. No need to store it.
|
|
//
|
|
if (dwValue != QM_PROTOCOL_HTTP)
|
|
{
|
|
throw ComError( E_NOTIMPL );
|
|
}
|
|
break;
|
|
|
|
case GROUPPROP_NOTIFYFLAGS:
|
|
|
|
THROW_HRESULT( LockedJob->SetNotifyFlags( MapOldNotifyToNewNotify( dwValue ) ) );
|
|
break;
|
|
|
|
case GROUPPROP_NOTIFYCLSID:
|
|
{
|
|
if (NULL == bstrIn)
|
|
{
|
|
throw ComError( E_INVALIDARG );
|
|
}
|
|
|
|
GUID clsid;
|
|
THROW_HRESULT( IIDFromString( bstrIn, &clsid ) );
|
|
|
|
m_NotifyClsid = clsid;
|
|
break;
|
|
}
|
|
|
|
case GROUPPROP_DISPLAYNAME:
|
|
THROW_HRESULT( LockedJob->SetDisplayName( (WCHAR *)bstrIn ) );
|
|
break;
|
|
|
|
case GROUPPROP_DESCRIPTION:
|
|
THROW_HRESULT( LockedJob->SetDescription( (WCHAR *)bstrIn ) );
|
|
break;
|
|
|
|
default:
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
}
|
|
catch( ComError Error )
|
|
{
|
|
Hr = Error.Error();
|
|
}
|
|
|
|
LogPublicApiEnd( "property %u, pVal %p", property, pvarVal );
|
|
return Hr;
|
|
|
|
}
|
|
|
|
STDMETHODIMP
|
|
COldGroupInterface::GetProgressInternal(
|
|
DWORD flags,
|
|
DWORD * pProgress
|
|
)
|
|
{
|
|
|
|
HRESULT Hr = S_OK;
|
|
CLockedJobReadPointer LockedJob(m_pJob);
|
|
LogPublicApiBegin( "flags %u", flags );
|
|
|
|
try
|
|
{
|
|
|
|
ASSERT( pProgress );
|
|
THROW_HRESULT( LockedJob.ValidateAccess() );
|
|
|
|
BG_JOB_PROGRESS JobProgress;
|
|
LockedJob->GetProgress( &JobProgress );
|
|
|
|
switch( flags )
|
|
{
|
|
case QM_PROGRESS_SIZE_DONE:
|
|
{
|
|
|
|
*pProgress = NewJobSizeToOldSize( JobProgress.BytesTransferred );
|
|
break;
|
|
}
|
|
|
|
case QM_PROGRESS_PERCENT_DONE:
|
|
{
|
|
|
|
if ( ( -1 == JobProgress.BytesTotal ) ||
|
|
( -1 == JobProgress.BytesTransferred ) ||
|
|
( 0 == JobProgress.BytesTotal ) )
|
|
{
|
|
*pProgress = 0;
|
|
}
|
|
else
|
|
{
|
|
double ratio = double(JobProgress.BytesTransferred) / double(JobProgress.BytesTotal );
|
|
*pProgress = DWORD( ratio * 100.0 );
|
|
}
|
|
break;
|
|
}
|
|
|
|
default:
|
|
{
|
|
throw ComError( E_NOTIMPL );
|
|
}
|
|
}
|
|
}
|
|
catch( ComError Error )
|
|
{
|
|
Hr = Error.Error();
|
|
*pProgress = 0;
|
|
}
|
|
|
|
LogPublicApiEnd( "progress %d", *pProgress );
|
|
return Hr;
|
|
}
|
|
|
|
STDMETHODIMP
|
|
COldGroupInterface::GetStatusInternal(
|
|
DWORD *pdwStatus,
|
|
DWORD *pdwJobIndex)
|
|
{
|
|
|
|
HRESULT Hr = S_OK;
|
|
CLockedJobReadPointer LockedJob(m_pJob);
|
|
LogPublicApiBegin( "pdwStatus %p, pdwJobIndex %p", pdwStatus, pdwJobIndex );
|
|
|
|
try
|
|
{
|
|
ASSERT( pdwStatus && pdwJobIndex );
|
|
*pdwStatus = *pdwJobIndex = 0;
|
|
|
|
THROW_HRESULT( LockedJob.ValidateAccess() );
|
|
|
|
// Note: we never increment the JobIndex anymore
|
|
|
|
BG_JOB_STATE State = LockedJob->_GetState();
|
|
BG_JOB_PRIORITY Priority = LockedJob->_GetPriority();
|
|
|
|
if ( BG_JOB_PRIORITY_FOREGROUND == Priority )
|
|
*pdwStatus |= QM_STATUS_GROUP_FOREGROUND;
|
|
|
|
switch( State )
|
|
{
|
|
case BG_JOB_STATE_QUEUED:
|
|
case BG_JOB_STATE_CONNECTING:
|
|
case BG_JOB_STATE_TRANSFERRING:
|
|
*pdwStatus |= QM_STATUS_GROUP_INCOMPLETE;
|
|
break;
|
|
|
|
case BG_JOB_STATE_SUSPENDED:
|
|
*pdwStatus |= ( QM_STATUS_GROUP_SUSPENDED | QM_STATUS_GROUP_INCOMPLETE );
|
|
break;
|
|
|
|
case BG_JOB_STATE_ERROR:
|
|
*pdwStatus |= ( QM_STATUS_GROUP_ERROR | QM_STATUS_GROUP_INCOMPLETE | QM_STATUS_GROUP_SUSPENDED );
|
|
break;
|
|
|
|
case BG_JOB_STATE_TRANSIENT_ERROR:
|
|
*pdwStatus |= ( QM_STATUS_GROUP_INCOMPLETE );
|
|
break;
|
|
|
|
case BG_JOB_STATE_TRANSFERRED:
|
|
*pdwStatus |= ( QM_STATUS_GROUP_COMPLETE | QM_STATUS_GROUP_SUSPENDED );
|
|
break;
|
|
|
|
case BG_JOB_STATE_ACKNOWLEDGED:
|
|
*pdwStatus |= ( QM_STATUS_GROUP_COMPLETE | QM_STATUS_GROUP_SUSPENDED );
|
|
break;
|
|
|
|
case BG_JOB_STATE_CANCELLED:
|
|
break;
|
|
}
|
|
|
|
}
|
|
catch( ComError Error )
|
|
{
|
|
Hr = Error.Error();
|
|
*pdwStatus = 0;
|
|
}
|
|
|
|
LogPublicApiEnd( "pdwStatus %p, pdwJobIndex %p", pdwStatus, pdwJobIndex );
|
|
return Hr;
|
|
|
|
}
|
|
|
|
STDMETHODIMP
|
|
COldGroupInterface::GetJobInternal(
|
|
GUID jobID,
|
|
IBackgroundCopyJob1 **ppJob)
|
|
{
|
|
|
|
HRESULT Hr = S_OK;
|
|
CLockedJobReadPointer LockedJob(m_pJob);
|
|
LogPublicApiBegin( "jobID %!guid!, ppJob %p", &jobID, ppJob );
|
|
|
|
try
|
|
{
|
|
ASSERT( ppJob );
|
|
*ppJob = NULL;
|
|
|
|
THROW_HRESULT( LockedJob.ValidateAccess() );
|
|
|
|
COldJobInterface *pOldJob = m_pJob->GetOldExternalJobInterface();
|
|
|
|
if (!pOldJob)
|
|
throw ComError( QM_E_ITEM_NOT_FOUND );
|
|
|
|
if (jobID != pOldJob->GetOldJobId() )
|
|
throw ComError( QM_E_ITEM_NOT_FOUND );
|
|
|
|
*ppJob = pOldJob;
|
|
(*ppJob)->AddRef();
|
|
|
|
}
|
|
catch( ComError Error )
|
|
{
|
|
Hr = Error.Error();
|
|
}
|
|
|
|
LogPublicApiEnd( "jobID %!guid!, ppJob %p", &jobID, ppJob );
|
|
return Hr;
|
|
|
|
}
|
|
|
|
STDMETHODIMP
|
|
COldGroupInterface::SuspendGroupInternal(
|
|
)
|
|
{
|
|
|
|
HRESULT Hr = S_OK;
|
|
CLockedJobWritePointer LockedJob(m_pJob);
|
|
LogPublicApiBegin( "void" );
|
|
|
|
try
|
|
{
|
|
THROW_HRESULT( LockedJob.ValidateAccess() );
|
|
THROW_HRESULT( LockedJob->Suspend() );
|
|
}
|
|
catch( ComError Error )
|
|
{
|
|
Hr = Error.Error();
|
|
}
|
|
|
|
LogPublicApiEnd( "void" );
|
|
return Hr;
|
|
}
|
|
|
|
STDMETHODIMP
|
|
COldGroupInterface::ResumeGroupInternal(
|
|
)
|
|
{
|
|
HRESULT Hr = S_OK;
|
|
CLockedJobWritePointer LockedJob(m_pJob);
|
|
LogPublicApiBegin( " " );
|
|
|
|
try
|
|
{
|
|
THROW_HRESULT( LockedJob.ValidateAccess() );
|
|
|
|
THROW_HRESULT( LockedJob->Resume() );
|
|
}
|
|
catch( ComError Error )
|
|
{
|
|
Hr = Error.Error();
|
|
}
|
|
|
|
LogPublicApiEnd( " " );
|
|
return Hr;
|
|
}
|
|
|
|
STDMETHODIMP
|
|
COldGroupInterface::CancelGroupInternal(
|
|
)
|
|
{
|
|
HRESULT Hr = S_OK;
|
|
CLockedJobWritePointer LockedJob(m_pJob);
|
|
LogPublicApiBegin( " " );
|
|
|
|
try
|
|
{
|
|
THROW_HRESULT( LockedJob.ValidateAccess() );
|
|
THROW_HRESULT( LockedJob->Complete() );
|
|
}
|
|
catch( ComError Error )
|
|
{
|
|
Hr = Error.Error();
|
|
}
|
|
|
|
LogPublicApiEnd( " " );
|
|
return Hr;
|
|
}
|
|
|
|
STDMETHODIMP
|
|
COldGroupInterface::get_SizeInternal(
|
|
DWORD *pdwSize
|
|
)
|
|
{
|
|
|
|
HRESULT Hr = S_OK;
|
|
CLockedJobReadPointer LockedJob(m_pJob);
|
|
LogPublicApiBegin( " " );
|
|
|
|
try
|
|
{
|
|
ASSERT( pdwSize );
|
|
|
|
THROW_HRESULT( LockedJob.ValidateAccess() );
|
|
|
|
BG_JOB_PROGRESS Progress;
|
|
LockedJob->GetProgress( &Progress );
|
|
|
|
*pdwSize = NewJobSizeToOldSize( Progress.BytesTotal );
|
|
}
|
|
catch( ComError Error )
|
|
{
|
|
Hr = Error.Error();
|
|
*pdwSize = 0;
|
|
}
|
|
|
|
|
|
LogPublicApiEnd( "dwSize %d", *pdwSize );
|
|
return Hr;
|
|
}
|
|
|
|
STDMETHODIMP
|
|
COldGroupInterface::get_GroupIDInternal(
|
|
GUID *pguidGroupID )
|
|
{
|
|
|
|
HRESULT Hr = S_OK;
|
|
CLockedJobReadPointer LockedJob(m_pJob);
|
|
LogPublicApiBegin( " " );
|
|
|
|
try
|
|
{
|
|
ASSERT( pguidGroupID );
|
|
|
|
THROW_HRESULT( LockedJob.ValidateAccess() );
|
|
|
|
*pguidGroupID = LockedJob->GetId();
|
|
|
|
}
|
|
catch( ComError Error )
|
|
{
|
|
Hr = Error.Error();
|
|
memset( pguidGroupID, 0 , sizeof(*pguidGroupID) );
|
|
}
|
|
|
|
LogPublicApiEnd( "id %!guid!", pguidGroupID );
|
|
return Hr;
|
|
|
|
}
|
|
|
|
STDMETHODIMP
|
|
COldGroupInterface::CreateJobInternal(
|
|
GUID guidJobID,
|
|
IBackgroundCopyJob1 **ppJob )
|
|
{
|
|
|
|
HRESULT Hr = S_OK;
|
|
CLockedJobWritePointer LockedJob(m_pJob);
|
|
LogPublicApiBegin( "guidJobID %!guid!", &guidJobID );
|
|
|
|
try
|
|
{
|
|
ASSERT( ppJob );
|
|
*ppJob = NULL;
|
|
|
|
THROW_HRESULT( LockedJob.ValidateAccess() );
|
|
|
|
BG_JOB_STATE State = LockedJob->_GetState();
|
|
switch( State )
|
|
{
|
|
|
|
case BG_JOB_STATE_QUEUED:
|
|
case BG_JOB_STATE_CONNECTING:
|
|
case BG_JOB_STATE_TRANSFERRING:
|
|
throw ComError( QM_E_INVALID_STATE );
|
|
break;
|
|
|
|
case BG_JOB_STATE_SUSPENDED:
|
|
case BG_JOB_STATE_ERROR:
|
|
break;
|
|
|
|
case BG_JOB_STATE_TRANSIENT_ERROR:
|
|
case BG_JOB_STATE_TRANSFERRED:
|
|
case BG_JOB_STATE_ACKNOWLEDGED:
|
|
case BG_JOB_STATE_CANCELLED:
|
|
throw ComError( QM_E_INVALID_STATE );
|
|
break;
|
|
|
|
default:
|
|
throw ComError( QM_E_INVALID_STATE );
|
|
break;
|
|
}
|
|
|
|
if (LockedJob->GetOldExternalJobInterface())
|
|
throw ComError( E_NOTIMPL );
|
|
|
|
COldJobInterface *pOldJob = new COldJobInterface( guidJobID, m_pJob );
|
|
|
|
LockedJob->SetOldExternalJobInterface( pOldJob );
|
|
|
|
*ppJob = pOldJob;
|
|
(*ppJob)->AddRef();
|
|
|
|
g_Manager->Serialize();
|
|
|
|
}
|
|
catch( ComError Error )
|
|
{
|
|
Hr = Error.Error();
|
|
}
|
|
|
|
LogPublicApiEnd( "ppJob %p", *ppJob );
|
|
return Hr;
|
|
}
|
|
|
|
STDMETHODIMP
|
|
COldGroupInterface::EnumJobsInternal(
|
|
DWORD dwFlags,
|
|
IEnumBackgroundCopyJobs1 **ppEnumJobs )
|
|
{
|
|
|
|
HRESULT Hr = S_OK;
|
|
CLockedJobReadPointer LockedJob(m_pJob);
|
|
LogPublicApiBegin( "dwFlags %u, ppEnumJobs %p", dwFlags, ppEnumJobs );
|
|
|
|
CEnumOldJobs* pEnum = NULL;
|
|
try
|
|
{
|
|
ASSERT( ppEnumJobs );
|
|
*ppEnumJobs = NULL;
|
|
|
|
THROW_HRESULT( LockedJob.ValidateAccess() );
|
|
|
|
if (dwFlags)
|
|
throw ComError( E_NOTIMPL );
|
|
|
|
pEnum = new CEnumOldJobs;
|
|
|
|
COldJobInterface *pOldJob = LockedJob->GetOldExternalJobInterface();
|
|
if (pOldJob)
|
|
{
|
|
GUID guid = pOldJob->GetOldJobId();
|
|
pEnum->Add( guid );
|
|
}
|
|
|
|
*ppEnumJobs = pEnum;
|
|
|
|
}
|
|
catch( ComError Error )
|
|
{
|
|
Hr = Error.Error();
|
|
}
|
|
|
|
LogPublicApiEnd( "dwFlags %u, ppEnumJobs %p", dwFlags, ppEnumJobs );
|
|
return Hr;
|
|
|
|
}
|
|
|
|
STDMETHODIMP
|
|
COldGroupInterface::SwitchToForegroundInternal(
|
|
)
|
|
{
|
|
|
|
HRESULT Hr = S_OK;
|
|
CLockedJobWritePointer LockedJob(m_pJob);
|
|
LogPublicApiBegin( " " );
|
|
|
|
try
|
|
{
|
|
THROW_HRESULT( LockedJob.ValidateAccess() );
|
|
|
|
THROW_HRESULT( LockedJob->SetPriority( BG_JOB_PRIORITY_FOREGROUND ) );
|
|
}
|
|
catch( ComError Error )
|
|
{
|
|
Hr = Error.Error();
|
|
}
|
|
|
|
LogPublicApiEnd( " " );
|
|
return Hr;
|
|
|
|
}
|
|
|
|
STDMETHODIMP
|
|
COldGroupInterface::QueryNewJobInterface(
|
|
REFIID iid,
|
|
IUnknown **pUnk
|
|
)
|
|
{
|
|
LogInfo("QueryNewJobInterface %!guid!", &iid);
|
|
|
|
if (iid != __uuidof(IBackgroundCopyJob))
|
|
{
|
|
LogError("E_NOTIMPL");
|
|
*pUnk = NULL;
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
*pUnk = m_pJob->GetExternalInterface();
|
|
(*pUnk)->AddRef();
|
|
|
|
LogInfo("OK");
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP
|
|
COldGroupInterface::SetNotificationPointer(
|
|
REFIID iid,
|
|
IUnknown *pUnk
|
|
)
|
|
{
|
|
HRESULT Hr = S_OK;
|
|
|
|
IBackgroundCopyCallback1 *pICB = NULL;
|
|
|
|
LogPublicApiBegin( "IID %!guid! ptr %p", &iid, pUnk );
|
|
|
|
if (iid != __uuidof(IBackgroundCopyCallback1))
|
|
{
|
|
Hr = E_NOTIMPL;
|
|
}
|
|
else if ( pUnk )
|
|
{
|
|
try
|
|
{
|
|
CNestedImpersonation imp;
|
|
|
|
//
|
|
// Gotta do it twice, because SwitchToLogonToken will fail
|
|
// if the user is not interactively logged in.
|
|
//
|
|
THROW_HRESULT( SetStaticCloaking( pUnk ) );
|
|
|
|
imp.SwitchToLogonToken();
|
|
|
|
THROW_HRESULT( SetStaticCloaking( pUnk ) );
|
|
|
|
THROW_HRESULT( pUnk->QueryInterface( iid, (void**)&pICB ) );
|
|
|
|
THROW_HRESULT( SetStaticCloaking( pICB ) );
|
|
|
|
SafeRelease( m_NotifyPointer );
|
|
|
|
m_NotifyPointer = pICB;
|
|
}
|
|
catch( ComError Error )
|
|
{
|
|
SafeRelease( pICB );
|
|
Hr = Error.Error();
|
|
}
|
|
}
|
|
|
|
LogPublicApiEnd( " " );
|
|
|
|
return Hr;
|
|
}
|
|
|
|
IBackgroundCopyCallback1 *
|
|
COldGroupInterface::GetNotificationPointer()
|
|
{
|
|
if (m_NotifyPointer)
|
|
{
|
|
m_NotifyPointer->AddRef();
|
|
}
|
|
|
|
return m_NotifyPointer;
|
|
}
|
|
|
|
|
|
void
|
|
COldGroupInterface::Serialize(
|
|
HANDLE hFile
|
|
)
|
|
{
|
|
SafeWriteFile( hFile, m_NotifyClsid );
|
|
|
|
if ( m_pJob->GetOldExternalJobInterface() )
|
|
{
|
|
SafeWriteFile( hFile, (bool)true );
|
|
m_pJob->GetOldExternalJobInterface()->Serialize( hFile );
|
|
}
|
|
else
|
|
{
|
|
SafeWriteFile( hFile, (bool)false );
|
|
}
|
|
return;
|
|
}
|
|
|
|
COldGroupInterface *
|
|
COldGroupInterface::UnSerialize(
|
|
HANDLE hFile,
|
|
CJob* Job
|
|
)
|
|
{
|
|
COldGroupInterface * group = NULL;
|
|
|
|
try
|
|
{
|
|
group = new COldGroupInterface(Job);
|
|
if (!group)
|
|
{
|
|
throw ComError( E_OUTOFMEMORY );
|
|
}
|
|
|
|
SafeReadFile( hFile, &group->m_NotifyClsid );
|
|
|
|
bool bHasOldExternalJobInterface;
|
|
|
|
SafeReadFile( hFile, &bHasOldExternalJobInterface );
|
|
|
|
if ( bHasOldExternalJobInterface )
|
|
{
|
|
COldJobInterface *OldJobInterface = COldJobInterface::Unserialize( hFile, Job );
|
|
Job->SetOldExternalJobInterface( OldJobInterface );
|
|
}
|
|
|
|
}
|
|
catch ( ComError Error )
|
|
{
|
|
delete group;
|
|
throw;
|
|
}
|
|
|
|
return group;
|
|
}
|
|
|
|
COldJobInterface::COldJobInterface(
|
|
GUID JobGuid,
|
|
CJob *pJob ) :
|
|
m_refs(1),
|
|
m_ServiceInstance( g_ServiceInstance ),
|
|
m_OldJobGuid( JobGuid ),
|
|
m_pJob( pJob ),
|
|
m_pJobExternal( pJob->GetExternalInterface() )
|
|
{
|
|
m_pJobExternal->AddRef();
|
|
}
|
|
|
|
COldJobInterface::~COldJobInterface()
|
|
{
|
|
m_pJobExternal->Release();
|
|
}
|
|
|
|
STDMETHODIMP
|
|
COldJobInterface::QueryInterface(
|
|
REFIID iid,
|
|
void** ppvObject
|
|
)
|
|
{
|
|
BEGIN_EXTERNAL_FUNC
|
|
|
|
LogPublicApiBegin( "iid %!guid!, ppvObject %p", &iid, ppvObject );
|
|
HRESULT Hr = S_OK;
|
|
*ppvObject = NULL;
|
|
|
|
if ((iid == _uuidof(IUnknown)) || (iid == __uuidof(IBackgroundCopyJob1)) )
|
|
{
|
|
*ppvObject = (IBackgroundCopyJob1 *)this;
|
|
((IUnknown *)(*ppvObject))->AddRef();
|
|
}
|
|
else
|
|
{
|
|
Hr = E_NOINTERFACE;
|
|
}
|
|
|
|
LogPublicApiEnd( "iid %!guid!, ppvObject %p", &iid, ppvObject );
|
|
return Hr;
|
|
|
|
END_EXTERNAL_FUNC
|
|
}
|
|
|
|
ULONG _stdcall
|
|
COldJobInterface::AddRef(void)
|
|
{
|
|
BEGIN_EXTERNAL_FUNC
|
|
|
|
ULONG newrefs = InterlockedIncrement(&m_refs);
|
|
|
|
LogRef( "job %p, refs = %d", m_pJob, newrefs );
|
|
|
|
return newrefs;
|
|
|
|
END_EXTERNAL_FUNC
|
|
}
|
|
|
|
ULONG _stdcall
|
|
COldJobInterface::Release(void)
|
|
{
|
|
BEGIN_EXTERNAL_FUNC
|
|
|
|
ULONG newrefs = InterlockedDecrement(&m_refs);
|
|
|
|
LogRef( "job %p, refs = %d", m_pJob, newrefs );
|
|
|
|
if (newrefs == 0)
|
|
{
|
|
delete this;
|
|
}
|
|
|
|
return newrefs;
|
|
|
|
END_EXTERNAL_FUNC
|
|
}
|
|
|
|
|
|
STDMETHODIMP
|
|
COldJobInterface::AddFilesInternal(
|
|
ULONG cFileCount,
|
|
FILESETINFO **ppFileSet
|
|
)
|
|
{
|
|
HRESULT Hr = S_OK;
|
|
CLockedJobWritePointer LockedJob(m_pJob);
|
|
LogPublicApiBegin( "cFileCount %u, ppFileSet %p", cFileCount, ppFileSet );
|
|
|
|
BG_FILE_INFO *pFileInfo = NULL;
|
|
|
|
try
|
|
{
|
|
ASSERT( ppFileSet );
|
|
|
|
THROW_HRESULT( LockedJob.ValidateAccess() );
|
|
|
|
pFileInfo = new BG_FILE_INFO[cFileCount];
|
|
if (!pFileInfo )
|
|
{
|
|
throw ComError(E_OUTOFMEMORY);
|
|
}
|
|
|
|
for(ULONG c = 0; c < cFileCount; c++ )
|
|
{
|
|
if ( !ppFileSet[c])
|
|
throw ComError(E_INVALIDARG);
|
|
|
|
// BSTRS act like WCHAR *
|
|
pFileInfo[c].LocalName = LPWSTR( (ppFileSet[c])->bstrLocalFile );
|
|
pFileInfo[c].RemoteName = LPWSTR( (ppFileSet[c])->bstrRemoteFile );
|
|
|
|
}
|
|
|
|
THROW_HRESULT( LockedJob->AddFileSet( cFileCount,
|
|
pFileInfo ) );
|
|
|
|
}
|
|
catch(ComError Error )
|
|
{
|
|
Hr = Error.Error();
|
|
}
|
|
|
|
// Should handle NULL
|
|
delete[] pFileInfo;
|
|
|
|
LogPublicApiEnd( "cFileCount %u, ppFileSet %p", cFileCount, ppFileSet );
|
|
return Hr;
|
|
}
|
|
|
|
STDMETHODIMP
|
|
COldJobInterface::GetFileCountInternal(
|
|
DWORD * pCount
|
|
)
|
|
{
|
|
HRESULT Hr = S_OK;
|
|
CLockedJobReadPointer LockedJob(m_pJob);
|
|
LogPublicApiBegin( "pCount %p", pCount );
|
|
|
|
try
|
|
{
|
|
ASSERT( pCount );
|
|
|
|
THROW_HRESULT( LockedJob.ValidateAccess() );
|
|
|
|
BG_JOB_PROGRESS JobProgress;
|
|
LockedJob->GetProgress( &JobProgress );
|
|
|
|
*pCount = JobProgress.FilesTotal;
|
|
|
|
}
|
|
catch(ComError Error )
|
|
{
|
|
Hr = Error.Error();
|
|
*pCount = 0;
|
|
}
|
|
|
|
LogPublicApiEnd( "pCount %p", pCount );
|
|
return Hr;
|
|
|
|
}
|
|
|
|
STDMETHODIMP
|
|
COldJobInterface::GetFileInternal(
|
|
ULONG cFileIndex,
|
|
FILESETINFO *pFileInfo
|
|
)
|
|
{
|
|
HRESULT Hr = S_OK;
|
|
CLockedJobReadPointer LockedJob(m_pJob);
|
|
LogPublicApiBegin( "cFileIndex %u, pFileInfo %p", cFileIndex, pFileInfo );
|
|
|
|
WCHAR *pLocalName = NULL;
|
|
WCHAR *pRemoteName = NULL;
|
|
try
|
|
{
|
|
|
|
ASSERT( pFileInfo );
|
|
memset( pFileInfo, 0, sizeof(FILESETINFO) );
|
|
|
|
THROW_HRESULT( LockedJob.ValidateAccess() );
|
|
|
|
CFile *pFile = LockedJob->_GetFileIndex( cFileIndex );
|
|
if (!pFile)
|
|
throw ComError ( QM_E_ITEM_NOT_FOUND );
|
|
|
|
|
|
THROW_HRESULT( pFile->GetLocalName( &pLocalName ) );
|
|
THROW_HRESULT( pFile->GetRemoteName( &pRemoteName ) );
|
|
|
|
pFileInfo->bstrLocalFile = SysAllocString( pLocalName );
|
|
pFileInfo->bstrRemoteFile = SysAllocString( pRemoteName );
|
|
|
|
if ( !pFileInfo->bstrLocalFile ||
|
|
!pFileInfo->bstrRemoteFile )
|
|
throw ComError( E_OUTOFMEMORY );
|
|
|
|
BG_FILE_PROGRESS FileProgress;
|
|
pFile->GetProgress( &FileProgress );
|
|
|
|
pFileInfo->dwSizeHint = NewJobSizeToOldSize( FileProgress.BytesTotal );
|
|
|
|
}
|
|
catch ( ComError Error )
|
|
{
|
|
Hr = Error.Error();
|
|
|
|
if ( pFileInfo )
|
|
{
|
|
SysFreeString( pFileInfo->bstrLocalFile );
|
|
SysFreeString( pFileInfo->bstrRemoteFile );
|
|
memset( pFileInfo, 0, sizeof(FILESETINFO) );
|
|
}
|
|
}
|
|
|
|
// CoTaskMemFree handles NULL
|
|
CoTaskMemFree( pLocalName );
|
|
CoTaskMemFree( pRemoteName );
|
|
|
|
LogPublicApiEnd( "cFileIndex %u, pFileInfo %p", cFileIndex, pFileInfo );
|
|
return Hr;
|
|
}
|
|
|
|
STDMETHODIMP
|
|
COldJobInterface::CancelJobInternal()
|
|
{
|
|
HRESULT Hr = E_NOTIMPL;
|
|
LogPublicApiBegin( "void" );
|
|
LogPublicApiEnd( "void" );
|
|
return Hr;
|
|
}
|
|
|
|
|
|
STDMETHODIMP
|
|
COldJobInterface::get_JobIDInternal(
|
|
GUID * pId
|
|
)
|
|
{
|
|
HRESULT Hr = S_OK;
|
|
CLockedJobReadPointer LockedJob(m_pJob);
|
|
LogPublicApiBegin( "pId %p", pId );
|
|
|
|
try
|
|
{
|
|
ASSERT( pId );
|
|
THROW_HRESULT( LockedJob.ValidateAccess() );
|
|
|
|
*pId = GetOldJobId();
|
|
}
|
|
catch(ComError Error )
|
|
{
|
|
Hr = Error.Error();
|
|
memset( pId, 0, sizeof(*pId) );
|
|
}
|
|
|
|
LogPublicApiEnd( "pId %p", pId );
|
|
return Hr;
|
|
}
|
|
|
|
|
|
|
|
STDMETHODIMP
|
|
COldJobInterface::GetProgressInternal(
|
|
DWORD flags,
|
|
DWORD * pProgress
|
|
)
|
|
{
|
|
HRESULT Hr = S_OK;
|
|
CLockedJobReadPointer LockedJob(m_pJob);
|
|
LogPublicApiBegin( "flags %u, pProgress %p", flags, pProgress );
|
|
|
|
try
|
|
{
|
|
|
|
ASSERT( pProgress );
|
|
*pProgress = NULL;
|
|
|
|
THROW_HRESULT( LockedJob.ValidateAccess() );
|
|
|
|
BG_JOB_PROGRESS JobProgress;
|
|
LockedJob->GetProgress( &JobProgress );
|
|
|
|
switch (flags)
|
|
{
|
|
case QM_PROGRESS_SIZE_DONE:
|
|
{
|
|
|
|
*pProgress = NewJobSizeToOldSize( JobProgress.BytesTransferred );
|
|
break;
|
|
}
|
|
|
|
case QM_PROGRESS_PERCENT_DONE:
|
|
{
|
|
|
|
if ( ( -1 == JobProgress.BytesTotal ) ||
|
|
( -1 == JobProgress.BytesTransferred ) ||
|
|
( 0 == JobProgress.BytesTotal ) )
|
|
{
|
|
*pProgress = 0;
|
|
}
|
|
else
|
|
{
|
|
double ratio = double(JobProgress.BytesTransferred) / double(JobProgress.BytesTotal );
|
|
*pProgress = DWORD( ratio * 100.0 );
|
|
}
|
|
break;
|
|
}
|
|
|
|
default:
|
|
{
|
|
throw ComError( E_NOTIMPL );
|
|
}
|
|
}
|
|
|
|
}
|
|
catch( ComError Error )
|
|
{
|
|
Hr = Error.Error();
|
|
}
|
|
|
|
LogPublicApiEnd( "flags %u, pProgress %p", flags, pProgress );
|
|
return Hr;
|
|
}
|
|
|
|
STDMETHODIMP
|
|
COldJobInterface::SwitchToForegroundInternal()
|
|
{
|
|
|
|
HRESULT Hr = S_OK;
|
|
CLockedJobWritePointer LockedJob(m_pJob);
|
|
LogPublicApiBegin( "void" );
|
|
|
|
try
|
|
{
|
|
THROW_HRESULT( LockedJob.ValidateAccess() );
|
|
Hr = E_NOTIMPL;
|
|
}
|
|
catch( ComError Error )
|
|
{
|
|
Hr = Error.Error();
|
|
}
|
|
|
|
LogPublicApiEnd( "void" );
|
|
return Hr;
|
|
}
|
|
|
|
STDMETHODIMP
|
|
COldJobInterface::GetStatusInternal(
|
|
DWORD *pdwStatus,
|
|
DWORD *pdwWin32Result,
|
|
DWORD *pdwTransportResult,
|
|
DWORD *pdwNumOfRetries
|
|
)
|
|
{
|
|
|
|
HRESULT Hr = S_OK;
|
|
CLockedJobReadPointer LockedJob(m_pJob);
|
|
LogPublicApiBegin( "pdwStatus %p, pdwWin32Result %p, pdwTransportResult %p, pdwNumOfRetries %p",
|
|
pdwStatus, pdwWin32Result, pdwTransportResult, pdwNumOfRetries );
|
|
|
|
try
|
|
{
|
|
ASSERT( pdwStatus && pdwWin32Result &&
|
|
pdwTransportResult && pdwNumOfRetries );
|
|
|
|
*pdwStatus = *pdwWin32Result = *pdwTransportResult = *pdwNumOfRetries = 0;
|
|
|
|
THROW_HRESULT( LockedJob.ValidateAccess() );
|
|
|
|
BG_JOB_PRIORITY Priority = LockedJob->_GetPriority();
|
|
BG_JOB_STATE State = LockedJob->_GetState();
|
|
|
|
THROW_HRESULT( LockedJob->GetErrorCount( pdwNumOfRetries ) );
|
|
|
|
if ( BG_JOB_PRIORITY_FOREGROUND == Priority )
|
|
*pdwStatus |= QM_STATUS_JOB_FOREGROUND;
|
|
|
|
switch( State )
|
|
{
|
|
case BG_JOB_STATE_QUEUED:
|
|
case BG_JOB_STATE_CONNECTING:
|
|
case BG_JOB_STATE_TRANSFERRING:
|
|
*pdwStatus |= QM_STATUS_JOB_INCOMPLETE;
|
|
break;
|
|
case BG_JOB_STATE_SUSPENDED:
|
|
*pdwStatus |= QM_STATUS_JOB_INCOMPLETE;
|
|
break;
|
|
case BG_JOB_STATE_ERROR:
|
|
*pdwStatus |= QM_STATUS_JOB_ERROR;
|
|
break;
|
|
case BG_JOB_STATE_TRANSIENT_ERROR:
|
|
*pdwStatus |= QM_STATUS_JOB_INCOMPLETE;
|
|
break;
|
|
case BG_JOB_STATE_TRANSFERRED:
|
|
*pdwStatus |= QM_STATUS_JOB_COMPLETE;
|
|
break;
|
|
case BG_JOB_STATE_ACKNOWLEDGED:
|
|
*pdwStatus |= QM_STATUS_JOB_COMPLETE;
|
|
break;
|
|
case BG_JOB_STATE_CANCELLED:
|
|
break;
|
|
default:
|
|
ASSERT(0);
|
|
break;
|
|
}
|
|
|
|
if ( BG_JOB_STATE_ERROR == State )
|
|
{
|
|
|
|
const CJobError * pError = LockedJob->GetError();
|
|
|
|
ASSERT( pError );
|
|
|
|
if ( pError )
|
|
{
|
|
pError->GetOldInterfaceErrors( pdwWin32Result, pdwTransportResult );
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
catch( ComError Error )
|
|
{
|
|
Hr = Error.Error();
|
|
|
|
*pdwStatus = 0;
|
|
*pdwWin32Result = 0;
|
|
*pdwTransportResult = 0;
|
|
*pdwNumOfRetries = 0;
|
|
}
|
|
|
|
LogPublicApiEnd( "pdwStatus %p, pdwWin32Result %p, pdwTransportResult %p, pdwNumOfRetries %p",
|
|
pdwStatus, pdwWin32Result, pdwTransportResult, pdwNumOfRetries );
|
|
return Hr;
|
|
}
|
|
|
|
void
|
|
COldJobInterface::Serialize(
|
|
HANDLE hFile
|
|
)
|
|
{
|
|
SafeWriteFile( hFile, m_OldJobGuid );
|
|
}
|
|
|
|
COldJobInterface *
|
|
COldJobInterface::Unserialize(
|
|
HANDLE hFile,
|
|
CJob* Job
|
|
)
|
|
{
|
|
COldJobInterface * OldJob = NULL;
|
|
|
|
try
|
|
{
|
|
GUID OldJobGuid;
|
|
SafeReadFile( hFile, &OldJobGuid );
|
|
OldJob = new COldJobInterface( OldJobGuid, Job );
|
|
if (!OldJob)
|
|
{
|
|
throw ComError( E_OUTOFMEMORY );
|
|
}
|
|
}
|
|
catch ( ComError Error )
|
|
{
|
|
delete OldJob;
|
|
throw;
|
|
}
|
|
|
|
return OldJob;
|
|
}
|
|
|
|
COldQmgrInterface::COldQmgrInterface() :
|
|
m_refs(1),
|
|
m_ServiceInstance( g_ServiceInstance )
|
|
{
|
|
}
|
|
|
|
|
|
STDMETHODIMP
|
|
COldQmgrInterface::QueryInterface(
|
|
REFIID iid,
|
|
void** ppvObject
|
|
)
|
|
{
|
|
BEGIN_EXTERNAL_FUNC
|
|
|
|
LogPublicApiBegin( "iid %!guid!, ppvObject %p", &iid, ppvObject );
|
|
HRESULT Hr = S_OK;
|
|
*ppvObject = NULL;
|
|
|
|
if ((iid == _uuidof(IUnknown)) || (iid == __uuidof(IBackgroundCopyQMgr)) )
|
|
{
|
|
*ppvObject = (IBackgroundCopyQMgr *)this;
|
|
((IUnknown *)(*ppvObject))->AddRef();
|
|
}
|
|
else if ( iid == __uuidof(IClassFactory) )
|
|
{
|
|
*ppvObject = (IClassFactory *)this;
|
|
((IUnknown *)(*ppvObject))->AddRef();
|
|
}
|
|
else
|
|
{
|
|
Hr = E_NOINTERFACE;
|
|
}
|
|
|
|
LogPublicApiEnd( "iid %!guid!, ppvObject %p", &iid, ppvObject );
|
|
return Hr;
|
|
|
|
END_EXTERNAL_FUNC
|
|
}
|
|
|
|
ULONG _stdcall
|
|
COldQmgrInterface::AddRef(void)
|
|
{
|
|
BEGIN_EXTERNAL_FUNC
|
|
|
|
ULONG newrefs = InterlockedIncrement(&m_refs);
|
|
|
|
LogRef( "new refs = %d", newrefs );
|
|
|
|
return newrefs;
|
|
|
|
END_EXTERNAL_FUNC
|
|
}
|
|
|
|
ULONG _stdcall
|
|
COldQmgrInterface::Release(void)
|
|
{
|
|
BEGIN_EXTERNAL_FUNC
|
|
|
|
ULONG newrefs = InterlockedDecrement(&m_refs);
|
|
|
|
LogRef( "new refs = %d", newrefs );
|
|
|
|
if (newrefs == 0)
|
|
{
|
|
delete this;
|
|
}
|
|
|
|
return newrefs;
|
|
|
|
END_EXTERNAL_FUNC
|
|
}
|
|
|
|
STDMETHODIMP
|
|
COldQmgrInterface::CreateInstance(
|
|
IUnknown * pUnkOuter,
|
|
REFIID riid,
|
|
void ** ppvObject )
|
|
{
|
|
|
|
BEGIN_EXTERNAL_FUNC
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
if (g_ServiceInstance != m_ServiceInstance ||
|
|
g_ServiceState != MANAGER_ACTIVE)
|
|
{
|
|
hr = CO_E_SERVER_STOPPING;
|
|
}
|
|
else if (pUnkOuter != NULL)
|
|
{
|
|
hr = CLASS_E_NOAGGREGATION;
|
|
}
|
|
else
|
|
{
|
|
if ((riid == IID_IBackgroundCopyQMgr) || (riid == IID_IUnknown))
|
|
{
|
|
hr = QueryInterface(riid, ppvObject);
|
|
}
|
|
else
|
|
{
|
|
// BUGBUG why this error coed?
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
}
|
|
return hr;
|
|
|
|
END_EXTERNAL_FUNC
|
|
|
|
}
|
|
|
|
STDMETHODIMP
|
|
COldQmgrInterface::LockServer(
|
|
BOOL fLock
|
|
)
|
|
{
|
|
BEGIN_EXTERNAL_FUNC
|
|
|
|
return GlobalLockServer( fLock );
|
|
|
|
END_EXTERNAL_FUNC
|
|
}
|
|
|
|
STDMETHODIMP
|
|
COldQmgrInterface::CreateGroupInternal(
|
|
GUID id,
|
|
IBackgroundCopyGroup **ppGroup
|
|
)
|
|
{
|
|
HRESULT Hr = S_OK;
|
|
CLockedJobManagerWritePointer LockedJobManager( m_pJobManager );
|
|
LogPublicApiBegin( "id %!guid!", &id );
|
|
|
|
CJob *job = NULL;
|
|
|
|
//
|
|
// create the job
|
|
//
|
|
try
|
|
{
|
|
|
|
THROW_HRESULT( LockedJobManager.ValidateAccess() );
|
|
|
|
ASSERT( ppGroup );
|
|
|
|
const WCHAR *DisplayName = L"";
|
|
CLSID *CallbackClass = NULL;
|
|
BG_JOB_TYPE Type = BG_JOB_TYPE_DOWNLOAD;
|
|
|
|
THROW_HRESULT( LockedJobManager->CreateJob( DisplayName,
|
|
Type,
|
|
id,
|
|
GetThreadClientSid(),
|
|
&job,
|
|
true
|
|
));
|
|
|
|
THROW_HRESULT( job->SetNotifyFlags( MapOldNotifyToNewNotify(0) ) );
|
|
|
|
*ppGroup = ( IBackgroundCopyGroup * )job->GetOldExternalGroupInterface();
|
|
ASSERT( *ppGroup );
|
|
|
|
(*ppGroup)->AddRef();
|
|
|
|
}
|
|
|
|
catch( ComError exception )
|
|
{
|
|
Hr = exception.Error();
|
|
|
|
if ( job )
|
|
job->Cancel();
|
|
}
|
|
|
|
LogPublicApiEnd( "id %!guid!, group %p", &id, *ppGroup );
|
|
return Hr;
|
|
}
|
|
|
|
|
|
STDMETHODIMP
|
|
COldQmgrInterface::GetGroupInternal(
|
|
GUID id,
|
|
IBackgroundCopyGroup ** ppGroup
|
|
)
|
|
{
|
|
HRESULT Hr = S_OK;
|
|
CLockedJobManagerWritePointer LockedJobManager( m_pJobManager );
|
|
LogPublicApiBegin( "id %!guid!", &id );
|
|
|
|
CJob *pJob = NULL;
|
|
|
|
try
|
|
{
|
|
ASSERT( ppGroup );
|
|
*ppGroup = NULL;
|
|
|
|
THROW_HRESULT( LockedJobManager.ValidateAccess() );
|
|
|
|
Hr = LockedJobManager->GetJob( id, &pJob );
|
|
|
|
if (FAILED(Hr))
|
|
{
|
|
if (Hr == BG_E_NOT_FOUND)
|
|
{
|
|
Hr = QM_E_ITEM_NOT_FOUND;
|
|
}
|
|
|
|
throw ComError( Hr );
|
|
}
|
|
|
|
COldGroupInterface *pOldGroup = pJob->GetOldExternalGroupInterface();
|
|
if ( !pOldGroup )
|
|
throw ComError( QM_E_ITEM_NOT_FOUND );
|
|
|
|
// try to take ownership of the job/group
|
|
// this should suceed even if we are the current owner
|
|
|
|
THROW_HRESULT( pJob->AssignOwnership( GetThreadClientSid() ) );
|
|
|
|
pOldGroup->AddRef();
|
|
|
|
*ppGroup = (IBackgroundCopyGroup*)pOldGroup;
|
|
}
|
|
catch( ComError Error )
|
|
{
|
|
Hr = Error.Error();
|
|
}
|
|
|
|
LogPublicApiEnd( "id %!guid!, group %p", &id, *ppGroup );
|
|
return Hr;
|
|
|
|
}
|
|
|
|
STDMETHODIMP
|
|
COldQmgrInterface::EnumGroupsInternal(
|
|
DWORD flags,
|
|
IEnumBackgroundCopyGroups **ppEnum
|
|
)
|
|
{
|
|
|
|
HRESULT Hr = S_OK;
|
|
CLockedJobManagerWritePointer LockedJobManager( m_pJobManager );
|
|
LogPublicApiBegin( "flags %u, ppEnum %p", flags, ppEnum );
|
|
|
|
CEnumOldGroups *pEnum = NULL;
|
|
|
|
try
|
|
{
|
|
|
|
ASSERT( ppEnum );
|
|
*ppEnum = NULL;
|
|
|
|
THROW_HRESULT( LockedJobManager.ValidateAccess() );
|
|
|
|
if (flags)
|
|
{
|
|
LogWarning( "rejecting nonzero dwFlags");
|
|
throw ComError( E_NOTIMPL );
|
|
}
|
|
|
|
pEnum = new CEnumOldGroups;
|
|
|
|
for (CJobList::iterator iter = LockedJobManager->m_OnlineJobs.begin();
|
|
iter != LockedJobManager->m_OnlineJobs.end();
|
|
++iter)
|
|
{
|
|
|
|
Hr = (*iter).IsVisible();
|
|
if (FAILED(Hr))
|
|
{
|
|
throw ComError( Hr );
|
|
}
|
|
|
|
if (Hr == S_FALSE)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// Skip jobs that were not created with the old interface.
|
|
if (!(*iter).GetOldExternalGroupInterface())
|
|
{
|
|
continue;
|
|
}
|
|
|
|
GUID guid = (*iter).GetId();
|
|
pEnum->Add( guid );
|
|
}
|
|
|
|
*ppEnum = pEnum;
|
|
}
|
|
catch( ComError Error )
|
|
{
|
|
Hr = Error.Error();
|
|
delete pEnum;
|
|
}
|
|
|
|
LogPublicApiEnd( "flags %u, ppEnum %p", flags, ppEnum );
|
|
return Hr;
|
|
|
|
}
|