http://bbs.pediy.com/showthread.php?t=87504
标 题: 【原创】发个WM手机开关GSM模块的代码(即飞行模式开关)
作 者: NETTF小金
时 间: 2009-04-30,11:52
链 接: http://bbs.pediy.com/showthread.php?t=87504
哎,真不知道怎么一个两个都把它藏着掖着,查了半天资料以及IDA逆了来电精灵和一个一键飞行工具才明白了其中的内幕。
成品界面看附件图。
不多说了,用法是:
SetPhoneState(LINEEQUIPSTATE_MINIMUM); //开飞机
SetPhoneState(LINEEQUIPSTATE_FULL); //安全着陆
------------------------------------------------------------------------------------
DWORD GetTSPLineDeviceID(const HLINEAPP hLineApp, const DWORD dwNumberDevices, const DWORD dwAPIVersionLow, const DWORD dwAPIVersionHigh, const TCHAR* const psTSPLineName)
{
DWORD dwReturn = 0xffffffff;
for(DWORD dwCurrentDevID = 0 ; dwCurrentDevID < dwNumberDevices ; dwCurrentDevID++)
{
DWORD dwAPIVersion;
LINEEXTENSIONID LineExtensionID;
if(0 == lineNegotiateAPIVersion(hLineApp, dwCurrentDevID,
dwAPIVersionLow, dwAPIVersionHigh,
&dwAPIVersion, &LineExtensionID))
{
LINEDEVCAPS LineDevCaps;
LineDevCaps.dwTotalSize = sizeof(LineDevCaps);
if(0 == lineGetDevCaps(hLineApp, dwCurrentDevID,
dwAPIVersion, 0, &LineDevCaps))
{
BYTE* pLineDevCapsBytes = new BYTE[LineDevCaps.dwNeededSize];
if(0 != pLineDevCapsBytes)
{
LINEDEVCAPS* pLineDevCaps = (LINEDEVCAPS*)pLineDevCapsBytes;
pLineDevCaps->dwTotalSize = LineDevCaps.dwNeededSize;
if(0 == lineGetDevCaps(hLineApp, dwCurrentDevID,
dwAPIVersion, 0, pLineDevCaps))
{
if(0 == _tcscmp((TCHAR*)((BYTE*)pLineDevCaps+pLineDevCaps->dwLineNameOffset),
psTSPLineName))
{
dwReturn = dwCurrentDevID;
}
}
delete[] pLineDevCapsBytes;
}
}
}
}
return dwReturn;
}
DWORD SetPhoneState(DWORD state)
{
HLINEAPP m_hLineApp = 0;
DWORD m_dwAPIVersion = TAPI_API_HIGH_VERSION;
DWORD dwNumDevs;
LINEINITIALIZEEXPARAMS liep;
liep.dwTotalSize = sizeof(liep);
liep.dwOptions = LINEINITIALIZEEXOPTION_USEEVENT;
HLINE hLine = 0;
LONG lRC = 0;
DWORD dwState, dwRadioSupport;
TCHAR gszFriendlyAppName[160];
if(lineInitializeEx(&m_hLineApp, 0, 0, gszFriendlyAppName, &dwNumDevs, &m_dwAPIVersion, &liep)) {
return PHONEDEVICE_ERROR;
}
if(NULL == m_hLineApp)
{
return -1;
}
DWORD dwDeviceID = GetTSPLineDeviceID(m_hLineApp, dwNumDevs, TAPI_API_LOW_VERSION, TAPI_API_HIGH_VERSION, CELLTSP_LINENAME_STRING);
lRC = lineOpen( m_hLineApp, dwDeviceID, &hLine, m_dwAPIVersion, 0,
NULL, LINECALLPRIVILEGE_OWNER, LINEMEDIAMODE_DATAMODEM,
NULL);
if(lRC < 0)
{
if(hLine != NULL)
{
lineClose(hLine);
hLine = NULL;
}
return lRC;
}
//lRC = lineGetEquipmentState(hLine, &dwState, &dwRadioSupport);
//if(lRC < 0)
//{
// lineClose(hLine);
// return lRC;
//}
//if((LINEEQUIPSTATE_MINIMUM == state) ||
// (LINEEQUIPSTATE_NOTXRX == state))
//{
// lRC = lineUnregister(hLine);
// if(lRC < 0)
// {
// lineClose(hLine);
// return lRC;
// }
//}
//if(dwState != state)
//{
lRC = lineSetEquipmentState(hLine, state);
//}
if(lRC < 0)
{
lineClose(hLine);
return lRC;
}
if((LINEEQUIPSTATE_FULL == state) ||
(LINEEQUIPSTATE_RXONLY == state) ||
(LINEEQUIPSTATE_TXONLY == state))
{
lRC = lineRegister(hLine, LINEREGMODE_AUTOMATIC, NULL, LINEOPFORMAT_NONE);
if(lRC < 0)
{
lineClose(hLine);
return lRC;
}
}
lRC = lineClose(hLine);
return lRC;
}
引用库是CellCore.lib
-------------------------------------
#include <windows.h>
#include <commctrl.h>
#include <tapi.h>
#include <tsp.h>
#include <extapi.h>
#define TAPI_API_LOW_VERSION 0x00020000
#define TAPI_API_HIGH_VERSION 0x00020000
#define EXT_API_LOW_VERSION 0x00010000
#define EXT_API_HIGH_VERSION 0x00010000
#define PHONEDEVICE_ERROR 0x00000000
#define PHONEDEVICE_ERROR_SUCCESS 0x00000001
#define PHONEDEVICE_ERROR_LINEOPEN 0x00000002
#define PHONEDEVICE_ERROR_LINECLOSE 0x00000004
#define PHONEDEVICE_ERROR_GETSTATE 0x00000008
#define PHONEDEVICE_ERROR_SETSTATE 0x00000010
#define PHONEDEVICE_ERROR_UNREGISTER 0x00000020
#define PHONEDEVICE_ERROR_REGISTER 0x00000040
TAPI标准里应该是先用lineUnregister注销网络然后再lineSetEquipmentState关闭GSM,但是注销网络这一步会导致程序停止响应一会儿(因为lineUnregister要等待返回,除非用多线程去做),同时由于要注销网络,会稍慢一些,而国内其他飞行功能软件都是跳过这一步直接关GSM的,大概现在的GSM通讯升级了吧,关闭前系统会自动通知基站电话关闭的,所以去掉了lineUnregister这步,达到迅速关闭GSM的目的。