#ifndef _MBN_EVENT_HELPER_ #define _MBN_EVENT_HELPER_ #include #include "mbnapi.h" #include #include #include #include "PortableDevice.h" #include "MbnEventInternal.h" // Macro that releases a COM object if not NULL. #define SAFE_RELEASE(p) do { if ((p)) { (p)->Release(); (p) = NULL; } } while(0) LPCTSTR ConvertToString(BSTR& bstrValue); void FreeBString(BSTR& bstrValue); class CMbnImplHelper; void EnterWowRedirection(); void LeaveWowRedirection(); class CustomSignalEvents : IMbnSignalEvents { private: DWORD m_dwRefCount; CMbnImplHelper* m_pHelper; int m_nFormattedVal; int m_nOldValue; public: DWORD GetRef() { return m_dwRefCount; } CustomSignalEvents(CMbnImplHelper* helper): m_dwRefCount(0), m_pHelper(helper), m_nFormattedVal(0), m_nOldValue(4){} HRESULT STDMETHODCALLTYPE OnSignalStateChange(IMbnSignal *newInterface); HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) { if (IsEqualGUID(riid, IID_IUnknown) || IsEqualGUID(riid, IID_IMbnSignalEvents)) { *ppvObject = static_cast(this); AddRef(); return S_OK; } return E_NOINTERFACE; } ULONG STDMETHODCALLTYPE AddRef() { m_dwRefCount++; return m_dwRefCount; } ULONG STDMETHODCALLTYPE Release() { m_dwRefCount--; if (0 == m_dwRefCount) { delete this; return 0; } return m_dwRefCount; } }; class CustomConnectionEvents : IMbnConnectionEvents { private: DWORD m_dwRefCount; CMbnImplHelper* m_pHelper; public: CustomConnectionEvents(CMbnImplHelper* helper): m_dwRefCount(0), m_pHelper(helper){} HRESULT STDMETHODCALLTYPE OnConnectComplete( IMbnConnection *newConnection, ULONG requestID, HRESULT status); HRESULT STDMETHODCALLTYPE OnDisconnectComplete( IMbnConnection *newConnection, ULONG reqeustID, HRESULT status); HRESULT STDMETHODCALLTYPE OnConnectStateChange( IMbnConnection *newConnection); HRESULT STDMETHODCALLTYPE OnVoiceCallStateChange( IMbnConnection *newConnection); HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) { if (IsEqualGUID(riid, IID_IUnknown) || IsEqualGUID(riid, IID_IMbnConnectionEvents)) { *ppvObject = static_cast(this); AddRef(); return S_OK; } return E_NOINTERFACE; } ULONG STDMETHODCALLTYPE AddRef() { return ++m_dwRefCount; } ULONG STDMETHODCALLTYPE Release() { if (0 == --m_dwRefCount) { delete this; return 0; } return m_dwRefCount; } }; class CustomConnctionMnrEvents : IMbnConnectionManagerEvents { private: DWORD m_dwRefCount; CMbnImplHelper* m_pHelper; public: CustomConnctionMnrEvents(CMbnImplHelper* helper): m_dwRefCount(0), m_pHelper(helper){} HRESULT STDMETHODCALLTYPE OnConnectionArrival(IMbnConnection *newConnection); HRESULT STDMETHODCALLTYPE OnConnectionRemoval(IMbnConnection *oldConnection); HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) { if (IsEqualGUID(riid, IID_IUnknown) || IsEqualGUID(riid, IID_IMbnConnectionManagerEvents)) { *ppvObject = static_cast(this); AddRef(); return S_OK; } return E_NOINTERFACE; } ULONG STDMETHODCALLTYPE AddRef() { return ++m_dwRefCount; } ULONG STDMETHODCALLTYPE Release() { if (0 == --m_dwRefCount) { delete this; return 0; } return m_dwRefCount; } }; class CustomConnectionProfileManagerEvents : IMbnConnectionProfileManagerEvents { private: DWORD m_dwRefCount; CMbnImplHelper* m_pHelper; public: CustomConnectionProfileManagerEvents(CMbnImplHelper* helper): m_dwRefCount(0), m_pHelper(helper){} HRESULT STDMETHODCALLTYPE OnConnectionProfileArrival( IMbnConnectionProfile *newConnectionProfile ); HRESULT STDMETHODCALLTYPE OnConnectionProfileRemoval( IMbnConnectionProfile *oldConnectionProfile ); HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) { if (IsEqualGUID(riid, IID_IUnknown) || IsEqualGUID(riid, IID_IMbnConnectionProfileManagerEvents)) { *ppvObject = static_cast(this); AddRef(); return S_OK; } return E_NOINTERFACE; } ULONG STDMETHODCALLTYPE AddRef() { return ++m_dwRefCount; } ULONG STDMETHODCALLTYPE Release() { if (0 == --m_dwRefCount) { delete this; return 0; } return m_dwRefCount; } }; class CustomConnectionProfileEvents : IMbnConnectionProfileEvents { private: DWORD m_dwRefCount; CMbnImplHelper* m_pHelper; public: CustomConnectionProfileEvents(CMbnImplHelper* helper): m_dwRefCount(0), m_pHelper(helper){} HRESULT STDMETHODCALLTYPE OnProfileUpdate( IMbnConnectionProfile *newProfile ); HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) { if (IsEqualGUID(riid, IID_IUnknown) || IsEqualGUID(riid, IID_IMbnConnectionProfileEvents)) { *ppvObject = static_cast(this); AddRef(); return S_OK; } return E_NOINTERFACE; } ULONG STDMETHODCALLTYPE AddRef() { return ++m_dwRefCount; } ULONG STDMETHODCALLTYPE Release() { if (0 == --m_dwRefCount) { delete this; return 0; } return m_dwRefCount; } }; class CMbnImplHelper { private: HRESULT m_hrConInit; //ATL::CComPtr m_pCurInterface; ATL::CComPtr m_pTmpInterface; CustomConnectionEvents* m_cntEvent; CustomSignalEvents* m_signalEvent; CustomConnctionMnrEvents* m_cntMnrEvent; CustomConnectionProfileManagerEvents* m_cntPfMnrEvent; CustomConnectionProfileEvents* m_cntPfEvent; BOOL m_bSignalEventInitied; BOOL m_bCntEventInitied; BOOL m_bCntMnrEventInitied; BOOL m_bCntPfMnrEventInited; BOOL m_bCntPfEventInited; IConnectionPoint* m_pCntPointForSignal; IConnectionPoint* m_pCntPointForCntEvent; IConnectionPoint* m_pCntPointForCntMnrEvent; IConnectionPoint* m_pCntPointForCntProfileMnrEvent; IConnectionPoint* m_pCntPointForProfileEvent; IConnectionPointContainer* m_pContainer, *m_pContainer2; DWORD m_dwCkCnt, m_dwCkSignal, m_dwCkCntMnr, m_dwCkCntPfMnr, m_dwCkPf; MBN_ACTIVATION_STATE m_cntState; MOBILEDIAL_CONNECTION_STATE m_curState; MOBILEDIAL_CONNECTION_STATE m_tmpState; CSimpleStringA m_csXmlData; CSimpleStringA m_csProfileName; CSimpleStringA m_interfaceID; //Set value valid in two way: //1. listen from Event //2. Invoke Connect routine and returned suc. //it cannot programmatic disconnect if the value is invalid(-1) //[Josephus in 16:33:04 2016/5/26] ULONG m_ulRequestID; ULONG m_ulTempID; int m_nSignalVal; BOOL m_bSelected; int m_nWhichGnrt; DWORD m_dwErroCode; CSimpleStringA m_csTmpProfileName; BOOL m_bDialFromDialog; BOOL m_bHasProfile; public: CMbnImplHelper(): m_hrConInit(S_FALSE), /*m_pCurInterface(NULL),*/m_pTmpInterface(NULL), m_signalEvent(NULL), m_cntEvent(NULL), m_cntMnrEvent(NULL), m_cntPfMnrEvent(NULL), m_cntPfEvent(NULL), m_bSignalEventInitied(FALSE), m_bCntEventInitied(FALSE), m_bCntMnrEventInitied(FALSE), m_bCntPfMnrEventInited(FALSE), m_bCntPfEventInited(FALSE), m_pCntPointForSignal(NULL), m_pCntPointForCntEvent(NULL), m_pCntPointForCntMnrEvent(NULL), m_pCntPointForProfileEvent(NULL), m_pContainer(NULL), m_pContainer2(NULL), m_dwCkCnt(0), m_dwCkSignal(0), m_dwCkCntMnr(0), m_dwCkCntPfMnr(0), m_dwCkPf(0), m_cntState(MBN_ACTIVATION_STATE_NONE), m_curState(MBD_NO_MOBILEDONGLE), m_csProfileName(true), m_interfaceID(""), m_ulRequestID(-1), m_ulTempID(-1), m_nSignalVal(0), m_bSelected(FALSE), m_nWhichGnrt(0), m_dwErroCode(0), m_csTmpProfileName(true), m_bDialFromDialog(FALSE), m_bHasProfile(FALSE) { m_hrConInit = CoInitializeEx(NULL, COINIT_MULTITHREADED); if(FAILED(m_hrConInit)) { if(m_hrConInit != RPC_E_CHANGED_MODE) { DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("*** ERROR: Failed to ConInitializeEx with code 0x%08x", m_hrConInit); } else { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("*** Warning: A previous call to CoInitializeEx specified the concurrency model for this thread as MTA."); } } m_signalEvent = new CustomSignalEvents(this); m_cntEvent = new CustomConnectionEvents(this); m_cntMnrEvent = new CustomConnctionMnrEvents(this); m_cntPfMnrEvent = new CustomConnectionProfileManagerEvents(this); m_cntPfEvent = new CustomConnectionProfileEvents(this); } ~CMbnImplHelper() { SAFE_RELEASE(m_pContainer); SAFE_RELEASE(m_pContainer); SAFE_RELEASE(m_pContainer); SAFE_RELEASE(m_pContainer); SAFE_RELEASE(m_pContainer); SAFE_RELEASE(m_signalEvent); SAFE_RELEASE(m_cntMnrEvent); SAFE_RELEASE(m_cntEvent); SAFE_RELEASE(m_cntPfMnrEvent); SAFE_RELEASE(m_cntPfEvent); if(m_hrConInit != S_FALSE && SUCCEEDED(m_hrConInit)) { CoUninitialize(); } } // bUpdateOnly : TRUE:只是更新网卡列表, FALSE:选取当前网卡,兼容旧接口 // >0 如果当前未存储接口值,则将找到的第一个进行赋予 // =0 无设备 // <0 也有可能是无设备造成的错误,或者是有设备但是打不开接口 int EnumerateInterfaces(BOOL bUpdateOnly = FALSE); //Store in m_pTmpInterface if returned true. BOOL GetInterface(LPCTSTR interfaceID); ATL::CComPtr GetInterfaceEx(LPCTSTR interfaceID); BOOL SetCurInterface(LPCTSTR interfaceID); BOOL IsValidInterface(LPCTSTR interfaceID); BOOL GetInterfaceInfo(LPCTSTR interfaceID, pMbnDongleSubInfo pSubInfo); BOOL CheckAndRefleshCurInterface(); BOOL AdviseSignalEvent(); BOOL AdviseCntMnrEvent(); BOOL AdviseConnectEvent(); BOOL AdviseCntProfileMnrEvent(); BOOL AdviseCntProfileEvent(); BOOL UnAdviseCustomEvents(); BOOL GetConnectState(); // 0: 表示无网卡; 1: 错误 2: 稍后查询; 3: 3G; 4: 4G; int GetGeneration(ATL::CComPtr pInterface); BOOL GetConnectState(ATL::CComPtr pInterface, MBN_ACTIVATION_STATE& state); // 仅获取网络信号 BOOL GetSignalValue(ATL::CComPtr pInterface, ULONG& ulSignalStrength); BOOL SearchForProfileName(ptMbnDongleInfo pInfo = NULL); BOOL Connect(); BOOL DisConnect(BOOL bManual = FALSE, LPCTSTR lpszInterface = ""); ULONG ConnectEx2(LPCTSTR lpcszInterface, LPCTSTR lpcszProfileName); BOOL ConnectEx(LPCTSTR lpcszInterface, LPCTSTR lpcszProfileName); MOBILEDIAL_CONNECTION_STATE GetCurState() { return m_curState; } void SetInteralError(LRESULT result) { SetMBNCode(result); SetTmpState(MBD_INTERNAL_ERROR); } void SetStatusFromTmp2Main() { SetCurState(m_tmpState); } BOOL GetInterfaceID(CSimpleStringA& csItfID) { if(m_bSelected){ csItfID = m_interfaceID; } return m_bSelected; } void SetSignalVal(int val, ULONG ulOrigin) { if(m_nSignalVal != val) { m_nSignalVal = val; } } int GetGenerationVal() { return m_nWhichGnrt; } void ClearCurInterface() { m_bSelected = FALSE; m_interfaceID = ""; m_nWhichGnrt = 0; SetCurState(MBD_NO_MOBILEDONGLE); } BOOL HasAnyProfile() const { return m_bHasProfile; } //For MBD_INTERNAL_ERROR error-type. void SetMBNCode(DWORD dwVal) {m_dwErroCode = dwVal;} DWORD GetMBNCode() {return m_dwErroCode;} void OnConnectComplete(ULONG requestID, LPCTSTR newInterface, HRESULT status); void OnDisconnectComplete(ULONG requestID, LPCTSTR newInterface); void OnConnectStateChange(HRESULT hr, MBN_ACTIVATION_STATE state, LPCTSTR newInterface); void OnConnectionArrival(LPCTSTR newInterface); void OnConnectionRemoval(LPCTSTR newInterface); void OnConnectionProfileRemoval(IMbnConnectionProfile *oldConnectionProfile); void OnConnectionProfileArrival(IMbnConnectionProfile *newConnectionProfile); void OnProfileUpdate(IMbnConnectionProfile *newProfile); void SetRequestID(ULONG requestID = (ULONG)-1) { m_ulRequestID = requestID; } private: // m_tmpState store the error status when return FALSE BOOL _IsValidInterface(ATL::CComPtr pInterface); void SetCurState(MOBILEDIAL_CONNECTION_STATE newState) { //if(newState != m_curState && m_pFSM->GetCurrState()->id == CMobileDialFSM::s3) { // FSMEvent* fsmEvent = new FSMEvent(USER_EVT_STATUSCHANGE); // fsmEvent->param1 = newState; // m_pFSM->PostEventLIFO(fsmEvent); //} m_curState = newState; } void SetTmpState(MOBILEDIAL_CONNECTION_STATE newState) { m_tmpState = newState; } ErrorCodeEnum _CreateProfile(const CSimpleStringA& csInterfaceID, const AccessKeyInfo& newInfo, bool fApplyNow, bool bUpdate, CSimpleStringW& csContent); }; #endif