/****************************************************************************** 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 m_sink_onProgressFiles; // CComPtr m_sink_onProgressBytes; // CComPtr 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); }