⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 connection.h

📁 windows mobile手机通过CMNET、CMWAP两种方式联网。
💻 H
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR INDEMNITIES.
//
// Connection.h: interface for the CConnection class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_CONNECTION_H__33D8B1CD_31D7_409D_8565_D53240608E57__INCLUDED_)
#define AFX_CONNECTION_H__33D8B1CD_31D7_409D_8565_D53240608E57__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <connmgr.h>
#include <connmgr_proxy.h>
#pragma comment( lib, "cellcore.lib" )

extern const GUID IID_ConnPrv_IProxyExtension;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Connection manager helper class
//
class CConnection
{
public:
    CConnection()
    {
        m_hThreadStop = CreateEvent(NULL, FALSE, FALSE, NULL);
        m_hConnectionThread = NULL;
        m_pszPath = NULL;
    }

    virtual ~CConnection()
    {
        HangupConnection();

        if( m_hThreadStop )
        {
            CloseHandle( m_hThreadStop );
            m_hThreadStop=NULL;
        }

        delete m_pszPath;
    }

    //
    // Can we get to this resource 'quickly'
    //
    HRESULT IsAvailable( LPCTSTR pszPath=NULL, BOOL bProxy=FALSE )
    {
        HRESULT hr=GetNetworkFromPath(pszPath);
        SetProxy(bProxy);

        if(SUCCEEDED(hr))
        {
            BOOL bAvailable = FALSE;
            HANDLE hConn = NULL;

            CONNMGR_CONNECTIONINFO ci = { 0 };
            ci.cbSize           = sizeof(ci);
            ci.dwParams         = CONNMGR_PARAM_GUIDDESTNET
                                        | CONNMGR_PARAM_MAXCONNLATENCY;
            ci.dwFlags          = bProxy?CONNMGR_FLAG_PROXY_HTTP:0;
            ci.ulMaxConnLatency = 4000;         // 4 second
            ci.bDisabled        = TRUE;
            ci.dwPriority       = CONNMGR_PRIORITY_USERINTERACTIVE;
            ci.guidDestNet      = GetNetworkGuid();

            if (SUCCEEDED(hr=ConnMgrEstablishConnection(&ci, &hConn)))
            {
                DWORD dwResult = WaitForSingleObject(hConn, 400);

                switch (dwResult)
                {
                    case WAIT_OBJECT_0:
                    {
                        DWORD dwStatus;
                        if( SUCCEEDED(ConnMgrConnectionStatus(hConn, &dwStatus)) &&
                            ( (dwStatus == CONNMGR_STATUS_CONNECTED) || (dwStatus == CONNMGR_STATUS_CONNECTIONDISABLED) ))
                        {
                            hr=S_OK;
                            CheckForRequiredProxy(hConn);
                        }
                        else
                        {
                            hr=S_FALSE;
                        }
                        break;
                    }

                    case WAIT_TIMEOUT:
                        hr=E_FAIL;
                        break;
                }
                ConnMgrReleaseConnection(hConn, FALSE);
            }
        }
        return hr;
    }

    //
    // Attempts to connect to the network
    // overried the Do* methods to see what's happening.
    //
    HRESULT AttemptConnect( LPCTSTR pszPath=NULL, BOOL bProxy=FALSE )
    {
        HRESULT hr=GetNetworkFromPath(pszPath);
        SetProxy(bProxy);

        if( m_hThreadStop == NULL )
            return E_INVALIDARG;

        if( SUCCEEDED(hr) )
        {
            if( SUCCEEDED ( hr=HangupConnection() ))
            {
                // kick off new thread,
                DWORD dwDummy;

                m_hConnectionThread = CreateThread(NULL, 0, s_ConnectionThread, (LPVOID)this, 0, &dwDummy);

                if ( m_hConnectionThread == NULL )
                    hr=E_FAIL;
            }
        }
        return hr;
    }

    HRESULT HangupConnection()
    {
        if( m_hConnectionThread )
        {
            SetEvent(m_hThreadStop);
			//wait a few seconds at most for the thread to die
			WaitForSingleObject(m_hConnectionThread, 3000); 
            m_hConnectionThread=NULL;
        }
        return S_OK;
    }

    BOOL    IsProxyRequired() { return m_bProxyRequired; }

    //
    // Properties on this object
    //
    HANDLE  GetConnection() { return m_hConnection; }
    DWORD   GetStatus()     { return m_dwStatus; }
    void    SetCache(BOOL b){ m_bCache=b; }
    BOOL    GetCache() { return m_bCache; }
    GUID    GetNetworkGuid() { return m_gNetwork; }
    BOOL    GetProxy() { return m_bProxy; }
    void    SetProxy(BOOL bProxy) { m_bProxy = bProxy; }
    LPTSTR  GetNetworkPath() { return m_pszPath; }
    LPTSTR  GetProxyServer() { if(m_bProxyRequired) return m_ProxyInfo.szProxyServer; else return NULL; }

    static LPTSTR GetInternetPath() { return CConnection::s_szInternetPath; }
    static LPTSTR GetCorpNetPath() { return CConnection::s_szCorpNetPath; }

protected:      // Methods to override.
    //
    // return S_OK to carry on.
    // return E_FAIL to hangup the connection
    //
    virtual HRESULT DoStatusUpdate(DWORD dwStatus)
    {
        HRESULT hRes=S_OK;
        if( dwStatus & CONNMGR_STATUS_DISCONNECTED )
        {
            if( dwStatus != CONNMGR_STATUS_DISCONNECTED )
                hRes = DoConnectingError();
            else
                hRes= DoDisconnected();
            SetCache( dwStatus == CONNMGR_STATUS_DISCONNECTED );
        }
        else if ( dwStatus == CONNMGR_STATUS_CONNECTED )
        {
            hRes = DoConnected();
        }
        else if ( dwStatus & CONNMGR_STATUS_WAITINGCONNECTION )
        {   
            hRes = DoWaitingForConnection();
        }
        return hRes;
    }

    //
    // Override these methods
    //

    //
    // Called when we 
    //
    virtual HRESULT DoEstablishingConnection()
    {
        return S_OK;
    }

    //
    // Called when there was an error while connecting
    // generally due to network connection not being available (no modem, no nic etc).
    //
    virtual HRESULT DoConnectingError()
    {
        // we received an error to do with connecting.
        SHELLEXECUTEINFO sei = {0};
        TCHAR szExec[MAX_PATH];
        wsprintf( szExec, TEXT("-CMERROR 0x%x -report"), GetStatus() );
        sei.cbSize = sizeof(sei);
        sei.hwnd = NULL;
        sei.lpFile = TEXT(":MSREMNET");
        sei.lpParameters = szExec;
        sei.nShow = SW_SHOWNORMAL;
        ShellExecuteEx( &sei );
        return E_FAIL;
    }

    //
    // Called when a connection is now available.
    //
    virtual HRESULT DoConnected()
    {
        CheckForRequiredProxy( GetConnection() );
        return S_OK;
    }

    //
    // Called when the existing connection has been disconnected
    // by another network request. we return E_FAIL to hangup here
    //
    virtual HRESULT DoDisconnected()
    {
        return E_FAIL;
    }

    //
    // Called when we are waiting for the network to become available.
    //
    virtual HRESULT DoWaitingForConnection()
    {
        return S_OK;
    }

    //
    // Called when we have released the connection
    //
    virtual HRESULT DoReleaseConnection()
    {
        return S_OK;
    }

    //
    // Sets the network GUID from a path.
    //
    HRESULT GetNetworkFromPath(LPCTSTR pszPath)
    {
        if( pszPath )
        {
            if( m_pszPath )
                delete m_pszPath;
            m_pszPath = new TCHAR[lstrlen(pszPath)+1];
            if( m_pszPath == NULL ) 
                return E_OUTOFMEMORY;
            lstrcpy(m_pszPath, pszPath);
        }
        return ConnMgrMapURL(m_pszPath, &m_gNetwork, 0);
    }

    //
    // Thread stub cast and calls.
    //
    static DWORD s_ConnectionThread(LPVOID pData)
    {
        CConnection * pConnection=(CConnection*)pData;
        if( pData )
            return pConnection->ConnectionThread();
        return -1;
    }

    //
    // Thread proc
    // Starts a connection to the network
    //
    DWORD ConnectionThread()
    {
        HANDLE hThisThread=m_hConnectionThread;
        CONNMGR_CONNECTIONINFO ConnInfo={0};
        ConnInfo.cbSize=sizeof(ConnInfo);
        ConnInfo.dwParams=CONNMGR_PARAM_GUIDDESTNET;
        ConnInfo.dwFlags=GetProxy() ? CONNMGR_FLAG_PROXY_HTTP: 0;
        ConnInfo.dwPriority=CONNMGR_PRIORITY_USERINTERACTIVE ;
        ConnInfo.guidDestNet = GetNetworkGuid();

        HRESULT hr = ConnMgrEstablishConnection(&ConnInfo, &m_hConnection);
        if( FAILED( hr ) )
        {
            DoConnectingError();
            SetCache(FALSE);
        }
        else
        {
            DoEstablishingConnection();

            HANDLE hObjects[2];
            hObjects[0]=m_hConnection;
            hObjects[1]=m_hThreadStop;
            BOOL    bStop=FALSE;
            
            ResetEvent(m_hThreadStop);

            while( bStop == FALSE )
            {
                DWORD dwResult = WaitForMultipleObjects( 2, hObjects, FALSE, INFINITE); 
                
                if (dwResult == (WAIT_OBJECT_0))
                { 
                    HRESULT hr;
                    DWORD   dwStatus;
                    hr=ConnMgrConnectionStatus(m_hConnection,&dwStatus);
                    m_dwStatus = dwStatus;
                    if( SUCCEEDED(hr))
                    {
                        if( DoStatusUpdate(m_dwStatus) != S_OK )
                            bStop=TRUE;
                    }
                    else
                    {
                        m_dwStatus=hr;
                        bStop=TRUE;
                    }
                }
                else // failures, or signalled to stop.
                {
                    bStop = TRUE;
                    ResetEvent(m_hThreadStop);
                }
            }
        }

        DoReleaseConnection();

        // Release the connection, caching if we should.
        if( m_hConnection )
        {
            ConnMgrReleaseConnection(m_hConnection, GetCache() );
        }

        CloseHandle(hThisThread);

        return GetStatus();
    }


private:
    LPTSTR  m_pszPath;
    BOOL    m_bProxy;
    HANDLE  m_hConnection;  // Connection Manager Handle
    BOOL    m_bCache;       // should we cache this connection when we 'hangup'
    GUID    m_gNetwork;     // the GUID for the network we are connecting to.
    DWORD   m_dwStatus;      // last connection status
    HANDLE  m_hThreadStop;  // Event
    HANDLE  m_hConnectionThread;    // Thread
    BOOL    m_bProxyRequired;

    BOOL    CheckForRequiredProxy(HANDLE hConn)
    {
        m_bProxyRequired=FALSE;
        ZeroMemory(&m_ProxyInfo, sizeof(m_ProxyInfo));
        m_ProxyInfo.dwType = CONNMGR_FLAG_PROXY_HTTP;
        if (SUCCEEDED(ConnMgrProviderMessage(   hConn,
                                                &IID_ConnPrv_IProxyExtension,
                                                NULL,
                                                0,
                                                0,
                                                (PBYTE)&m_ProxyInfo,
                                                sizeof(m_ProxyInfo))))
        {
            if (m_ProxyInfo.dwType == CONNMGR_FLAG_PROXY_HTTP)
            {
                m_bProxyRequired=TRUE;
               // SECURITY: Zero out the username/password from memory.
               ZeroMemory(&(m_ProxyInfo.szUsername), sizeof(m_ProxyInfo.szUsername));
               ZeroMemory(&(m_ProxyInfo.szPassword), sizeof(m_ProxyInfo.szPassword));
            }
        }
        return m_bProxyRequired;
    }


    // Rigged paths that will map  to the correct GUID.
    static LPTSTR s_szInternetPath;
    static LPTSTR s_szCorpNetPath;

    PROXY_CONFIG    m_ProxyInfo;
};

#endif // !defined(AFX_CONNECTION_H__33D8B1CD_31D7_409D_8565_D53240608E57__INCLUDED_)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -