You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
377 lines
9.3 KiB
377 lines
9.3 KiB
/******************************************************************************
|
|
|
|
Copyright (c) 1999 Microsoft Corporation
|
|
|
|
Module Name:
|
|
Cabinet.cpp
|
|
|
|
Abstract:
|
|
This file contains the implementation of the CSAFCabinet class,
|
|
which implements the data collection functionality.
|
|
|
|
Revision History:
|
|
Davide Massarenti (Dmassare) 08/25/99
|
|
created
|
|
|
|
******************************************************************************/
|
|
|
|
#include "stdafx.h"
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
#define CHECK_MODIFY() __MPC_EXIT_IF_METHOD_FAILS(hr, CanModifyProperties())
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
CSAFCabinet::CSAFCabinet()
|
|
{
|
|
__HCP_FUNC_ENTRY( "CSAFCabinet::CSAFCabinet" );
|
|
|
|
// MPC::Impersonation m_imp;
|
|
//
|
|
// MPC::Cabinet m_cab;
|
|
//
|
|
m_hResult = 0; // HRESULT m_hResult;
|
|
m_cbStatus = CB_NOTACTIVE; // CB_STATUS m_cbStatus;
|
|
//
|
|
// CComPtr<IDispatch> m_sink_onProgressFiles;
|
|
// CComPtr<IDispatch> m_sink_onProgressBytes;
|
|
// CComPtr<IDispatch> m_sink_onComplete;
|
|
|
|
|
|
(void)m_cab.put_IgnoreMissingFiles( TRUE );
|
|
(void)m_cab.put_UserData ( this );
|
|
(void)m_cab.put_onProgress_Files ( fnCallback_Files );
|
|
(void)m_cab.put_onProgress_Bytes ( fnCallback_Bytes );
|
|
}
|
|
|
|
void CSAFCabinet::FinalRelease()
|
|
{
|
|
__HCP_FUNC_ENTRY( "CSAFCabinet::FinalRelease" );
|
|
|
|
(void)Abort();
|
|
|
|
Thread_Wait();
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
HRESULT CSAFCabinet::Run()
|
|
{
|
|
__HCP_FUNC_ENTRY( "CSAFCabinet::Run" );
|
|
|
|
HRESULT hr;
|
|
BOOL res;
|
|
MPC::SmartLock<_ThreadModel> lock( this );
|
|
|
|
|
|
::SetThreadPriority( ::GetCurrentThread(), THREAD_PRIORITY_LOWEST );
|
|
|
|
__MPC_TRY_BEGIN();
|
|
|
|
put_Status( CB_COMPRESSING );
|
|
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, m_imp.Impersonate());
|
|
lock = NULL;
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, m_cab.Compress());
|
|
lock = this;
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, m_imp.RevertToSelf());
|
|
|
|
|
|
put_Status( CB_COMPLETED );
|
|
hr = S_OK;
|
|
|
|
__HCP_FUNC_CLEANUP;
|
|
|
|
__MPC_TRY_CATCHALL(hr);
|
|
|
|
lock = this;
|
|
|
|
m_hResult = hr;
|
|
if(FAILED(hr))
|
|
{
|
|
put_Status( CB_FAILED );
|
|
}
|
|
|
|
//
|
|
// Release the lock on current object, otherwise a deadlock could occur.
|
|
//
|
|
lock = NULL;
|
|
|
|
Fire_onComplete( this, hr );
|
|
|
|
Thread_Abort(); // To tell the MPC:Thread object to close the worker thread...
|
|
|
|
__HCP_FUNC_EXIT(hr);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
////////////////
|
|
// //
|
|
// Properties //
|
|
// //
|
|
////////////////
|
|
|
|
STDMETHODIMP CSAFCabinet::put_IgnoreMissingFiles( /*[in]*/ VARIANT_BOOL fIgnoreMissingFiles )
|
|
{
|
|
__HCP_BEGIN_PROPERTY_PUT("CSAFCabinet::put_IgnoreMissingFiles",hr);
|
|
|
|
CHECK_MODIFY();
|
|
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, m_cab.put_IgnoreMissingFiles( fIgnoreMissingFiles == VARIANT_TRUE ));
|
|
|
|
|
|
__HCP_END_PROPERTY(hr);
|
|
}
|
|
|
|
STDMETHODIMP CSAFCabinet::put_onProgressFiles( /*[in]*/ IDispatch* function )
|
|
{
|
|
__HCP_BEGIN_PROPERTY_PUT("CSAFCabinet::put_onProgressFiles",hr);
|
|
|
|
CHECK_MODIFY();
|
|
|
|
m_sink_onProgressFiles = function;
|
|
|
|
|
|
__HCP_END_PROPERTY(hr);
|
|
}
|
|
|
|
STDMETHODIMP CSAFCabinet::put_onProgressBytes( /*[in]*/ IDispatch* function )
|
|
{
|
|
__HCP_BEGIN_PROPERTY_PUT("CSAFCabinet::put_onProgressBytes",hr);
|
|
|
|
CHECK_MODIFY();
|
|
|
|
m_sink_onProgressBytes = function;
|
|
|
|
|
|
__HCP_END_PROPERTY(hr);
|
|
}
|
|
|
|
STDMETHODIMP CSAFCabinet::put_onComplete( /*[in]*/ IDispatch* function )
|
|
{
|
|
__HCP_BEGIN_PROPERTY_PUT("CSAFCabinet::put_onComplete",hr);
|
|
|
|
CHECK_MODIFY();
|
|
|
|
m_sink_onComplete = function;
|
|
|
|
|
|
__HCP_END_PROPERTY(hr);
|
|
}
|
|
|
|
|
|
HRESULT CSAFCabinet::put_Status( /*[in]*/ CB_STATUS pVal ) // Inner method
|
|
{
|
|
__HCP_FUNC_ENTRY( "CSAFCabinet::put_Status" );
|
|
|
|
HRESULT hr;
|
|
MPC::SmartLock<_ThreadModel> lock( this );
|
|
|
|
|
|
m_cbStatus = pVal;
|
|
hr = S_OK;
|
|
|
|
|
|
__HCP_FUNC_EXIT(hr);
|
|
}
|
|
|
|
STDMETHODIMP CSAFCabinet::get_Status( /*[out]*/ CB_STATUS *pVal )
|
|
{
|
|
__HCP_BEGIN_PROPERTY_GET2("CSAFCabinet::get_Status",hr,pVal,m_cbStatus);
|
|
|
|
__HCP_END_PROPERTY(hr);
|
|
}
|
|
|
|
STDMETHODIMP CSAFCabinet::get_ErrorCode( /*[out]*/ long *pVal )
|
|
{
|
|
__HCP_BEGIN_PROPERTY_GET2("CSAFCabinet::get_ErrorCode",hr,pVal,m_hResult);
|
|
|
|
__HCP_END_PROPERTY(hr);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
STDMETHODIMP CSAFCabinet::AddFile( /*[in]*/ BSTR bstrFilePath ,
|
|
/*[in]*/ VARIANT vFileName )
|
|
{
|
|
__HCP_FUNC_ENTRY( "CSAFCabinet::AddFile" );
|
|
|
|
HRESULT hr;
|
|
MPC::SmartLock<_ThreadModel> lock( this );
|
|
LPCWSTR szFileName = (vFileName.vt == VT_BSTR ? SAFEBSTR( vFileName.bstrVal ) : L"");
|
|
|
|
__MPC_PARAMCHECK_BEGIN(hr)
|
|
__MPC_PARAMCHECK_STRING_NOT_EMPTY(bstrFilePath);
|
|
__MPC_PARAMCHECK_END();
|
|
|
|
CHECK_MODIFY();
|
|
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, m_cab.AddFile( bstrFilePath, szFileName ));
|
|
|
|
hr = S_OK;
|
|
|
|
|
|
__HCP_FUNC_CLEANUP;
|
|
|
|
__HCP_FUNC_EXIT(hr);
|
|
}
|
|
|
|
STDMETHODIMP CSAFCabinet::Compress( /*[in]*/ BSTR bstrCabinetFile )
|
|
{
|
|
__HCP_FUNC_ENTRY( "CSAFCabinet::Compress" );
|
|
|
|
HRESULT hr;
|
|
MPC::SmartLock<_ThreadModel> lock( this );
|
|
|
|
__MPC_PARAMCHECK_BEGIN(hr)
|
|
__MPC_PARAMCHECK_STRING_NOT_EMPTY(bstrCabinetFile);
|
|
__MPC_PARAMCHECK_END();
|
|
|
|
CHECK_MODIFY();
|
|
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, m_cab.put_CabinetFile( bstrCabinetFile ));
|
|
|
|
|
|
//
|
|
// Release the lock on current object, otherwise a deadlock could occur.
|
|
//
|
|
lock = NULL;
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, m_imp.Initialize());
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, Thread_Start( this, Run, NULL ));
|
|
|
|
hr = S_OK;
|
|
|
|
|
|
__HCP_FUNC_CLEANUP;
|
|
|
|
__HCP_FUNC_EXIT(hr);
|
|
}
|
|
|
|
STDMETHODIMP CSAFCabinet::Abort()
|
|
{
|
|
__HCP_FUNC_ENTRY( "CSAFCabinet::Abort" );
|
|
|
|
Thread_Abort(); // To tell the MPC:Thread object to close the worker thread...
|
|
|
|
__HCP_FUNC_EXIT(S_OK);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
//////////////////////
|
|
// //
|
|
// Callback Methods //
|
|
// //
|
|
//////////////////////
|
|
|
|
HRESULT CSAFCabinet::fnCallback_Files( MPC::Cabinet* cabinet, LPCWSTR szFile, ULONG lDone, ULONG lTotal, LPVOID user )
|
|
{
|
|
CSAFCabinet* pThis = (CSAFCabinet*)user;
|
|
HRESULT hr;
|
|
|
|
if(pThis->Thread_IsAborted())
|
|
{
|
|
hr = E_FAIL;
|
|
}
|
|
else
|
|
{
|
|
hr = pThis->Fire_onProgressFiles( pThis, CComBSTR( szFile ), lDone, lTotal );
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CSAFCabinet::fnCallback_Bytes( MPC::Cabinet* cabinet, ULONG lDone, ULONG lTotal, LPVOID user )
|
|
{
|
|
CSAFCabinet* pThis = (CSAFCabinet*)user;
|
|
HRESULT hr;
|
|
|
|
if(pThis->Thread_IsAborted())
|
|
{
|
|
hr = E_FAIL;
|
|
}
|
|
else
|
|
{
|
|
hr = pThis->Fire_onProgressBytes( pThis, lDone, lTotal );
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
//////////////////////////
|
|
// //
|
|
// Event Firing Methods //
|
|
// //
|
|
//////////////////////////
|
|
|
|
HRESULT CSAFCabinet::Fire_onProgressFiles( ISAFCabinet* hcpcb, BSTR bstrFile, long lDone, long lTotal )
|
|
{
|
|
CComVariant pvars[4];
|
|
|
|
pvars[3] = hcpcb;
|
|
pvars[2] = bstrFile;
|
|
pvars[1] = lDone;
|
|
pvars[0] = lTotal;
|
|
|
|
return FireAsync_Generic( DISPID_SAF_CBE__ONPROGRESSFILES, pvars, ARRAYSIZE( pvars ), m_sink_onProgressFiles );
|
|
}
|
|
|
|
HRESULT CSAFCabinet::Fire_onProgressBytes( ISAFCabinet* hcpcb, long lDone, long lTotal )
|
|
{
|
|
CComVariant pvars[3];
|
|
|
|
pvars[2] = hcpcb;
|
|
pvars[1] = lDone;
|
|
pvars[0] = lTotal;
|
|
|
|
return FireAsync_Generic( DISPID_SAF_CBE__ONPROGRESSBYTES, pvars, ARRAYSIZE( pvars ), m_sink_onProgressBytes );
|
|
}
|
|
|
|
HRESULT CSAFCabinet::Fire_onComplete( ISAFCabinet* hcpcb, HRESULT hrRes )
|
|
{
|
|
CComVariant pvars[2];
|
|
|
|
pvars[1] = hcpcb;
|
|
pvars[0] = hrRes;
|
|
|
|
return FireAsync_Generic( DISPID_SAF_CBE__ONCOMPLETE, pvars, ARRAYSIZE( pvars ), m_sink_onComplete );
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
/////////////////////
|
|
// //
|
|
// Utility Methods //
|
|
// //
|
|
/////////////////////
|
|
|
|
HRESULT CSAFCabinet::CanModifyProperties()
|
|
{
|
|
__HCP_FUNC_ENTRY( "CSAFCabinet::CanModifyProperties" );
|
|
|
|
HRESULT hr = E_ACCESSDENIED;
|
|
|
|
|
|
if(m_cbStatus != CB_COMPRESSING)
|
|
{
|
|
hr = S_OK;
|
|
}
|
|
|
|
|
|
__HCP_FUNC_EXIT(hr);
|
|
}
|