2011-08-03 65 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'一樣,但效率更高......」 –