2017-10-20 106 views
1

我正在寫一個低級別的記錄器函數,它將文本字符串追加到文本(日誌)文件的末尾。要求是這個函數不應該調用來自DLL的任何WinAPI,這些DLL可能還不能用於該進程 - 例如當它從一個DllMain處理程序調用時。換句話說,它不能使用除保證被加載到任何用戶模式進程中的庫之外的任何庫,即kernel32.dllntdll.dll從低級庫(如kernel32.dll或ntdll.dll)是否有wsprintf()類型的函數?

我能夠很好地與剛剛CreateFileWriteFileCloseHandleHeapAllocHeapFree等,其均來自kernel32.dll得到。

問題是格式化輸出字符串。例如,我需要添加一些額外的(自動生成的)詳細信息,例如當前時間,進程ID,會話ID等。我通常會使用wsprintf類型函數,或者StringCchPrintf準確地使用,因此:

StringCchPrintf(buffer, buffer_size, L"%04u-%02u-%02u %02u:%02u:%02u pid=0x%x, sessID=%d, %s\r\n", /* parameters */); 

但這些API違反了我上面提到的規則。

有誰知道是否有低級printf類型格式化API可用?

+1

sprintf和swprintf從* ntdll *導出。你可以免費使用它。只有一個限制 - 它不支持浮點格式 – RbMm

+0

@RbMm:嗯,有趣的我認爲這些都是CRT的功能。你從哪裏拿?還有,如果我使用浮點格式會發生什麼? – c00000fd

+0

ntdll支持幾乎所有的字符串格式化函數,不僅是這2個,而且還有'_snprintf','_snwprintf','_vsnprintf','_vsnwprintf',..如果你要使用'%f'或'%g' - 它根本不支持處理它 – RbMm

回答

2

所有版本的ntdll.dll的如何支持未來最低(從XP)字符串格式化功能:

_snprintf 
_snwprintf 
_vsnprintf 
_vsnwprintf 
sprintf 
swprintf 
vsprintf 

當然完全匹配從CRT相同功能的簽名。我們可以免費使用這個api。 ntdll的新版本添加一些新的格式字符串API。說win7(和所有最新版本)ntdll.dll導出下一個:

_snprintf 
_snprintf_s 
_snwprintf 
_snwprintf_s 
_swprintf 
_vscwprintf 
_vsnprintf 
_vsnprintf_s 
_vsnwprintf 
_vsnwprintf_s 
_vswprintf 
swprintf 
swprintf_s 
vsprintf 
vsprintf_s 
vswprintf_s 
+0

好的。很高興知道。謝謝。但有一個問題,你如何讓它鏈接到'ntdll.dll'中的函數而不是它的CRT對應的?他們中的大多數都被命名爲相同。 – c00000fd

+0

@ c00000fd - 首先lib命令很重要。如果某個函數可以在多個lib中找到 - 將首先按順序使用lib。所以你需要在任何crt庫之前使用'ntdll.lib'。然而,非常可能會在crt libs和ntdll之間產生一些衝突(這取決於您使用哪個crt庫)。我沒有這個問題,因爲我從來沒有使用crt。如果是ntdll和crt庫之間的嚴重衝突 - 你在運行時如何得到這個過程的最小地址 – RbMm

+0

注意:NTDLL中的打印函數不支持浮點數/雙精度值。 – Anders

相關問題