最近看了下windows mobile上电话过滤的开发,网上的代码都是c#的,没有找到c++的,就把代码移植到了c++上,废话不多说,直接上代码。
#include <regext.h>
#include "snapi.h"
#include "Tlhelp32.h"
const TCHAR c_szPhoneRegistryRootkey[] = TEXT("System\\State");
const TCHAR c_szPhoneRegistrySubkey[] = TEXT("Phone");
const TCHAR c_szPhoneIncomingCallerNumber[] = TEXT("Incoming Caller Number");
HREGNOTIFY g_hRegNotify ;
// The call-back function for Registry Notifications.
void RegistryNotifyCallbackFunc(HREGNOTIFY hNotify, DWORD dwUserData, const PBYTE pData, const UINT cbData)
{
if(pData != NULL && 0 == _tcscmp((TCHAR*)pData, TEXT("12345678965")))//后边这个是要拒绝的电话
{
keybd_event(0x73, 0, 0, 0);
keybd_event(0x73, 0, 0x0002, 0);
}
return;
}
void RegisterForPhoneNotifications()
{
HKEY hKey;
if (S_OK == RegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szPhoneRegistryRootkey, 0, KEY_QUERY_VALUE, &hKey))
{
//下边是注册注册表修改回调函数
HRESULT hr = RegistryNotifyCallback(hKey,
c_szPhoneRegistrySubkey,
c_szPhoneIncomingCallerNumber,
RegistryNotifyCallbackFunc,
1,
NULL,
&g_hRegNotify );
RegCloseKey(hKey);
}
}
void wmain()
{
RegisterForPhoneNotifications();
Sleep(1000000);
}
原理是这样的:监控注册表的某项值,上边有来电的号码,然后如果不想接听的话那么就模拟发送键盘码。
但是这样的问题是还会在手机上的未接来电表中留下记录,把那个记录删除就行了。删除的方法就是删除pim.vol中的clog.db。
记得前段时间写过怎么样禁用存储卡,就是将HKLM\drivers\active中存储卡驱动对应的handle卸载掉就成了。虽然能够卸载,但是再重新插上存储卡还是加载上了,因此需要监控存储卡的消息。那么如何解决时刻监控是否有存储卡插入呢?
答案是在消息循环中处理WM_DEVICECHANGE消息,如果wParam是DBT_DEVICEARRIVAL的话,那么就是插入的消息。这时候再枚举上面提到的注册表,找到存储卡驱动的handle并DeactivateDevice就成了。
由于开发的需要,需要在模拟器上实现连接gprs的功能。检索google相关资料很少,只在msdn上看到了篇英文文章。下边哥截图来说下步骤:
首先,当然是配置连接windows mobile SDK带的cellular emulator了。
点模拟器上的文件–配置–接口(我的是英文的,翻译过来应该是这样)。串口0改成cellular emulator左下角显示的端口,我的是COM3.

然后就是在模拟器中设置网络连接了,打开开始菜单–设置–连接,在连接选项中点击添加新调制解调器,

然后输入连接名,并选择调制解调器为”电话线路(GPRS)”,如图:

点下一步,输入一个名称(我输入的是GPRS),再点下一步,点确定。
然后就是在开始菜单–设置–连接点“高级”,点击 “选择网络”,在程序自动连接到Internet时,使用这个选项选择“单位设置”。
重启模拟器,然后在IE中输入个网址,在cellular emulatoe中的network选项卡下可以看到接受的数据,发送的数据以及使用时间。

搞定。上图的左下角就是在模拟器中设置的端口。
今天开始这个系列的第三期。
经过一个多星期的研究,还是有一些成果的。但是还有些问题需要解决。
首先是发送的数据包,这个数据包在MiniportSendPackets这个函数里。代码如下:
PUCHAR pPacketContent;
NDIS_STATUS ntStatus = NDIS_STATUS_SUCCESS;
UINT i;
MDL *pNext;
NDIS_PHYSICAL_ADDRESS HighestAcceptableMax = NDIS_PHYSICAL_ADDRESS_CONST(-1, -1);
UINT BufLength;
PUCHAR pBuf;
ntStatus = NdisAllocateMemory(&pPacketContent,2000,0,HighestAcceptableMax);
if(ntStatus != NDIS_STATUS_SUCCESS)
{
a = fopen("123.txt", "a+");
fprintf(a, "NdisAllocateMemory failed \n");
fclose(a);
}
NdisZeroMemory(pPacketContent,2000);
NdisQueryBufferSafe(pPacket->Private.Head,&pBuf,&BufLength,32);
NdisMoveMemory(pPacketContent,pBuf,BufLength);
i = BufLength;
pNext = pPacket->Private.Head;
for(;;)
{
if(pNext == pPacket->Private.Tail)
break;
pNext = pNext->Next;
if(pNext == NULL)
break;
NdisQueryBufferSafe(pNext,&pBuf,&BufLength,32);
NdisMoveMemory(pPacketContent+i,pBuf,BufLength);
i+=BufLength;
}
;
这里的pPacketContent就是发送的数据包的内容,从MAC层开始的,只要解析这里的内容就成了。
接着是接收的数据包,在ProtocolReceive函数中,其中参数pvHeaderBuffer表示的是MAC层的数据,pvLookAheadBuffer是ip层+传输层+应用层的数据,但是数据不全,我上边说的问题就是这个地方,得找个办法把全部数据给获取出来。
明天接着研究。
去年做这个的时候,使用的是假驱动的方式。就是把注册表中的storage card的驱动名改成我们自己做的假驱动,然后在这个驱动中导出和原来的驱动一模一样的函数。在这些假函数中调用真正的驱动的对应函数。如果禁用的话,那么就直接返回false,从而无法读写storage card。但是这种方法还是有很大的问题的,首先,不是真正的禁用storage card,在文件管理器中还能看到有,只是没法读写而已。其次,如果手机待机的话,很有可能起不来。
今天发现了一种方法,可以完美去禁用storage card。我们知道,在注册表的HKLM\drivers\active中,是那些已经启用的驱动,而每个子键中都有这个驱动对应的句柄。所以只要能找到storage card对应的驱动的句柄,然后再调用deactivatedevice,把驱动给注销了,storage card就从文件管理器中消失了。
先说个题外话,哥上次得的那个财付通的信用卡打折密码是20元。
昨天提到使用模拟器绑定网卡无法上网的问题,今天来说下解决办法。
首先说下这个使用模拟器上网配置的办法。在模拟器上点击file->configure->network,勾选第一个复选框,然后在下边选择你的物理网卡。
这时候会提示安装模拟器网卡驱动,去安装个virtual pc就成了。
还没完,关键是下边。在模拟器模拟的windows mobile系统,点“开始”->“设置”->“连接”->“网卡”,在“我的网卡连接到”这个下拉列表中选“默认Internet设置”,双击下边的“NE2000兼容Ethernet驱动程序”,在这里按你电脑的配置配就行了。
大功告成,可以上网了!
该系列可能会持续几个,所以先暂时用系列方式写。
今天开始研究windows mobile也就是windows ce上的网络过滤驱动,在去年六七月份曾经研究过一段时间,但是当时刚接触windows mobile开发,没有整理出头绪出来。
今天开始接着去年的做,上午试验了下platform builder5自带的ndisuio,能编译过去,但是发现windows mobile手机已经自带了这个驱动,没辙,只能换另一个了。也就是passthru。
这个驱动编译起来也不困难。打上签名,改好注册表,放进去,结果死活起不来。
注册表的位置是:[HKEY_LOCAL_MACHINE\Comm\PASSTHRU]
“Group”=”NDIS”
“ImagePath”=”passthru.dll”
“NoDeviceCreate”=dword:1
没办法,突发奇想,是不是签名的证书不对啊,前几天发了篇日志介绍了在mobile SDK自带的证书过期的情况下,换DTK证书替代的日志。司马当活马医,又把原来的证书安装上,把日期刚到09年,编译居然能加载驱动了。估计是windows mobile 6自带的模拟器上没有带DTK证书对应的证书。
加载了却没有打印出日志,只是显示了driverentry和绑定网卡的日志。我在模拟器上是通过crade的办法通过activesync上网的。后来换了种方法,在模拟器上换成让模拟器直接绑定物理网卡的方法。哈哈,居然所有的日志都打印出来了。但是这种情况却没有办法上网。唉,明天还得接着调。
however,撒花庆祝下。
自从开始windows mobile开发以来,顺顺当当,没有出过什么大的问题。但是有的地方需要证书签名才成,如mapirule,否则的话加载不起来,签名就签名吧。无所谓,也不费事。
但是灾难来临了,2010年1月1日,崩溃了,死活签不了,后来查看错误代码,才发现windows mobile自带的测试证书过期时间是2009年12月31日。天那,从那以后就只能先调时间再签名了。 阅读全文…
今天测试了下,windows mobile 6最多能够加载10个存储卡,在注册表中drivers\active里显示的名称顺序如下:
第一个加载的存储卡是DSK1:,第二个是DSK2:。以此类推,一直到DSK9:。
第10个就成DSK0:了。因为这个设备名只能是5位,而前3位是DSK,最后一位是冒号,因此最多就只能加载10个存储卡了。
昨天买的那个福彩3D没中。
昨天装了个家财通,哥要开始记账了,赶紧稍微有点复杂,不过以哥的能力这种软件哪有玩不转那么一说。
今天测试的时候发现程序有大问题。有个dll注入去判断进程名,如果符合某些特征就在dllmain中返回false。结果发现同样的进程名,如果打开这个进程的快捷方式没问题,如果这个进程是后台程序没问题,但是如果是窗口程序就挂死了。也不知道是模拟器的问题还是这个程序的问题。