2011-08-03 27 views
2

这个问题有点遥远,但我想也许有人知道一个聪明的解决方案。陷阱Windows应用程序崩溃和刷新文件缓冲区

我在Windows中有一个RTS游戏的特殊情况(凯恩的愤怒),它可以保存重放文件。不利的对手有可能在游戏中触发崩溃。在这种情况下,尽可能完整的重放文件将是有利的。

但是,重播文件输出似乎被缓冲,只发生在4096字节(这是很多游戏时间)的集合中。我想知道是否有可能以某种方式强制程序在发生崩溃时刷新其所有文件句柄。是否有一些内置的操作系统功能,可以禁用应用程序的缓冲?

如果失败了,我可能会为此问题编写一个启动程序/包装器。我想它应该注入一些代码,这些代码a)为崩溃安装信号处理程序(是SIGSEGV?),和b)重定向CreateFile(我知道程序使用跟踪跟踪)来存储句柄。碰撞处理程序然后将冲洗所有处理程序FlushFileBuffers

或者是否有可能获得另一个进程的打开文件句柄?

这是否有机会工作,你能给我一些关于如何用最少的入侵来达到最佳效果的建议吗?


小更新: @CatPlusPlus曾建议Detours挂接到程序,截取文件打开调用和修改它们是无缓冲。这可能是解决方案!

XCrashReport : Exception Handling and Crash Reporting - Part 1

基本上做这样的事情:

int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPTSTR lpstrCmdLine, int nCmdShow) 
{ 
    int Result = -1; 
    __try 
    { 
     Result = HandledWinMain(hInstance, NULL, lpstrCmdLine, nCmdShow); 
    } 

    __except(RecordExceptionInfo(hInstance,GetExceptionInformation(), "main thread")) 
    { 
     // Do nothing here - RecordExceptionInfo() has already done 
     // everything that is needed. Actually this code won't even 
     // get called unless you return EXCEPTION_EXECUTE_HANDLER from 
     // the __except clause. 
    } 

    return Result; 
} 

当然

+0

有没有内置的操作系统功能来做到这一点,怎么可能?操作系统并不知道缓冲甚至发生 - 它看到的是,每隔一段时间,有人会说“嗨,我想写入4096字节到这个文件”,它就这样做了。 –

+0

@Adam:好吧,和Linux上的类似,你有'ulimit'来告诉程序不要做某些事情。我想操作系统可能会说,“对于下一个过程,我们禁用所有IO缓冲”,因为IO最终会使用系统调用。 –

回答

1

那么你可以通过在try/catch块这样 文章中介绍了包装的winmain开始我不确定你的缓冲区的状态是什么,但是这将允许你进入这个过程。

+0

我可以通过这个捕获另一个程序的异常吗?请记住,我没有游戏程序的源代码,只有可执行文件。我不知何故必须得到excutable的文件句柄并捕获崩溃。 –

+0

不确定没有附加调试器是可能的,这可能不会给你任何有用的东西,你也可能想看到这个答案:http://stackoverflow.com/questions/2385859/is-it-possible-for-a -process-to-catch-an-unhandled-exception-of-another-process-o –

0

我能想到的唯一的事情就是在其汇编输出中附加一个调试器和修补程序。

我记得在某些程序中,当它们碰撞到我时,请执行此操作:跳过违规的机器指令到该函数的末尾,并让它运行。在大约50%的情况下,这将使程序达到我可以保存数据的程度。当然,之后重新启动是强制性的。

+0

好的,我希望能够将其作为包装游戏的单个启动器应用程序或类似的东西发布,所以它如果可能的话,应该是非交互的... –

1

假设该过程不是你的, 你唯一的选择似乎是挂钩WriteFile函数,而不是WriteFile,然后是Flush。
WriteFile可以挂钩IAT直接挂钩或使用像eashook这样的库。

+0

感谢您的提示!我正在考虑hooking'CreateFile',并将标志更改为无缓冲,根据MSDN,“就像在每次写入之后调用'FlushFileBuffers'一样,但效率更高......” –