|
|
#include "stdafx.h"
#include "dccsink.h"
//#include "findleak.h"
#ifdef ATTEMPT_DEVICE_CONNECTION_NOTIFICATION
#include "cewmdmdbt.h"
#endif
#define SAFE_CLOSEHANDLE(h) CloseHandle((h))
//DECLARE_THIS_FILE;
//
// Construction/Destruction
//
CDCCSink::CDCCSink() : m_hThread(NULL), m_hThreadEvent(NULL), m_dwThreadId(0), m_dwDccSink(-1), m_hrRapi( 0 ) { }
HRESULT CDCCSink::Initialize() { HRESULT hr = S_OK;
m_hThreadEvent = CreateEvent(NULL, FALSE, FALSE, NULL ); if( NULL == m_hThreadEvent ) { hr = HRESULT_FROM_WIN32( GetLastError() ); }
if( SUCCEEDED( hr ) ) { m_hThread = CreateThread( NULL, 0, CreateDCCManProc, this, 0, &m_dwThreadId );
if( NULL == m_hThread ) { hr = HRESULT_FROM_WIN32( GetLastError() ); } }
if( SUCCEEDED( hr ) ) { if( WAIT_OBJECT_0 != WaitForSingleObject( m_hThreadEvent, INFINITE ) ) { hr = E_FAIL; } else { hr = m_hrRapi; } }
return( hr ); }
void CDCCSink::FinalRelease() { if( m_hThread ) { SAFE_CLOSEHANDLE( m_hThread ); }
if( m_hThreadEvent ) { SAFE_CLOSEHANDLE( m_hThreadEvent ); } }
//
// IDccManSink
//
STDMETHODIMP CDCCSink::OnLogActive ( void ) { m_hrRapi = CeRapiInit();
return( S_OK ); }
STDMETHODIMP CDCCSink::OnLogAnswered ( void ) { return( S_OK ); }
STDMETHODIMP CDCCSink::OnLogDisconnection ( void ) { DeviceDisconnected(); return( S_OK ); }
STDMETHODIMP CDCCSink::OnLogError ( void ) { DeviceDisconnected(); return( S_OK ); }
STDMETHODIMP CDCCSink::OnLogInactive ( void ) { DeviceDisconnected(); return( S_OK ); }
STDMETHODIMP CDCCSink::OnLogIpAddr ( DWORD dwIpAddr ) { #ifdef ATTEMPT_DEVICE_CONNECTION_NOTIFICATION
if( !_Module.g_fInitialAttempt ) { ACTIVESYNC_DEV_BROADCAST_USERDEFINED dbu; DWORD dwRecips = BSM_APPLICATIONS;
memset( &dbu, 0, sizeof(dbu) );
dbu.DBHeader.dbch_size = sizeof(dbu); dbu.fConnected = TRUE; strcpy( dbu.szName, g_szActiveSyncDeviceName ); BroadcastSystemMessage( BSF_POSTMESSAGE | BSF_FORCEIFHUNG | BSF_NOHANG, &dwRecips, WM_DEVICECHANGE, DBT_USERDEFINED, (LPARAM)&dbu ); } #endif
_Module.g_fDeviceConnected = TRUE;
return( S_OK ); }
STDMETHODIMP CDCCSink::OnLogListen ( void ) { return( S_OK ); }
STDMETHODIMP CDCCSink::OnLogTerminated ( void ) { DeviceDisconnected(); return( S_OK ); }
//
// Helper functions
//
void CDCCSink::DeviceDisconnected() { if( SUCCEEDED( m_hrRapi ) ) { _Module.g_fDeviceConnected = FALSE; CeRapiUninit(); m_hrRapi = E_FAIL;
#ifdef ATTEMPT_DEVICE_CONNECTION_NOTIFICATION
ACTIVESYNC_DEV_BROADCAST_USERDEFINED dbu; DWORD dwRecips = BSM_APPLICATIONS;
memset( &dbu, 0, sizeof(dbu) );
dbu.DBHeader.dbch_size = sizeof(dbu); dbu.fConnected = FALSE; strcpy( dbu.szName, g_szActiveSyncDeviceName ); BroadcastSystemMessage( BSF_POSTMESSAGE | BSF_FORCEIFHUNG | BSF_NOHANG, &dwRecips, WM_DEVICECHANGE, DBT_USERDEFINED, (LPARAM)&dbu ); #endif
} }
void CDCCSink::Shutdown() { if( m_hThread ) { PostThreadMessage( m_dwThreadId, WM_QUIT, 0, 0 ); WaitForSingleObject( m_hThread, INFINITE ); } }
DWORD WINAPI CDCCSink::CreateDCCManProc(LPVOID lpParam ) { HRESULT hr = S_OK; MSG msg;
_ASSERTE( lpParam );
CDCCSink *pThis = (CDCCSink *)lpParam;
CoInitialize(NULL); if( SUCCEEDED( hr ) ) { hr = CoCreateInstance(CLSID_DccMan, NULL, CLSCTX_ALL, IID_IDccMan, (LPVOID *)&(pThis->m_spDccMan) ); }
if( SUCCEEDED( hr ) ) { hr = pThis->m_spDccMan->Advise(pThis, &(pThis->m_dwDccSink) ); }
pThis->m_hrRapi = hr; SetEvent( pThis->m_hThreadEvent );
while( GetMessage( &msg, NULL, 0, 0 ) ) { DispatchMessage( &msg ); }
if( NULL != pThis->m_spDccMan.p ) { if( (DWORD)-1 != pThis->m_dwDccSink ) { pThis->m_spDccMan->Unadvise( pThis->m_dwDccSink ); } }
CoUninitialize();
return( 0 ); }
|