https://git.reactos.org/?p=reactos.git;a=commitdiff;h=85377ee3dbe2373d40dc401b1d6349c391cd9d94

commit 85377ee3dbe2373d40dc401b1d6349c391cd9d94
Author:     Katayama Hirofumi MZ <katayama.hirofumi...@gmail.com>
AuthorDate: Mon Sep 11 04:37:27 2023 +0900
Commit:     GitHub <nore...@github.com>
CommitDate: Mon Sep 11 04:37:27 2023 +0900

    [SDK][CRT][MSVCRT] Implement _CrtSetReportMode and _CrtSetReportFile (#5662)
    
    - Implement reporting to file.
    CORE-11835, CORE-15517, ROSTESTS-386
---
 dll/win32/msvcrt/msvcrt.spec |  8 +++---
 sdk/include/crt/crtdbg.h     |  9 ++++---
 sdk/lib/crt/misc/dbgrpt.cpp  | 60 +++++++++++++++++++++++++++++++++++++++-----
 sdk/lib/crt/misc/misc.cmake  |  1 +
 4 files changed, 64 insertions(+), 14 deletions(-)

diff --git a/dll/win32/msvcrt/msvcrt.spec b/dll/win32/msvcrt/msvcrt.spec
index e80a290e2fd..9f2c5a55eb6 100644
--- a/dll/win32/msvcrt/msvcrt.spec
+++ b/dll/win32/msvcrt/msvcrt.spec
@@ -199,9 +199,9 @@
 @ cdecl -arch=i386 _CItanh()
 @ stub -version=0x600+ _CrtCheckMemory
 @ stub -version=0x600+ _CrtDbgBreak
-@ stub -version=0x600+ _CrtDbgReport
+@ cdecl -version=0x600+ _CrtDbgReport(long str long str str)
 @ stub -version=0x600+ _CrtDbgReportV
-@ stub -version=0x600+ _CrtDbgReportW
+@ cdecl -version=0x600+ _CrtDbgReportW(long wstr long wstr wstr)
 @ stub -version=0x600+ _CrtDbgReportWV
 @ stub -version=0x600+ _CrtDoForAllClientObjects
 @ stub -version=0x600+ _CrtDumpMemoryLeaks
@@ -218,10 +218,10 @@
 @ stub -version=0x600+ _CrtSetDbgBlockType
 @ stub -version=0x600+ _CrtSetDbgFlag
 @ stub -version=0x600+ _CrtSetDumpClient
-@ stub -version=0x600+ _CrtSetReportFile
+@ cdecl -version=0x600+ _CrtSetReportFile(long ptr)
 @ stub -version=0x600+ _CrtSetReportHook
 @ stub -version=0x600+ _CrtSetReportHook2
-@ stub -version=0x600+ _CrtSetReportMode
+@ cdecl -version=0x600+ _CrtSetReportMode(long long)
 @ stdcall _CxxThrowException(long long)
 @ cdecl -arch=i386 -norelay _EH_prolog()
 @ cdecl _Getdays()
diff --git a/sdk/include/crt/crtdbg.h b/sdk/include/crt/crtdbg.h
index 3a20d5316fb..f9545698e89 100644
--- a/sdk/include/crt/crtdbg.h
+++ b/sdk/include/crt/crtdbg.h
@@ -91,8 +91,6 @@ extern "C" {
 #endif
 
 
-
-
 // Assertion and error reporting
 
 #ifndef _DEBUG
@@ -124,6 +122,8 @@ extern "C" {
     #define _RPTFW0(rptno,msg)
     #define _RPTFWN(rptno,msg,...)
 
+    #define _CrtSetReportMode(t,f) ((int)0)
+    #define _CrtSetReportFile(t,f) ((_HFILE)0)
 
 #else // _DEBUG
 
@@ -161,6 +161,9 @@ extern "C" {
     #define _RPTFW0(rptno,msg)      _RPT_BASEW(rptno, _CRT_WIDE(__FILE__), 
__LINE__, NULL, L"%s", msg)
     #define _RPTFWN(rptno,msg,...)  _RPT_BASEW(rptno, _CRT_WIDE(__FILE__), 
__LINE__, NULL, msg, __VA_ARGS__)
 
+    int __cdecl _CrtSetReportMode(int reportType, int reportMode);
+    _HFILE __cdecl _CrtSetReportFile(int reportType, _HFILE reportFile);
+
 #endif
 
 
@@ -230,8 +233,6 @@ extern "C" {
 #define _CrtGetReportHook() ((_CRT_REPORT_HOOK)0)
 #define _CrtSetReportHook2(t,f) ((int)0)
 #define _CrtSetReportHookW2(t,f) ((int)0)
-#define _CrtSetReportMode(t,f) ((int)0)
-#define _CrtSetReportFile(t,f) ((_HFILE)0)
 
 #define _CrtSetBreakAlloc(a) ((long)0)
 #define _CrtSetAllocHook(f) ((_CRT_ALLOC_HOOK)0)
diff --git a/sdk/lib/crt/misc/dbgrpt.cpp b/sdk/lib/crt/misc/dbgrpt.cpp
index dbb1ebbc966..131a918a2e2 100644
--- a/sdk/lib/crt/misc/dbgrpt.cpp
+++ b/sdk/lib/crt/misc/dbgrpt.cpp
@@ -16,6 +16,8 @@
 #include <windows.h>
 
 #undef OutputDebugString
+#undef _CrtSetReportMode
+#undef _CrtSetReportFile
 
 #define DBGRPT_MAX_BUFFER_SIZE  4096
 #define DBGRPT_ASSERT_PREFIX_MESSAGE    "Assertion failed: "
@@ -38,6 +40,13 @@ static const wchar_t* _CrtModeMessages[_CRT_ERRCNT] =
     L"Error",
     L"Assertion Failed"
 };
+// Report files
+static _HFILE _CrtReportFiles[_CRT_ERRCNT] =
+{
+    _CRTDBG_INVALID_HFILE,
+    _CRTDBG_INVALID_HFILE,
+    _CRTDBG_INVALID_HFILE
+};
 
 // Manually delay-load as to not have a dependency on user32
 typedef int (WINAPI *tMessageBoxW)(_In_opt_ HWND hWnd, _In_opt_ LPCWSTR 
lpText, _In_opt_ LPCWSTR lpCaption, _In_ UINT uType);
@@ -57,6 +66,7 @@ struct dbgrpt_char_traits<char>
     static const char_t* szUnknownFile;
 
     static void OutputDebugString(const char_t* message);
+    static size_t StringLength(const char_t* str) { return strlen(str); }
 };
 
 template<>
@@ -69,13 +79,13 @@ struct dbgrpt_char_traits<wchar_t>
     static const char_t* szUnknownFile;
 
     static void OutputDebugString(const char_t* message);
+    static size_t StringLength(const char_t* str) { return wcslen(str); };
 };
 
 // Shortcut
 typedef dbgrpt_char_traits<char> achar_traits;
 typedef dbgrpt_char_traits<wchar_t> wchar_traits;
 
-
 const wchar_t* achar_traits::szAssertionMessage =
     L"Debug %s!\n"
     L"%s%hs" /* module */
@@ -97,17 +107,16 @@ const wchar_traits::char_t* wchar_traits::szEmptyString = 
L"";
 const achar_traits::char_t* achar_traits::szUnknownFile = "<unknown file>";
 const wchar_traits::char_t* wchar_traits::szUnknownFile = L"<unknown file>";
 
-void achar_traits::OutputDebugString(const char* message)
+inline void achar_traits::OutputDebugString(const char* message)
 {
     OutputDebugStringA(message);
 }
 
-void wchar_traits::OutputDebugString(const wchar_t* message)
+inline void wchar_traits::OutputDebugString(const wchar_t* message)
 {
     OutputDebugStringW(message);
 }
 
-
 static
 HMODULE _CrtGetUser32()
 {
@@ -221,6 +230,46 @@ void _CrtLeaveDbgReport(int reportType)
         _InterlockedDecrement(&_CrtInAssert);
 }
 
+EXTERN_C
+int __cdecl _CrtSetReportMode(int reportType, int reportMode)
+{
+    if (reportType >= _CRT_ERRCNT || reportType < 0)
+        return 0;
+
+    int oldReportMode = _CrtModeOutputFormat[reportType];
+    if (reportMode != _CRTDBG_REPORT_MODE)
+        _CrtModeOutputFormat[reportType] = reportMode;
+    return oldReportMode;
+}
+
+EXTERN_C
+_HFILE __cdecl _CrtSetReportFile(int reportType, _HFILE reportFile)
+{
+    if (reportType >= _CRT_ERRCNT || reportType < 0)
+        return NULL;
+
+    _HFILE oldReportFile = _CrtReportFiles[reportType];
+    if (reportFile != _CRTDBG_REPORT_FILE)
+        _CrtReportFiles[reportType] = reportFile;
+    return oldReportFile;
+}
+
+template <typename char_t>
+static inline BOOL _CrtDbgReportToFile(HANDLE hFile, const char_t* szMsg)
+{
+    typedef dbgrpt_char_traits<char_t> traits;
+
+    if (hFile == _CRTDBG_INVALID_HFILE || hFile == NULL)
+        return FALSE;
+
+    if (hFile == _CRTDBG_FILE_STDOUT)
+        hFile = ::GetStdHandle(STD_OUTPUT_HANDLE);
+    else if (hFile == _CRTDBG_FILE_STDERR)
+        hFile = ::GetStdHandle(STD_ERROR_HANDLE);
+
+    DWORD cbMsg = (DWORD)(traits::StringLength(szMsg) * sizeof(char_t));
+    return ::WriteFile(hFile, szMsg, cbMsg, &cbMsg, NULL);
+}
 
 template <typename char_t>
 static int _CrtHandleDbgReport(int reportType, const char_t* 
szCompleteMessage, const char_t* szFormatted,
@@ -230,8 +279,7 @@ static int _CrtHandleDbgReport(int reportType, const 
char_t* szCompleteMessage,
 
     if (_CrtModeOutputFormat[reportType] & _CRTDBG_MODE_FILE)
     {
-        OutputDebugStringA("ERROR: Please implement _CrtSetReportFile 
first\n");
-        _CrtDbgBreak();
+        _CrtDbgReportToFile<char_t>(_CrtReportFiles[reportType], 
szCompleteMessage);
     }
 
     if (_CrtModeOutputFormat[reportType] & _CRTDBG_MODE_DEBUG)
diff --git a/sdk/lib/crt/misc/misc.cmake b/sdk/lib/crt/misc/misc.cmake
index d5cea9dd5cc..7b8bb4c9efd 100644
--- a/sdk/lib/crt/misc/misc.cmake
+++ b/sdk/lib/crt/misc/misc.cmake
@@ -15,6 +15,7 @@ list(APPEND CRT_MISC_SOURCE
     misc/amsg.c
     misc/assert.c
     misc/crt_init.c
+    misc/dbgrpt.cpp
     misc/environ.c
     misc/getargs.c
     misc/i10output.c

Reply via email to