none
还是GPRS拨号连接建立的问题,请高手进来看看 RRS feed

  • 问题

  • 还是GPRS拨号连接建立的问题,请高手进来看看:

    现在网络上的资料,有很多关于怎样在Windows CE上建立GPRS拨号的例子,有如下几个方面:
    1. 用ConnMgrMapURL函数,找到一个最佳的网络连接方式,然后连接;
    2. 用ConnMgrEnumDestinations,遍历所有的网络连接,然后叫用户自己选择一个接入点,进行GPRS拨号连接;
    3. 另外还有就是,读注册表,用一个XML文件创建连接或者找到接入点,进行拨号连接。

    但是我的需求都不是上面的这些。大家知道在Winodws Mobile手机里面,有个“设置-连接项-连接-高级-选择网络-网络管理”里面有两个设置项:
    1.【在程序自动连接到Internet时,使用:】
    2.【在程序自动连接到专用网络时,使用:】
    如果我的程序,能够知道这两个设置项,就用这个来进行拨号连接,既不用自动去找最佳的网络,也不用用户手动选,WM手机IE用什么拨号上网,我的应用就用什么拨号上网,岂不是很好?
    可惜,我到现在都不知道如何使用这两个设置项里面的连接的接入点进行拨号的。

    我猜想有两种方法:
    1. 注册表里面可能会有哪个地方记录了这两个值,可惜我始终没有找到;
    2. 那个经典的函数:ConnMgrEstablishConnectionSync,需要指定ConnInfo.guidDestNet的,有没有不需要指定,默认就用和IE一样连接设置拨号的方法,或者参数?

    高手都来看看吧,困扰了我很久了。不会大家都没有用过我说的方法吧。很多软件貌似都是这么做的啊!!!我是Win CE的,谢谢了。。。
    2009年6月9日 9:33

答案

  • 不管楼主你的为问题是否解决了我都回答一下,为了让其他人少走一些弯路,另外楼主你的前面观点是正确的只是不知道将这些东西整合应用。楼主所说的Winodws Mobile手机里面“设置-连接项-连接-高级-选择网络-网络管理”这些设置的结果在注册表中是找不到什么端倪的(我也花了一周时间来研究),但透过ConnMgrMapURL、ConnMgrEstablishConnectionSync、ConnMgrQueryDetailedStatus这三个函数的组合是可以达到楼主想要的结果。步骤如下:
    1、先用ConnMgrMapURL让系统来选择一个最佳的连接,其实系统选择的就是我们在网络管理中所设置的。
      GUID guid;
        memset(&guid, 0, sizeof(GUID));
        DWORD dwIndex = 0;
       ::ConnMgrMapURL(L"http://wap.baidu.com", &guid, &dwIndex);
    这边的url是用http开头还是wsp开题我没研究过,但值得注意的是dwIndex一定要初始化为0。

    2、然后用ConnMgrEstablishConnectionSync建立连接
               CONNMGR_CONNECTIONINFO connInfo;
            ZeroMemory(&connInfo, sizeof(CONNMGR_CONNECTIONINFO));
            //为了能够建立连接要填写CONNMGR_CONNECTIONINFO结构体
            connInfo.cbSize = sizeof(connInfo);
            connInfo.dwParams = CONNMGR_PARAM_GUIDDESTNET;
            connInfo.dwFlags = CONNMGR_FLAG_PROXY_HTTP | CONNMGR_FLAG_PROXY_WAP | CONNMGR_FLAG_PROXY_SOCKS4 | CONNMGR_FLAG_PROXY_SOCKS5;
            connInfo.dwPriority = CONNMGR_PRIORITY_USERINTERACTIVE;
            connInfo.guidDestNet = guid;//这边的GUID用的就是刚才ConnMgrMapURL所得到的GUID
            connInfo.bExclusive        = FALSE;
            connInfo.bDisabled = FALSE;        
            //通过同步方式建立连接
            hResult = ::ConnMgrEstablishConnectionSync(&connInfo, &m_hConnection, 10*1000, &dwStatus);

    3、通过以上两个步骤其实已经建立的GPRS连接,但并非就这样完事了,就如同网上经常有人讨论的那样这边不可避免的还得牵扯CMWAP和CMNET的问题(简单点就是是否使用代理),但获取代理之前得先找到当前建立的连接,这个可以通过ConnMgrQueryDetailedStatus来实现。
            DWORD dwSize = 0;
            GUID destGuid;
            char m_sNowTraffic[255];
            HRESULT hr = E_FAIL;
            hr = ConnMgrQueryDetailedStatus(NULL, &dwSize);
            if(STRSAFE_E_INSUFFICIENT_BUFFER != hr)
                    return hr;

            LPBYTE pBuffer = new BYTE[dwSize];
            if(NULL == pBuffer)
                    return E_OUTOFMEMORY;

            hr = ConnMgrQueryDetailedStatus((CONNMGR_CONNECTION_DETAILED_STATUS*)pBuffer, &dwSize);
            if(S_OK == hr)
            {
                    CONNMGR_CONNECTION_DETAILED_STATUS* cmStatus  = (CONNMGR_CONNECTION_DETAILED_STATUS*)pBuffer;
                    while(NULL != cmStatus)
                    {
                            // 找到当前处于连接状态的GPRS连接
                     if((cmStatus->dwParams &
                             (CONNMGRDETAILEDSTATUS_PARAM_TYPE |CONNMGRDETAILEDSTATUS_PARAM_DESCRIPTION | CONNMGRDETAILEDSTATUS_PARAM_CONNSTATUS))
                                    &&CM_CONNTYPE_CELLULAR == cmStatus->dwType &&CONNMGR_STATUS_CONNECTED == cmStatus->dwConnectionStatus &&NULL != cmStatus->szDescription)        
                            {
                                    //我不知道这个destGuid的学名叫什么,但是它在寻找代理的过程中很有用处                           
                                      memcpy(&destGuid, &(cmStatus->guidDestNet), sizeof(GUID));

                            }
                            cmStatus = cmStatus->pNext;
                    }
            }
            // clear the buffer
            delete pBuffer;
    4、接着就是通过查找注册表来得到代理了,当然如果是CMNET的话就没有代理了,因而通过以下函数也就不会有什么结果
    bool GetProxyFromReg(TCHAR * szProxy, int nProxySize)
    {
                    HKEY hKey;
            //打开注册表
            if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE, SEARCH_KEY, 0 ,0, &hKey))
            {
                    return false;
            }
            DWORD dwSubKeysNumber;
            DWORD dwMaxSubKeyLen;
            if (ERROR_SUCCESS != RegQueryInfoKey(hKey, NULL, NULL, NULL, &dwSubKeysNumber, &dwMaxSubKeyLen, NULL, NULL, NULL, NULL, NULL, NULL) )
            {
                    return false;
            }
            
            int nIndex = 0;
            DWORD dwSize;
            DWORD dwType;
            DWORD dwNSize = MAX_PATH;
            TCHAR szSubKeyName[MAX_PATH] = {0};
            TCHAR szDestId[MAX_PATH] = {0};

            CString strSrcGuid;
            //这边的m_guid就是步骤3中所得到的那个destGuid
            strSrcGuid.Format(_T("{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}"),
                                         m_guid.Data1, m_guid.Data2, m_guid.Data3,
                                         m_guid.Data4[0], m_guid.Data4[1],  m_guid.Data4[2],
                                         m_guid.Data4[3], m_guid.Data4[4],m_guid.Data4[5],
                                         m_guid.Data4[6], m_guid.Data4[7]);

            bool bSearch = false;
            while (!bSearch && ERROR_NO_MORE_ITEMS != RegEnumKeyEx(hKey, nIndex, szSubKeyName, &dwNSize, NULL, NULL, NULL, NULL))
            {
                    HKEY hSubKey;
                    CString strSubPath = SEARCH_KEY + CString(_T("\\")) + CString(szSubKeyName);
                    DWORD dwNetType = -1;
                    DWORD dwEnable = -1;
                    TCHAR szSrcId[MAX_PATH] = {0};

                    if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, strSubPath, 0, 0, &hSubKey) == ERROR_SUCCESS)
                    {
                            dwSize = sizeof(szSrcId);
                            RegQueryValueEx(hSubKey, _T("SrcId"), NULL, &dwType, (LPBYTE)szSrcId, &dwSize);
                                    
                            dwSize = sizeof(dwNetType);
                            RegQueryValueEx(hSubKey, _T("Type"), NULL, &dwType, (LPBYTE)&dwNetType, &dwSize);
                            
                            dwSize = sizeof(dwEnable);
                            RegQueryValueEx(hSubKey, _T("Enable"), NULL, &dwType, (LPBYTE)&dwEnable, &dwSize);
                            if (strSrcGuid.CompareNoCase(szSrcId) == 0 && (dwNetType == CONNMGR_FLAG_PROXY_HTTP) && dwEnable == 1)
                            {
                                   //就在这边了,只是得到是类似于10.0.0.172:80的东西                           
                                    dwSize = nProxySize;
                                    RegQueryValueEx(hSubKey, _T("Proxy"), NULL, &dwType, (LPBYTE)szProxy, &dwSize);
                                    bSearch = true;
       
                           }
                            RegCloseKey(hSubKey);
                    }        
                    nIndex++;
                    dwNSize = MAX_PATH;
            }
             RegCloseKey(hKey);
             if( bSearch && szProxy[0] == NULL )
                     return FALSE;
             return bSearch;
    }
    2009年6月9日 9:35