12 #undef USE_ULIB_DBGOUTPUT // Temp dbg squelch... 13 #define USE_ULIB_DBGOUTPUT 0 // DbgOutput fails to emit in rare corner cases ?? 15 #ifndef USE_ULIB_DBGOUTPUT // Use custom DbgOutput instead of OutputDebugString? 16 #ifdef HAVE_STRUCTURED_EH 17 #define USE_ULIB_DBGOUTPUT 1 19 #define USE_ULIB_DBGOUTPUT 0 // __try/__except is required. 23 #if !defined(HAVE_STRUCTURED_EH) || defined(_UNICODE) 26 #undef USE_ULIB_DBGOUTPUT 27 #define USE_ULIB_DBGOUTPUT 0 41 static __thread_local TCHAR sBuf[ MAX_PATH ];
43 if (!Err) Err = GetLastError();
53 DWORD flags = FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS;
54 DWORD len = FormatMessage( flags, 0, Err, 0, Buf, Length, 0 );
56 _stprintf_s( Buf, Length, _T(
"Error %lu (0x%08lX)"), HRESULT_CODE(Err), Err );
60 while( *end ==
CR || *end ==
LF ) *end-- = 0;
69 return SysErrorMsg( LsaNtStatusToWinError( Status ), Buf, Size );
76 static VOID (NTAPI *RtlSetLastErrorFromNtStatus)( NTSTATUS Status );
77 if (!RtlSetLastErrorFromNtStatus)
79 HMODULE hMod = GetModuleHandleA(
"NTDLL" );
84 static CCASTR S_Api =
"RtlSetLastWin32ErrorAndNtStatusFromNtStatus";
85 (FARPROC&) RtlSetLastErrorFromNtStatus = GetProcAddress( hMod, S_Api );
87 bool ok = (RtlSetLastErrorFromNtStatus != NULL);
88 if (ok) RtlSetLastErrorFromNtStatus( Status );
89 else SetLastError( LsaNtStatusToWinError( Status ));
120 #define _DP_MAXLEN_ 512 // DPrint buffer size (512 = kernel debugger's buffer) 122 #if USE_ULIB_DBGOUTPUT 125 #define DbgOutput(s) OutputDebugString(s) 128 static volatile bool __inDPrint =
false;
162 default: pch += _stprintf( pch, _T(
" LEVEL%i: "), Level );
166 int len = int( pch - buf );
167 int remain =
dimof(buf) - len;
170 #ifndef HAVE_STRUCTURED_EH // No SEH in GCC. ("Libify" ReactOS's SEH2/3 and use that?) 171 len += _vstprintf_s( pch, remain, Fmt, va );
178 len += _vsntprintf( pch, remain, Fmt, va );
185 xCode = GetExceptionCode();
187 _T(
"[uLib] SEVERE: [DPrint] Exception 0x%08X in _vsntprintf.")
188 _T(
" Check your code!\n"), xCode
203 WideCharToMultiByte( CP_ACP, 0, buf,-1, ansi,
dimof(ansi), NULL, NULL );
224 DWORD dispo = Append ? OPEN_ALWAYS : CREATE_ALWAYS;
225 DWORD flags = FILE_FLAG_SEQUENTIAL_SCAN;
226 DWORD share = FILE_SHARE_READ;
228 HANDLE hFile =
CheckHandle( CreateFile( Name, GENERIC_WRITE, share, NULL, dispo, flags, NULL ));
232 if (Append) SetFilePointer( hFile, 0,0, FILE_END );
241 static TCHAR LogName[ MAX_PATH ];
242 int len = GetModuleFileName( hModule, LogName,
dimof(LogName) );
245 TSTR pzDot = _tcsrchr( LogName,
DOT );
246 if (!pzDot) pzDot = LogName + _tcslen( LogName );
249 _tcscpy( pzDot, _T(
".log") );
255 #if USE_ULIB_DBGOUTPUT 298 #define BUFFER_READY_EVT_NAME _T("DBWIN_BUFFER_READY") 299 #define DATA_READY_EVT_NAME _T("DBWIN_DATA_READY") 300 #define DBMUTEX_NAME _T("DBWinMutex") 301 #define SHARED_BUFFER_NAME _T("DBWIN_BUFFER") 302 #define SHARED_BUFFER_SIZE 4096 304 #ifndef DBG_PRINTEXCEPTION_C 305 #define DBG_PRINTEXCEPTION_C 0x40010006L 310 static int __stdcall dbo_ExecFilter(
DWORD xCode )
312 static const int Execute = EXCEPTION_EXECUTE_HANDLER;
313 static const int Search = EXCEPTION_CONTINUE_SEARCH;
314 return (xCode == DBG_PRINTEXCEPTION_C) ? Execute : Search;
319 static const UINT MAX_BUFAVAIL = SHARED_BUFFER_SIZE -
sizeof(
DWORD) - 1;
320 static const UINT DBWIN_TIMEOUT = 10000;
324 static HANDLE hSharedFile;
325 static PBYTE pSharedMem;
326 static HANDLE hAckEvent;
327 static HANDLE hReadyEvent;
328 static HANDLE hDbgMutex;
335 if (pSharedMem) { UnmapViewOfFile( pSharedMem ); pSharedMem = NULL; }
348 xArg[0] = 1 + _tcslen( Str );
349 xArg[1] = (ULONG_PTR) Str;
351 RaiseException( DBG_PRINTEXCEPTION_C, 0, 2, xArg );
353 __except( dbo_ExecFilter( GetExceptionCode() ))
380 if (!
DefSec.lpSecurityDescriptor)
386 hDbgMutex = CreateMutex( &
DefSec, FALSE, DBMUTEX_NAME );
391 if (!
WaitFor( hDbgMutex, DBWIN_TIMEOUT ))
399 hSharedFile = OpenFileMapping( FILE_MAP_WRITE, FALSE, SHARED_BUFFER_NAME );
400 pSharedMem = hSharedFile
401 ? (
PBYTE) MapViewOfFile( hSharedFile, FILE_MAP_WRITE, 0,0,0 )
403 hAckEvent = pSharedMem
404 ? OpenEvent( SYNCHRONIZE, FALSE, BUFFER_READY_EVT_NAME )
406 hReadyEvent = hAckEvent
407 ? OpenEvent( EVENT_MODIFY_STATE, FALSE, DATA_READY_EVT_NAME )
410 ReleaseMutex( hDbgMutex );
413 if (!hReadyEvent)
goto dbgout_Exit;
416 nRemain = (UINT)_tcslen( pzOutput );
417 DWORD procId = GetCurrentProcessId();
421 if (
WaitFor( hAckEvent, DBWIN_TIMEOUT ))
423 *
PDWORD( pSharedMem ) = procId;
425 UINT Used = (nRemain < MAX_BUFAVAIL) ? nRemain : MAX_BUFAVAIL;
426 PBYTE pzShared = (pSharedMem +
sizeof(
DWORD));
427 memcpy( pzShared, pzOutput, Used );
428 pzShared[ Used ] = 0;
430 Sent =
bool_cast( SetEvent( hReadyEvent ));
442 #endif//USE_ULIB_DBGOUTPUT HANDLE CloseHandleEx(HANDLE H)
HANDLE CheckHandle(HANDLE Hnd)
CSTR FileTimeStr(FILETIME *FTime, CSTR Fmt=_T("%Y-%m-%d %H.%M.%S"))
bool WaitFor(HANDLE hObj, DWORD msWait)
#define BEGIN_STRSAFE_OVERRIDE
void __cdecl DPrint(int Level, CSTR Fmt,...)
TSTR newStrBuf(WORD nChar)
HANDLE OpenLogFile(CSTR Name, bool Append)
bool InitializeSecDesc(PSECURITY_DESCRIPTOR pSecDesc, PACL AccsList=NULL)
volatile ULONG nDPrintSkipped
SECURITY_DESCRIPTOR DefSecDesc
bool SetLastErrorFromNtStatus(NTSTATUS Status)
int SetDebugLevel(int Level)
CSTR SysErrorMsg(DWORD Err, TSTR Buf, UINT Length)
SECURITY_ATTRIBUTES DefSec
bool __forceinline bool_cast(BOOL B52)
CSTR NtErrorMsg(NTSTATUS Status, TSTR Buf, UINT Size)
Debug and error handling support.
FILETIME Now(eTimeType Domain)
CSTR DefaultLogFileName(HMODULE hModule)
#define END_STRSAFE_OVERRIDE