引用计数和对象的有效性

之前搞东方弹幕游戏OGG版本的时候,用了这么一套机制:实现自定义的CreateFileA、ReadFile、SetFilePointer、CloseHandle这些函数,然后替换掉程序对这些API的调用。如果CreateFileA打开的文件是thbgm.dat,那么就创建一个读取OGG文件的对象,然后把对象指针加入到一个列表中,并返回给程序;如果调用ReadFile的时候送入的HANDLE是在列表中的某个对象,就执行对象上的Read操作;SetFilePointer同理;如果调用CloseHandle的时候送入的是列表里的某个对象,就把对象从列表中删除,然后delete掉它。

继续阅读引用计数和对象的有效性

.net 2.0下往流输出文本多了抛异常

前天在群里聊天的时候,喵喵提到.net 2.0平台下,有个控制台程序运行时间久了,呃,要说有多久可能一个月那种程度吧,崩了。而且是崩在Console.Write里面。说上网找了以后说是.net平台自己有问题。

第二天有空的时候,我自己试验了一下,确实很坑,我开了个文本文件(FileStream),然后以它创建一个StreamWriter,之后往里面写了三四个G的数据,写一半的时候就直接抛出了异常,异常信息和喵喵描述的一致。

继续阅读.net 2.0下往流输出文本多了抛异常

curl_easy_perform卡着了

之前想做个挂stage1st论坛在线时间的工具,用C#写出来以后虽然用着也确实可以登录和浏览,但是用mono在vps的linux系统上跑,内存占了实在是有点多,想到vps本来内存就这么小,还跑了一大堆奇怪的服务,最后作罢。

但是果然想想还是不甘心,于是就又操起C++来弄,调用了CURL函数库来搞,这样windows和Linux下就都可以使用了。弄好以后也确实可以运行,于是就这么挂着。

为了详细知道这工具现在在干什么,所以我让它输出当前动作的信息。挂了几天之后,发现好像没有新的信息输出了。用gdb附加上去看调用栈,卡在curl_select里面了(和自己的代码的接口是curl_easy_perform)。这个时候的工具在输出信息的时候还不会附上当前的时间,所以也不太确定到底什么时候出的问题。于是我就改了一下代码,在输出的地方加上了时间,然后挂着。今天下午又发现它卡着了,看了时间,卡了2个多小时了。用gdb再附加上去,还是那个地方卡着。

继续阅读curl_easy_perform卡着了

使用WDK开发普通XP应用程序注意点

这几天尝试拿WDK的库和编译器编译普通程序。目的是为了能链接到MSVCRT.DLL上去,减小自身程序体积。

很长时间了也没有人报有什么问题,自己是Win7的系统,其实也没有测试过XP下能不能使用。

但是很坑爹的是,事实证明不行……今天贴吧上有人报了XP下无法启动,报msvcrt.dll中找不到_except_handler4_common入口。

我检查了一下我编译出来的程序的导入表,果不其然有_except_handler4_common……

网上搜了一下,出来的基本都是说你把dwmapi.dll改名吧。但是我现在是导入表中直接有这一项,明显不是这个的问题。

继续阅读使用WDK开发普通XP应用程序注意点

EasyHook的使用

在函数调用下钩子的做法,在制作非想天则对战平台以及Vorbis版的东方弹幕游戏,以及数据文件压缩版的东方非想天则的时候都做过了。无非也就是两种做法,一个是修改IAT,编译器在生成调用DLL里函数的代码的时候,用的是JMP DWORD [mm32]这样的语句,Windows在把EXE读入内存以后,查找它引用的DLL里的函数,然后加载这些DLL,然后把函数的地址填入一个表(数组)中,mm32就是这样的函数地址被填入的地方。那么只要修改这个地址,就能修改调用DLL中的函数的时候真正调用的函数。另一做法是修改函数入口处的机器代码,改为一个JMP rel32这样的语句,使得调用指定函数的时候会直接JUMP到自己的函数里面。这两种做法都要注意自己要调用真实函数的时候不要受影响就好了:导入表是以模块区分的,一个进程中的各个模块的导入表互不影响,所以如果是一个DLL把EXE的导入表改了,那么只要这个DLL的导入表是正常的,那么这个DLL中就可以随意调用原函数不受影响;修改入口处机器代码的做法,因为只修改了一个入口,所以能够执行入口处的几条指令,然后跳转到没有修改的地方继续执行下去,问题就能解决了。

继续阅读EasyHook的使用

算了一天终于把CRC32算对了,也理解了boost库的做法

满满的一种“被坑了”的感觉。

CRC32不是有什么多项式、初始值、调换bit顺序、结果xor值、调换结果位序之类的参数吗,常用的这个

多项式:0x104C11DB7
初始值:0xFFFFFFFF
结果异或值:0xFFFFFFFF
调换输入字节位序:是
调换结果字节位序:是

CRC的理论也不难,我就一个比特一个比特处理,写了这样的代码

继续阅读算了一天终于把CRC32算对了,也理解了boost库的做法

对话框开不开

写了个心绮楼改名工具,其实就是给你转个内码改个文件名的东西,期间用到了开启对话框显示图形界面的API函数DialogBox。但是似乎在某个用户的系统里,对话框连开都开不起来。这里面有什么学问实在不知。本来是想用GetLastError让该用户协助一下的,不过在那之前我去qq上敲了Riatre一下,想试试能不能敲诈出什么现成的经验来。

结果居然是大有收获。我用Resedit制作的对话框资源,和Visual Studio自带的资源编辑器制作的资源比起来,对话框少了DS_NOFAILCREATE样式( http://msdn.microsoft.com/en-us/library/windows/desktop/ff729172(v=vs.85).aspx 或者VS帮助文档的Windows desktop app development -> windows application ui development -> dialog boxes -> dialog box styles)。这样式看名字,不太像是正常情况下需要开启的啊……但是VS自带的资源编辑器居然会给你加这个!坑爹啊……

Resedit在对话框的属性里有一个No Fail Create,设为true即可。

另:据说当年萃梦想的config打不开也和没有这个样式有关

 

但是事情还没完,加上这个样式以后,那个人还是跟我说没解决。但是设置成兼容win2000可以。我就觉得很奇怪。突然间想起来xp样式那边,好像除了加清单文件,还要InitCommonControls一下。所以我在创建对话框前加了这个函数。……结果问题解决了

现在域名是 blog.sorayuki.net ~