C++解析Foxmail本地时间存储文件recvdate.ind

写给C++开发人员,研究过程当然是曲折的,自己不懂delphi导致花了近4天才研究出来,还是要多了解其他语言,他山之石可以攻玉。

Foxmail7.0往后本地邮件数据不再是类似eml格式了,要获取数据只能自己逆向。

在软件安装路径下有用户数据文件夹,里面可以找到时间文件如C:\Foxmail 7.2\Storage\xxx@163.com\Indexes\recvdate.ind。

用UE打开后取出一封邮件的ascii信息来,如下:

00000020h: A1 C2 3F AE 00 00 00 01 00 0B 3C E0 03 55 74 60 ; ÷??.....<?Ut`

PS:这个的实际时间是 2017-05-31 15:32:12

分析一下,“A1 C2 3F AE ”是标识头,“ 00 00 00 01”是邮件编号,“00 0B 3C E0 03 55 74 60”当然就是时间信息了,但是坑来了,我一开始觉得“00 0B 3C E0 03 55 74 60”按4位分开明显是一个FILETIME的高位低位,百度一下还真的有这样的写法,于是各种组合,FileTimeToSystemTime函数结果都不对。

后面怀疑是是double类型的OLD时间,但是计算结果的年份一直不对,又没进展了。

百度得知Foxmail是用delphi开发的,直到看了delphi中TDateTime的基本知识http://blog.sina.com.cn/s/blog_56592a9f010008ku.html

才知道“在delphi里TDateTime类型本质上是Double类型的,其中整数位用于表达从1899年12月30日到现在所已经过去的天数”,也就是说“ OLD 转为 字符串日期” 中间要减去“1899年12月30日”并不是常见的1900-0-0的间隔。

上面说错了不过可以参考一下,其实并不是直接减去这么简单,是要把delphi的Double日期转为windows的Double日期,详情百度“delphi里TDateTime转FILETIME”。

简单提一下我的转法:

将d整数部分+1然后拿date里面的年-1899,小数部分自己计算。

	QString qtstr = maptable->data43.toHex().toUpper();
	long qtlong = qtstr.toLong(0, 16);//年月日
	char chBuff[128];
	sprintf(chBuff, "%d.%d", qtlong, 0);//计算方式不同不可用于计算时分秒
	double d = atof(chBuff);
	d += 1;//delphi里TDateTime转FILETIME 天数差1(1899-12-30 1990-0-0)
	_variant_t GetMaliTime;
	GetMaliTime.ChangeType(VT_DATE);
	GetMaliTime = d;
	_bstr_t Btime(GetMaliTime);
	std::string strData = Btime;//3916/05/30 00:00:00
	//处理年月日
	std::string strnyr[3];
	int n = 0;
	for (int s = 0; s < strData.size();s++)
	{
		if (strData[s]=='/'){
			n++;
		}
		else if (strData[s] == '\040'){
			break;
		}
		else{
			strnyr[n] += strData[s];
		}
	}
	int iyear = atoi(strnyr[0].c_str());//delphi里TDateTime转FILETIME 年要-1899
	iyear -= 1899;
	//计算时分秒
	qtstr = maptable->data44.toHex().toUpper();
	qtlong = qtstr.toLong(0, 16);
	DWORD haomiao = qtlong;//0x020808B3 
	DWORD miao = haomiao / 1000;
	DWORD real_haomiao = haomiao - miao * 1000;//毫秒
	DWORD fen = miao / 60;
	DWORD real_miao = miao - fen * 60;//秒
	DWORD shi = fen / 60;
	DWORD real_fen = fen - shi * 60;//分

	char chtime[32] = { 0 };
	sprintf(chtime, "%04d/%02s/%02s %02d:%02d:%02d", 
		iyear, strnyr[1].c_str(), strnyr[2].c_str(), shi, real_fen, real_miao);

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值