mirror of
https://github.com/vosen/ZLUDA.git
synced 2025-04-23 01:04:44 +00:00
847 lines
28 KiB
C++
Vendored
847 lines
28 KiB
C++
Vendored
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// 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.
|