848 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			C++
		
	
	
	
		
		
			
		
	
	
			848 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			C++
		
	
	
	
|  | //////////////////////////////////////////////////////////////////////////////
 | ||
|  | //
 | ||
|  | //  Detours Test Program (syelog.cpp of syelog.lib)
 | ||
|  | //
 | ||
|  | //  Microsoft Research Detours Package
 | ||
|  | //
 | ||
|  | //  Copyright (c) Microsoft Corporation.  All rights reserved.
 | ||
|  | //
 | ||
|  | #include <windows.h>
 | ||
|  | #include <stdarg.h>
 | ||
|  | #include <stddef.h>
 | ||
|  | #include <stdlib.h>
 | ||
|  | #include "detours.h"
 | ||
|  | #include "syelog.h"
 | ||
|  | 
 | ||
|  | #include <stdio.h>
 | ||
|  | 
 | ||
|  | //////////////////////////////////////////////////////////////////////////////
 | ||
|  | extern "C" { | ||
|  |     extern HANDLE ( WINAPI * Real_CreateFileW)(LPCWSTR a0, | ||
|  |                                                DWORD a1, | ||
|  |                                                DWORD a2, | ||
|  |                                                LPSECURITY_ATTRIBUTES a3, | ||
|  |                                                DWORD a4, | ||
|  |                                                DWORD a5, | ||
|  |                                                HANDLE a6); | ||
|  |     extern BOOL ( WINAPI * Real_WriteFile)(HANDLE hFile, | ||
|  |                                            LPCVOID lpBuffer, | ||
|  |                                            DWORD nNumberOfBytesToWrite, | ||
|  |                                            LPDWORD lpNumberOfBytesWritten, | ||
|  |                                            LPOVERLAPPED lpOverlapped); | ||
|  |     extern BOOL ( WINAPI * Real_FlushFileBuffers)(HANDLE hFile); | ||
|  |     extern BOOL ( WINAPI * Real_CloseHandle)(HANDLE hObject); | ||
|  | 
 | ||
|  |     extern BOOL ( WINAPI * Real_WaitNamedPipeW)(LPCWSTR lpNamedPipeName, DWORD nTimeOut); | ||
|  |     extern BOOL ( WINAPI * Real_SetNamedPipeHandleState)(HANDLE hNamedPipe, | ||
|  |                                                          LPDWORD lpMode, | ||
|  |                                                          LPDWORD lpMaxCollectionCount, | ||
|  |                                                          LPDWORD lpCollectDataTimeout); | ||
|  | 
 | ||
|  |     extern DWORD ( WINAPI * Real_GetCurrentProcessId)(VOID); | ||
|  |     extern VOID ( WINAPI * Real_GetSystemTimeAsFileTime)(LPFILETIME lpSystemTimeAsFileTime); | ||
|  | 
 | ||
|  |     extern VOID ( WINAPI * Real_InitializeCriticalSection)(LPCRITICAL_SECTION lpSection); | ||
|  |     extern VOID ( WINAPI * Real_EnterCriticalSection)(LPCRITICAL_SECTION lpSection); | ||
|  |     extern VOID ( WINAPI * Real_LeaveCriticalSection)(LPCRITICAL_SECTION lpSection); | ||
|  | } | ||
|  | 
 | ||
|  | ///////////////////////////////////////////////////////////////////// VPrintf.
 | ||
|  | //
 | ||
|  | // Completely side-effect free printf replacement (but no FP numbers).
 | ||
|  | //
 | ||
|  | static PCHAR do_base(PCHAR pszOut, UINT64 nValue, UINT nBase, PCSTR pszDigits) | ||
|  | { | ||
|  |     CHAR szTmp[96]; | ||
|  |     int nDigit = sizeof(szTmp)-2; | ||
|  |     for (; nDigit >= 0; nDigit--) { | ||
|  |         szTmp[nDigit] = pszDigits[nValue % nBase]; | ||
|  |         nValue /= nBase; | ||
|  |     } | ||
|  |     for (nDigit = 0; nDigit < sizeof(szTmp) - 2 && szTmp[nDigit] == '0'; nDigit++) { | ||
|  |         // skip leading zeros.
 | ||
|  |     } | ||
|  |     for (; nDigit < sizeof(szTmp) - 1; nDigit++) { | ||
|  |         *pszOut++ = szTmp[nDigit]; | ||
|  |     } | ||
|  |     *pszOut = '\0'; | ||
|  |     return pszOut; | ||
|  | } | ||
|  | 
 | ||
|  | static PCHAR do_str(PCHAR pszOut, PCHAR pszEnd, PCSTR pszIn) | ||
|  | { | ||
|  |     while (*pszIn && pszOut < pszEnd) { | ||
|  |         *pszOut++ = *pszIn++; | ||
|  |     } | ||
|  |     *pszOut = '\0'; | ||
|  |     return pszOut; | ||
|  | } | ||
|  | 
 | ||
|  | static PCHAR do_wstr(PCHAR pszOut, PCHAR pszEnd, PCWSTR pszIn) | ||
|  | { | ||
|  |     while (*pszIn && pszOut < pszEnd) { | ||
|  |         *pszOut++ = (CHAR)*pszIn++; | ||
|  |     } | ||
|  |     *pszOut = '\0'; | ||
|  |     return pszOut; | ||
|  | } | ||
|  | 
 | ||
|  | static PCHAR do_estr(PCHAR pszOut, PCHAR pszEnd, PCSTR pszIn) | ||
|  | { | ||
|  |     while (*pszIn && pszOut < pszEnd) { | ||
|  |         if (*pszIn == '<') { | ||
|  |             if (pszOut + 4 > pszEnd) { | ||
|  |                 break; | ||
|  |             } | ||
|  |             pszIn++; | ||
|  |             *pszOut++ = '&'; | ||
|  |             *pszOut++ = 'l'; | ||
|  |             *pszOut++ = 't'; | ||
|  |             *pszOut++ = ';'; | ||
|  |         } | ||
|  |         else if (*pszIn == '>') { | ||
|  |             if (pszOut + 4 > pszEnd) { | ||
|  |                 break; | ||
|  |             } | ||
|  |             pszIn++; | ||
|  |             *pszOut++ = '&'; | ||
|  |             *pszOut++ = 'g'; | ||
|  |             *pszOut++ = 't'; | ||
|  |             *pszOut++ = ';'; | ||
|  |         } | ||
|  |         else if (*pszIn == '&') { | ||
|  |             if (pszOut + 5 > pszEnd) { | ||
|  |                 break; | ||
|  |             } | ||
|  |             pszIn++; | ||
|  |             *pszOut++ = '&'; | ||
|  |             *pszOut++ = 'a'; | ||
|  |             *pszOut++ = 'm'; | ||
|  |             *pszOut++ = 'p'; | ||
|  |             *pszOut++ = ';'; | ||
|  |         } | ||
|  |         else if (*pszIn == '\"') { | ||
|  |             if (pszOut + 6 > pszEnd) { | ||
|  |                 break; | ||
|  |             } | ||
|  |             pszIn++; | ||
|  |             *pszOut++ = '&'; | ||
|  |             *pszOut++ = 'q'; | ||
|  |             *pszOut++ = 'u'; | ||
|  |             *pszOut++ = 'o'; | ||
|  |             *pszOut++ = 't'; | ||
|  |             *pszOut++ = ';'; | ||
|  |         } | ||
|  |         else if (*pszIn == '\'') { | ||
|  |             if (pszOut + 6 > pszEnd) { | ||
|  |                 break; | ||
|  |             } | ||
|  |             pszIn++; | ||
|  |             *pszOut++ = '&'; | ||
|  |             *pszOut++ = 'a'; | ||
|  |             *pszOut++ = 'p'; | ||
|  |             *pszOut++ = 'o'; | ||
|  |             *pszOut++ = 's'; | ||
|  |             *pszOut++ = ';'; | ||
|  |         } | ||
|  |         else if (*pszIn  < ' ') { | ||
|  |             BYTE c = (BYTE)(*pszIn++); | ||
|  |             if (c < 10 && pszOut + 4 <= pszEnd) { | ||
|  |                 *pszOut++ = '&'; | ||
|  |                 *pszOut++ = '#'; | ||
|  |                 *pszOut++ = '0' + (c % 10); | ||
|  |                 *pszOut++ = ';'; | ||
|  |             } | ||
|  |             else if (c < 100 && pszOut + 5 <= pszEnd) { | ||
|  |                 *pszOut++ = '&'; | ||
|  |                 *pszOut++ = '#'; | ||
|  |                 *pszOut++ = '0' + ((c / 10) % 10); | ||
|  |                 *pszOut++ = '0' + (c % 10); | ||
|  |                 *pszOut++ = ';'; | ||
|  |             } | ||
|  |             else if (c < 1000 && pszOut + 6 <= pszEnd) { | ||
|  |                 *pszOut++ = '&'; | ||
|  |                 *pszOut++ = '#'; | ||
|  |                 *pszOut++ = '0' + ((c / 100) % 10); | ||
|  |                 *pszOut++ = '0' + ((c / 10) % 10); | ||
|  |                 *pszOut++ = '0' + (c % 10); | ||
|  |                 *pszOut++ = ';'; | ||
|  |             } | ||
|  |             else { | ||
|  |                 break; | ||
|  |             } | ||
|  |         } | ||
|  |         else { | ||
|  |             *pszOut++ = *pszIn++; | ||
|  |         } | ||
|  |     } | ||
|  |     *pszOut = '\0'; | ||
|  |     return pszOut; | ||
|  | } | ||
|  | 
 | ||
|  | static PCHAR do_ewstr(PCHAR pszOut, PCHAR pszEnd, PCWSTR pszIn) | ||
|  | { | ||
|  |     while (*pszIn && pszOut < pszEnd) { | ||
|  |         if (*pszIn == '<') { | ||
|  |             if (pszOut + 4 > pszEnd) { | ||
|  |                 break; | ||
|  |             } | ||
|  |             pszIn++; | ||
|  |             *pszOut++ = '&'; | ||
|  |             *pszOut++ = 'l'; | ||
|  |             *pszOut++ = 't'; | ||
|  |             *pszOut++ = ';'; | ||
|  |         } | ||
|  |         else if (*pszIn == '>') { | ||
|  |             if (pszOut + 4 > pszEnd) { | ||
|  |                 break; | ||
|  |             } | ||
|  |             pszIn++; | ||
|  |             *pszOut++ = '&'; | ||
|  |             *pszOut++ = 'g'; | ||
|  |             *pszOut++ = 't'; | ||
|  |             *pszOut++ = ';'; | ||
|  |         } | ||
|  |         else if (*pszIn == '&') { | ||
|  |             if (pszOut + 5 > pszEnd) { | ||
|  |                 break; | ||
|  |             } | ||
|  |             pszIn++; | ||
|  |             *pszOut++ = '&'; | ||
|  |             *pszOut++ = 'a'; | ||
|  |             *pszOut++ = 'm'; | ||
|  |             *pszOut++ = 'p'; | ||
|  |             *pszOut++ = ';'; | ||
|  |         } | ||
|  |         else if (*pszIn == '\"') { | ||
|  |             if (pszOut + 6 > pszEnd) { | ||
|  |                 break; | ||
|  |             } | ||
|  |             pszIn++; | ||
|  |             *pszOut++ = '&'; | ||
|  |             *pszOut++ = 'q'; | ||
|  |             *pszOut++ = 'u'; | ||
|  |             *pszOut++ = 'o'; | ||
|  |             *pszOut++ = 't'; | ||
|  |             *pszOut++ = ';'; | ||
|  |         } | ||
|  |         else if (*pszIn == '\'') { | ||
|  |             if (pszOut + 6 > pszEnd) { | ||
|  |                 break; | ||
|  |             } | ||
|  |             pszIn++; | ||
|  |             *pszOut++ = '&'; | ||
|  |             *pszOut++ = 'a'; | ||
|  |             *pszOut++ = 'p'; | ||
|  |             *pszOut++ = 'o'; | ||
|  |             *pszOut++ = 's'; | ||
|  |             *pszOut++ = ';'; | ||
|  |         } | ||
|  |         else if (*pszIn  < ' ' || *pszIn > 127) { | ||
|  |             WCHAR c = *pszIn++; | ||
|  |             if (c < 10 && pszOut + 4 <= pszEnd) { | ||
|  |                 *pszOut++ = '&'; | ||
|  |                 *pszOut++ = '#'; | ||
|  |                 *pszOut++ = '0' + (CHAR)(c % 10); | ||
|  |                 *pszOut++ = ';'; | ||
|  |             } | ||
|  |             else if (c < 100 && pszOut + 5 <= pszEnd) { | ||
|  |                 *pszOut++ = '&'; | ||
|  |                 *pszOut++ = '#'; | ||
|  |                 *pszOut++ = '0' + (CHAR)((c / 10) % 10); | ||
|  |                 *pszOut++ = '0' + (CHAR)(c % 10); | ||
|  |                 *pszOut++ = ';'; | ||
|  |             } | ||
|  |             else if (c < 1000 && pszOut + 6 <= pszEnd) { | ||
|  |                 *pszOut++ = '&'; | ||
|  |                 *pszOut++ = '#'; | ||
|  |                 *pszOut++ = '0' + (CHAR)((c / 100) % 10); | ||
|  |                 *pszOut++ = '0' + (CHAR)((c / 10) % 10); | ||
|  |                 *pszOut++ = '0' + (CHAR)(c % 10); | ||
|  |                 *pszOut++ = ';'; | ||
|  |             } | ||
|  |             else { | ||
|  |                 break; | ||
|  |             } | ||
|  |         } | ||
|  |         else { | ||
|  |             *pszOut++ = (CHAR)*pszIn++; | ||
|  |         } | ||
|  |     } | ||
|  |     *pszOut = '\0'; | ||
|  |     return pszOut; | ||
|  | } | ||
|  | 
 | ||
|  | #if _MSC_VER >= 1900
 | ||
|  | #pragma warning(push)
 | ||
|  | #pragma warning(disable:4456) // declaration hides previous local declaration
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | VOID VSafePrintf(PCSTR pszMsg, va_list args, PCHAR pszBuffer, LONG cbBuffer) | ||
|  | { | ||
|  |     PCHAR pszOut = pszBuffer; | ||
|  |     PCHAR pszEnd = pszBuffer + cbBuffer - 1; | ||
|  |     pszBuffer[0] = '\0'; | ||
|  | 
 | ||
|  |     __try { | ||
|  |         while (*pszMsg && pszOut < pszEnd) { | ||
|  |             if (*pszMsg == '%') { | ||
|  |                 CHAR szHead[4] = ""; | ||
|  |                 INT nLen; | ||
|  |                 INT nWidth = 0; | ||
|  |                 INT nPrecision = 0; | ||
|  |                 BOOL fLeft = FALSE; | ||
|  |                 BOOL fPositive = FALSE; | ||
|  |                 BOOL fPound = FALSE; | ||
|  |                 BOOL fBlank = FALSE; | ||
|  |                 BOOL fZero = FALSE; | ||
|  |                 BOOL fDigit = FALSE; | ||
|  |                 BOOL fSmall = FALSE; | ||
|  |                 BOOL fLarge = FALSE; | ||
|  |                 BOOL f64Bit = FALSE; | ||
|  |                 PCSTR pszArg = pszMsg; | ||
|  | 
 | ||
|  |                 pszMsg++; | ||
|  | 
 | ||
|  |                 for (; (*pszMsg == '-' || | ||
|  |                         *pszMsg == '+' || | ||
|  |                         *pszMsg == '#' || | ||
|  |                         *pszMsg == ' ' || | ||
|  |                         *pszMsg == '0'); pszMsg++) { | ||
|  |                     switch (*pszMsg) { | ||
|  |                       case '-': fLeft = TRUE; break; | ||
|  |                       case '+': fPositive = TRUE; break; | ||
|  |                       case '#': fPound = TRUE; break; | ||
|  |                       case ' ': fBlank = TRUE; break; | ||
|  |                       case '0': fZero = TRUE; break; | ||
|  |                     } | ||
|  |                 } | ||
|  | 
 | ||
|  |                 if (*pszMsg == '*') { | ||
|  |                     nWidth = va_arg(args, INT); | ||
|  |                     pszMsg++; | ||
|  |                 } | ||
|  |                 else { | ||
|  |                     while (*pszMsg >= '0' && *pszMsg <= '9') { | ||
|  |                         nWidth = nWidth * 10 + (*pszMsg++ - '0'); | ||
|  |                     } | ||
|  |                 } | ||
|  |                 if (*pszMsg == '.') { | ||
|  |                     pszMsg++; | ||
|  |                     fDigit = TRUE; | ||
|  |                     if (*pszMsg == '*') { | ||
|  |                         nPrecision = va_arg(args, INT); | ||
|  |                         pszMsg++; | ||
|  |                     } | ||
|  |                     else { | ||
|  |                         while (*pszMsg >= '0' && *pszMsg <= '9') { | ||
|  |                             nPrecision = nPrecision * 10 + (*pszMsg++ - '0'); | ||
|  |                         } | ||
|  |                     } | ||
|  |                 } | ||
|  | 
 | ||
|  |                 if (*pszMsg == 'h') { | ||
|  |                     fSmall = TRUE; | ||
|  |                     pszMsg++; | ||
|  |                 } | ||
|  |                 else if (*pszMsg == 'l') { | ||
|  |                     fLarge = TRUE; | ||
|  |                     pszMsg++; | ||
|  |                 } | ||
|  |                 else if (*pszMsg == 'I' && pszMsg[1] == '6' && pszMsg[2] == '4') { | ||
|  |                     f64Bit = TRUE; | ||
|  |                     pszMsg += 3; | ||
|  |                 } | ||
|  | 
 | ||
|  |                 if (*pszMsg == 's' || *pszMsg == 'e' || *pszMsg == 'c') { | ||
|  |                     // We ignore the length, precision, and alignment
 | ||
|  |                     // to avoid using a temporary buffer.
 | ||
|  | 
 | ||
|  |                     if (*pszMsg == 's') { // [GalenH] need to not use temp.
 | ||
|  |                         PVOID pvData = va_arg(args, PVOID); | ||
|  | 
 | ||
|  |                         pszMsg++; | ||
|  | 
 | ||
|  |                         if (fSmall) { | ||
|  |                             fLarge = FALSE; | ||
|  |                         } | ||
|  | 
 | ||
|  |                         __try { | ||
|  |                             if (pvData == NULL) { | ||
|  |                                 pszOut = do_str(pszOut, pszEnd, "<NULL>"); | ||
|  |                             } | ||
|  |                             else if (pvData < (PVOID)0x10000) { | ||
|  |                                 pszOut = do_str(pszOut, pszEnd, "#"); | ||
|  |                                 pszOut = do_base(pszOut, (UINT64)pvData, 16, | ||
|  |                                              "0123456789ABCDEF"); | ||
|  |                                 pszOut = do_str(pszOut, pszEnd, "#"); | ||
|  |                             } | ||
|  |                             else if (fLarge) { | ||
|  |                                 pszOut = do_wstr(pszOut, pszEnd, (PWCHAR)pvData); | ||
|  |                             } | ||
|  |                             else { | ||
|  |                                 pszOut = do_str(pszOut, pszEnd, (PCHAR)pvData); | ||
|  |                             } | ||
|  |                         } __except(EXCEPTION_EXECUTE_HANDLER) { | ||
|  |                             pszOut = do_str(pszOut, pszEnd, "-"); | ||
|  |                             pszOut = do_base(pszOut, (UINT64)pvData, 16, | ||
|  |                                              "0123456789ABCDEF"); | ||
|  |                             pszOut = do_str(pszOut, pszEnd, "-"); | ||
|  |                         } | ||
|  |                     } | ||
|  |                     else if (*pszMsg == 'e')    {   // Escape the string.
 | ||
|  |                         PVOID pvData = va_arg(args, PVOID); | ||
|  | 
 | ||
|  |                         pszMsg++; | ||
|  | 
 | ||
|  |                         if (fSmall) { | ||
|  |                             fLarge = FALSE; | ||
|  |                         } | ||
|  | 
 | ||
|  |                         __try { | ||
|  |                             if (pvData == NULL) { | ||
|  |                                 pszOut = do_str(pszOut, pszEnd, "<NULL>"); | ||
|  |                             } | ||
|  |                             else if (pvData < (PVOID)0x10000) { | ||
|  |                                 pszOut = do_str(pszOut, pszEnd, ">"); | ||
|  |                                 pszOut = do_base(pszOut, (UINT64)pvData, 16, | ||
|  |                                              "0123456789ABCDEF"); | ||
|  |                                 pszOut = do_str(pszOut, pszEnd, ">"); | ||
|  |                             } | ||
|  |                             else if (fLarge) { | ||
|  |                                 pszOut = do_ewstr(pszOut, pszEnd, (PWCHAR)pvData); | ||
|  |                             } | ||
|  |                             else { | ||
|  |                                 pszOut = do_estr(pszOut, pszEnd, (PCHAR)pvData); | ||
|  |                             } | ||
|  |                         } __except(EXCEPTION_EXECUTE_HANDLER) { | ||
|  |                             pszOut = do_str(pszOut, pszEnd, "-"); | ||
|  |                             pszOut = do_base(pszOut, (UINT64)pvData, 16, | ||
|  |                                              "0123456789ABCDEF"); | ||
|  |                             pszOut = do_str(pszOut, pszEnd, "-"); | ||
|  |                         } | ||
|  |                     } | ||
|  |                     else { | ||
|  |                         CHAR szTemp[2]; | ||
|  |                         pszMsg++; | ||
|  | 
 | ||
|  |                         szTemp[0] = (CHAR)va_arg(args, INT); | ||
|  |                         szTemp[1] = '\0'; | ||
|  |                         pszOut = do_str(pszOut, pszEnd, szTemp); | ||
|  |                     } | ||
|  |                 } | ||
|  |                 else if (*pszMsg == 'd' || *pszMsg == 'i' || *pszMsg == 'o' || | ||
|  |                          *pszMsg == 'x' || *pszMsg == 'X' || *pszMsg == 'b' || | ||
|  |                          *pszMsg == 'u') { | ||
|  |                     CHAR szTemp[128]; | ||
|  |                     UINT64 value; | ||
|  |                     if (f64Bit) { | ||
|  |                         value = va_arg(args, UINT64); | ||
|  |                     } | ||
|  |                     else { | ||
|  |                         value = va_arg(args, UINT); | ||
|  |                     } | ||
|  | 
 | ||
|  |                     if (*pszMsg == 'x') { | ||
|  |                         pszMsg++; | ||
|  |                         nLen = (int)(do_base(szTemp, value, 16, "0123456789abcdef") - szTemp); | ||
|  |                         if (fPound && value) { | ||
|  |                             do_str(szHead, szHead + sizeof(szHead) - 1, "0x"); | ||
|  |                         } | ||
|  |                     } | ||
|  |                     else if (*pszMsg == 'X') { | ||
|  |                         pszMsg++; | ||
|  |                         nLen = (int)(do_base(szTemp, value, 16, "0123456789ABCDEF") - szTemp); | ||
|  |                         if (fPound && value) { | ||
|  |                             do_str(szHead, szHead + sizeof(szHead) - 1, "0X"); | ||
|  |                         } | ||
|  |                     } | ||
|  |                     else if (*pszMsg == 'd') { | ||
|  |                         pszMsg++; | ||
|  |                         if ((INT64)value < 0) { | ||
|  |                             value = -(INT64)value; | ||
|  |                             do_str(szHead, szHead + sizeof(szHead) - 1, "-"); | ||
|  |                         } | ||
|  |                         else if (fPositive) { | ||
|  |                             if (value > 0) { | ||
|  |                                 do_str(szHead, szHead + sizeof(szHead) - 1, "+"); | ||
|  |                             } | ||
|  |                         } | ||
|  |                         else if (fBlank) { | ||
|  |                             if (value > 0) { | ||
|  |                                 do_str(szHead, szHead + sizeof(szHead) - 1, " "); | ||
|  |                             } | ||
|  |                         } | ||
|  |                         nLen = (int)(do_base(szTemp, value, 10, "0123456789") - szTemp); | ||
|  |                         nPrecision = 0; | ||
|  |                     } | ||
|  |                     else if (*pszMsg == 'u') { | ||
|  |                         pszMsg++; | ||
|  |                         nLen = (int)(do_base(szTemp, value, 10, "0123456789") - szTemp); | ||
|  |                         nPrecision = 0; | ||
|  |                     } | ||
|  |                     else if (*pszMsg == 'o') { | ||
|  |                         pszMsg++; | ||
|  |                         nLen = (int)(do_base(szTemp, value, 8, "01234567") - szTemp); | ||
|  |                         nPrecision = 0; | ||
|  | 
 | ||
|  |                         if (fPound && value) { | ||
|  |                             do_str(szHead, szHead + sizeof(szHead) - 1, "0"); | ||
|  |                         } | ||
|  |                     } | ||
|  |                     else if (*pszMsg == 'b') { | ||
|  |                         pszMsg++; | ||
|  |                         nLen = (int)(do_base(szTemp, value, 2, "01") - szTemp); | ||
|  |                         nPrecision = 0; | ||
|  | 
 | ||
|  |                         if (fPound && value) { | ||
|  |                             do_str(szHead, szHead + sizeof(szHead) - 1, "0b"); | ||
|  |                         } | ||
|  |                     } | ||
|  |                     else { | ||
|  |                         pszMsg++; | ||
|  |                         if ((INT64)value < 0) { | ||
|  |                             value = -(INT64)value; | ||
|  |                             do_str(szHead, szHead + sizeof(szHead) - 1, "-"); | ||
|  |                         } | ||
|  |                         else if (fPositive) { | ||
|  |                             if (value > 0) { | ||
|  |                                 do_str(szHead, szHead + sizeof(szHead) - 1, "+"); | ||
|  |                             } | ||
|  |                         } | ||
|  |                         else if (fBlank) { | ||
|  |                             if (value > 0) { | ||
|  |                                 do_str(szHead, szHead + sizeof(szHead) - 1, " "); | ||
|  |                             } | ||
|  |                         } | ||
|  |                         nLen = (int)(do_base(szTemp, value, 10, "0123456789") - szTemp); | ||
|  |                         nPrecision = 0; | ||
|  |                     } | ||
|  | 
 | ||
|  |                     INT nHead = 0; | ||
|  |                     for (; szHead[nHead]; nHead++) { | ||
|  |                         // Count characters in head string.
 | ||
|  |                     } | ||
|  | 
 | ||
|  |                     if (fLeft) { | ||
|  |                         if (nHead) { | ||
|  |                             pszOut = do_str(pszOut, pszEnd, szHead); | ||
|  |                             nLen += nHead; | ||
|  |                         } | ||
|  |                         pszOut = do_str(pszOut, pszEnd, szTemp); | ||
|  |                         for (; nLen < nWidth && pszOut < pszEnd; nLen++) { | ||
|  |                             *pszOut++ = ' '; | ||
|  |                         } | ||
|  |                     } | ||
|  |                     else if (fZero) { | ||
|  |                         if (nHead) { | ||
|  |                             pszOut = do_str(pszOut, pszEnd, szHead); | ||
|  |                             nLen += nHead; | ||
|  |                         } | ||
|  |                         for (; nLen < nWidth && pszOut < pszEnd; nLen++) { | ||
|  |                             *pszOut++ = '0'; | ||
|  |                         } | ||
|  |                         pszOut = do_str(pszOut, pszEnd, szTemp); | ||
|  |                     } | ||
|  |                     else { | ||
|  |                         if (nHead) { | ||
|  |                             nLen += nHead; | ||
|  |                         } | ||
|  |                         for (; nLen < nWidth && pszOut < pszEnd; nLen++) { | ||
|  |                             *pszOut++ = ' '; | ||
|  |                         } | ||
|  |                         if (nHead) { | ||
|  |                             pszOut = do_str(pszOut, pszEnd, szHead); | ||
|  |                         } | ||
|  |                         pszOut = do_str(pszOut, pszEnd, szTemp); | ||
|  |                     } | ||
|  |                 } | ||
|  |                 else if (*pszMsg == 'p') { | ||
|  |                     CHAR szTemp[64]; | ||
|  |                     ULONG_PTR value; | ||
|  |                     value = va_arg(args, ULONG_PTR); | ||
|  | 
 | ||
|  |                     if ((INT64)value == (INT64)-1 || | ||
|  |                         (INT64)value == (INT64)-2) { | ||
|  |                         if (*pszMsg == 'p') { | ||
|  |                             pszMsg++; | ||
|  |                         } | ||
|  |                         szTemp[0] = '-'; | ||
|  |                         szTemp[1] = ((INT64)value == (INT64)-1) ? '1' : '2'; | ||
|  |                         szTemp[2] = '\0'; | ||
|  |                         nLen = 2; | ||
|  |                     } | ||
|  |                     else { | ||
|  |                         if (*pszMsg == 'p') { | ||
|  |                             pszMsg++; | ||
|  |                             nLen = (int)(do_base(szTemp, (UINT64)value, 16, "0123456789abcdef") - szTemp); | ||
|  |                             if (fPound && value) { | ||
|  |                                 do_str(szHead, szHead + sizeof(szHead) - 1, "0x"); | ||
|  |                             } | ||
|  |                         } | ||
|  |                         else { | ||
|  |                             pszMsg++; | ||
|  |                             nLen = (int)(do_base(szTemp, (UINT64)value, 16, "0123456789ABCDEF") - szTemp); | ||
|  |                             if (fPound && value) { | ||
|  |                                 do_str(szHead, szHead + sizeof(szHead) - 1, "0x"); | ||
|  |                             } | ||
|  |                         } | ||
|  |                     } | ||
|  | 
 | ||
|  |                     INT nHead = 0; | ||
|  |                     for (; szHead[nHead]; nHead++) { | ||
|  |                         // Count characters in head string.
 | ||
|  |                     } | ||
|  | 
 | ||
|  |                     if (nHead) { | ||
|  |                         pszOut = do_str(pszOut, pszEnd, szHead); | ||
|  |                         nLen += nHead; | ||
|  |                     } | ||
|  |                     for (; nLen < nWidth && pszOut < pszEnd; nLen++) { | ||
|  |                         *pszOut++ = '0'; | ||
|  |                     } | ||
|  |                     pszOut = do_str(pszOut, pszEnd, szTemp); | ||
|  |                 } | ||
|  |                 else { | ||
|  |                     pszMsg++; | ||
|  |                     while (pszArg < pszMsg && pszOut < pszEnd) { | ||
|  |                         *pszOut++ = *pszArg++; | ||
|  |                     } | ||
|  |                 } | ||
|  |             } | ||
|  |             else { | ||
|  |                 if (pszOut < pszEnd) { | ||
|  |                     *pszOut++ = *pszMsg++; | ||
|  |                 } | ||
|  |             } | ||
|  |         } | ||
|  |         *pszOut = '\0'; | ||
|  |         pszBuffer[cbBuffer - 1] = '\0'; | ||
|  |     } __except(EXCEPTION_EXECUTE_HANDLER) { | ||
|  |         PCHAR pszOut = pszBuffer; | ||
|  |         *pszOut = '\0'; | ||
|  |         pszOut = do_str(pszOut, pszEnd, "-exception:"); | ||
|  |         pszOut = do_base(pszOut, (UINT64)GetExceptionCode(), 10, "0123456789"); | ||
|  |         pszOut = do_str(pszOut, pszEnd, "-"); | ||
|  |     } | ||
|  | } | ||
|  | 
 | ||
|  | #if _MSC_VER >= 1900
 | ||
|  | #pragma warning(pop)
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | PCHAR SafePrintf(PCHAR pszBuffer, LONG cbBuffer, PCSTR pszMsg, ...) | ||
|  | { | ||
|  |     va_list args; | ||
|  |     va_start(args, pszMsg); | ||
|  |     VSafePrintf(pszMsg, args, pszBuffer, cbBuffer); | ||
|  |     va_end(args); | ||
|  | 
 | ||
|  |     while (*pszBuffer) { | ||
|  |         pszBuffer++; | ||
|  |     } | ||
|  |     return pszBuffer; | ||
|  | } | ||
|  | 
 | ||
|  | //////////////////////////////////////////////////////////////////////////////
 | ||
|  | //
 | ||
|  | static CRITICAL_SECTION s_csPipe;                       // Guards access to hPipe.
 | ||
|  | static HANDLE           s_hPipe = INVALID_HANDLE_VALUE; | ||
|  | static DWORD            s_nPipeError = 0; | ||
|  | static FILETIME         s_ftRetry = {0,0}; | ||
|  | static BYTE             s_nFacility = SYELOG_FACILITY_APPLICATION; | ||
|  | static CHAR             s_szIdent[256] = ""; | ||
|  | static DWORD            s_nProcessId = 0; | ||
|  | 
 | ||
|  | static inline INT syelogCompareTimes(CONST PFILETIME pft1, CONST PFILETIME pft2) | ||
|  | { | ||
|  |     INT64 ut1 = *(PINT64)pft1; | ||
|  |     INT64 ut2 = *(PINT64)pft2; | ||
|  | 
 | ||
|  |     if (ut1 < ut2) { | ||
|  |         return -1; | ||
|  |     } | ||
|  |     else if (ut1 > ut2) { | ||
|  |         return 1; | ||
|  |     } | ||
|  |     else { | ||
|  |         return 0; | ||
|  |     } | ||
|  | } | ||
|  | 
 | ||
|  | static inline VOID syelogAddMilliseconds(PFILETIME pft, DWORD nMilliseconds) | ||
|  | { | ||
|  |     *(PINT64&)pft += ((INT64)nMilliseconds * 10000); | ||
|  | } | ||
|  | 
 | ||
|  | //////////////////////////////////////////////////////////////////////////////
 | ||
|  | //
 | ||
|  | // Tries to insure that a named-pipe connection to the system log is open
 | ||
|  | // If the pipe closes, the next call will immediately try to re-open the pipe.
 | ||
|  | // If the pipe doesn't open again, we wait 5 minutes before trying again.
 | ||
|  | // We wait 5 minutes, because each attempt may take up to a full second to
 | ||
|  | // time out.
 | ||
|  | //
 | ||
|  | static BOOL syelogIsOpen(PFILETIME pftLog) | ||
|  | { | ||
|  |     if (s_hPipe != INVALID_HANDLE_VALUE) { | ||
|  |         return TRUE; | ||
|  |     } | ||
|  | 
 | ||
|  |     if (syelogCompareTimes(pftLog, &s_ftRetry) < 0) { | ||
|  |         return FALSE; | ||
|  |     } | ||
|  | 
 | ||
|  |     s_hPipe = Real_CreateFileW(SYELOG_PIPE_NAMEW, | ||
|  |                                GENERIC_WRITE, 0, NULL, OPEN_EXISTING, | ||
|  |                                SECURITY_ANONYMOUS, NULL); | ||
|  |     if (s_hPipe != INVALID_HANDLE_VALUE) { | ||
|  |         DWORD dwMode = PIPE_READMODE_MESSAGE; | ||
|  |         if (Real_SetNamedPipeHandleState(s_hPipe, &dwMode, NULL, NULL)) { | ||
|  |             return TRUE; | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     if (Real_WaitNamedPipeW(SYELOG_PIPE_NAMEW, 2000)) { // Wait 2 seconds.
 | ||
|  |         // Pipe connected, change to message-read mode.
 | ||
|  |         //
 | ||
|  |         s_hPipe = Real_CreateFileW(SYELOG_PIPE_NAMEW, | ||
|  |                                    GENERIC_WRITE, 0, NULL, OPEN_EXISTING, | ||
|  |                                    SECURITY_ANONYMOUS, NULL); | ||
|  |         if (s_hPipe != INVALID_HANDLE_VALUE) { | ||
|  |             DWORD dwMode = PIPE_READMODE_MESSAGE; | ||
|  |             if (Real_SetNamedPipeHandleState(s_hPipe, &dwMode, NULL, NULL)) { | ||
|  |                 return TRUE; | ||
|  |             } | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     // Couldn't open pipe.
 | ||
|  |     s_ftRetry = *pftLog; | ||
|  |     syelogAddMilliseconds(&s_ftRetry, 300000);           // Wait 5 minute before retry.
 | ||
|  | 
 | ||
|  |     return FALSE; | ||
|  | } | ||
|  | 
 | ||
|  | VOID SyelogOpen(PCSTR pszIdentifier, BYTE nFacility) | ||
|  | { | ||
|  |     Real_InitializeCriticalSection(&s_csPipe); | ||
|  | 
 | ||
|  |     if (pszIdentifier) { | ||
|  |         PCHAR pszOut = s_szIdent; | ||
|  |         PCHAR pszEnd = s_szIdent + ARRAYSIZE(s_szIdent) - 1; | ||
|  |         pszOut = do_str(pszOut, pszEnd, pszIdentifier); | ||
|  |         pszOut = do_str(pszOut, pszEnd, ": "); | ||
|  |         *pszEnd = '\0'; | ||
|  |     } | ||
|  |     else { | ||
|  |         s_szIdent[0] = '\0'; | ||
|  |     } | ||
|  | 
 | ||
|  |     s_nFacility = nFacility; | ||
|  |     s_nProcessId = Real_GetCurrentProcessId(); | ||
|  | } | ||
|  | 
 | ||
|  | VOID SyelogExV(BOOL fTerminate, BYTE nSeverity, PCSTR pszMsgf, va_list args) | ||
|  | { | ||
|  |     SYELOG_MESSAGE Message; | ||
|  |     DWORD cbWritten = 0; | ||
|  | 
 | ||
|  |     Real_GetSystemTimeAsFileTime(&Message.ftOccurance); | ||
|  |     Message.fTerminate = fTerminate; | ||
|  |     Message.nFacility = s_nFacility; | ||
|  |     Message.nSeverity = nSeverity; | ||
|  |     Message.nProcessId = s_nProcessId; | ||
|  |     PCHAR pszBuf = Message.szMessage; | ||
|  |     PCHAR pszEnd = Message.szMessage + ARRAYSIZE(Message.szMessage) - 1; | ||
|  |     if (s_szIdent[0]) { | ||
|  |         pszBuf = do_str(pszBuf, pszEnd, s_szIdent); | ||
|  |     } | ||
|  |     *pszEnd = '\0'; | ||
|  |     VSafePrintf(pszMsgf, args, | ||
|  |                 pszBuf, (int)(Message.szMessage + sizeof(Message.szMessage) - 1 - pszBuf)); | ||
|  | 
 | ||
|  |     pszEnd = Message.szMessage; | ||
|  |     for (; *pszEnd; pszEnd++) { | ||
|  |         // no internal contents.
 | ||
|  |     } | ||
|  | 
 | ||
|  |     // Insure that the message always ends with a '\n'
 | ||
|  |     //
 | ||
|  |     if (pszEnd > Message.szMessage) { | ||
|  |         if (pszEnd[-1] != '\n') { | ||
|  |             *pszEnd++ = '\n'; | ||
|  |             *pszEnd++ = '\0'; | ||
|  |         } | ||
|  |         else { | ||
|  |             *pszEnd++ = '\0'; | ||
|  |         } | ||
|  |     } | ||
|  |     else { | ||
|  |         *pszEnd++ = '\n'; | ||
|  |         *pszEnd++ = '\0'; | ||
|  |     } | ||
|  |     Message.nBytes = (USHORT)(pszEnd - ((PCSTR)&Message)); | ||
|  | 
 | ||
|  |     Real_EnterCriticalSection(&s_csPipe); | ||
|  | 
 | ||
|  |     if (syelogIsOpen(&Message.ftOccurance)) { | ||
|  |         if (!Real_WriteFile(s_hPipe, &Message, Message.nBytes, &cbWritten, NULL)) { | ||
|  |             s_nPipeError = GetLastError(); | ||
|  |             if (s_nPipeError == ERROR_BAD_IMPERSONATION_LEVEL) { | ||
|  |                 // Don't close the file just for a temporary impersonation level.
 | ||
|  |             } | ||
|  |             else { | ||
|  |                 if (s_hPipe != INVALID_HANDLE_VALUE) { | ||
|  |                     Real_CloseHandle(s_hPipe); | ||
|  |                     s_hPipe = INVALID_HANDLE_VALUE; | ||
|  |                 } | ||
|  |                 if (syelogIsOpen(&Message.ftOccurance)) { | ||
|  |                     Real_WriteFile(s_hPipe, &Message, Message.nBytes, &cbWritten, NULL); | ||
|  |                 } | ||
|  |             } | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     Real_LeaveCriticalSection(&s_csPipe); | ||
|  | } | ||
|  | 
 | ||
|  | VOID SyelogV(BYTE nSeverity, PCSTR pszMsgf, va_list args) | ||
|  | { | ||
|  |     SyelogExV(FALSE, nSeverity, pszMsgf, args); | ||
|  | } | ||
|  | 
 | ||
|  | VOID Syelog(BYTE nSeverity, PCSTR pszMsgf, ...) | ||
|  | { | ||
|  |     va_list args; | ||
|  |     va_start(args, pszMsgf); | ||
|  |     SyelogExV(FALSE, nSeverity, pszMsgf, args); | ||
|  |     va_end(args); | ||
|  | } | ||
|  | 
 | ||
|  | VOID SyelogEx(BOOL fTerminate, BYTE nSeverity, PCSTR pszMsgf, ...) | ||
|  | { | ||
|  |     va_list args; | ||
|  |     va_start(args, pszMsgf); | ||
|  |     SyelogExV(fTerminate, nSeverity, pszMsgf, args); | ||
|  |     va_end(args); | ||
|  | } | ||
|  | 
 | ||
|  | VOID SyelogClose(BOOL fTerminate) | ||
|  | { | ||
|  |     if (fTerminate) { | ||
|  |         SyelogEx(TRUE, SYELOG_SEVERITY_NOTICE, "Requesting exit on close.\n"); | ||
|  |     } | ||
|  | 
 | ||
|  |     Real_EnterCriticalSection(&s_csPipe); | ||
|  | 
 | ||
|  |     if (s_hPipe != INVALID_HANDLE_VALUE) { | ||
|  |         Real_FlushFileBuffers(s_hPipe); | ||
|  |         Real_CloseHandle(s_hPipe); | ||
|  |         s_hPipe = INVALID_HANDLE_VALUE; | ||
|  |     } | ||
|  | 
 | ||
|  |     Real_LeaveCriticalSection(&s_csPipe); | ||
|  | } | ||
|  | //
 | ||
|  | ///////////////////////////////////////////////////////////////// End of File.
 |