達成 RAS Entry Porperties Set 功能已經四天了, 再不紀錄就快忘了. 先提幾個 Key Point, (1) Binary Data Structure 似乎找不到正式文件, 得笨笨的一個一個猜, (2) Device Name 和 Entry Name 不要混淆, 上週一就是這部份混淆了, 否則上週一就完成了, 之後還是靠比對 寫入 & Dialog 產生 的 Binary Data 才知道問提出在這.
RASRegSet 是以 Export Entire Class 的 DLL 方式 Implement, 主要的檔案有 3 個, Macro.h, CRASRegSet.h CRASRegSet.cpp, 分別 List 如下 (For WinCE 5.0) :
Macro.h (For Export Entire Class PreDefine)

#ifndef __RAS_MACRO__
#define __RAS_MACRO__

#ifndef AFX_EXT_DATA
#ifdef _AFXEXT
#define AFX_EXT_CLASS AFX_CLASS_EXPORT
#define AFX_EXT_API AFX_API_EXPORT
#define AFX_EXT_DATA AFX_DATA_EXPORT
#define AFX_EXT_DATADEF
#else
#define AFX_EXT_CLASS AFX_CLASS_IMPORT
#define AFX_EXT_API AFX_API_IMPORT
#define AFX_EXT_DATA AFX_DATA_IMPORT
#define AFX_EXT_DATADEF
#endif
#endif

#endif

CRASRegSet.h

// CRASRegSet.h: interface for the CRASRegSet class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_CRASREGSET_H__96AA9E65_FEE2_441F_A7E2_57CEF87FA627__INCLUDED_)
#define AFX_CRASREGSET_H__96AA9E65_FEE2_441F_A7E2_57CEF87FA627__INCLUDED_

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

#include "Macro.h"
#include
#include

#define __REG_NAME__ _T("BT Connection")
#define __DEVICE_NAME__ _T("Bluetooth DUN on COM2")
#define __PHONE_NUMBER__ _T("\*99\#")
#define __COUNTRY_CODE__ 0×376
#define __AREA_CODE__ _T("03")
#define __AT_CMD_LEN__ 331

// Following Data Struct Is Reversing From HKEY_CURRENT_USER\Comm\RasBook\Xxxx, (Xxxx Is Modem Device Name)
// Use For API RasSetEntryProperties Parameter, For Set Modem & Extra Command Like "+cgdcont=1,"ip","internet"
// 2008/10/03, Tony.Jou

typedef struct {

WORD wHeader; // 0×00(L:2), Val = 0×30, Unknown

WORD wWaitForCreditCardSec; // 0×02(L:2), Val = 0×0, Wait For Credit Card Tone Seconds,

WORD wCancelTimeOut; // 0×04(L:2), Val = 78 00 -> 0×78

WORD wReserved1; // 0×06(L:2), Val = 0×0,

BYTE bFlowControl; // 0×08(L:1), Val = 0×0,
// F.C. = None, Val = 0×0,
// F.C. = H.W., Val = 0×10,
// F.C. = S.W., Val = 0×20,

BYTE bWaitForDialTone; // 0×09(L:1), Val = 0×1, Wait For Dial Tone Before Dialing
// Enable Wait For Dial Tone Before Dialing, Val = 0×1
// Disable Wait For Dial Tone Before Dialing, Val = 0×3

WORD wReserved2; // 0×0A(L:2), Val = 0×0,

UINT uBaudRate; // 0×0C(L:4), Val = 00 c2 01 00, 0×0001c200 = 115200

WORD wTerminal; // 0×10(L:2), Val = 00(L^) 00(H) -> 0×0, digital (d2)(d1)(d0),
// d2:Manual Dial,
// d1:Use terminal window before dialing,
// d0:Use terminal window after dialing,

BYTE bDataBits; // 0×12(L:1), Val = 0×8,

BYTE bStopBits; // 0×13(L:1), Val = 0×0,
// StopBits = 1, Val = 0×0
// StopBits = 1.5,Val = 0×1
// StopBits = 2, Val = 0×2

WORD wParity; // 0×14(L:2), Val = 00(^L) 00(H) -> 0×0
// Parity = None, Val = 0×0
// Parity = Odd, Val = 0×1
// Parity = Even, Val = 0×2
// Parity = Mark, Val = 0×3
// Parity = Space,Val = 0×4

WCHAR wszAtCmd[__AT_CMD_LEN__]; // 0×16(L:662),
// __AT_CMD_LEN__ ->331, Why "331" -> Reg DevCfg TotalLen : 684(0~0×2AB)
// 684(0~0×2AB) - 22(0×0~0×15->0×16) = 662(0×16~0×2AB->0×296)
// 662(0×16~0×2AB->0×296) / sizeof(WCHAR)
} sDevConfig;

class AFX_EXT_CLASS CRASRegSet
{
public:
CRASRegSet();
virtual ~CRASRegSet();
bool UpdateRASReg();

private:
sDevConfig m_DevConfig;
RASENTRY m_RASEntry;
bool InitVar();
bool GetRASEntries();
bool GetDeficeID(TCHAR *btname, int *iDeviceID);
};

#endif // !defined(AFX_CRASREGSET_H__96AA9E65_FEE2_441F_A7E2_57CEF87FA627__INCLUDED_)

CRASRegSet.cpp

// CRASRegSet.cpp: implementation of the CRASRegSet class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "CRASRegSet.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CRASRegSet::CRASRegSet()
{
memset(m_DevConfig.wszAtCmd,0,__AT_CMD_LEN__*sizeof(WCHAR));
}

CRASRegSet::~CRASRegSet()
{

}

bool CRASRegSet::UpdateRASReg()
{
DWORD dwRet = 0;
bool bRet = false;
DWORD dwBufferSize = 0;
DWORD dwSize = 0;

int iLineID = 0;
int iDeviceID = 0;

LONG lRet = -1;

// This is important! Find the buffer size (different from sizeof(RASENTRY)).
RasGetEntryProperties(NULL, L"", NULL, &dwBufferSize, NULL, NULL);
dwSize = sizeof(m_DevConfig);

bRet = InitVar();
//bRet = true;

if (bRet) {

dwRet = RasSetEntryProperties(
NULL,
__REG_NAME__,
&m_RASEntry,
dwBufferSize,
(LPBYTE)&m_DevConfig,
dwSize
);

switch (dwRet) {
case ERROR_BUFFER_INVALID:
MessageBox(NULL,_T("ERROR_BUFFER_INVALID"),NULL,MB_OK);
break;
case ERROR_CANNOT_OPEN_PHONEBOOK:
MessageBox(NULL,_T("ERROR_CANNOT_OPEN_PHONEBOOK"),NULL,MB_OK);
break;
default:
break;
}

bRet = (dwRet?false:true);

dwBufferSize = 0;

m_RASEntry.dwSize = sizeof(RASENTRY);

RasGetEntryProperties(NULL, __REG_NAME__, NULL, &dwBufferSize, NULL, NULL);

dwRet = RasGetEntryProperties(
NULL,
__REG_NAME__,
&m_RASEntry,
&dwBufferSize,
(LPBYTE)&m_DevConfig,
&dwSize
);
bRet = (dwRet?false:true);
}

if (bRet) {
bRet = GetRASEntries();
}

if (bRet) {
bRet = GetDeficeID(L"Bluetooth", &iDeviceID);
}

return bRet;

if (bRet) {

//lRet = lineSetDevConfig((DWORD)iDeviceID, &m_DevConfig, dwSize, L"Comm");
//lRet = lineSetDevConfig((DWORD)iDeviceID, &m_DevConfig, dwSize, L"tapi/line");
// lRet = lineSetDevConfig((DWORD)iDeviceID, &m_DevConfig, dwSize, L"comm/datamodem/portname/Bluetooth DUN on COM2\0");
//lRet = lineSetDevConfig((DWORD)iDeviceID, &m_DevConfig, dwSize, L"Comm/datamodem");

bRet = (lRet?false:true);
}

return bRet;
}

bool CRASRegSet::InitVar()
{
// Read Config …

// m_RASEntry Variable
DWORD dwFlagOptions = 0;
DWORD dwChannel = 0;
bool bSpecificDNS = false;
bool bSpecificIpAddr = false;
int iDeviceType = 0;

// Set Variable

m_RASEntry.dwSize = sizeof(RASENTRY);

memset((void*)&m_RASEntry, 0, m_RASEntry.dwSize);

m_RASEntry.dwfOptions = RASEO_ProhibitEAP;

dwFlagOptions = RASEO_RemoteDefaultGateway;

if (bSpecificDNS) {
dwFlagOptions |= RASEO_SpecificNameServers;
// example : 168.95.1.1 -> 0xA8, 0×5F, 0×1, 0×1
m_RASEntry.ipaddrDns.a = 0×1;
m_RASEntry.ipaddrDns.b = 0×1;
m_RASEntry.ipaddrDns.c = 0×5F;
m_RASEntry.ipaddrDns.d = 0xA8;

// example : 168.95.1.2 -> 0xA8, 0×5F, 0×1, 0×2
m_RASEntry.ipaddrDnsAlt.a = 0×2;
m_RASEntry.ipaddrDnsAlt.b = 0×1;
m_RASEntry.ipaddrDnsAlt.c = 0×5F;
m_RASEntry.ipaddrDnsAlt.d = 0xA8;

// example : 168.95.1.3 -> 0xA8, 0×5F, 0×1, 0×3
m_RASEntry.ipaddrWins.a = 0×3;
m_RASEntry.ipaddrWins.b = 0×1;
m_RASEntry.ipaddrWins.c = 0×5F;
m_RASEntry.ipaddrWins.d = 0xA8;

// example : 168.95.1.4 -> 0xA8, 0×5F, 0×1, 0×4
m_RASEntry.ipaddrWinsAlt.a = 0×4;
m_RASEntry.ipaddrWinsAlt.b = 0×1;
m_RASEntry.ipaddrWinsAlt.c = 0×5F;
m_RASEntry.ipaddrWinsAlt.d = 0xA8;
}

if (bSpecificIpAddr) {
dwFlagOptions |= RASEO_SpecificIpAddr;
// example : 203.22.95.42 -> 0xCB, 0×16, 0×5F, 0×2A
m_RASEntry.ipaddr.a = 0×2A;
m_RASEntry.ipaddr.b = 0×5F;
m_RASEntry.ipaddr.c = 0×16;
m_RASEntry.ipaddr.d = 0xCB;
}

m_RASEntry.dwfOptions = dwFlagOptions;

m_RASEntry.dwCountryCode = __COUNTRY_CODE__; //

_tcscpy(m_RASEntry.szAreaCode, __AREA_CODE__);

_tcscpy(m_RASEntry.szLocalPhoneNumber, __PHONE_NUMBER__);

_tcscpy(m_RASEntry.szDeviceName, __DEVICE_NAME__);

_tcscpy(m_RASEntry.szX25PadType, _T(""));
_tcscpy(m_RASEntry.szX25Address, _T(""));
_tcscpy(m_RASEntry.szX25Facilities, _T(""));
_tcscpy(m_RASEntry.szX25UserData, _T(""));

m_RASEntry.dwfNetProtocols = RASNP_Ip;
m_RASEntry.dwFramingProtocol = RASFP_Ppp;

switch (iDeviceType) {
case 0:
_tcscpy (m_RASEntry.szDeviceType, RASDT_Modem);
break;
case 1:
_tcscpy (m_RASEntry.szDeviceType, RASDT_Direct);
break;
case 2:
_tcscpy (m_RASEntry.szDeviceType, RASDT_Modem);
break;
default:
_tcscpy (m_RASEntry.szDeviceType, RASDT_Vpn);
break;
}

// Number specifying the number of channels supported by the device,
// where 1 is mono, 2 is stereo, and so on.
m_RASEntry.dwChannels = dwChannel;
m_RASEntry.dwReserved1 = 0;
m_RASEntry.dwReserved2 = 0;
m_RASEntry.dwCustomAuthKey = 0;

// Init DevConfig
/*
WORD wHeader; // 0×00(L:2), Val = 0×30, Unknown

WORD wWaitForCreditCardSec; // 0×02(L:2), Val = 0×0, Wait For Credit Card Tone Seconds,

WORD wCancelTimeOut; // 0×04(L:2), Val = 78 00 -> 0×78

WORD wReserved1; // 0×06(L:2), Val = 0×0,

BYTE bFlowControl; // 0×08(L:1), Val = 0×0,
// F.C. = None, Val = 0×0,
// F.C. = H.W., Val = 0×10,
// F.C. = S.W., Val = 0×20,

BYTE bWaitForDialTone; // 0×09(L:1), Val = 0×1, Wait For Dial Tone Before Dialing
// Enable Wait For Dial Tone Before Dialing, Val = 0×1
// Disable Wait For Dial Tone Before Dialing, Val = 0×3

WORD wReserved2; // 0×0A(L:2), Val = 0×0,

UINT uBaudRate; // 0×0C(L:4), Val = 00 c2 01 00, 0×0001c200 = 115200

WORD wTerminal; // 0×10(L:2), Val = 00(L^) 00(H) -> 0×0, digital (d2)(d1)(d0),
// d2:Manual Dial,
// d1:Use terminal window before dialing,
// d0:Use terminal window after dialing,

BYTE bDataBits; // 0×12(L:1), Val = 0×8,

BYTE bStopBits; // 0×13(L:1), Val = 0×0,
// StopBits = 1, Val = 0×0
// StopBits = 1.5,Val = 0×1
// StopBits = 2, Val = 0×2

WORD wParity; // 0×14(L:2), Val = 00(^L) 00(H) -> 0×0
// Parity = None, Val = 0×0
// Parity = Odd, Val = 0×1
// Parity = Even, Val = 0×2
// Parity = Mark, Val = 0×3
// Parity = Space,Val = 0×4

WCHAR wszAtCmd[331]; // 0×16(L:662),
// Why "331" -> Reg DevCfg TotalLen : 684(0~0×2AB)
// 684(0~0×2AB) - 22(0×0~0×15->0×16) = 662(0×16~0×2AB->0×296)
// 662(0×16~0×2AB->0×296) / sizeof(WCHAR)
*/
m_DevConfig.wHeader = 0×30; // 0×00(L:2)
m_DevConfig.wWaitForCreditCardSec = 0×0;// 0×02(L:2),
m_DevConfig.wCancelTimeOut = 0×78; // 0×04(L:2),
m_DevConfig.wReserved1 = 0×0; // 0×06(L:2),
m_DevConfig.bFlowControl = 0×0; // 0×08(L:1),
m_DevConfig.bWaitForDialTone = 0×1; // 0×09(L:1),
m_DevConfig.wReserved2 = 0×0; // 0×0A(L:2),
m_DevConfig.uBaudRate = 0×0001c200; // 0×0C(L:4),
m_DevConfig.wTerminal = 0×0; // 0×10(L:2),
m_DevConfig.bDataBits = 0×8; // 0×12(L:1),
m_DevConfig.bStopBits = 0×0; // 0×13(L:1),
m_DevConfig.wParity = 0×0; // 0×14(L:2),
_tcscpy(m_DevConfig.wszAtCmd, _T("+cops=1,2,\"46692\";+cgdcont=1,\"ip\",\"internet\""));
return true;
}

bool CRASRegSet::GetRASEntries()
{
DWORD dwRet = -1;
DWORD cb;
DWORD cEntries;
bool bRet = false;
LPRASENTRYNAME lpRASEntryName;
int i = 0;

lpRASEntryName = (LPRASENTRYNAME)LocalAlloc(LPTR, sizeof(RASENTRYNAME));
lpRASEntryName->dwSize = sizeof(RASENTRYNAME);
if ((dwRet = RasEnumEntries(NULL, NULL, lpRASEntryName, &cb, &cEntries))
== ERROR_BUFFER_TOO_SMALL)
{
lpRASEntryName = (LPRASENTRYNAME)LocalAlloc(LPTR, cb);
lpRASEntryName->dwSize = sizeof(RASENTRYNAME);
}

// Calling RasEnumEntries to enumerate the phonebook entries
dwRet = RasEnumEntries(NULL, NULL, lpRASEntryName, &cb, &cEntries);

if (dwRet != ERROR_SUCCESS)
{
TRACE(_T("RasEnumEntries failed: Error %d\n"), dwRet);
}
else
{
TRACE(_T("Phone book entries in the default phonebook:\n\n"));
for(i=0;i < cEntries;i++)
{
TRACE(_T("%s\n"),lpRASEntryName->szEntryName);
if(_tcsncmp((lpRASEntryName + i)->szEntryName, __DEVICE_NAME__, _tcslen(__DEVICE_NAME__)) == 0)
{
lpRASEntryName = (LPRASENTRYNAME)LocalAlloc(LPTR, cb);
lpRASEntryName->dwSize = sizeof(RASENTRYNAME);
return TRUE;
}
}
}

bRet = (dwRet?false:true);

return bRet;
}

bool CRASRegSet::GetDeficeID(TCHAR *btname, int *iDeviceID)
{
LPRASDEVINFO lpRasDevInfo = NULL;
DWORD dwBufSize = 0;
DWORD dwNumDevices = 0;
DWORD dwDeviceID = 0;
DWORD dwErr;

// find the buffer size needed
dwErr = RasEnumDevices(NULL, &dwBufSize, &dwNumDevices);
if (!dwBufSize) return false;

lpRasDevInfo = (LPRASDEVINFO)LocalAlloc(LPTR, dwBufSize);

if (!lpRasDevInfo) return false;

lpRasDevInfo->dwSize = sizeof(RASDEVINFO);

if (RasEnumDevices(lpRasDevInfo, &dwBufSize, &dwNumDevices))
{
LocalFree(lpRasDevInfo);
return false;
}

dwDeviceID = 0;
//
// Find the correct device ID for this connection type
//
while (dwDeviceID < dwNumDevices)
{
if (wcsncmp((lpRasDevInfo + dwDeviceID)->szDeviceType, RASDT_Modem, wcslen(RASDT_Modem)) == 0)
{
if(wcsncmp((lpRasDevInfo + dwDeviceID)->szDeviceName, btname, wcslen(btname)) == 0)
{
LocalFree(lpRasDevInfo);
*iDeviceID = dwDeviceID;
return true;
}
}
dwDeviceID++;
}
LocalFree(lpRasDevInfo);
return false;
}

tonyjou 發表在 痞客邦 留言(0) 人氣()