4574 lines
		
	
	
		
			129 KiB
		
	
	
	
		
			C++
		
	
	
	
		
		
			
		
	
	
			4574 lines
		
	
	
		
			129 KiB
		
	
	
	
		
			C++
		
	
	
	
| 
								 | 
							
								/////////////////////////////////////////////////////////////////////////////
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								//  Detours Test Program (trcbld.cpp of trcbld.dll)
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								//  Microsoft Research Detours Package
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								//  Copyright (c) Microsoft Corporation.  All rights reserved.
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define _WIN32_WINNT        0x0500
							 | 
						||
| 
								 | 
							
								#define WIN32
							 | 
						||
| 
								 | 
							
								#define NT
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define DBG_TRACE   0
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <windows.h>
							 | 
						||
| 
								 | 
							
								#include <stdio.h>
							 | 
						||
| 
								 | 
							
								#pragma warning(push)
							 | 
						||
| 
								 | 
							
								#if _MSC_VER > 1400
							 | 
						||
| 
								 | 
							
								#pragma warning(disable:6102 6103) // /analyze warnings
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								#include <strsafe.h>
							 | 
						||
| 
								 | 
							
								#pragma warning(pop)
							 | 
						||
| 
								 | 
							
								#include "detours.h"
							 | 
						||
| 
								 | 
							
								#include "tracebld.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define PULONG_PTR          PVOID
							 | 
						||
| 
								 | 
							
								#define PLONG_PTR           PVOID
							 | 
						||
| 
								 | 
							
								#define ULONG_PTR           PVOID
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//////////////////////////////////////////////////////////////////////////////
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#pragma warning(disable:4127)   // Many of our asserts are constants.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define DEBUG_BREAK() DebugBreak()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define ASSERT_ALWAYS(x)   \
							 | 
						||
| 
								 | 
							
								    do {                                                        \
							 | 
						||
| 
								 | 
							
								        if (!(x)) {                                             \
							 | 
						||
| 
								 | 
							
								            AssertFailed(#x, __FILE__, __LINE__);               \
							 | 
						||
| 
								 | 
							
								            DebugBreak();                                       \
							 | 
						||
| 
								 | 
							
								        }                                                       \
							 | 
						||
| 
								 | 
							
								    } while (0)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifndef NDEBUG
							 | 
						||
| 
								 | 
							
								#define ASSERT(x)           ASSERT_ALWAYS(x)
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								#define ASSERT(x)
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define UNUSED(c)       (c) = (c)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//////////////////////////////////////////////////////////////////////////////
							 | 
						||
| 
								 | 
							
								static HMODULE s_hInst = NULL;
							 | 
						||
| 
								 | 
							
								static HMODULE s_hKernel32 = NULL;
							 | 
						||
| 
								 | 
							
								static CHAR s_szDllPath[MAX_PATH];
							 | 
						||
| 
								 | 
							
								static TBLOG_PAYLOAD s_Payload;
							 | 
						||
| 
								 | 
							
								static TBLOG_PAYLOAD s_ChildPayload;
							 | 
						||
| 
								 | 
							
								static CRITICAL_SECTION s_csChildPayload;
							 | 
						||
| 
								 | 
							
								static DWORD s_nTraceProcessId = 0;
							 | 
						||
| 
								 | 
							
								static LONG s_nChildCnt = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static CRITICAL_SECTION s_csPipe;                       // Guards access to hPipe.
							 | 
						||
| 
								 | 
							
								static HANDLE           s_hPipe = INVALID_HANDLE_VALUE;
							 | 
						||
| 
								 | 
							
								static TBLOG_MESSAGE    s_rMessage;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Logging Functions.
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								VOID Tblog(PCSTR pszMsgf, ...);
							 | 
						||
| 
								 | 
							
								VOID TblogV(PCSTR pszMsgf, va_list args);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								VOID VSafePrintf(PCSTR pszMsg, va_list args, PCHAR pszBuffer, LONG cbBuffer);
							 | 
						||
| 
								 | 
							
								PCHAR SafePrintf(PCHAR pszBuffer, LONG cbBuffer, PCSTR pszMsg, ...);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								LONG EnterFunc();
							 | 
						||
| 
								 | 
							
								VOID ExitFunc();
							 | 
						||
| 
								 | 
							
								VOID Print(PCSTR psz, ...);
							 | 
						||
| 
								 | 
							
								VOID NoteRead(PCSTR psz);
							 | 
						||
| 
								 | 
							
								VOID NoteRead(PCWSTR pwz);
							 | 
						||
| 
								 | 
							
								VOID NoteWrite(PCSTR psz);
							 | 
						||
| 
								 | 
							
								VOID NoteWrite(PCWSTR pwz);
							 | 
						||
| 
								 | 
							
								VOID NoteDelete(PCSTR psz);
							 | 
						||
| 
								 | 
							
								VOID NoteDelete(PCWSTR pwz);
							 | 
						||
| 
								 | 
							
								VOID NoteCleanup(PCSTR psz);
							 | 
						||
| 
								 | 
							
								VOID NoteCleanup(PCWSTR pwz);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								PBYTE LoadFile(HANDLE hFile, DWORD cbFile);
							 | 
						||
| 
								 | 
							
								static PCHAR RemoveReturns(PCHAR pszBuffer);
							 | 
						||
| 
								 | 
							
								static PWCHAR RemoveReturns(PWCHAR pwzBuffer);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								VOID AssertFailed(CONST PCHAR pszMsg, CONST PCHAR pszFile, ULONG nLine);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								int WINAPI Mine_EntryPoint(VOID);
							 | 
						||
| 
								 | 
							
								VOID WINAPI Mine_ExitProcess(UINT a0);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//////////////////////////////////////////////////////////////////////////////
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								int (WINAPI * Real_EntryPoint)(VOID)
							 | 
						||
| 
								 | 
							
								    = NULL;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								BOOL (WINAPI * Real_CreateDirectoryW)(LPCWSTR a0,
							 | 
						||
| 
								 | 
							
								                                      LPSECURITY_ATTRIBUTES a1)
							 | 
						||
| 
								 | 
							
								    = CreateDirectoryW;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								BOOL (WINAPI * Real_CreateDirectoryExW)(LPCWSTR a0,
							 | 
						||
| 
								 | 
							
								                                        LPCWSTR a1,
							 | 
						||
| 
								 | 
							
								                                        LPSECURITY_ATTRIBUTES a2)
							 | 
						||
| 
								 | 
							
								    = CreateDirectoryExW;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								HANDLE (WINAPI * Real_CreateFileW)(LPCWSTR a0,
							 | 
						||
| 
								 | 
							
								                                   DWORD a1,
							 | 
						||
| 
								 | 
							
								                                   DWORD a2,
							 | 
						||
| 
								 | 
							
								                                   LPSECURITY_ATTRIBUTES a3,
							 | 
						||
| 
								 | 
							
								                                   DWORD a4,
							 | 
						||
| 
								 | 
							
								                                   DWORD a5,
							 | 
						||
| 
								 | 
							
								                                   HANDLE a6)
							 | 
						||
| 
								 | 
							
								    = CreateFileW;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								HANDLE (WINAPI * Real_CreateFileMappingW)(HANDLE hFile,
							 | 
						||
| 
								 | 
							
								                                         LPSECURITY_ATTRIBUTES lpAttributes,
							 | 
						||
| 
								 | 
							
								                                         DWORD flProtect,
							 | 
						||
| 
								 | 
							
								                                         DWORD dwMaximumSizeHigh,
							 | 
						||
| 
								 | 
							
								                                         DWORD dwMaximumSizeLow,
							 | 
						||
| 
								 | 
							
								                                         LPCWSTR lpName
							 | 
						||
| 
								 | 
							
								                                        )
							 | 
						||
| 
								 | 
							
								    = CreateFileMappingW;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								BOOL (WINAPI * Real_CreatePipe)(PHANDLE hReadPipe,
							 | 
						||
| 
								 | 
							
								                                PHANDLE hWritePipe,
							 | 
						||
| 
								 | 
							
								                                LPSECURITY_ATTRIBUTES lpPipeAttributes,
							 | 
						||
| 
								 | 
							
								                                DWORD nSize)
							 | 
						||
| 
								 | 
							
								    = CreatePipe;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								BOOL (WINAPI * Real_CloseHandle)(HANDLE a0)
							 | 
						||
| 
								 | 
							
								    = CloseHandle;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								BOOL (WINAPI * Real_DuplicateHandle)(HANDLE hSourceProcessHandle,
							 | 
						||
| 
								 | 
							
								                                     HANDLE hSourceHandle,
							 | 
						||
| 
								 | 
							
								                                     HANDLE hTargetProcessHandle,
							 | 
						||
| 
								 | 
							
								                                     LPHANDLE lpTargetHandle,
							 | 
						||
| 
								 | 
							
								                                     DWORD dwDesiredAccess,
							 | 
						||
| 
								 | 
							
								                                     BOOL bInheritHandle,
							 | 
						||
| 
								 | 
							
								                                     DWORD dwOptions)
							 | 
						||
| 
								 | 
							
								    = DuplicateHandle;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								BOOL (WINAPI * Real_CreateProcessW)(LPCWSTR lpApplicationName,
							 | 
						||
| 
								 | 
							
								                                    LPWSTR lpCommandLine,
							 | 
						||
| 
								 | 
							
								                                    LPSECURITY_ATTRIBUTES lpProcessAttributes,
							 | 
						||
| 
								 | 
							
								                                    LPSECURITY_ATTRIBUTES lpThreadAttributes,
							 | 
						||
| 
								 | 
							
								                                    BOOL bInheritHandles,
							 | 
						||
| 
								 | 
							
								                                    DWORD dwCreationFlags,
							 | 
						||
| 
								 | 
							
								                                    LPVOID lpEnvironment,
							 | 
						||
| 
								 | 
							
								                                    LPCWSTR lpCurrentDirectory,
							 | 
						||
| 
								 | 
							
								                                    LPSTARTUPINFOW lpStartupInfo,
							 | 
						||
| 
								 | 
							
								                                    LPPROCESS_INFORMATION lpProcessInformation)
							 | 
						||
| 
								 | 
							
								    = CreateProcessW;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								BOOL (WINAPI * Real_CreateProcessA)(LPCSTR lpApplicationName,
							 | 
						||
| 
								 | 
							
								                                    LPSTR lpCommandLine,
							 | 
						||
| 
								 | 
							
								                                    LPSECURITY_ATTRIBUTES lpProcessAttributes,
							 | 
						||
| 
								 | 
							
								                                    LPSECURITY_ATTRIBUTES lpThreadAttributes,
							 | 
						||
| 
								 | 
							
								                                    BOOL bInheritHandles,
							 | 
						||
| 
								 | 
							
								                                    DWORD dwCreationFlags,
							 | 
						||
| 
								 | 
							
								                                    LPVOID lpEnvironment,
							 | 
						||
| 
								 | 
							
								                                    LPCSTR lpCurrentDirectory,
							 | 
						||
| 
								 | 
							
								                                    LPSTARTUPINFOA lpStartupInfo,
							 | 
						||
| 
								 | 
							
								                                    LPPROCESS_INFORMATION lpProcessInformation)
							 | 
						||
| 
								 | 
							
								    = CreateProcessA;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								BOOL (WINAPI * Real_DeleteFileW)(LPCWSTR a0)
							 | 
						||
| 
								 | 
							
								    = DeleteFileW;
							 | 
						||
| 
								 | 
							
								BOOL (WINAPI * Real_DeviceIoControl)(HANDLE a0,
							 | 
						||
| 
								 | 
							
								                                     DWORD dwIoControlCode,
							 | 
						||
| 
								 | 
							
								                                     LPVOID lpInBuffer,
							 | 
						||
| 
								 | 
							
								                                     DWORD nInBufferSize,
							 | 
						||
| 
								 | 
							
								                                     LPVOID lpOutBuffer,
							 | 
						||
| 
								 | 
							
								                                     DWORD nOutBufferSize,
							 | 
						||
| 
								 | 
							
								                                     LPDWORD lpBytesReturned,
							 | 
						||
| 
								 | 
							
								                                     LPOVERLAPPED lpOverlapped)
							 | 
						||
| 
								 | 
							
								    = DeviceIoControl;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								DWORD (WINAPI * Real_GetFileAttributesW)(LPCWSTR a0)
							 | 
						||
| 
								 | 
							
								    = GetFileAttributesW;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								BOOL (WINAPI * Real_MoveFileWithProgressW)(LPCWSTR lpExistingFileName,
							 | 
						||
| 
								 | 
							
								                                           LPCWSTR lpNewFileName,
							 | 
						||
| 
								 | 
							
								                                           LPPROGRESS_ROUTINE lpProgressRoutine,
							 | 
						||
| 
								 | 
							
								                                           LPVOID lpData,
							 | 
						||
| 
								 | 
							
								                                           DWORD dwFlags)
							 | 
						||
| 
								 | 
							
								    = MoveFileWithProgressW;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								BOOL (WINAPI * Real_MoveFileA)(LPCSTR a0,
							 | 
						||
| 
								 | 
							
								                               LPCSTR a1)
							 | 
						||
| 
								 | 
							
								    = MoveFileA;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								BOOL (WINAPI * Real_MoveFileW)(LPCWSTR a0,
							 | 
						||
| 
								 | 
							
								                               LPCWSTR a12)
							 | 
						||
| 
								 | 
							
								    = MoveFileW;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								BOOL (WINAPI * Real_MoveFileExA)(LPCSTR a0,
							 | 
						||
| 
								 | 
							
								                                 LPCSTR a1,
							 | 
						||
| 
								 | 
							
								                                 DWORD a2)
							 | 
						||
| 
								 | 
							
								    = MoveFileExA;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								BOOL (WINAPI * Real_MoveFileExW)(LPCWSTR a0,
							 | 
						||
| 
								 | 
							
								                                 LPCWSTR a1,
							 | 
						||
| 
								 | 
							
								                                 DWORD a2)
							 | 
						||
| 
								 | 
							
								    = MoveFileExW;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								BOOL (WINAPI * Real_CopyFileExA)(LPCSTR a0,
							 | 
						||
| 
								 | 
							
								                                 LPCSTR a1,
							 | 
						||
| 
								 | 
							
								                                 LPPROGRESS_ROUTINE a2,
							 | 
						||
| 
								 | 
							
								                                 LPVOID a4,
							 | 
						||
| 
								 | 
							
								                                 LPBOOL a5,
							 | 
						||
| 
								 | 
							
								                                 DWORD a6)
							 | 
						||
| 
								 | 
							
								    = CopyFileExA;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								BOOL (WINAPI * Real_CopyFileExW)(LPCWSTR a0,
							 | 
						||
| 
								 | 
							
								                                 LPCWSTR a1,
							 | 
						||
| 
								 | 
							
								                                 LPPROGRESS_ROUTINE a2,
							 | 
						||
| 
								 | 
							
								                                 LPVOID a4,
							 | 
						||
| 
								 | 
							
								                                 LPBOOL a5,
							 | 
						||
| 
								 | 
							
								                                 DWORD a6)
							 | 
						||
| 
								 | 
							
								    = CopyFileExW;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								BOOL (WINAPI * Real_PrivCopyFileExW)(LPCWSTR  lpExistingFileName,
							 | 
						||
| 
								 | 
							
								                                     LPCWSTR  lpNewFileName,
							 | 
						||
| 
								 | 
							
								                                     LPPROGRESS_ROUTINE  lpProgressRoutine,
							 | 
						||
| 
								 | 
							
								                                     LPVOID  lpData,
							 | 
						||
| 
								 | 
							
								                                     LPBOOL  pbCancel,
							 | 
						||
| 
								 | 
							
								                                     DWORD  dwCopyFlags)
							 | 
						||
| 
								 | 
							
								    = NULL;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								BOOL (WINAPI * Real_CreateHardLinkA)(LPCSTR a0,
							 | 
						||
| 
								 | 
							
								                                     LPCSTR a1,
							 | 
						||
| 
								 | 
							
								                                     LPSECURITY_ATTRIBUTES a2)
							 | 
						||
| 
								 | 
							
								    = CreateHardLinkA;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								BOOL (WINAPI * Real_CreateHardLinkW)(LPCWSTR a0,
							 | 
						||
| 
								 | 
							
								                                     LPCWSTR a1,
							 | 
						||
| 
								 | 
							
								                                     LPSECURITY_ATTRIBUTES a2)
							 | 
						||
| 
								 | 
							
								    = CreateHardLinkW;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								BOOL (WINAPI * Real_SetStdHandle)(DWORD a0,
							 | 
						||
| 
								 | 
							
								                                  HANDLE a1)
							 | 
						||
| 
								 | 
							
								    = SetStdHandle;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								HMODULE (WINAPI * Real_LoadLibraryA)(LPCSTR a0)
							 | 
						||
| 
								 | 
							
								    = LoadLibraryA;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								HMODULE (WINAPI * Real_LoadLibraryW)(LPCWSTR a0)
							 | 
						||
| 
								 | 
							
								    = LoadLibraryW;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								HMODULE (WINAPI * Real_LoadLibraryExA)(LPCSTR a0,
							 | 
						||
| 
								 | 
							
								                                       HANDLE a1,
							 | 
						||
| 
								 | 
							
								                                       DWORD a2)
							 | 
						||
| 
								 | 
							
								    = LoadLibraryExA;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								HMODULE (WINAPI * Real_LoadLibraryExW)(LPCWSTR a0,
							 | 
						||
| 
								 | 
							
								                                       HANDLE a1,
							 | 
						||
| 
								 | 
							
								                                       DWORD a2)
							 | 
						||
| 
								 | 
							
								    = LoadLibraryExW;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								DWORD (WINAPI * Real_SetFilePointer)(HANDLE hFile,
							 | 
						||
| 
								 | 
							
								                                     LONG lDistanceToMove,
							 | 
						||
| 
								 | 
							
								                                     PLONG lpDistanceToMoveHigh,
							 | 
						||
| 
								 | 
							
								                                     DWORD dwMoveMethod)
							 | 
						||
| 
								 | 
							
								    = SetFilePointer;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								BOOL (WINAPI * Real_SetFilePointerEx)(HANDLE hFile,
							 | 
						||
| 
								 | 
							
								                                      LARGE_INTEGER liDistanceToMove,
							 | 
						||
| 
								 | 
							
								                                      PLARGE_INTEGER lpNewFilePointer,
							 | 
						||
| 
								 | 
							
								                                      DWORD dwMoveMethod)
							 | 
						||
| 
								 | 
							
								    = SetFilePointerEx;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								BOOL (WINAPI * Real_ReadFile)(HANDLE a0,
							 | 
						||
| 
								 | 
							
								                                 LPVOID a1,
							 | 
						||
| 
								 | 
							
								                                 DWORD a2,
							 | 
						||
| 
								 | 
							
								                                 LPDWORD a3,
							 | 
						||
| 
								 | 
							
								                                 LPOVERLAPPED a4)
							 | 
						||
| 
								 | 
							
								    = ReadFile;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								BOOL (WINAPI * Real_ReadFileEx)(HANDLE a0,
							 | 
						||
| 
								 | 
							
								                                   LPVOID a1,
							 | 
						||
| 
								 | 
							
								                                   DWORD a2,
							 | 
						||
| 
								 | 
							
								                                   LPOVERLAPPED a3,
							 | 
						||
| 
								 | 
							
								                                   LPOVERLAPPED_COMPLETION_ROUTINE a4)
							 | 
						||
| 
								 | 
							
								    = ReadFileEx;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								BOOL (WINAPI * Real_WriteFile)(HANDLE a0,
							 | 
						||
| 
								 | 
							
								                                  LPCVOID a1,
							 | 
						||
| 
								 | 
							
								                                  DWORD a2,
							 | 
						||
| 
								 | 
							
								                                  LPDWORD a3,
							 | 
						||
| 
								 | 
							
								                                  LPOVERLAPPED a4)
							 | 
						||
| 
								 | 
							
								    = WriteFile;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								BOOL (WINAPI * Real_WriteFileEx)(HANDLE a0,
							 | 
						||
| 
								 | 
							
								                                    LPCVOID a1,
							 | 
						||
| 
								 | 
							
								                                    DWORD a2,
							 | 
						||
| 
								 | 
							
								                                    LPOVERLAPPED a3,
							 | 
						||
| 
								 | 
							
								                                    LPOVERLAPPED_COMPLETION_ROUTINE a4)
							 | 
						||
| 
								 | 
							
								    = WriteFileEx;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								BOOL (WINAPI * Real_WriteConsoleA)(HANDLE a0,
							 | 
						||
| 
								 | 
							
								                                      const VOID* a1,
							 | 
						||
| 
								 | 
							
								                                      DWORD a2,
							 | 
						||
| 
								 | 
							
								                                      LPDWORD a3,
							 | 
						||
| 
								 | 
							
								                                      LPVOID a4)
							 | 
						||
| 
								 | 
							
								    = WriteConsoleA;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								BOOL (WINAPI * Real_WriteConsoleW)(HANDLE a0,
							 | 
						||
| 
								 | 
							
								                                      const VOID* a1,
							 | 
						||
| 
								 | 
							
								                                      DWORD a2,
							 | 
						||
| 
								 | 
							
								                                      LPDWORD a3,
							 | 
						||
| 
								 | 
							
								                                      LPVOID a4)
							 | 
						||
| 
								 | 
							
								    = WriteConsoleW;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								VOID (WINAPI * Real_ExitProcess)(UINT a0)
							 | 
						||
| 
								 | 
							
								    = ExitProcess;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								DWORD (WINAPI * Real_ExpandEnvironmentStringsA)(PCSTR lpSrc, PCHAR lpDst, DWORD nSize)
							 | 
						||
| 
								 | 
							
								    = ExpandEnvironmentStringsA;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								DWORD (WINAPI * Real_ExpandEnvironmentStringsW)(PCWSTR lpSrc, PWCHAR lpDst, DWORD nSize)
							 | 
						||
| 
								 | 
							
								    = ExpandEnvironmentStringsW;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								DWORD (WINAPI * Real_GetEnvironmentVariableA)(PCSTR lpName, PCHAR lpBuffer, DWORD nSize)
							 | 
						||
| 
								 | 
							
								    = GetEnvironmentVariableA;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								DWORD (WINAPI * Real_GetEnvironmentVariableW)(PCWSTR lpName, PWCHAR lpBuffer, DWORD nSize)
							 | 
						||
| 
								 | 
							
								    = GetEnvironmentVariableW;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								PCWSTR (CDECL * Real_wgetenv)(PCWSTR var) = NULL;
							 | 
						||
| 
								 | 
							
								PCSTR (CDECL * Real_getenv)(PCSTR var) = NULL;
							 | 
						||
| 
								 | 
							
								DWORD (CDECL * Real_getenv_s)(DWORD *pValue, PCHAR pBuffer, DWORD cBuffer, PCSTR varname) = NULL;
							 | 
						||
| 
								 | 
							
								DWORD (CDECL * Real_wgetenv_s)(DWORD *pValue, PWCHAR pBuffer, DWORD cBuffer, PCWSTR varname) = NULL;
							 | 
						||
| 
								 | 
							
								DWORD (CDECL * Real_dupenv_s)(PCHAR *ppBuffer, DWORD *pcBuffer, PCSTR varname) = NULL;
							 | 
						||
| 
								 | 
							
								DWORD (CDECL * Real_wdupenv_s)(PWCHAR *ppBuffer, DWORD *pcBuffer, PCWSTR varname) = NULL;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//////////////////////////////////////////////////////////////////////////////
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								static VOID Copy(PWCHAR pwzDst, PCWSTR pwzSrc)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    while (*pwzSrc) {
							 | 
						||
| 
								 | 
							
								        *pwzDst++ = *pwzSrc++;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    *pwzDst = '\0';
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static DWORD Size(PCWSTR pwzSrc)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    DWORD c = 0;
							 | 
						||
| 
								 | 
							
								    while (pwzSrc[c]) {
							 | 
						||
| 
								 | 
							
								        c++;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return c;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static PCWSTR Save(PCWSTR pwzSrc)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    DWORD c = (Size(pwzSrc) + 1) * sizeof(WCHAR);
							 | 
						||
| 
								 | 
							
								    PWCHAR pwzDst = (PWCHAR)GlobalAlloc(GPTR, c);
							 | 
						||
| 
								 | 
							
								    CopyMemory(pwzDst, pwzSrc, c);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return pwzDst;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static BOOL HasSpace(PCWSTR pwz)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    for (; *pwz; pwz++) {
							 | 
						||
| 
								 | 
							
								        if (*pwz == ' ' || *pwz == '\t' || *pwz == '\r' || *pwz == '\n') {
							 | 
						||
| 
								 | 
							
								            return TRUE;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return FALSE;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static BOOL HasChar(PCWSTR pwz, WCHAR w)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    for (; *pwz; pwz++) {
							 | 
						||
| 
								 | 
							
								        if (*pwz == w) {
							 | 
						||
| 
								 | 
							
								            return TRUE;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return FALSE;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static DWORD Compare(PCWSTR pwzA, PCWSTR pwzB)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    for (;;) {
							 | 
						||
| 
								 | 
							
								        WCHAR cA = *pwzA++;
							 | 
						||
| 
								 | 
							
								        WCHAR cB = *pwzB++;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (cA >= 'A' && cA <= 'Z') {
							 | 
						||
| 
								 | 
							
								            cA += ('a' - 'A');
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        if (cB >= 'A' && cB <= 'Z') {
							 | 
						||
| 
								 | 
							
								            cB += ('a' - 'A');
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (cA == 0 && cB == 0) {
							 | 
						||
| 
								 | 
							
								            return 0;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        if (cA != cB) {
							 | 
						||
| 
								 | 
							
								            return cA - cB;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static DWORD Compare(PCWSTR pwzA, PCSTR pszB)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    for (;;) {
							 | 
						||
| 
								 | 
							
								        WCHAR cA = *pwzA++;
							 | 
						||
| 
								 | 
							
								        WCHAR cB = *pszB++;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (cA >= 'A' && cA <= 'Z') {
							 | 
						||
| 
								 | 
							
								            cA += ('a' - 'A');
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        if (cB >= 'A' && cB <= 'Z') {
							 | 
						||
| 
								 | 
							
								            cB += ('a' - 'A');
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (cA == 0 && cB == 0) {
							 | 
						||
| 
								 | 
							
								            return 0;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        if (cA != cB) {
							 | 
						||
| 
								 | 
							
								            return cA - cB;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static DWORD Compare(PCSTR pszA, PCSTR pszB)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    for (;;) {
							 | 
						||
| 
								 | 
							
								        CHAR cA = *pszA++;
							 | 
						||
| 
								 | 
							
								        CHAR cB = *pszB++;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (cA >= 'A' && cA <= 'Z') {
							 | 
						||
| 
								 | 
							
								            cA += ('a' - 'A');
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        if (cB >= 'A' && cB <= 'Z') {
							 | 
						||
| 
								 | 
							
								            cB += ('a' - 'A');
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (cA == 0 && cB == 0) {
							 | 
						||
| 
								 | 
							
								            return 0;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        if (cA != cB) {
							 | 
						||
| 
								 | 
							
								            return cA - cB;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//////////////////////////////////////////////////////////////////////////////
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static PCSTR s_rpszMsvcrNames[] = {
							 | 
						||
| 
								 | 
							
								    "msvcr80.dll",
							 | 
						||
| 
								 | 
							
								    "msvcr80d.dll",
							 | 
						||
| 
								 | 
							
								    "msvcr71.dll",
							 | 
						||
| 
								 | 
							
								    "msvcr71d.dll",
							 | 
						||
| 
								 | 
							
								    "msvcr70.dll",
							 | 
						||
| 
								 | 
							
								    "msvcr70d.dll",
							 | 
						||
| 
								 | 
							
								    NULL
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								HMODULE s_hMsvcr = NULL;
							 | 
						||
| 
								 | 
							
								PCSTR s_pszMsvcr = NULL;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static BOOL WINAPI ImportFileCallback(PVOID pContext, HMODULE hFile, PCSTR pszFile)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    UNUSED(pContext);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (pszFile != NULL) {
							 | 
						||
| 
								 | 
							
								        for (int i = 0; s_rpszMsvcrNames[i]; i++) {
							 | 
						||
| 
								 | 
							
								            if (Compare(pszFile, s_rpszMsvcrNames[i]) == 0) {
							 | 
						||
| 
								 | 
							
								                s_hMsvcr = hFile;
							 | 
						||
| 
								 | 
							
								                s_pszMsvcr = s_rpszMsvcrNames[i];
							 | 
						||
| 
								 | 
							
								                return FALSE;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return TRUE;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								BOOL FindMsvcr()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    DetourEnumerateImports(NULL, NULL, ImportFileCallback, NULL);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (s_hMsvcr != NULL) {
							 | 
						||
| 
								 | 
							
								        return TRUE;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return FALSE;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								BOOL FindProc(PVOID * ppvCode, PCSTR pwzFunc)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    PVOID pv = GetProcAddress(s_hMsvcr, pwzFunc);
							 | 
						||
| 
								 | 
							
								    if (pv != NULL) {
							 | 
						||
| 
								 | 
							
								        *ppvCode = pv;
							 | 
						||
| 
								 | 
							
								        return TRUE;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    else {
							 | 
						||
| 
								 | 
							
								        *ppvCode = NULL;
							 | 
						||
| 
								 | 
							
								        return FALSE;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//////////////////////////////////////////////////////////////////////////////
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								struct EnvInfo
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    DWORD   m_nHash;
							 | 
						||
| 
								 | 
							
								    DWORD   m_nIndex;
							 | 
						||
| 
								 | 
							
								    PCWSTR  m_pwzVar;
							 | 
						||
| 
								 | 
							
								    PCWSTR  m_pwzVal;
							 | 
						||
| 
								 | 
							
								    BOOL    m_fDefined;
							 | 
						||
| 
								 | 
							
								    BOOL    m_fUsed;
							 | 
						||
| 
								 | 
							
								    BOOL    m_fOriginal;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//////////////////////////////////////////////////////////////////////////////
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								class EnvVars
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  private:
							 | 
						||
| 
								 | 
							
								    static CRITICAL_SECTION s_csLock;
							 | 
						||
| 
								 | 
							
								    static DWORD            s_nVars;
							 | 
						||
| 
								 | 
							
								    static DWORD            s_nCapacity;
							 | 
						||
| 
								 | 
							
								    static EnvInfo **       s_pVars;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  private:
							 | 
						||
| 
								 | 
							
								    static DWORD Hash(PCWSTR pwzVar)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        DWORD hash = 5381;
							 | 
						||
| 
								 | 
							
								        while (*pwzVar != 0) {
							 | 
						||
| 
								 | 
							
								            WCHAR c = *pwzVar++;
							 | 
						||
| 
								 | 
							
								            if (c >= 'A' && c <= 'Z') {
							 | 
						||
| 
								 | 
							
								                c += ('a' - 'A');
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            hash = ((hash << 5) + hash) + c;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        return hash;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    static VOID LockAcquire()
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        EnterCriticalSection(&s_csLock);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    static VOID LockRelease()
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        LeaveCriticalSection(&s_csLock);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    static VOID Resize(DWORD nCapacity);
							 | 
						||
| 
								 | 
							
								    static VOID Set(EnvInfo *info);
							 | 
						||
| 
								 | 
							
								    static EnvInfo * Find(PCWSTR pwzVar);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  public:
							 | 
						||
| 
								 | 
							
								    static BOOL Equal(PCWSTR pwzA, PCWSTR pwzB)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return (Compare(pwzA, pwzB) == 0);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  public:
							 | 
						||
| 
								 | 
							
								    static VOID Initialize();
							 | 
						||
| 
								 | 
							
								    static VOID Dump();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    static VOID Add(PCWSTR pwzVar, PCWSTR pwzVal);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    static VOID Used(PCWSTR pwzVar);
							 | 
						||
| 
								 | 
							
								    static VOID Used(PCSTR pszVar);
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								CRITICAL_SECTION    EnvVars::s_csLock;
							 | 
						||
| 
								 | 
							
								DWORD               EnvVars::s_nVars = 0;
							 | 
						||
| 
								 | 
							
								DWORD               EnvVars::s_nCapacity = 0;
							 | 
						||
| 
								 | 
							
								EnvInfo **          EnvVars::s_pVars = NULL;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								VOID EnvVars::Initialize()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    InitializeCriticalSection(&s_csLock);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    Resize(919);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								VOID EnvVars::Resize(DWORD nCapacity)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    if (nCapacity > s_nCapacity) {
							 | 
						||
| 
								 | 
							
								        DWORD nOld = s_nCapacity;
							 | 
						||
| 
								 | 
							
								        EnvInfo ** pOld = s_pVars;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // DEBUG_BREAK();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        s_pVars = (EnvInfo **)GlobalAlloc(GPTR, nCapacity * sizeof(EnvInfo *));
							 | 
						||
| 
								 | 
							
								        s_nCapacity = nCapacity;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (pOld != NULL) {
							 | 
						||
| 
								 | 
							
								            for (DWORD n = 0; n < nOld; n++) {
							 | 
						||
| 
								 | 
							
								                if (pOld[n] != NULL) {
							 | 
						||
| 
								 | 
							
								                    Set(pOld[n]);
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            GlobalFree((HGLOBAL)pOld);
							 | 
						||
| 
								 | 
							
								            pOld = NULL;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								VOID EnvVars::Set(EnvInfo *info)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    DWORD hash = info->m_nHash;
							 | 
						||
| 
								 | 
							
								    DWORD slot = hash % s_nCapacity;
							 | 
						||
| 
								 | 
							
								    DWORD death = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // Find an empty slot.
							 | 
						||
| 
								 | 
							
								    for (; s_pVars[slot] != NULL; slot = (slot + 1) % s_nCapacity) {
							 | 
						||
| 
								 | 
							
								        if (++death > s_nCapacity) {
							 | 
						||
| 
								 | 
							
								            // We should have dropped out at some point...
							 | 
						||
| 
								 | 
							
								            DEBUG_BREAK();
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    s_pVars[slot] = info;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								EnvInfo * EnvVars::Find(PCWSTR pwzVar)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    DWORD hash = Hash(pwzVar);
							 | 
						||
| 
								 | 
							
								    DWORD slot = hash % s_nCapacity;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    LockAcquire();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // Find the the matching slot, or an empty one.
							 | 
						||
| 
								 | 
							
								    for (; s_pVars[slot] != NULL; slot = (slot + 1) % s_nCapacity) {
							 | 
						||
| 
								 | 
							
								        if (Equal(s_pVars[slot]->m_pwzVar, pwzVar)) {
							 | 
						||
| 
								 | 
							
								            LockRelease();
							 | 
						||
| 
								 | 
							
								            return s_pVars[slot];
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    LockRelease();
							 | 
						||
| 
								 | 
							
								    return NULL;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								VOID EnvVars::Add(PCWSTR pwzVar, PCWSTR pwzVal)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    if (pwzVar == NULL) {
							 | 
						||
| 
								 | 
							
								        return;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    WCHAR wzVar[MAX_PATH];
							 | 
						||
| 
								 | 
							
								    PWCHAR pwzDst = wzVar;
							 | 
						||
| 
								 | 
							
								    while (*pwzVar) {
							 | 
						||
| 
								 | 
							
								        if (*pwzVar >= 'a' && *pwzVar <= 'z') {
							 | 
						||
| 
								 | 
							
								            *pwzDst++ = *pwzVar - ('a' - 'A');
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        else {
							 | 
						||
| 
								 | 
							
								            *pwzDst++ = *pwzVar;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        pwzVar++;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    *pwzDst = '\0';
							 | 
						||
| 
								 | 
							
								    pwzVar = wzVar;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    WCHAR wzVal[] = L"";
							 | 
						||
| 
								 | 
							
								    if (pwzVal != NULL) {
							 | 
						||
| 
								 | 
							
								        while (*pwzVal == ' ' || *pwzVal == '\t') {
							 | 
						||
| 
								 | 
							
								            *pwzVal++;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    else {
							 | 
						||
| 
								 | 
							
								        pwzVal = wzVal;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // Tblog("<!-- ::Add var=[%le] val=[%le] -->\n", pwzVar, pwzVal);
							 | 
						||
| 
								 | 
							
								    LockAcquire();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // DEBUG_BREAK();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    DWORD hash = Hash(pwzVar);
							 | 
						||
| 
								 | 
							
								    DWORD slot = hash % s_nCapacity;
							 | 
						||
| 
								 | 
							
								    EnvInfo *info = NULL;
							 | 
						||
| 
								 | 
							
								    DWORD death = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // Find the the matching slot, or an empty one.
							 | 
						||
| 
								 | 
							
								    for (; s_pVars[slot] != NULL; slot = (slot + 1) % s_nCapacity) {
							 | 
						||
| 
								 | 
							
								        if (Equal(s_pVars[slot]->m_pwzVar, pwzVar)) {
							 | 
						||
| 
								 | 
							
								            LockRelease();
							 | 
						||
| 
								 | 
							
								            return;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        if (++death > s_nCapacity) {
							 | 
						||
| 
								 | 
							
								            // We should have dropped out at some point...
							 | 
						||
| 
								 | 
							
								            DEBUG_BREAK();
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // Add the var to list of known vars.
							 | 
						||
| 
								 | 
							
								    info = (EnvInfo *)GlobalAlloc(GPTR, sizeof(EnvInfo));
							 | 
						||
| 
								 | 
							
								    info->m_nHash = hash;
							 | 
						||
| 
								 | 
							
								    info->m_nIndex = s_nVars++;
							 | 
						||
| 
								 | 
							
								    info->m_pwzVar = Save(pwzVar);
							 | 
						||
| 
								 | 
							
								    info->m_pwzVal = Save(pwzVal);
							 | 
						||
| 
								 | 
							
								    if (pwzVal[0] == '\0') {
							 | 
						||
| 
								 | 
							
								        info->m_fDefined = FALSE;
							 | 
						||
| 
								 | 
							
								        info->m_fUsed = TRUE;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    else {
							 | 
						||
| 
								 | 
							
								        info->m_fDefined = TRUE;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    s_pVars[slot] = info;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // Check if we should grow the table.
							 | 
						||
| 
								 | 
							
								    if (s_nVars > (s_nCapacity / 2)) {
							 | 
						||
| 
								 | 
							
								        Resize(s_nCapacity * 2 - 1);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    LockRelease();
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								VOID EnvVars::Used(PCWSTR pwzVar)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    if (pwzVar != NULL) {
							 | 
						||
| 
								 | 
							
								        // Tblog("<!-- Used [%le] -->\n", pwzVar);
							 | 
						||
| 
								 | 
							
								        EnvInfo *pInfo = Find(pwzVar);
							 | 
						||
| 
								 | 
							
								        if (pInfo) {
							 | 
						||
| 
								 | 
							
								            pInfo->m_fUsed = TRUE;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								#if 0
							 | 
						||
| 
								 | 
							
								        else {
							 | 
						||
| 
								 | 
							
								            Add(pwzVar, NULL);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								VOID EnvVars::Used(PCSTR pszVar)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    if (pszVar != NULL) {
							 | 
						||
| 
								 | 
							
								        WCHAR wzVar[MAX_PATH];
							 | 
						||
| 
								 | 
							
								        PWCHAR pwzVar = wzVar;
							 | 
						||
| 
								 | 
							
								        while (*pszVar) {
							 | 
						||
| 
								 | 
							
								            *pwzVar++ = *pszVar++;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        *pwzVar = '\0';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        Used(wzVar);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								VOID EnvVars::Dump()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    if (s_nVars == 0) {
							 | 
						||
| 
								 | 
							
								        return;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    LockAcquire();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    Tblog("<t:Vars>\n");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // Remove any variables that match the original environment.
							 | 
						||
| 
								 | 
							
								    PCWSTR pwzz = s_Payload.wzzEnvironment;
							 | 
						||
| 
								 | 
							
								    while (*pwzz) {
							 | 
						||
| 
								 | 
							
								        WCHAR wzVar[MAX_PATH];
							 | 
						||
| 
								 | 
							
								        PWCHAR pwzVar = wzVar;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        while (*pwzz && *pwzz != '=') {
							 | 
						||
| 
								 | 
							
								            *pwzVar++ = *pwzz++;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        *pwzVar = '\0';
							 | 
						||
| 
								 | 
							
								        if (*pwzz == '=') {
							 | 
						||
| 
								 | 
							
								            pwzz++;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        EnvInfo *pInfo = Find(wzVar);
							 | 
						||
| 
								 | 
							
								        if (pInfo) {
							 | 
						||
| 
								 | 
							
								            if (Compare(pwzz, pInfo->m_pwzVal) == 0) {
							 | 
						||
| 
								 | 
							
								                pInfo->m_fUsed = FALSE;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        pwzz += Size(pwzz) + 1;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    EnvInfo ** pSorted = (EnvInfo **)GlobalAlloc(GPTR, s_nVars * sizeof(EnvInfo *));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    for (DWORD n = 0; n < s_nCapacity; n++) {
							 | 
						||
| 
								 | 
							
								        if (s_pVars[n] != NULL) {
							 | 
						||
| 
								 | 
							
								            if (s_pVars[n]->m_nIndex > s_nVars) {
							 | 
						||
| 
								 | 
							
								                DEBUG_BREAK();
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            pSorted[s_pVars[n]->m_nIndex] = s_pVars[n];
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    for (DWORD n = 0; n < s_nVars; n++) {
							 | 
						||
| 
								 | 
							
								        EnvInfo *pInfo = pSorted[n];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (pInfo == NULL) {
							 | 
						||
| 
								 | 
							
								            Print("<!-- Warning: Missing %d of %d -->\n", n, s_nVars);
							 | 
						||
| 
								 | 
							
								            continue;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (pInfo->m_fUsed && pInfo->m_pwzVal[0]) {
							 | 
						||
| 
								 | 
							
								            Print("<t:Var var=\"%le\">%le</t:Var>\n", pInfo->m_pwzVar, pInfo->m_pwzVal);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    GlobalFree((HGLOBAL)pSorted);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    Tblog("</t:Vars>\n");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    LockRelease();
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void SaveEnvironment()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    LPWCH pwStrings = GetEnvironmentStringsW();
							 | 
						||
| 
								 | 
							
								    PCWSTR pwEnv = (PCWSTR)pwStrings;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    while (*pwEnv != '\0') {
							 | 
						||
| 
								 | 
							
								        WCHAR wzVar[MAX_PATH];
							 | 
						||
| 
								 | 
							
								        PWCHAR pwzDst = wzVar;
							 | 
						||
| 
								 | 
							
								        PCWSTR pwzVal = NULL;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (*pwEnv == '=') {
							 | 
						||
| 
								 | 
							
								            *pwzDst++ = *pwEnv++;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        while (*pwEnv != '\0' && *pwEnv != '=') {
							 | 
						||
| 
								 | 
							
								            *pwzDst++ = *pwEnv++;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        *pwzDst++ = '\0';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (*pwEnv == '=') {
							 | 
						||
| 
								 | 
							
								            pwEnv++;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        pwzVal = pwEnv;
							 | 
						||
| 
								 | 
							
								        while (*pwEnv != '\0') {
							 | 
						||
| 
								 | 
							
								            pwEnv++;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        if (*pwEnv == '\0') {
							 | 
						||
| 
								 | 
							
								            pwEnv++;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        if (wzVar[0] != '=') {
							 | 
						||
| 
								 | 
							
								            EnvVars::Add(wzVar, pwzVal);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    FreeEnvironmentStringsW(pwStrings);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//////////////////////////////////////////////////////////////////////////////
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								struct ProcInfo
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    HANDLE  m_hProc;
							 | 
						||
| 
								 | 
							
								    DWORD   m_nProcId;
							 | 
						||
| 
								 | 
							
								    DWORD   m_nProc;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class Procs
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  private:
							 | 
						||
| 
								 | 
							
								    static CRITICAL_SECTION s_csLock;
							 | 
						||
| 
								 | 
							
								    static DWORD            s_nProcs;
							 | 
						||
| 
								 | 
							
								    static ProcInfo         s_rProcs[4049];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  private:
							 | 
						||
| 
								 | 
							
								    static ProcInfo& HashToSlot(HANDLE handle)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return s_rProcs[((DWORD_PTR)handle) % ARRAYSIZE(s_rProcs)];
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    static VOID LockAcquire()
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        EnterCriticalSection(&s_csLock);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    static VOID LockRelease()
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        LeaveCriticalSection(&s_csLock);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  public:
							 | 
						||
| 
								 | 
							
								    static VOID Initialize();
							 | 
						||
| 
								 | 
							
								    static ProcInfo * Create(HANDLE hProc, DWORD nProcId);
							 | 
						||
| 
								 | 
							
								    static BOOL Close(HANDLE hProc);
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								CRITICAL_SECTION    Procs::s_csLock;
							 | 
						||
| 
								 | 
							
								DWORD               Procs::s_nProcs = 0;
							 | 
						||
| 
								 | 
							
								ProcInfo            Procs::s_rProcs[4049];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								VOID Procs::Initialize()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    InitializeCriticalSection(&s_csLock);
							 | 
						||
| 
								 | 
							
								    for (DWORD i = 0; i < ARRAYSIZE(s_rProcs); i++) {
							 | 
						||
| 
								 | 
							
								        s_rProcs[i].m_hProc = INVALID_HANDLE_VALUE;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								ProcInfo * Procs::Create(HANDLE hProc, DWORD nProcId)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    LockAcquire();
							 | 
						||
| 
								 | 
							
								    s_nProcs++;
							 | 
						||
| 
								 | 
							
								    ProcInfo& slot = HashToSlot(hProc);
							 | 
						||
| 
								 | 
							
								    slot.m_hProc = hProc;
							 | 
						||
| 
								 | 
							
								    slot.m_nProcId = nProcId;
							 | 
						||
| 
								 | 
							
								    slot.m_nProc = s_nProcs;
							 | 
						||
| 
								 | 
							
								    Print("<!-- CreateProcess (%d)-->\n", slot.m_nProc);
							 | 
						||
| 
								 | 
							
								    LockRelease();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return &slot;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								BOOL Procs::Close(HANDLE hProc)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    BOOL first = false;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    LockAcquire();
							 | 
						||
| 
								 | 
							
								    ProcInfo& slot = HashToSlot(hProc);
							 | 
						||
| 
								 | 
							
								    if (slot.m_hProc == hProc) {
							 | 
						||
| 
								 | 
							
								        first = true;
							 | 
						||
| 
								 | 
							
								        Print("<!-- CloseProcess (%d)-->\n", slot.m_nProc);
							 | 
						||
| 
								 | 
							
								        slot.m_hProc = INVALID_HANDLE_VALUE;
							 | 
						||
| 
								 | 
							
								        slot.m_nProcId = 0;
							 | 
						||
| 
								 | 
							
								        slot.m_nProc = 0;
							 | 
						||
| 
								 | 
							
								        s_nProcs--;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    LockRelease();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return first;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//////////////////////////////////////////////////////////////////////////////
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								struct FileInfo
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    DWORD   m_nHash;
							 | 
						||
| 
								 | 
							
								    DWORD   m_nIndex;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    BOOL    m_fCantRead;        // Set for file that are opened Create
							 | 
						||
| 
								 | 
							
								    BOOL    m_fRead;
							 | 
						||
| 
								 | 
							
								    BOOL    m_fWrite;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    BOOL    m_fDelete;
							 | 
						||
| 
								 | 
							
								    BOOL    m_fCleanup;
							 | 
						||
| 
								 | 
							
								    BOOL    m_fSystemPath;
							 | 
						||
| 
								 | 
							
								    BOOL    m_fTemporaryPath;
							 | 
						||
| 
								 | 
							
								    BOOL    m_fTemporaryFile;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    DWORD   m_cbRead;
							 | 
						||
| 
								 | 
							
								    DWORD   m_cbWrite;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    BOOL    m_fAppend;
							 | 
						||
| 
								 | 
							
								    BOOL    m_fAbsorbed;        // Absorbed by TraceBld.
							 | 
						||
| 
								 | 
							
								    BOOL    m_fDirectory;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    PCWSTR  m_pwzPath;
							 | 
						||
| 
								 | 
							
								    PBYTE   m_pbContent;
							 | 
						||
| 
								 | 
							
								    DWORD   m_cbContent;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//////////////////////////////////////////////////////////////////////////////
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								class FileNames
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  private:
							 | 
						||
| 
								 | 
							
								    static CRITICAL_SECTION s_csLock;
							 | 
						||
| 
								 | 
							
								    static DWORD            s_nFiles;
							 | 
						||
| 
								 | 
							
								    static DWORD            s_nCapacity;
							 | 
						||
| 
								 | 
							
								    static FileInfo **      s_pFiles;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  public:
							 | 
						||
| 
								 | 
							
								    static WCHAR            s_wzSysPath[MAX_PATH];
							 | 
						||
| 
								 | 
							
								    static WCHAR            s_wzS64Path[MAX_PATH];
							 | 
						||
| 
								 | 
							
								    static WCHAR            s_wzTmpPath[MAX_PATH];
							 | 
						||
| 
								 | 
							
								    static WCHAR            s_wzExePath[MAX_PATH];
							 | 
						||
| 
								 | 
							
								    static DWORD            s_wcSysPath;
							 | 
						||
| 
								 | 
							
								    static DWORD            s_wcS64Path;
							 | 
						||
| 
								 | 
							
								    static DWORD            s_wcTmpPath;
							 | 
						||
| 
								 | 
							
								    static DWORD            s_wcExePath;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  private:
							 | 
						||
| 
								 | 
							
								    static DWORD Hash(PCWSTR pwzFile)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        DWORD hash = 5381;
							 | 
						||
| 
								 | 
							
								        while (*pwzFile != 0) {
							 | 
						||
| 
								 | 
							
								            WCHAR c = *pwzFile++;
							 | 
						||
| 
								 | 
							
								            if (c >= 'A' && c <= 'Z') {
							 | 
						||
| 
								 | 
							
								                c += ('a' - 'A');
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            hash = ((hash << 5) + hash) + c;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        return hash;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    static VOID LockAcquire()
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        EnterCriticalSection(&s_csLock);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    static VOID LockRelease()
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        LeaveCriticalSection(&s_csLock);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    static VOID Resize(DWORD nCapacity);
							 | 
						||
| 
								 | 
							
								    static VOID Set(FileInfo *info);
							 | 
						||
| 
								 | 
							
								    static VOID Replace(PWCHAR pwzBuffer, PWCHAR pwzDstEnd, DWORD cwOld, PCWSTR pwzNew);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  public:
							 | 
						||
| 
								 | 
							
								    static BOOL Equal(PCWSTR pwzA, PCWSTR pwzB)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return (Compare(pwzA, pwzB) == 0);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    static BOOL PrefixMatch(PCWSTR pwzFile, PCWSTR pwzPrefix)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        for (;;) {
							 | 
						||
| 
								 | 
							
								            WCHAR cFile = *pwzFile++;
							 | 
						||
| 
								 | 
							
								            WCHAR cPrefix = *pwzPrefix++;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if (cFile >= 'A' && cFile <= 'Z') {
							 | 
						||
| 
								 | 
							
								                cFile += ('a' - 'A');
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            if (cPrefix >= 'A' && cPrefix <= 'Z') {
							 | 
						||
| 
								 | 
							
								                cPrefix += ('a' - 'A');
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if (cPrefix == 0) {
							 | 
						||
| 
								 | 
							
								                return TRUE;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            if (cFile != cPrefix) {
							 | 
						||
| 
								 | 
							
								                return FALSE;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    static BOOL SuffixMatch(PCWSTR pwzFile, PCWSTR pwzSuffix)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        // Move both pointers to the end of the strings.
							 | 
						||
| 
								 | 
							
								        PCWSTR pwzFileBeg = pwzFile;
							 | 
						||
| 
								 | 
							
								        while (*pwzFile) {
							 | 
						||
| 
								 | 
							
								            pwzFile++;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        PCWSTR pwzSuffixBeg = pwzSuffix;
							 | 
						||
| 
								 | 
							
								        while (*pwzSuffix) {
							 | 
						||
| 
								 | 
							
								            pwzSuffix++;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // Now walk backwards comparing strings.
							 | 
						||
| 
								 | 
							
								        for (;;) {
							 | 
						||
| 
								 | 
							
								            WCHAR cFile = (pwzFile > pwzFileBeg) ? *--pwzFile : 0;
							 | 
						||
| 
								 | 
							
								            WCHAR cSuffix = (pwzSuffix > pwzSuffixBeg) ? *--pwzSuffix : 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if (cFile >= 'A' && cFile <= 'Z') {
							 | 
						||
| 
								 | 
							
								                cFile += ('a' - 'A');
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            if (cSuffix >= 'A' && cSuffix <= 'Z') {
							 | 
						||
| 
								 | 
							
								                cSuffix += ('a' - 'A');
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if (cSuffix == 0) {
							 | 
						||
| 
								 | 
							
								                return TRUE;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            if (cFile != cSuffix) {
							 | 
						||
| 
								 | 
							
								                return FALSE;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    static VOID EndInSlash(PWCHAR pwzPath)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        if (*pwzPath) {
							 | 
						||
| 
								 | 
							
								            while (*pwzPath) {
							 | 
						||
| 
								 | 
							
								                pwzPath++;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            if (pwzPath[-1] != '\\') {
							 | 
						||
| 
								 | 
							
								                *pwzPath++ = '\\';
							 | 
						||
| 
								 | 
							
								                *pwzPath = '\0';
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  public:
							 | 
						||
| 
								 | 
							
								    static VOID Initialize();
							 | 
						||
| 
								 | 
							
								    static VOID Dump();
							 | 
						||
| 
								 | 
							
								    static FileInfo * FindPartial(PCWSTR pwzPath);
							 | 
						||
| 
								 | 
							
								    static FileInfo * FindPartial(PCSTR pszPath);
							 | 
						||
| 
								 | 
							
								    static FileInfo * FindFull(PCWSTR pwzPath);
							 | 
						||
| 
								 | 
							
								    static PCWSTR ParameterizeName(PWCHAR pwzDst, DWORD cMaxDst, PCWSTR pwzPath);
							 | 
						||
| 
								 | 
							
								    static PCWSTR ParameterizeName(PWCHAR pwzDst, DWORD cMaxDst, FileInfo *pInfo);
							 | 
						||
| 
								 | 
							
								    static VOID ParameterizeLine(PWCHAR pwzDst, PWCHAR pwzDstEnd);
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								CRITICAL_SECTION    FileNames::s_csLock;
							 | 
						||
| 
								 | 
							
								DWORD               FileNames::s_nFiles = 0;
							 | 
						||
| 
								 | 
							
								DWORD               FileNames::s_nCapacity = 0;
							 | 
						||
| 
								 | 
							
								FileInfo **         FileNames::s_pFiles;
							 | 
						||
| 
								 | 
							
								WCHAR               FileNames::s_wzSysPath[MAX_PATH];
							 | 
						||
| 
								 | 
							
								WCHAR               FileNames::s_wzS64Path[MAX_PATH];
							 | 
						||
| 
								 | 
							
								WCHAR               FileNames::s_wzTmpPath[MAX_PATH];
							 | 
						||
| 
								 | 
							
								WCHAR               FileNames::s_wzExePath[MAX_PATH];
							 | 
						||
| 
								 | 
							
								DWORD               FileNames::s_wcSysPath;
							 | 
						||
| 
								 | 
							
								DWORD               FileNames::s_wcS64Path;
							 | 
						||
| 
								 | 
							
								DWORD               FileNames::s_wcTmpPath;
							 | 
						||
| 
								 | 
							
								DWORD               FileNames::s_wcExePath;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								VOID FileNames::Initialize()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    InitializeCriticalSection(&s_csLock);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    s_wzSysPath[0] = '\0';
							 | 
						||
| 
								 | 
							
								    GetSystemDirectoryW(s_wzSysPath, ARRAYSIZE(s_wzSysPath));
							 | 
						||
| 
								 | 
							
								    EndInSlash(s_wzSysPath);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    s_wzS64Path[0] = '\0';
							 | 
						||
| 
								 | 
							
								    GetWindowsDirectoryW(s_wzS64Path, ARRAYSIZE(s_wzS64Path));
							 | 
						||
| 
								 | 
							
								    EndInSlash(s_wzS64Path);
							 | 
						||
| 
								 | 
							
								    Copy(s_wzS64Path + Size(s_wzS64Path), L"SysWOW64\\");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    s_wzTmpPath[0] = '\0';
							 | 
						||
| 
								 | 
							
								    GetTempPathW(ARRAYSIZE(s_wzTmpPath), s_wzTmpPath);
							 | 
						||
| 
								 | 
							
								    EndInSlash(s_wzTmpPath);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    s_wzExePath[0] = '\0';
							 | 
						||
| 
								 | 
							
								    GetModuleFileNameW(NULL, s_wzExePath, ARRAYSIZE(s_wzExePath));
							 | 
						||
| 
								 | 
							
								    PWCHAR pwzLast = s_wzExePath;
							 | 
						||
| 
								 | 
							
								    for (PWCHAR pwz = s_wzExePath; *pwz; pwz++) {
							 | 
						||
| 
								 | 
							
								        if (*pwz == '\\') {
							 | 
						||
| 
								 | 
							
								            pwzLast = pwz;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    if (*pwzLast == '\\') {
							 | 
						||
| 
								 | 
							
								        *++pwzLast = '\0';
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    s_wcSysPath = Size(s_wzSysPath);
							 | 
						||
| 
								 | 
							
								    s_wcS64Path = Size(s_wzS64Path);
							 | 
						||
| 
								 | 
							
								    s_wcTmpPath = Size(s_wzTmpPath);
							 | 
						||
| 
								 | 
							
								    s_wcExePath = Size(s_wzExePath);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    Resize(4049);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								VOID FileNames::Resize(DWORD nCapacity)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    if (nCapacity > s_nCapacity) {
							 | 
						||
| 
								 | 
							
								        DWORD nOld = s_nCapacity;
							 | 
						||
| 
								 | 
							
								        FileInfo ** pOld = s_pFiles;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        s_pFiles = (FileInfo **)GlobalAlloc(GPTR, nCapacity * sizeof(FileInfo *));
							 | 
						||
| 
								 | 
							
								        s_nCapacity = nCapacity;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (pOld != NULL) {
							 | 
						||
| 
								 | 
							
								            for (DWORD n = 0; n < nOld; n++) {
							 | 
						||
| 
								 | 
							
								                if (pOld[n] != NULL) {
							 | 
						||
| 
								 | 
							
								                    Set(pOld[n]);
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            GlobalFree((HGLOBAL)pOld);
							 | 
						||
| 
								 | 
							
								            pOld = NULL;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        s_nCapacity = nCapacity;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								VOID FileNames::Set(FileInfo *info)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    DWORD hash = info->m_nHash;
							 | 
						||
| 
								 | 
							
								    DWORD slot = hash % s_nCapacity;
							 | 
						||
| 
								 | 
							
								    DWORD death = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // Find an empty slot.
							 | 
						||
| 
								 | 
							
								    for (; s_pFiles[slot] != NULL; slot = (slot + 1) % s_nCapacity) {
							 | 
						||
| 
								 | 
							
								        if (++death > s_nCapacity) {
							 | 
						||
| 
								 | 
							
								            // We should have dropped out at some point...
							 | 
						||
| 
								 | 
							
								            DEBUG_BREAK();
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    s_pFiles[slot] = info;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								FileInfo * FileNames::FindFull(PCWSTR pwzPath)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    if (pwzPath == NULL) {
							 | 
						||
| 
								 | 
							
								        return NULL;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    LockAcquire();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    DWORD hash = Hash(pwzPath);
							 | 
						||
| 
								 | 
							
								    DWORD slot = hash % s_nCapacity;
							 | 
						||
| 
								 | 
							
								    FileInfo *info = NULL;
							 | 
						||
| 
								 | 
							
								    DWORD death = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // Find the the matching slot, or an empty one.
							 | 
						||
| 
								 | 
							
								    for (; s_pFiles[slot] != NULL; slot = (slot + 1) % s_nCapacity) {
							 | 
						||
| 
								 | 
							
								        if (Equal(s_pFiles[slot]->m_pwzPath, pwzPath)) {
							 | 
						||
| 
								 | 
							
								            info = s_pFiles[slot];
							 | 
						||
| 
								 | 
							
								            goto succeed;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        if (++death > s_nCapacity) {
							 | 
						||
| 
								 | 
							
								            // We should have dropped out at some point...
							 | 
						||
| 
								 | 
							
								            DEBUG_BREAK();
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // Add the file to list of known files.
							 | 
						||
| 
								 | 
							
								    info = (FileInfo *)GlobalAlloc(GPTR, sizeof(FileInfo));
							 | 
						||
| 
								 | 
							
								    info->m_nHash = hash;
							 | 
						||
| 
								 | 
							
								    info->m_nIndex = s_nFiles++;
							 | 
						||
| 
								 | 
							
								    info->m_pwzPath = Save(pwzPath);
							 | 
						||
| 
								 | 
							
								    info->m_fSystemPath = (PrefixMatch(info->m_pwzPath, s_wzSysPath) ||
							 | 
						||
| 
								 | 
							
								                           PrefixMatch(info->m_pwzPath, s_wzS64Path));
							 | 
						||
| 
								 | 
							
								    info->m_fTemporaryPath = PrefixMatch(info->m_pwzPath, s_wzTmpPath);
							 | 
						||
| 
								 | 
							
								    info->m_fTemporaryFile = SuffixMatch(info->m_pwzPath, L".tmp");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    s_pFiles[slot] = info;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // Check if we should grow the table.
							 | 
						||
| 
								 | 
							
								    if (s_nFiles > (s_nCapacity / 2)) {
							 | 
						||
| 
								 | 
							
								        Resize(s_nCapacity * 2 - 1);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  succeed:
							 | 
						||
| 
								 | 
							
								    LockRelease();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return info;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								FileInfo * FileNames::FindPartial(PCWSTR pwzPath)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    WCHAR wzPath[MAX_PATH];
							 | 
						||
| 
								 | 
							
								    PWCHAR pwzFile = NULL;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (!GetFullPathNameW(pwzPath, ARRAYSIZE(wzPath), wzPath, &pwzFile)) {
							 | 
						||
| 
								 | 
							
								        return FindFull(pwzPath);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    else {
							 | 
						||
| 
								 | 
							
								        return FindFull(wzPath);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								FileInfo * FileNames::FindPartial(PCSTR pwzPath)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    WCHAR wzPath[MAX_PATH];
							 | 
						||
| 
								 | 
							
								    PWCHAR pwzFile = wzPath;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    while (*pwzPath) {
							 | 
						||
| 
								 | 
							
								        *pwzFile++ = *pwzPath++;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    *pwzFile = '\0';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return FindPartial(wzPath);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								PCWSTR FileNames::ParameterizeName(PWCHAR pwzDst, DWORD cMaxDst, FileInfo *pInfo)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    return ParameterizeName(pwzDst, cMaxDst, pInfo->m_pwzPath);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								PCWSTR FileNames::ParameterizeName(PWCHAR pwzDst, DWORD cMaxDst, PCWSTR pwzPath)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    if (PrefixMatch(pwzPath, s_wzSysPath)) {
							 | 
						||
| 
								 | 
							
								        Copy(pwzDst, L"%SYSDIR%\\");
							 | 
						||
| 
								 | 
							
								        Copy(pwzDst + Size(pwzDst), pwzPath + s_wcSysPath);
							 | 
						||
| 
								 | 
							
								        goto finish;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    else if (PrefixMatch(pwzPath, s_wzS64Path)) {
							 | 
						||
| 
								 | 
							
								        Copy(pwzDst, L"%SYSDIR%\\");
							 | 
						||
| 
								 | 
							
								        Copy(pwzDst + Size(pwzDst), pwzPath + s_wcS64Path);
							 | 
						||
| 
								 | 
							
								        goto finish;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    else if (PrefixMatch(pwzPath, s_wzTmpPath)) {
							 | 
						||
| 
								 | 
							
								        Copy(pwzDst, L"%TMPDIR%\\");
							 | 
						||
| 
								 | 
							
								        Copy(pwzDst + Size(pwzDst), pwzPath + s_wcTmpPath);
							 | 
						||
| 
								 | 
							
								        goto finish;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    else {
							 | 
						||
| 
								 | 
							
								        Copy(pwzDst, pwzPath);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      finish:
							 | 
						||
| 
								 | 
							
								#if 0 // to convert to all lower case.
							 | 
						||
| 
								 | 
							
								        for (PWCHAR pwz = pwzDst; *pwz && pwz < pwzDst + cMaxDst; pwz++) {
							 | 
						||
| 
								 | 
							
								            if (*pwz >= 'A' && *pwz <= 'Z') {
							 | 
						||
| 
								 | 
							
								                *pwz = 'a' + (*pwz - 'A');
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								        (void)cMaxDst;
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								        return pwzDst;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								VOID FileNames::Replace(PWCHAR pwzDst, PWCHAR pwzDstEnd, DWORD cwOld, PCWSTR pwzNew)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    DWORD cwNew = Size(pwzNew);
							 | 
						||
| 
								 | 
							
								    DWORD cwDst = Size(pwzDst);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (cwOld < cwNew) {        // We have to insert.
							 | 
						||
| 
								 | 
							
								        if ((cwDst + cwNew - cwOld) >= (DWORD)(pwzDstEnd - pwzDst)) {
							 | 
						||
| 
								 | 
							
								            // Won't fit, so abort.
							 | 
						||
| 
								 | 
							
								            return;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        PWCHAR pwzTo = pwzDst + cwDst + (cwNew - cwOld);
							 | 
						||
| 
								 | 
							
								        PWCHAR pwzFm = pwzDst + cwDst;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        while (pwzTo >= pwzDst) {
							 | 
						||
| 
								 | 
							
								            *pwzTo-- = *pwzFm--;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    else if (cwOld > cwNew) {  // We have to remove.
							 | 
						||
| 
								 | 
							
								        PWCHAR pwzTo = pwzDst + cwNew;
							 | 
						||
| 
								 | 
							
								        PWCHAR pwzFm = pwzDst + cwOld;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        while (*pwzFm) {
							 | 
						||
| 
								 | 
							
								            *pwzTo++ = *pwzFm++;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        *pwzTo = '\0';
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // Now write the new string.
							 | 
						||
| 
								 | 
							
								    while (*pwzNew) {
							 | 
						||
| 
								 | 
							
								        *pwzDst++ = *pwzNew++;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								VOID FileNames::ParameterizeLine(PWCHAR pwzDst, PWCHAR pwzDstEnd)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    for (; *pwzDst != '\0'; pwzDst++) {
							 | 
						||
| 
								 | 
							
								        if (PrefixMatch(pwzDst, s_wzSysPath)) {
							 | 
						||
| 
								 | 
							
								            Replace(pwzDst, pwzDstEnd, s_wcSysPath, L"%SYSDIR%\\");
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        else if (PrefixMatch(pwzDst, s_wzS64Path)) {
							 | 
						||
| 
								 | 
							
								            Replace(pwzDst, pwzDstEnd, s_wcS64Path, L"%SYSDIR%\\");
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        else if (PrefixMatch(pwzDst, s_wzTmpPath)) {
							 | 
						||
| 
								 | 
							
								            Replace(pwzDst, pwzDstEnd, s_wcTmpPath, L"%TMPDIR%\\");
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								VOID FileNames::Dump()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    WCHAR wzPath[MAX_PATH];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (s_nFiles == 0) {
							 | 
						||
| 
								 | 
							
								        return;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    LockAcquire();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    Tblog("<t:Files>\n");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    FileInfo ** pSorted = (FileInfo **)GlobalAlloc(GPTR, s_nFiles * sizeof(FileInfo *));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    for (DWORD n = 0; n < s_nCapacity; n++) {
							 | 
						||
| 
								 | 
							
								        if (s_pFiles[n] != NULL) {
							 | 
						||
| 
								 | 
							
								            if (s_pFiles[n]->m_nIndex > s_nFiles) {
							 | 
						||
| 
								 | 
							
								                DEBUG_BREAK();
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            pSorted[s_pFiles[n]->m_nIndex] = s_pFiles[n];
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    for (DWORD n = 0; n < s_nFiles; n++) {
							 | 
						||
| 
								 | 
							
								        FileInfo *pInfo = pSorted[n];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (pInfo == NULL) {
							 | 
						||
| 
								 | 
							
								            Print("<!-- Warning: Missing %d of %d -->\n", n, s_nFiles);
							 | 
						||
| 
								 | 
							
								            continue;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        BOOL fRead = pInfo->m_fRead;
							 | 
						||
| 
								 | 
							
								        BOOL fWrite = pInfo->m_fWrite;
							 | 
						||
| 
								 | 
							
								        BOOL fDelete = (pInfo->m_fDelete);
							 | 
						||
| 
								 | 
							
								        BOOL fCleanup = (pInfo->m_fCleanup);
							 | 
						||
| 
								 | 
							
								        BOOL fAppend = (pInfo->m_fAppend);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#if 0
							 | 
						||
| 
								 | 
							
								        if (fDelete && !fRead && !fWrite) {
							 | 
						||
| 
								 | 
							
								            Print("<!-- Discarding: %ls -->\n", pInfo->m_pwzPath);
							 | 
						||
| 
								 | 
							
								            // Discard pipe files only passed to children.
							 | 
						||
| 
								 | 
							
								            continue;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								        if (pInfo->m_fAbsorbed) {
							 | 
						||
| 
								 | 
							
								            // Discard response fles
							 | 
						||
| 
								 | 
							
								            continue;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (PrefixMatch(pInfo->m_pwzPath, s_wzExePath) ||
							 | 
						||
| 
								 | 
							
								            PrefixMatch(pInfo->m_pwzPath, s_wzSysPath) ||
							 | 
						||
| 
								 | 
							
								            PrefixMatch(pInfo->m_pwzPath, s_wzS64Path)) {
							 | 
						||
| 
								 | 
							
								            // Discard files from exec directory (because considered internal to code).
							 | 
						||
| 
								 | 
							
								            continue;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#if 1 // Ignore PIPEs.
							 | 
						||
| 
								 | 
							
								        if (FileNames::PrefixMatch(pInfo->m_pwzPath, L"\\\\.\\PIPE\\")) {
							 | 
						||
| 
								 | 
							
								            continue;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								        if (FileNames::SuffixMatch(pInfo->m_pwzPath, L"\\conout$")) {
							 | 
						||
| 
								 | 
							
								            continue;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        if (FileNames::SuffixMatch(pInfo->m_pwzPath, L"\\conin$")) {
							 | 
						||
| 
								 | 
							
								            continue;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        if (FileNames::SuffixMatch(pInfo->m_pwzPath, L"\\nul")) {
							 | 
						||
| 
								 | 
							
								            continue;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        ParameterizeName(wzPath, ARRAYSIZE(wzPath), pInfo);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (pInfo->m_fDirectory) {
							 | 
						||
| 
								 | 
							
								            Print("<t:File mkdir=\"true\">%ls</t:File>\n", wzPath);
							 | 
						||
| 
								 | 
							
								            continue;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (!fRead && !fWrite && !fDelete && !fCleanup) {
							 | 
						||
| 
								 | 
							
								            // Discard do "none" files.
							 | 
						||
| 
								 | 
							
								            continue;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (pInfo->m_pbContent == NULL ||
							 | 
						||
| 
								 | 
							
								            pInfo->m_fDelete ||
							 | 
						||
| 
								 | 
							
								            pInfo->m_fCleanup ||
							 | 
						||
| 
								 | 
							
								            pInfo->m_fWrite) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            Print("<t:File%s%s%s%s%s>%ls</t:File>\n",
							 | 
						||
| 
								 | 
							
								                  fRead ? " read=\"true\"" : "",
							 | 
						||
| 
								 | 
							
								                  fWrite ? " write=\"true\"" : "",
							 | 
						||
| 
								 | 
							
								                  fDelete ? " delete=\"true\"" : "",
							 | 
						||
| 
								 | 
							
								                  fCleanup ? " cleanup=\"true\"" : "",
							 | 
						||
| 
								 | 
							
								                  fAppend ? " append=\"true\"" : "",
							 | 
						||
| 
								 | 
							
								                  // size=\"%d\" pInfo->m_cbContent,
							 | 
						||
| 
								 | 
							
								                  wzPath);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        else if ((pInfo->m_pbContent)[0] == 0xff && (pInfo->m_pbContent)[1] == 0xfe) {
							 | 
						||
| 
								 | 
							
								            // Unicode
							 | 
						||
| 
								 | 
							
								            Print("<t:File%s%s%s%s%s>%ls<t:Data>%le</t:Data></t:File>\n",
							 | 
						||
| 
								 | 
							
								                  fRead ? " read=\"true\"" : "",
							 | 
						||
| 
								 | 
							
								                  fWrite ? " write=\"true\"" : "",
							 | 
						||
| 
								 | 
							
								                  fDelete ? " delete=\"true\"" : "",
							 | 
						||
| 
								 | 
							
								                  fCleanup ? " cleanup=\"true\"" : "",
							 | 
						||
| 
								 | 
							
								                  fAppend ? " append=\"true\"" : "",
							 | 
						||
| 
								 | 
							
								                  //  size=\"%d\" pInfo->m_cbContent,
							 | 
						||
| 
								 | 
							
								                  wzPath,
							 | 
						||
| 
								 | 
							
								                  RemoveReturns((PWCHAR)pInfo->m_pbContent));
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        else {
							 | 
						||
| 
								 | 
							
								            // Ascii
							 | 
						||
| 
								 | 
							
								            Print("<t:File%s%s%s%s%s>%ls<t:Data>%he</t:Data></t:File>\n",
							 | 
						||
| 
								 | 
							
								                  fRead ? " read=\"true\"" : "",
							 | 
						||
| 
								 | 
							
								                  fWrite ? " write=\"true\"" : "",
							 | 
						||
| 
								 | 
							
								                  fDelete ? " delete=\"true\"" : "",
							 | 
						||
| 
								 | 
							
								                  fCleanup ? " cleanup=\"true\"" : "",
							 | 
						||
| 
								 | 
							
								                  fAppend ? " append=\"true\"" : "",
							 | 
						||
| 
								 | 
							
								                  //  size=\"%d\" pInfo->m_cbContent,
							 | 
						||
| 
								 | 
							
								                  wzPath,
							 | 
						||
| 
								 | 
							
								                  RemoveReturns((PCHAR)pInfo->m_pbContent));
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (pInfo->m_pbContent != NULL) {
							 | 
						||
| 
								 | 
							
								            GlobalFree((HGLOBAL)pInfo->m_pbContent);
							 | 
						||
| 
								 | 
							
								            pInfo->m_pbContent = NULL;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    GlobalFree((HGLOBAL)pSorted);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    Tblog("</t:Files>\n");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    LockRelease();
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//////////////////////////////////////////////////////////////////////////////
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								class OpenFiles
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  private:
							 | 
						||
| 
								 | 
							
								    struct SLOT
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        HANDLE      m_hHandle;
							 | 
						||
| 
								 | 
							
								        FileInfo *  m_pFile;
							 | 
						||
| 
								 | 
							
								        ProcInfo *  m_pProc;
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  private:
							 | 
						||
| 
								 | 
							
								    static CRITICAL_SECTION s_csLock;
							 | 
						||
| 
								 | 
							
								    static DWORD            s_nHandles;
							 | 
						||
| 
								 | 
							
								    static SLOT             s_rHandles[4049];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  private:
							 | 
						||
| 
								 | 
							
								    static SLOT& HashToSlot(HANDLE handle)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return s_rHandles[((DWORD_PTR)handle) % ARRAYSIZE(s_rHandles)];
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    static VOID LockAcquire()
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        EnterCriticalSection(&s_csLock);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    static VOID LockRelease()
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        LeaveCriticalSection(&s_csLock);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  public:
							 | 
						||
| 
								 | 
							
								    static VOID Initialize();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    static VOID SetWrite(HANDLE hFile, DWORD cbData)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        SLOT& slot = HashToSlot(hFile);
							 | 
						||
| 
								 | 
							
								        if (slot.m_hHandle == hFile) {
							 | 
						||
| 
								 | 
							
								            slot.m_pFile->m_fWrite = TRUE;
							 | 
						||
| 
								 | 
							
								            slot.m_pFile->m_cbWrite += cbData;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    static VOID SetRead(HANDLE hFile, DWORD cbData)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        SLOT& slot = HashToSlot(hFile);
							 | 
						||
| 
								 | 
							
								        if (slot.m_hHandle == hFile) {
							 | 
						||
| 
								 | 
							
								            slot.m_pFile->m_fRead = TRUE;
							 | 
						||
| 
								 | 
							
								            slot.m_pFile->m_cbRead += cbData;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    static BOOL Forget(HANDLE handle);
							 | 
						||
| 
								 | 
							
								    static BOOL Remember(HANDLE hFile, FileInfo *pInfo);
							 | 
						||
| 
								 | 
							
								    static BOOL Remember(HANDLE hProc, ProcInfo *pInfo);
							 | 
						||
| 
								 | 
							
								    static FileInfo * RecallFile(HANDLE hFile);
							 | 
						||
| 
								 | 
							
								    static ProcInfo * RecallProc(HANDLE hProc);
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								CRITICAL_SECTION    OpenFiles::s_csLock;  // Guards access to OpenFile stuctures.
							 | 
						||
| 
								 | 
							
								DWORD               OpenFiles::s_nHandles = 0;
							 | 
						||
| 
								 | 
							
								OpenFiles::SLOT     OpenFiles::s_rHandles[4049];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								VOID OpenFiles::Initialize()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    InitializeCriticalSection(&s_csLock);
							 | 
						||
| 
								 | 
							
								    for (DWORD n = 0; n < ARRAYSIZE(s_rHandles); n++) {
							 | 
						||
| 
								 | 
							
								        s_rHandles[n].m_hHandle = INVALID_HANDLE_VALUE;
							 | 
						||
| 
								 | 
							
								        s_rHandles[n].m_pFile = NULL;
							 | 
						||
| 
								 | 
							
								        s_rHandles[n].m_pProc = NULL;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								BOOL OpenFiles::Forget(HANDLE handle)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    LockAcquire();
							 | 
						||
| 
								 | 
							
								    OpenFiles::SLOT& slot = HashToSlot(handle);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (slot.m_hHandle == handle    ) {
							 | 
						||
| 
								 | 
							
								        slot.m_hHandle = INVALID_HANDLE_VALUE;
							 | 
						||
| 
								 | 
							
								        slot.m_pFile = NULL;
							 | 
						||
| 
								 | 
							
								        slot.m_pProc = NULL;
							 | 
						||
| 
								 | 
							
								        s_nHandles--;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    LockRelease();
							 | 
						||
| 
								 | 
							
								    return FALSE;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								BOOL OpenFiles::Remember(HANDLE hFile, FileInfo *pFile)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    LockAcquire();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    OpenFiles::SLOT& slot = HashToSlot(hFile);
							 | 
						||
| 
								 | 
							
								    if (slot.m_hHandle != hFile && slot.m_hHandle != INVALID_HANDLE_VALUE) {
							 | 
						||
| 
								 | 
							
								        // hash collision
							 | 
						||
| 
								 | 
							
								        DEBUG_BREAK();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    slot.m_hHandle = hFile;
							 | 
						||
| 
								 | 
							
								    slot.m_pFile = pFile;
							 | 
						||
| 
								 | 
							
								    slot.m_pProc = NULL;
							 | 
						||
| 
								 | 
							
								    s_nHandles++;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    LockRelease();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return TRUE;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								BOOL OpenFiles::Remember(HANDLE hProc, ProcInfo *pProc)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    LockAcquire();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    OpenFiles::SLOT& slot = HashToSlot(hProc);
							 | 
						||
| 
								 | 
							
								    if (slot.m_hHandle != hProc && slot.m_hHandle != INVALID_HANDLE_VALUE) {
							 | 
						||
| 
								 | 
							
								        // hash collision
							 | 
						||
| 
								 | 
							
								        DEBUG_BREAK();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    slot.m_hHandle = hProc;
							 | 
						||
| 
								 | 
							
								    slot.m_pProc = pProc;
							 | 
						||
| 
								 | 
							
								    slot.m_pFile = NULL;
							 | 
						||
| 
								 | 
							
								    s_nHandles++;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    LockRelease();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return TRUE;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								FileInfo * OpenFiles::RecallFile(HANDLE hFile)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    LockAcquire();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    OpenFiles::SLOT& slot = HashToSlot(hFile);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (slot.m_hHandle == hFile) {
							 | 
						||
| 
								 | 
							
								        LockRelease();
							 | 
						||
| 
								 | 
							
								        return slot.m_pFile;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    LockRelease();
							 | 
						||
| 
								 | 
							
								    return NULL;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								ProcInfo * OpenFiles::RecallProc(HANDLE hProc)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    LockAcquire();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    OpenFiles::SLOT& slot = HashToSlot(hProc);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (slot.m_hHandle == hProc) {
							 | 
						||
| 
								 | 
							
								        LockRelease();
							 | 
						||
| 
								 | 
							
								        return slot.m_pProc;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    LockRelease();
							 | 
						||
| 
								 | 
							
								    return NULL;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								///////////////////////////////////////////////////////////////////// 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 (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 (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 (*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;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//////////////////////////////////////////////////////////////////////////////
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								BOOL TblogOpen()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    EnterCriticalSection(&s_csPipe);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    WCHAR wzPipe[256];
							 | 
						||
| 
								 | 
							
								    StringCchPrintfW(wzPipe, ARRAYSIZE(wzPipe), L"%ls.%d", TBLOG_PIPE_NAMEW, s_nTraceProcessId);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    for (int retries = 0; retries < 10; retries++) {
							 | 
						||
| 
								 | 
							
								        WaitNamedPipeW(wzPipe, 10000); // Wait up to 10 seconds for a pipe to appear.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        s_hPipe = Real_CreateFileW(wzPipe, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
							 | 
						||
| 
								 | 
							
								        if (s_hPipe != INVALID_HANDLE_VALUE) {
							 | 
						||
| 
								 | 
							
								            DWORD dwMode = PIPE_READMODE_MESSAGE;
							 | 
						||
| 
								 | 
							
								            if (SetNamedPipeHandleState(s_hPipe, &dwMode, NULL, NULL)) {
							 | 
						||
| 
								 | 
							
								                LeaveCriticalSection(&s_csPipe);
							 | 
						||
| 
								 | 
							
								                return TRUE;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    LeaveCriticalSection(&s_csPipe);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // Couldn't open pipe.
							 | 
						||
| 
								 | 
							
								    DEBUG_BREAK();
							 | 
						||
| 
								 | 
							
								    Real_ExitProcess(9990);
							 | 
						||
| 
								 | 
							
								    return FALSE;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								VOID TblogV(PCSTR pszMsgf, va_list args)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    if (s_hPipe == INVALID_HANDLE_VALUE) {
							 | 
						||
| 
								 | 
							
								        return;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    EnterCriticalSection(&s_csPipe);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    DWORD cbWritten = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    PCHAR pszBuf = s_rMessage.szMessage;
							 | 
						||
| 
								 | 
							
								    VSafePrintf(pszMsgf, args,
							 | 
						||
| 
								 | 
							
								                pszBuf, (int)(s_rMessage.szMessage + sizeof(s_rMessage.szMessage) - pszBuf));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    PCHAR pszEnd = s_rMessage.szMessage;
							 | 
						||
| 
								 | 
							
								    for (; *pszEnd; pszEnd++) {
							 | 
						||
| 
								 | 
							
								        // no internal contents.
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    s_rMessage.nBytes = (DWORD)(pszEnd - ((PCSTR)&s_rMessage));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // If the write fails, then we abort
							 | 
						||
| 
								 | 
							
								    if (s_hPipe != INVALID_HANDLE_VALUE) {
							 | 
						||
| 
								 | 
							
								        if (!Real_WriteFile(s_hPipe, &s_rMessage, s_rMessage.nBytes, &cbWritten, NULL)) {
							 | 
						||
| 
								 | 
							
								            Real_ExitProcess(9991);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    LeaveCriticalSection(&s_csPipe);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								VOID Tblog(PCSTR pszMsgf, ...)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    if (s_hPipe == INVALID_HANDLE_VALUE) {
							 | 
						||
| 
								 | 
							
								        return;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    va_list args;
							 | 
						||
| 
								 | 
							
								    va_start(args, pszMsgf);
							 | 
						||
| 
								 | 
							
								    TblogV(pszMsgf, args);
							 | 
						||
| 
								 | 
							
								    va_end(args);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								VOID TblogClose()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    EnterCriticalSection(&s_csPipe);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (s_hPipe != INVALID_HANDLE_VALUE) {
							 | 
						||
| 
								 | 
							
								        DWORD cbWritten = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        s_rMessage.nBytes = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        Real_WriteFile(s_hPipe, &s_rMessage, 4, &cbWritten, NULL);
							 | 
						||
| 
								 | 
							
								        FlushFileBuffers(s_hPipe);
							 | 
						||
| 
								 | 
							
								        Real_CloseHandle(s_hPipe);
							 | 
						||
| 
								 | 
							
								        s_hPipe = INVALID_HANDLE_VALUE;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    LeaveCriticalSection(&s_csPipe);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/////////////////////////////////////////////////////////////
							 | 
						||
| 
								 | 
							
								// Detours
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								static BOOL IsInherited(HANDLE hHandle)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    DWORD dwFlags;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (GetHandleInformation(hHandle, &dwFlags)) {
							 | 
						||
| 
								 | 
							
								        return (dwFlags & HANDLE_FLAG_INHERIT) ? TRUE : FALSE;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return FALSE;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static void SaveStdHandleName(HANDLE hFile, PWCHAR pwzBuffer, BOOL *fAppend)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    pwzBuffer[0] = '\0';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if ((hFile != INVALID_HANDLE_VALUE) && IsInherited(hFile)) {
							 | 
						||
| 
								 | 
							
								        FileInfo * pInfo = OpenFiles::RecallFile(hFile);
							 | 
						||
| 
								 | 
							
								        if (pInfo) {
							 | 
						||
| 
								 | 
							
								            Copy(pwzBuffer, pInfo->m_pwzPath);
							 | 
						||
| 
								 | 
							
								            if (pInfo->m_fAppend && fAppend != NULL) {
							 | 
						||
| 
								 | 
							
								                *fAppend = TRUE;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static void LoadStdHandleName(DWORD id, PCWSTR pwzBuffer, BOOL fAppend)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    HANDLE hFile = GetStdHandle(id);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if ((hFile != INVALID_HANDLE_VALUE) && pwzBuffer[0] != '\0') {
							 | 
						||
| 
								 | 
							
								        FileInfo *pInfo = FileNames::FindPartial(pwzBuffer);
							 | 
						||
| 
								 | 
							
								        if (fAppend) {
							 | 
						||
| 
								 | 
							
								            pInfo->m_fAppend = TRUE;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        OpenFiles::Remember(hFile, pInfo);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								BOOL CreateProcessInternals(HANDLE hProcess, DWORD nProcessId, PCHAR pszId,
							 | 
						||
| 
								 | 
							
								                            HANDLE hStdin, HANDLE hStdout, HANDLE hStderr)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    EnterCriticalSection(&s_csChildPayload);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    ProcInfo *proc = Procs::Create(hProcess, nProcessId);
							 | 
						||
| 
								 | 
							
								    OpenFiles::Remember(hProcess, proc);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    ZeroMemory(&s_ChildPayload, sizeof(s_ChildPayload));
							 | 
						||
| 
								 | 
							
								    CopyMemory(&s_ChildPayload, &s_Payload, sizeof(s_ChildPayload));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    s_ChildPayload.nParentProcessId = GetCurrentProcessId();
							 | 
						||
| 
								 | 
							
								    s_ChildPayload.rGeneology[s_ChildPayload.nGeneology]
							 | 
						||
| 
								 | 
							
								        = (DWORD)InterlockedIncrement(&s_nChildCnt);
							 | 
						||
| 
								 | 
							
								    s_ChildPayload.nGeneology++;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    SaveStdHandleName(hStdin, s_ChildPayload.wzStdin, NULL);
							 | 
						||
| 
								 | 
							
								    SaveStdHandleName(hStdout, s_ChildPayload.wzStdout, &s_ChildPayload.fStdoutAppend);
							 | 
						||
| 
								 | 
							
								    SaveStdHandleName(hStderr, s_ChildPayload.wzStderr, &s_ChildPayload.fStderrAppend);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    DetourCopyPayloadToProcess(hProcess, s_guidTrace, &s_ChildPayload, sizeof(s_ChildPayload));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    for (DWORD i = 0; i < s_ChildPayload.nGeneology; i++) {
							 | 
						||
| 
								 | 
							
								        pszId = SafePrintf(pszId, 16, "%d.", s_ChildPayload.rGeneology[i]);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    *pszId = '\0';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    LeaveCriticalSection(&s_csChildPayload);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return TRUE;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								BOOL WINAPI Mine_CreateProcessW(LPCWSTR lpApplicationName,
							 | 
						||
| 
								 | 
							
								                                LPWSTR lpCommandLine,
							 | 
						||
| 
								 | 
							
								                                LPSECURITY_ATTRIBUTES lpProcessAttributes,
							 | 
						||
| 
								 | 
							
								                                LPSECURITY_ATTRIBUTES lpThreadAttributes,
							 | 
						||
| 
								 | 
							
								                                BOOL bInheritHandles,
							 | 
						||
| 
								 | 
							
								                                DWORD dwCreationFlags,
							 | 
						||
| 
								 | 
							
								                                LPVOID lpEnvironment,
							 | 
						||
| 
								 | 
							
								                                LPCWSTR lpCurrentDirectory,
							 | 
						||
| 
								 | 
							
								                                LPSTARTUPINFOW lpStartupInfo,
							 | 
						||
| 
								 | 
							
								                                LPPROCESS_INFORMATION lpProcessInformation)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    EnterFunc();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (lpCommandLine == NULL) {
							 | 
						||
| 
								 | 
							
								        lpCommandLine = (LPWSTR)lpApplicationName;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    CHAR szProc[MAX_PATH];
							 | 
						||
| 
								 | 
							
								    BOOL rv = 0;
							 | 
						||
| 
								 | 
							
								    __try {
							 | 
						||
| 
								 | 
							
								        LPPROCESS_INFORMATION ppi = lpProcessInformation;
							 | 
						||
| 
								 | 
							
								        PROCESS_INFORMATION pi;
							 | 
						||
| 
								 | 
							
								        if (ppi == NULL) {
							 | 
						||
| 
								 | 
							
								            ppi = π
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        rv = DetourCreateProcessWithDllExW(lpApplicationName,
							 | 
						||
| 
								 | 
							
								                                           lpCommandLine,
							 | 
						||
| 
								 | 
							
								                                           lpProcessAttributes,
							 | 
						||
| 
								 | 
							
								                                           lpThreadAttributes,
							 | 
						||
| 
								 | 
							
								                                           bInheritHandles,
							 | 
						||
| 
								 | 
							
								                                           dwCreationFlags | CREATE_SUSPENDED,
							 | 
						||
| 
								 | 
							
								                                           lpEnvironment,
							 | 
						||
| 
								 | 
							
								                                           lpCurrentDirectory,
							 | 
						||
| 
								 | 
							
								                                           lpStartupInfo,
							 | 
						||
| 
								 | 
							
								                                           ppi,
							 | 
						||
| 
								 | 
							
								                                           s_szDllPath,
							 | 
						||
| 
								 | 
							
								                                           Real_CreateProcessW);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (rv) {
							 | 
						||
| 
								 | 
							
								            HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
							 | 
						||
| 
								 | 
							
								            HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
							 | 
						||
| 
								 | 
							
								            HANDLE hStderr = GetStdHandle(STD_ERROR_HANDLE);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if (lpStartupInfo != NULL && (lpStartupInfo->dwFlags & STARTF_USESTDHANDLES) != 0) {
							 | 
						||
| 
								 | 
							
								                hStdin = lpStartupInfo->hStdInput;
							 | 
						||
| 
								 | 
							
								                hStdout = lpStartupInfo->hStdOutput;
							 | 
						||
| 
								 | 
							
								                hStderr = lpStartupInfo->hStdError;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            CreateProcessInternals(ppi->hProcess, ppi->dwProcessId,
							 | 
						||
| 
								 | 
							
								                                   szProc, hStdin, hStdout, hStderr);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            Print("<t:Child id=\"::%hs::\">\n", szProc);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            WCHAR wzPath[MAX_PATH];
							 | 
						||
| 
								 | 
							
								            FileInfo *pInfo = NULL;
							 | 
						||
| 
								 | 
							
								            if (lpApplicationName == NULL) {
							 | 
						||
| 
								 | 
							
								                PWCHAR pwzDst = wzPath;
							 | 
						||
| 
								 | 
							
								                PWCHAR pwzSrc = lpCommandLine;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                if (*pwzSrc == '\"') {
							 | 
						||
| 
								 | 
							
								                    WCHAR cQuote = *pwzSrc++;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                    while (*pwzSrc && *pwzSrc != cQuote) {
							 | 
						||
| 
								 | 
							
								                        *pwzDst++ = *pwzSrc++;
							 | 
						||
| 
								 | 
							
								                    }
							 | 
						||
| 
								 | 
							
								                    *pwzDst++ = '\0';
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								                else {
							 | 
						||
| 
								 | 
							
								                    while (*pwzSrc && *pwzSrc != ' ' && *pwzSrc != '\t') {
							 | 
						||
| 
								 | 
							
								                        if (*pwzSrc == '\t') {
							 | 
						||
| 
								 | 
							
								                            *pwzSrc = ' ';
							 | 
						||
| 
								 | 
							
								                        }
							 | 
						||
| 
								 | 
							
								                        *pwzDst++ = *pwzSrc++;
							 | 
						||
| 
								 | 
							
								                    }
							 | 
						||
| 
								 | 
							
								                    *pwzDst++ = '\0';
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								                pInfo = FileNames::FindPartial(wzPath);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            else {
							 | 
						||
| 
								 | 
							
								                pInfo = FileNames::FindPartial(lpApplicationName);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            Print("<t:Executable>%ls</t:Executable>\n",
							 | 
						||
| 
								 | 
							
								                  FileNames::ParameterizeName(wzPath, ARRAYSIZE(wzPath), pInfo));
							 | 
						||
| 
								 | 
							
								            Print("<t:Line>%le</t:Line>\n", lpCommandLine);
							 | 
						||
| 
								 | 
							
								            Print("</t:Child>\n");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if (pInfo) {
							 | 
						||
| 
								 | 
							
								                pInfo->m_fAbsorbed = true;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if (!(dwCreationFlags & CREATE_SUSPENDED)) {
							 | 
						||
| 
								 | 
							
								                ResumeThread(ppi->hThread);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if (ppi == &pi) {
							 | 
						||
| 
								 | 
							
								                Real_CloseHandle(ppi->hThread);
							 | 
						||
| 
								 | 
							
								                Real_CloseHandle(ppi->hProcess);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    } __finally {
							 | 
						||
| 
								 | 
							
								        ExitFunc();
							 | 
						||
| 
								 | 
							
								        if (!rv) {
							 | 
						||
| 
								 | 
							
								            Print("<!-- Warning: CreateProcessW failed %d: %ls; %ls -->\n",
							 | 
						||
| 
								 | 
							
								                  GetLastError(), lpApplicationName, lpCommandLine);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return rv;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								BOOL WINAPI Mine_CreateProcessA(LPCSTR lpApplicationName,
							 | 
						||
| 
								 | 
							
								                                LPSTR lpCommandLine,
							 | 
						||
| 
								 | 
							
								                                LPSECURITY_ATTRIBUTES lpProcessAttributes,
							 | 
						||
| 
								 | 
							
								                                LPSECURITY_ATTRIBUTES lpThreadAttributes,
							 | 
						||
| 
								 | 
							
								                                BOOL bInheritHandles,
							 | 
						||
| 
								 | 
							
								                                DWORD dwCreationFlags,
							 | 
						||
| 
								 | 
							
								                                LPVOID lpEnvironment,
							 | 
						||
| 
								 | 
							
								                                LPCSTR lpCurrentDirectory,
							 | 
						||
| 
								 | 
							
								                                LPSTARTUPINFOA lpStartupInfo,
							 | 
						||
| 
								 | 
							
								                                LPPROCESS_INFORMATION lpProcessInformation)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    EnterFunc();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (lpCommandLine == NULL) {
							 | 
						||
| 
								 | 
							
								        lpCommandLine = (LPSTR)lpApplicationName;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    CHAR szProc[MAX_PATH];
							 | 
						||
| 
								 | 
							
								    BOOL rv = 0;
							 | 
						||
| 
								 | 
							
								    __try {
							 | 
						||
| 
								 | 
							
								        LPPROCESS_INFORMATION ppi = lpProcessInformation;
							 | 
						||
| 
								 | 
							
								        PROCESS_INFORMATION pi;
							 | 
						||
| 
								 | 
							
								        if (ppi == NULL) {
							 | 
						||
| 
								 | 
							
								            ppi = π
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        rv = DetourCreateProcessWithDllExA(lpApplicationName,
							 | 
						||
| 
								 | 
							
								                                           lpCommandLine,
							 | 
						||
| 
								 | 
							
								                                           lpProcessAttributes,
							 | 
						||
| 
								 | 
							
								                                           lpThreadAttributes,
							 | 
						||
| 
								 | 
							
								                                           bInheritHandles,
							 | 
						||
| 
								 | 
							
								                                           dwCreationFlags | CREATE_SUSPENDED,
							 | 
						||
| 
								 | 
							
								                                           lpEnvironment,
							 | 
						||
| 
								 | 
							
								                                           lpCurrentDirectory,
							 | 
						||
| 
								 | 
							
								                                           lpStartupInfo,
							 | 
						||
| 
								 | 
							
								                                           ppi,
							 | 
						||
| 
								 | 
							
								                                           s_szDllPath,
							 | 
						||
| 
								 | 
							
								                                           Real_CreateProcessA);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (rv) {
							 | 
						||
| 
								 | 
							
								            HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
							 | 
						||
| 
								 | 
							
								            HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
							 | 
						||
| 
								 | 
							
								            HANDLE hStderr = GetStdHandle(STD_ERROR_HANDLE);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if (lpStartupInfo != NULL && (lpStartupInfo->dwFlags & STARTF_USESTDHANDLES) != 0) {
							 | 
						||
| 
								 | 
							
								                hStdin = lpStartupInfo->hStdInput;
							 | 
						||
| 
								 | 
							
								                hStdout = lpStartupInfo->hStdOutput;
							 | 
						||
| 
								 | 
							
								                hStderr = lpStartupInfo->hStdError;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            CreateProcessInternals(ppi->hProcess, ppi->dwProcessId,
							 | 
						||
| 
								 | 
							
								                                   szProc, hStdin, hStdout, hStderr);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            Print("<t:Child id=\"::%hs::\">\n", szProc);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            WCHAR wzPath[MAX_PATH];
							 | 
						||
| 
								 | 
							
								            FileInfo *pInfo = NULL;
							 | 
						||
| 
								 | 
							
								            if (lpApplicationName == NULL) {
							 | 
						||
| 
								 | 
							
								                PCHAR pszDst = szProc;
							 | 
						||
| 
								 | 
							
								                PCHAR pszSrc = lpCommandLine;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                if (*pszSrc == '\"') {
							 | 
						||
| 
								 | 
							
								                    CHAR cQuote = *pszSrc++;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                    while (*pszSrc && *pszSrc != cQuote) {
							 | 
						||
| 
								 | 
							
								                        *pszDst++ = *pszSrc++;
							 | 
						||
| 
								 | 
							
								                    }
							 | 
						||
| 
								 | 
							
								                    *pszDst++ = '\0';
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								                else {
							 | 
						||
| 
								 | 
							
								                    while (*pszSrc && *pszSrc != ' ' && *pszSrc != '\t') {
							 | 
						||
| 
								 | 
							
								                        if (*pszSrc == '\t') {
							 | 
						||
| 
								 | 
							
								                            *pszSrc = ' ';
							 | 
						||
| 
								 | 
							
								                        }
							 | 
						||
| 
								 | 
							
								                        *pszDst++ = *pszSrc++;
							 | 
						||
| 
								 | 
							
								                    }
							 | 
						||
| 
								 | 
							
								                    *pszDst++ = '\0';
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								                pInfo = FileNames::FindPartial(szProc);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            else {
							 | 
						||
| 
								 | 
							
								                pInfo = FileNames::FindPartial(lpApplicationName);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            Print("<t:Executable>%ls</t:Executable>\n",
							 | 
						||
| 
								 | 
							
								                  FileNames::ParameterizeName(wzPath, ARRAYSIZE(wzPath), pInfo));
							 | 
						||
| 
								 | 
							
								            Print("<t:Line>%he</t:Line>\n", lpCommandLine);
							 | 
						||
| 
								 | 
							
								            Print("</t:Child>\n");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if (pInfo) {
							 | 
						||
| 
								 | 
							
								                pInfo->m_fAbsorbed = true;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if (!(dwCreationFlags & CREATE_SUSPENDED)) {
							 | 
						||
| 
								 | 
							
								                ResumeThread(ppi->hThread);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            if (ppi == &pi) {
							 | 
						||
| 
								 | 
							
								                Real_CloseHandle(ppi->hThread);
							 | 
						||
| 
								 | 
							
								                Real_CloseHandle(ppi->hProcess);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    } __finally {
							 | 
						||
| 
								 | 
							
								        ExitFunc();
							 | 
						||
| 
								 | 
							
								        if (!rv) {
							 | 
						||
| 
								 | 
							
								            Print("<!-- Warning: CreateProcessA failed %d: %hs; %hs -->\n",
							 | 
						||
| 
								 | 
							
								                  GetLastError(), lpApplicationName, lpCommandLine);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return rv;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								//////////////////////////////////////////////////////////////////////////////
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								BOOL WINAPI Mine_CopyFileExA(LPCSTR a0,
							 | 
						||
| 
								 | 
							
								                             LPCSTR a1,
							 | 
						||
| 
								 | 
							
								                             LPPROGRESS_ROUTINE a2,
							 | 
						||
| 
								 | 
							
								                             LPVOID a3,
							 | 
						||
| 
								 | 
							
								                             LPBOOL a4,
							 | 
						||
| 
								 | 
							
								                             DWORD a5)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    EnterFunc();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    BOOL rv = 0;
							 | 
						||
| 
								 | 
							
								    __try {
							 | 
						||
| 
								 | 
							
								        rv = Real_CopyFileExA(a0, a1, a2, a3, a4, a5);
							 | 
						||
| 
								 | 
							
								    } __finally {
							 | 
						||
| 
								 | 
							
								        ExitFunc();
							 | 
						||
| 
								 | 
							
								        if (rv) {
							 | 
						||
| 
								 | 
							
								#if 0
							 | 
						||
| 
								 | 
							
								            Print("<!-- CopyFileExA %he to %he -->\n", a0, a1);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								            NoteRead(a0);
							 | 
						||
| 
								 | 
							
								            NoteWrite(a1);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								    return rv;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								BOOL WINAPI Mine_CopyFileExW(LPCWSTR a0,
							 | 
						||
| 
								 | 
							
								                             LPCWSTR a1,
							 | 
						||
| 
								 | 
							
								                             LPPROGRESS_ROUTINE a2,
							 | 
						||
| 
								 | 
							
								                             LPVOID a3,
							 | 
						||
| 
								 | 
							
								                             LPBOOL a4,
							 | 
						||
| 
								 | 
							
								                             DWORD a5)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    EnterFunc();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    BOOL rv = 0;
							 | 
						||
| 
								 | 
							
								    __try {
							 | 
						||
| 
								 | 
							
								#if 0
							 | 
						||
| 
								 | 
							
								        Print("\n");
							 | 
						||
| 
								 | 
							
								        Print("<!-- CopyFileExW %le to %le before -->\n", a0, a1);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								        rv = Real_CopyFileExW(a0, a1, a2, a3, a4, a5);
							 | 
						||
| 
								 | 
							
								    } __finally {
							 | 
						||
| 
								 | 
							
								        ExitFunc();
							 | 
						||
| 
								 | 
							
								        if (rv) {
							 | 
						||
| 
								 | 
							
								#if 0
							 | 
						||
| 
								 | 
							
								            Print("<!-- CopyFileExW %le to %le -->\n", a0, a1);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								            NoteRead(a0);
							 | 
						||
| 
								 | 
							
								            NoteWrite(a1);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								    return rv;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								BOOL WINAPI Mine_PrivCopyFileExW(LPCWSTR a0,
							 | 
						||
| 
								 | 
							
								                                 LPCWSTR a1,
							 | 
						||
| 
								 | 
							
								                                 LPPROGRESS_ROUTINE a2,
							 | 
						||
| 
								 | 
							
								                                 LPVOID a3,
							 | 
						||
| 
								 | 
							
								                                 LPBOOL a4,
							 | 
						||
| 
								 | 
							
								                                 DWORD a5)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    EnterFunc();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    BOOL rv = 0;
							 | 
						||
| 
								 | 
							
								    __try {
							 | 
						||
| 
								 | 
							
								        rv = Real_PrivCopyFileExW(a0, a1, a2, a3, a4, a5);
							 | 
						||
| 
								 | 
							
								    } __finally {
							 | 
						||
| 
								 | 
							
								        ExitFunc();
							 | 
						||
| 
								 | 
							
								        if (rv) {
							 | 
						||
| 
								 | 
							
								#if 0
							 | 
						||
| 
								 | 
							
								            Print("<!-- PrivCopyFileExW %le to %le -->\n", a0, a1);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								            NoteRead(a0);
							 | 
						||
| 
								 | 
							
								            NoteWrite(a1);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								    return rv;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								BOOL WINAPI Mine_CreateHardLinkA(LPCSTR a0,
							 | 
						||
| 
								 | 
							
								                                 LPCSTR a1,
							 | 
						||
| 
								 | 
							
								                                 LPSECURITY_ATTRIBUTES a2)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    EnterFunc();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    BOOL rv = 0;
							 | 
						||
| 
								 | 
							
								    __try {
							 | 
						||
| 
								 | 
							
								        rv = Real_CreateHardLinkA(a0, a1, a2);
							 | 
						||
| 
								 | 
							
								    } __finally {
							 | 
						||
| 
								 | 
							
								        ExitFunc();
							 | 
						||
| 
								 | 
							
								        if (rv) {
							 | 
						||
| 
								 | 
							
								#if 0
							 | 
						||
| 
								 | 
							
								            Print("<!-- CreateHardLinkA %he to %he -->\n", a0, a1);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								            NoteRead(a1);
							 | 
						||
| 
								 | 
							
								            NoteWrite(a0);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								    return rv;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								BOOL WINAPI Mine_CreateHardLinkW(LPCWSTR a0,
							 | 
						||
| 
								 | 
							
								                                 LPCWSTR a1,
							 | 
						||
| 
								 | 
							
								                                 LPSECURITY_ATTRIBUTES a2)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    EnterFunc();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    BOOL rv = 0;
							 | 
						||
| 
								 | 
							
								    __try {
							 | 
						||
| 
								 | 
							
								        rv = Real_CreateHardLinkW(a0, a1, a2);
							 | 
						||
| 
								 | 
							
								    } __finally {
							 | 
						||
| 
								 | 
							
								        ExitFunc();
							 | 
						||
| 
								 | 
							
								        if (rv) {
							 | 
						||
| 
								 | 
							
								#if 0
							 | 
						||
| 
								 | 
							
								            Print("<!-- CreateHardLinkW %le to %le -->\n", a0, a1);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								            NoteRead(a1);
							 | 
						||
| 
								 | 
							
								            NoteWrite(a0);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								    return rv;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								BOOL WINAPI Mine_CloseHandle(HANDLE a0)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    /*int nIndent =*/ EnterFunc();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    BOOL rv = 0;
							 | 
						||
| 
								 | 
							
								    __try {
							 | 
						||
| 
								 | 
							
								        ProcInfo * pProc = OpenFiles::RecallProc(a0);
							 | 
						||
| 
								 | 
							
								        if (pProc != NULL) {
							 | 
						||
| 
								 | 
							
								            Procs::Close(pProc->m_hProc);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        FileInfo * pFile = OpenFiles::RecallFile(a0);
							 | 
						||
| 
								 | 
							
								        if (pFile != NULL) {
							 | 
						||
| 
								 | 
							
								            DWORD dwErr = GetLastError();
							 | 
						||
| 
								 | 
							
								            pFile->m_cbContent = GetFileSize(a0, NULL);
							 | 
						||
| 
								 | 
							
								            if (pFile->m_cbContent == INVALID_FILE_SIZE) {
							 | 
						||
| 
								 | 
							
								                pFile->m_cbContent = 0;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if (pFile->m_fCantRead) {
							 | 
						||
| 
								 | 
							
								                if (pFile->m_fRead) {
							 | 
						||
| 
								 | 
							
								#if 0
							 | 
						||
| 
								 | 
							
								                    Print("<!-- Warning: Removing read from %le -->\n", pFile->m_pwzPath);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								                    pFile->m_fRead = FALSE;
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            // Here we should think about reading the file contents as appropriate.
							 | 
						||
| 
								 | 
							
								            if (pFile->m_fTemporaryPath && pFile->m_fRead && !pFile->m_fAbsorbed &&
							 | 
						||
| 
								 | 
							
								                !pFile->m_fDelete && !pFile->m_fCleanup && !pFile->m_fWrite &&
							 | 
						||
| 
								 | 
							
								                pFile->m_pbContent == NULL &&
							 | 
						||
| 
								 | 
							
								                pFile->m_cbContent < 16384) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                pFile->m_pbContent = LoadFile(a0, pFile->m_cbContent);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            SetLastError(dwErr);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        rv = Real_CloseHandle(a0);
							 | 
						||
| 
								 | 
							
								    } __finally {
							 | 
						||
| 
								 | 
							
								        ExitFunc();
							 | 
						||
| 
								 | 
							
								        if (rv /* && nIndent == 0*/) {
							 | 
						||
| 
								 | 
							
								            OpenFiles::Forget(a0);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								    return rv;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								BOOL WINAPI Mine_DuplicateHandle(HANDLE hSourceProcessHandle,
							 | 
						||
| 
								 | 
							
								                                 HANDLE hSourceHandle,
							 | 
						||
| 
								 | 
							
								                                 HANDLE hTargetProcessHandle,
							 | 
						||
| 
								 | 
							
								                                 LPHANDLE lpTargetHandle,
							 | 
						||
| 
								 | 
							
								                                 DWORD dwDesiredAccess,
							 | 
						||
| 
								 | 
							
								                                 BOOL bInheritHandle,
							 | 
						||
| 
								 | 
							
								                                 DWORD dwOptions)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    HANDLE hTemp = INVALID_HANDLE_VALUE;
							 | 
						||
| 
								 | 
							
								    EnterFunc();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    BOOL rv = 0;
							 | 
						||
| 
								 | 
							
								    __try {
							 | 
						||
| 
								 | 
							
								        if (lpTargetHandle == NULL) {
							 | 
						||
| 
								 | 
							
								            lpTargetHandle = &hTemp;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        *lpTargetHandle = INVALID_HANDLE_VALUE;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        rv = Real_DuplicateHandle(hSourceProcessHandle,
							 | 
						||
| 
								 | 
							
								                                  hSourceHandle,
							 | 
						||
| 
								 | 
							
								                                  hTargetProcessHandle,
							 | 
						||
| 
								 | 
							
								                                  lpTargetHandle,
							 | 
						||
| 
								 | 
							
								                                  dwDesiredAccess,
							 | 
						||
| 
								 | 
							
								                                  bInheritHandle,
							 | 
						||
| 
								 | 
							
								                                  dwOptions);
							 | 
						||
| 
								 | 
							
								    } __finally {
							 | 
						||
| 
								 | 
							
								        ExitFunc();
							 | 
						||
| 
								 | 
							
								        if (*lpTargetHandle != INVALID_HANDLE_VALUE) {
							 | 
						||
| 
								 | 
							
								            FileInfo *pInfo = OpenFiles::RecallFile(hSourceHandle);
							 | 
						||
| 
								 | 
							
								            if (pInfo) {
							 | 
						||
| 
								 | 
							
								                OpenFiles::Remember(*lpTargetHandle, pInfo);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								    return rv;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static LONG s_nPipeCnt = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								BOOL WINAPI Mine_CreatePipe(PHANDLE hReadPipe,
							 | 
						||
| 
								 | 
							
								                            PHANDLE hWritePipe,
							 | 
						||
| 
								 | 
							
								                            LPSECURITY_ATTRIBUTES lpPipeAttributes,
							 | 
						||
| 
								 | 
							
								                            DWORD nSize)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    HANDLE hRead = INVALID_HANDLE_VALUE;
							 | 
						||
| 
								 | 
							
								    HANDLE hWrite = INVALID_HANDLE_VALUE;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (hReadPipe == NULL) {
							 | 
						||
| 
								 | 
							
								        hReadPipe = &hRead;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    if (hWritePipe == NULL) {
							 | 
						||
| 
								 | 
							
								        hWritePipe = &hWrite;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /*int nIndent = */ EnterFunc();
							 | 
						||
| 
								 | 
							
								    BOOL rv = 0;
							 | 
						||
| 
								 | 
							
								    __try {
							 | 
						||
| 
								 | 
							
								        rv = Real_CreatePipe(hReadPipe, hWritePipe, lpPipeAttributes, nSize);
							 | 
						||
| 
								 | 
							
								    } __finally {
							 | 
						||
| 
								 | 
							
								        ExitFunc();
							 | 
						||
| 
								 | 
							
								        if (rv) {
							 | 
						||
| 
								 | 
							
								            CHAR szPipe[128];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            SafePrintf(szPipe, ARRAYSIZE(szPipe), "\\\\.\\PIPE\\Temp.%d.%d",
							 | 
						||
| 
								 | 
							
								                       GetCurrentProcessId(),
							 | 
						||
| 
								 | 
							
								                       InterlockedIncrement(&s_nPipeCnt));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            FileInfo *pInfo = FileNames::FindPartial(szPipe);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            pInfo->m_fCleanup = TRUE;
							 | 
						||
| 
								 | 
							
								            OpenFiles::Remember(*hReadPipe, pInfo);
							 | 
						||
| 
								 | 
							
								            OpenFiles::Remember(*hWritePipe, pInfo);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								    return rv;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								BOOL WINAPI Mine_CreateDirectoryW(LPCWSTR a0,
							 | 
						||
| 
								 | 
							
								                                  LPSECURITY_ATTRIBUTES a1)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    /* int nIndent = */ EnterFunc();
							 | 
						||
| 
								 | 
							
								    BOOL rv = 0;
							 | 
						||
| 
								 | 
							
								    __try {
							 | 
						||
| 
								 | 
							
								        rv = Real_CreateDirectoryW(a0, a1);
							 | 
						||
| 
								 | 
							
								    } __finally {
							 | 
						||
| 
								 | 
							
								        ExitFunc();
							 | 
						||
| 
								 | 
							
								        if (rv) {
							 | 
						||
| 
								 | 
							
								            FileInfo *pInfo = FileNames::FindPartial(a0);
							 | 
						||
| 
								 | 
							
								            pInfo->m_fDirectory = TRUE;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								    return rv;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								BOOL WINAPI Mine_CreateDirectoryExW(LPCWSTR a0,
							 | 
						||
| 
								 | 
							
								                                    LPCWSTR a1,
							 | 
						||
| 
								 | 
							
								                                    LPSECURITY_ATTRIBUTES a2)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    /* int nIndent = */ EnterFunc();
							 | 
						||
| 
								 | 
							
								    BOOL rv = 0;
							 | 
						||
| 
								 | 
							
								    __try {
							 | 
						||
| 
								 | 
							
								        rv = Real_CreateDirectoryExW(a0, a1, a2);
							 | 
						||
| 
								 | 
							
								    } __finally {
							 | 
						||
| 
								 | 
							
								        ExitFunc();
							 | 
						||
| 
								 | 
							
								        if (rv) {
							 | 
						||
| 
								 | 
							
								            FileInfo *pInfo = FileNames::FindPartial(a1);
							 | 
						||
| 
								 | 
							
								            pInfo->m_fDirectory = TRUE;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								    return rv;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								HANDLE WINAPI Mine_CreateFileW(LPCWSTR a0,
							 | 
						||
| 
								 | 
							
								                               DWORD access,
							 | 
						||
| 
								 | 
							
								                               DWORD share,
							 | 
						||
| 
								 | 
							
								                               LPSECURITY_ATTRIBUTES a3,
							 | 
						||
| 
								 | 
							
								                               DWORD create,
							 | 
						||
| 
								 | 
							
								                               DWORD flags,
							 | 
						||
| 
								 | 
							
								                               HANDLE a6)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    /* int nIndent = */ EnterFunc();
							 | 
						||
| 
								 | 
							
								    HANDLE rv = 0;
							 | 
						||
| 
								 | 
							
								    __try {
							 | 
						||
| 
								 | 
							
								        rv = Real_CreateFileW(a0, access, share, a3, create, flags, a6);
							 | 
						||
| 
								 | 
							
								    } __finally {
							 | 
						||
| 
								 | 
							
								        ExitFunc();
							 | 
						||
| 
								 | 
							
								#if 0
							 | 
						||
| 
								 | 
							
								            Print("<!-- CreateFileW(%le, ac=%08x, cr=%08x, fl=%08x -->\n",
							 | 
						||
| 
								 | 
							
								                  a0,
							 | 
						||
| 
								 | 
							
								                  access,
							 | 
						||
| 
								 | 
							
								                  create,
							 | 
						||
| 
								 | 
							
								                  flags);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (access != 0 && /* nIndent == 0 && */ rv != INVALID_HANDLE_VALUE) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            FileInfo *pInfo = FileNames::FindPartial(a0);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            // FILE_FLAG_WRITE_THROUGH              0x80000000
							 | 
						||
| 
								 | 
							
								            // FILE_FLAG_OVERLAPPED                 0x40000000
							 | 
						||
| 
								 | 
							
								            // FILE_FLAG_NO_BUFFERING               0x20000000
							 | 
						||
| 
								 | 
							
								            // FILE_FLAG_RANDOM_ACCESS              0x10000000
							 | 
						||
| 
								 | 
							
								            // FILE_FLAG_SEQUENTIAL_SCAN            0x08000000
							 | 
						||
| 
								 | 
							
								            // FILE_FLAG_DELETE_ON_CLOSE            0x04000000
							 | 
						||
| 
								 | 
							
								            // FILE_FLAG_BACKUP_SEMANTICS           0x02000000
							 | 
						||
| 
								 | 
							
								            // FILE_FLAG_POSIX_SEMANTICS            0x01000000
							 | 
						||
| 
								 | 
							
								            // FILE_FLAG_OPEN_REPARSE_POINT         0x00200000
							 | 
						||
| 
								 | 
							
								            // FILE_FLAG_OPEN_NO_RECALL             0x00100000
							 | 
						||
| 
								 | 
							
								            // FILE_FLAG_FIRST_PIPE_INSTANCE        0x00080000
							 | 
						||
| 
								 | 
							
								            // FILE_ATTRIBUTE_ENCRYPTED             0x00004000
							 | 
						||
| 
								 | 
							
								            // FILE_ATTRIBUTE_NOT_CONTENT_INDEXED   0x00002000
							 | 
						||
| 
								 | 
							
								            // FILE_ATTRIBUTE_OFFLINE               0x00001000
							 | 
						||
| 
								 | 
							
								            // FILE_ATTRIBUTE_COMPRESSED            0x00000800
							 | 
						||
| 
								 | 
							
								            // FILE_ATTRIBUTE_REPARSE_POINT         0x00000400
							 | 
						||
| 
								 | 
							
								            // FILE_ATTRIBUTE_SPARSE_FILE           0x00000200
							 | 
						||
| 
								 | 
							
								            // FILE_ATTRIBUTE_TEMPORARY             0x00000100
							 | 
						||
| 
								 | 
							
								            // FILE_ATTRIBUTE_NORMAL                0x00000080
							 | 
						||
| 
								 | 
							
								            // FILE_ATTRIBUTE_DEVICE                0x00000040
							 | 
						||
| 
								 | 
							
								            // FILE_ATTRIBUTE_ARCHIVE               0x00000020
							 | 
						||
| 
								 | 
							
								            // FILE_ATTRIBUTE_DIRECTORY             0x00000010
							 | 
						||
| 
								 | 
							
								            // FILE_ATTRIBUTE_SYSTEM                0x00000004
							 | 
						||
| 
								 | 
							
								            // FILE_ATTRIBUTE_HIDDEN                0x00000002
							 | 
						||
| 
								 | 
							
								            // FILE_ATTRIBUTE_READONLY              0x00000001
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            // CREATE_NEW          1
							 | 
						||
| 
								 | 
							
								            // CREATE_ALWAYS       2
							 | 
						||
| 
								 | 
							
								            // OPEN_EXISTING       3
							 | 
						||
| 
								 | 
							
								            // OPEN_ALWAYS         4
							 | 
						||
| 
								 | 
							
								            // TRUNCATE_EXISTING   5
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if (create == CREATE_NEW ||
							 | 
						||
| 
								 | 
							
								                create == CREATE_ALWAYS ||
							 | 
						||
| 
								 | 
							
								                create == TRUNCATE_EXISTING) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                if (!pInfo->m_fRead) {
							 | 
						||
| 
								 | 
							
								                    pInfo->m_fCantRead = TRUE;
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            else if (create == OPEN_EXISTING) {
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            else if (create == OPEN_ALWAYS) {
							 | 
						||
| 
								 | 
							
								                // pInfo->m_fAppend = TRUE;    // !!!
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if ((flags & FILE_FLAG_DELETE_ON_CLOSE)) {
							 | 
						||
| 
								 | 
							
								                pInfo->m_fCleanup = TRUE;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            OpenFiles::Remember(rv, pInfo);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								    return rv;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								HANDLE WINAPI Mine_CreateFileMappingW(HANDLE hFile,
							 | 
						||
| 
								 | 
							
								                                      LPSECURITY_ATTRIBUTES a1,
							 | 
						||
| 
								 | 
							
								                                      DWORD flProtect,
							 | 
						||
| 
								 | 
							
								                                      DWORD a3,
							 | 
						||
| 
								 | 
							
								                                      DWORD a4,
							 | 
						||
| 
								 | 
							
								                                      LPCWSTR a5)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    /* int nIndent = */ EnterFunc();
							 | 
						||
| 
								 | 
							
								    HANDLE rv = 0;
							 | 
						||
| 
								 | 
							
								    __try {
							 | 
						||
| 
								 | 
							
								        rv = Real_CreateFileMappingW(hFile, a1, flProtect, a3, a4, a5);
							 | 
						||
| 
								 | 
							
								    } __finally {
							 | 
						||
| 
								 | 
							
								        ExitFunc();
							 | 
						||
| 
								 | 
							
								        if (rv != INVALID_HANDLE_VALUE) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            FileInfo *pInfo = OpenFiles::RecallFile(hFile);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if (pInfo != NULL) {
							 | 
						||
| 
								 | 
							
								                switch (flProtect) {
							 | 
						||
| 
								 | 
							
								                  case PAGE_READONLY:
							 | 
						||
| 
								 | 
							
								                    pInfo->m_fRead = TRUE;
							 | 
						||
| 
								 | 
							
								                    break;
							 | 
						||
| 
								 | 
							
								                  case PAGE_READWRITE:
							 | 
						||
| 
								 | 
							
								                    pInfo->m_fRead = TRUE;
							 | 
						||
| 
								 | 
							
								                    pInfo->m_fWrite = TRUE;
							 | 
						||
| 
								 | 
							
								                    break;
							 | 
						||
| 
								 | 
							
								                  case PAGE_WRITECOPY:
							 | 
						||
| 
								 | 
							
								                    pInfo->m_fRead = TRUE;
							 | 
						||
| 
								 | 
							
								                    break;
							 | 
						||
| 
								 | 
							
								                  case PAGE_EXECUTE_READ:
							 | 
						||
| 
								 | 
							
								                    pInfo->m_fRead = TRUE;
							 | 
						||
| 
								 | 
							
								                    break;
							 | 
						||
| 
								 | 
							
								                  case PAGE_EXECUTE_READWRITE:
							 | 
						||
| 
								 | 
							
								                    pInfo->m_fRead = TRUE;
							 | 
						||
| 
								 | 
							
								                    pInfo->m_fWrite = TRUE;
							 | 
						||
| 
								 | 
							
								                    break;
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								    return rv;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								BOOL WINAPI Mine_DeleteFileW(LPCWSTR a0)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    EnterFunc();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    BOOL rv = 0;
							 | 
						||
| 
								 | 
							
								    __try {
							 | 
						||
| 
								 | 
							
								        rv = Real_DeleteFileW(a0);
							 | 
						||
| 
								 | 
							
								    } __finally {
							 | 
						||
| 
								 | 
							
								        ExitFunc();
							 | 
						||
| 
								 | 
							
								#if 0
							 | 
						||
| 
								 | 
							
								        Print("<!-- DeleteFileW(%le -->\n", a0);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								        NoteDelete(a0);
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								    return rv;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static VOID Dump(LPVOID pvData, DWORD cbData)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    CHAR szBuffer[128];
							 | 
						||
| 
								 | 
							
								    PBYTE pbData = (PBYTE)pvData;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    for (DWORD i = 0; i < cbData; i += 16) {
							 | 
						||
| 
								 | 
							
								        PCHAR psz = szBuffer;
							 | 
						||
| 
								 | 
							
								        psz = SafePrintf(psz, (LONG)(szBuffer + ARRAYSIZE(szBuffer) - psz), "%4d: ", i);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        for (DWORD j = i; j < i + 16; j++) {
							 | 
						||
| 
								 | 
							
								            if (j < cbData) {
							 | 
						||
| 
								 | 
							
								                psz = SafePrintf(psz, (LONG)(szBuffer + ARRAYSIZE(szBuffer) - psz),
							 | 
						||
| 
								 | 
							
								                                 "%02x", pbData[j]);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            else {
							 | 
						||
| 
								 | 
							
								                psz = SafePrintf(psz, (LONG)(szBuffer + ARRAYSIZE(szBuffer) - psz), "  ");
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        for (DWORD j = i; j < i + 16; j++) {
							 | 
						||
| 
								 | 
							
								            if (j < cbData) {
							 | 
						||
| 
								 | 
							
								                if (pbData[j] >= ' ' && pbData[j] <= 127) {
							 | 
						||
| 
								 | 
							
								                    psz = SafePrintf(psz, (LONG)(szBuffer + ARRAYSIZE(szBuffer) - psz),
							 | 
						||
| 
								 | 
							
								                                     "%c", pbData[j]);
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								                else {
							 | 
						||
| 
								 | 
							
								                    psz = SafePrintf(psz, (LONG)(szBuffer + ARRAYSIZE(szBuffer) - psz), ".");
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            else {
							 | 
						||
| 
								 | 
							
								                psz = SafePrintf(psz, (LONG)(szBuffer + ARRAYSIZE(szBuffer) - psz), " ");
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        Print("%s\n", szBuffer);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								BOOL WINAPI Mine_DeviceIoControl(HANDLE a0,
							 | 
						||
| 
								 | 
							
								                                 DWORD a1,
							 | 
						||
| 
								 | 
							
								                                 LPVOID a2,
							 | 
						||
| 
								 | 
							
								                                 DWORD a3,
							 | 
						||
| 
								 | 
							
								                                 LPVOID a4,
							 | 
						||
| 
								 | 
							
								                                 DWORD a5,
							 | 
						||
| 
								 | 
							
								                                 LPDWORD a6,
							 | 
						||
| 
								 | 
							
								                                 LPOVERLAPPED a7)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    EnterFunc();
							 | 
						||
| 
								 | 
							
								    DWORD d6 = 0;
							 | 
						||
| 
								 | 
							
								    if (a6 == NULL) {
							 | 
						||
| 
								 | 
							
								        a6 = &d6;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    BOOL rv = 0;
							 | 
						||
| 
								 | 
							
								    __try {
							 | 
						||
| 
								 | 
							
								        rv = Real_DeviceIoControl(a0, a1, a2, a3, a4, a5, a6, a7);
							 | 
						||
| 
								 | 
							
								    } __finally {
							 | 
						||
| 
								 | 
							
								        ExitFunc();
							 | 
						||
| 
								 | 
							
								        OpenFiles::SetRead(a0, 0);
							 | 
						||
| 
								 | 
							
								        OpenFiles::SetWrite(a0, 0);
							 | 
						||
| 
								 | 
							
								        if (rv && a1 != 0x390008 && a1 != 0x4d0008 && a1 != 0x6d0008) {
							 | 
						||
| 
								 | 
							
								            FileInfo *pInfo = OpenFiles::RecallFile(a0);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            DWORD DeviceType    = (a1 & 0xffff0000) >> 16;
							 | 
						||
| 
								 | 
							
								            DWORD Access        = (a1 & 0x0000c000) >> 14;
							 | 
						||
| 
								 | 
							
								            DWORD Function      = (a1 & 0x00003ffc) >> 2;
							 | 
						||
| 
								 | 
							
								            DWORD Method        = (a1 & 0x00000003) >> 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if (pInfo) {
							 | 
						||
| 
								 | 
							
								                Print("<!-- DeviceIoControl %x [dev=%x,acc=%x,fun=%x,mth=%x] on %ls! -->\n",
							 | 
						||
| 
								 | 
							
								                      a1, DeviceType, Access, Function, Method, pInfo->m_pwzPath);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            else {
							 | 
						||
| 
								 | 
							
								                Print("<!-- DeviceIoControl %x [dev=%x,acc=%x,fun=%x,mth=%x,in=%d,out=%d/%d] on (%x)! -->\n",
							 | 
						||
| 
								 | 
							
								                      a1, DeviceType, Access, Function, Method, a3, *a6, a5, a0);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                if (a3 > 0) {
							 | 
						||
| 
								 | 
							
								                    Dump(a2, a3);
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								                if (a5 > 0) {
							 | 
						||
| 
								 | 
							
								                    Dump(a4, (*a6 < a5) ? *a6 : a5);
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								    return rv;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								DWORD WINAPI Mine_GetFileAttributesW(LPCWSTR a0)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    EnterFunc();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    DWORD rv = 0;
							 | 
						||
| 
								 | 
							
								    __try {
							 | 
						||
| 
								 | 
							
								        rv = Real_GetFileAttributesW(a0);
							 | 
						||
| 
								 | 
							
								    } __finally {
							 | 
						||
| 
								 | 
							
								        ExitFunc();
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								    return rv;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								BOOL WINAPI Mine_MoveFileWithProgressW(LPCWSTR a0,
							 | 
						||
| 
								 | 
							
								                                       LPCWSTR a1,
							 | 
						||
| 
								 | 
							
								                                       LPPROGRESS_ROUTINE a2,
							 | 
						||
| 
								 | 
							
								                                       LPVOID a3,
							 | 
						||
| 
								 | 
							
								                                       DWORD a4)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    EnterFunc();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    BOOL rv = 0;
							 | 
						||
| 
								 | 
							
								    __try {
							 | 
						||
| 
								 | 
							
								        rv = Real_MoveFileWithProgressW(a0, a1, a2, a3, a4);
							 | 
						||
| 
								 | 
							
								    } __finally {
							 | 
						||
| 
								 | 
							
								        ExitFunc();
							 | 
						||
| 
								 | 
							
								        if (rv) {
							 | 
						||
| 
								 | 
							
								            NoteRead(a0);
							 | 
						||
| 
								 | 
							
								            NoteWrite(a1);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								    return rv;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								BOOL WINAPI Mine_MoveFileA(LPCSTR a0,
							 | 
						||
| 
								 | 
							
								                           LPCSTR a1)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    EnterFunc();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    BOOL rv = 0;
							 | 
						||
| 
								 | 
							
								    __try {
							 | 
						||
| 
								 | 
							
								        rv = Real_MoveFileA(a0, a1);
							 | 
						||
| 
								 | 
							
								    } __finally {
							 | 
						||
| 
								 | 
							
								        ExitFunc();
							 | 
						||
| 
								 | 
							
								        if (rv) {
							 | 
						||
| 
								 | 
							
								            NoteRead(a0);
							 | 
						||
| 
								 | 
							
								            NoteCleanup(a0);
							 | 
						||
| 
								 | 
							
								            NoteWrite(a1);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								    return rv;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								BOOL WINAPI Mine_MoveFileW(LPCWSTR a0,
							 | 
						||
| 
								 | 
							
								                           LPCWSTR a1)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    EnterFunc();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    BOOL rv = 0;
							 | 
						||
| 
								 | 
							
								    __try {
							 | 
						||
| 
								 | 
							
								        rv = Real_MoveFileW(a0, a1);
							 | 
						||
| 
								 | 
							
								    } __finally {
							 | 
						||
| 
								 | 
							
								        ExitFunc();
							 | 
						||
| 
								 | 
							
								        if (rv) {
							 | 
						||
| 
								 | 
							
								            NoteRead(a0);
							 | 
						||
| 
								 | 
							
								            NoteCleanup(a0);
							 | 
						||
| 
								 | 
							
								            NoteWrite(a1);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								    return rv;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								BOOL WINAPI Mine_MoveFileExA(LPCSTR a0,
							 | 
						||
| 
								 | 
							
								                             LPCSTR a1,
							 | 
						||
| 
								 | 
							
								                             DWORD a2)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    EnterFunc();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    BOOL rv = 0;
							 | 
						||
| 
								 | 
							
								    __try {
							 | 
						||
| 
								 | 
							
								        rv = Real_MoveFileExA(a0, a1, a2);
							 | 
						||
| 
								 | 
							
								    } __finally {
							 | 
						||
| 
								 | 
							
								        ExitFunc();
							 | 
						||
| 
								 | 
							
								        if (rv) {
							 | 
						||
| 
								 | 
							
								            NoteRead(a0);
							 | 
						||
| 
								 | 
							
								            NoteCleanup(a0);
							 | 
						||
| 
								 | 
							
								            NoteWrite(a1);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								    return rv;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								BOOL WINAPI Mine_MoveFileExW(LPCWSTR a0,
							 | 
						||
| 
								 | 
							
								                             LPCWSTR a1,
							 | 
						||
| 
								 | 
							
								                             DWORD a2)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    EnterFunc();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    BOOL rv = 0;
							 | 
						||
| 
								 | 
							
								    __try {
							 | 
						||
| 
								 | 
							
								        rv = Real_MoveFileExW(a0, a1, a2);
							 | 
						||
| 
								 | 
							
								    } __finally {
							 | 
						||
| 
								 | 
							
								        ExitFunc();
							 | 
						||
| 
								 | 
							
								        if (rv) {
							 | 
						||
| 
								 | 
							
								            NoteRead(a0);
							 | 
						||
| 
								 | 
							
								            NoteCleanup(a0);
							 | 
						||
| 
								 | 
							
								            NoteWrite(a1);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								    return rv;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void SetHandle(PCSTR pszName, HANDLE h)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								#if 0
							 | 
						||
| 
								 | 
							
								    FileInfo *pInfo = OpenFiles::RecallFile(h);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (pInfo != NULL) {
							 | 
						||
| 
								 | 
							
								        Tblog("<!-- hset: %hs (%x) %ls -->\n", pszName, h, pInfo->m_pwzPath);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    else {
							 | 
						||
| 
								 | 
							
								        Tblog("<!-- hset: %hs (%x) ***Unknown*** -->\n", pszName, h);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								    (void)pszName;
							 | 
						||
| 
								 | 
							
								    (void)h;
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								BOOL WINAPI Mine_SetStdHandle(DWORD a0,
							 | 
						||
| 
								 | 
							
								                              HANDLE a1)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    EnterFunc();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    BOOL rv = 0;
							 | 
						||
| 
								 | 
							
								    __try {
							 | 
						||
| 
								 | 
							
								        rv = Real_SetStdHandle(a0, a1);
							 | 
						||
| 
								 | 
							
								        if (rv && a1 != 0) {
							 | 
						||
| 
								 | 
							
								            switch (a0) {
							 | 
						||
| 
								 | 
							
								              case STD_INPUT_HANDLE:
							 | 
						||
| 
								 | 
							
								                SetHandle("stdin", a1);
							 | 
						||
| 
								 | 
							
								                break;
							 | 
						||
| 
								 | 
							
								              case STD_OUTPUT_HANDLE:
							 | 
						||
| 
								 | 
							
								                SetHandle("stdout", a1);
							 | 
						||
| 
								 | 
							
								                break;
							 | 
						||
| 
								 | 
							
								              case STD_ERROR_HANDLE:
							 | 
						||
| 
								 | 
							
								                SetHandle("stderr", a1);
							 | 
						||
| 
								 | 
							
								                break;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    } __finally {
							 | 
						||
| 
								 | 
							
								        ExitFunc();
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								    return rv;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								HMODULE WINAPI Mine_LoadLibraryA(LPCSTR a0)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    EnterFunc();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    HMODULE rv = 0;
							 | 
						||
| 
								 | 
							
								    __try {
							 | 
						||
| 
								 | 
							
								        rv = Real_LoadLibraryA(a0);
							 | 
						||
| 
								 | 
							
								    } __finally {
							 | 
						||
| 
								 | 
							
								        ExitFunc();
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								    return rv;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								HMODULE WINAPI Mine_LoadLibraryW(LPCWSTR a0)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    EnterFunc();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    HMODULE rv = 0;
							 | 
						||
| 
								 | 
							
								    __try {
							 | 
						||
| 
								 | 
							
								        rv = Real_LoadLibraryW(a0);
							 | 
						||
| 
								 | 
							
								    } __finally {
							 | 
						||
| 
								 | 
							
								        ExitFunc();
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								    return rv;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								HMODULE WINAPI Mine_LoadLibraryExA(LPCSTR a0,
							 | 
						||
| 
								 | 
							
								                                   HANDLE a1,
							 | 
						||
| 
								 | 
							
								                                   DWORD a2)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    EnterFunc();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    HMODULE rv = 0;
							 | 
						||
| 
								 | 
							
								    __try {
							 | 
						||
| 
								 | 
							
								        rv = Real_LoadLibraryExA(a0, a1, a2);
							 | 
						||
| 
								 | 
							
								    } __finally {
							 | 
						||
| 
								 | 
							
								        ExitFunc();
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								    return rv;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								HMODULE WINAPI Mine_LoadLibraryExW(LPCWSTR a0,
							 | 
						||
| 
								 | 
							
								                                   HANDLE a1,
							 | 
						||
| 
								 | 
							
								                                   DWORD a2)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    EnterFunc();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    HMODULE rv = 0;
							 | 
						||
| 
								 | 
							
								    __try {
							 | 
						||
| 
								 | 
							
								        rv = Real_LoadLibraryExW(a0, a1, a2);
							 | 
						||
| 
								 | 
							
								    } __finally {
							 | 
						||
| 
								 | 
							
								        ExitFunc();
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								    return rv;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								DWORD WINAPI Mine_SetFilePointer(HANDLE hFile,
							 | 
						||
| 
								 | 
							
								                                 LONG lDistanceToMove,
							 | 
						||
| 
								 | 
							
								                                 PLONG lpDistanceToMoveHigh,
							 | 
						||
| 
								 | 
							
								                                 DWORD dwMoveMethod)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    EnterFunc();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    DWORD rv = 0;
							 | 
						||
| 
								 | 
							
								    __try {
							 | 
						||
| 
								 | 
							
								        rv = Real_SetFilePointer(hFile,
							 | 
						||
| 
								 | 
							
								                                 lDistanceToMove,
							 | 
						||
| 
								 | 
							
								                                 lpDistanceToMoveHigh,
							 | 
						||
| 
								 | 
							
								                                 dwMoveMethod);
							 | 
						||
| 
								 | 
							
								    } __finally {
							 | 
						||
| 
								 | 
							
								        LONG high = 0;
							 | 
						||
| 
								 | 
							
								        if (lpDistanceToMoveHigh == NULL) {
							 | 
						||
| 
								 | 
							
								            lpDistanceToMoveHigh = &high;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        FileInfo * pInfo = OpenFiles::RecallFile(hFile);
							 | 
						||
| 
								 | 
							
								        if (pInfo != NULL) {
							 | 
						||
| 
								 | 
							
								            if (dwMoveMethod == FILE_END && lDistanceToMove == 0xffffffff) {
							 | 
						||
| 
								 | 
							
								#if 0
							 | 
						||
| 
								 | 
							
								                Print("<!-- SetFilePointer(APPEND, %le) -->\n",
							 | 
						||
| 
								 | 
							
								                      pInfo->m_pwzPath);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								                pInfo->m_fAppend = TRUE;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								#if 0
							 | 
						||
| 
								 | 
							
								            else if (dwMoveMethod == FILE_END) {
							 | 
						||
| 
								 | 
							
								                Print("<!-- SetFilePointer(END:%08x:%08x, %le) -->\n",
							 | 
						||
| 
								 | 
							
								                      (int)lDistanceToMove,
							 | 
						||
| 
								 | 
							
								                      *lpDistanceToMoveHigh,
							 | 
						||
| 
								 | 
							
								                      pInfo->m_pwzPath);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            else if (dwMoveMethod == FILE_BEGIN) {
							 | 
						||
| 
								 | 
							
								                Print("<!-- SetFilePointer(BEG:%08x:%08x, %le) -->\n",
							 | 
						||
| 
								 | 
							
								                      (int)lDistanceToMove,
							 | 
						||
| 
								 | 
							
								                      *lpDistanceToMoveHigh,
							 | 
						||
| 
								 | 
							
								                      pInfo->m_pwzPath);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            else if (dwMoveMethod == FILE_CURRENT) {
							 | 
						||
| 
								 | 
							
								                Print("<!-- SetFilePointer(CUR:%08x:%08x, %le) -->\n",
							 | 
						||
| 
								 | 
							
								                      (int)lDistanceToMove,
							 | 
						||
| 
								 | 
							
								                      *lpDistanceToMoveHigh,
							 | 
						||
| 
								 | 
							
								                      pInfo->m_pwzPath);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        ExitFunc();
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								    return rv;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								BOOL WINAPI Mine_SetFilePointerEx(HANDLE hFile,
							 | 
						||
| 
								 | 
							
								                                  LARGE_INTEGER liDistanceToMove,
							 | 
						||
| 
								 | 
							
								                                  PLARGE_INTEGER lpNewFilePointer,
							 | 
						||
| 
								 | 
							
								                                  DWORD dwMoveMethod)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    EnterFunc();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    BOOL rv = 0;
							 | 
						||
| 
								 | 
							
								    __try {
							 | 
						||
| 
								 | 
							
								        rv = Real_SetFilePointerEx(hFile,
							 | 
						||
| 
								 | 
							
								                                   liDistanceToMove,
							 | 
						||
| 
								 | 
							
								                                   lpNewFilePointer,
							 | 
						||
| 
								 | 
							
								                                   dwMoveMethod);
							 | 
						||
| 
								 | 
							
								    } __finally {
							 | 
						||
| 
								 | 
							
								#if 0
							 | 
						||
| 
								 | 
							
								        FileInfo * pInfo = OpenFiles::RecallFile(hFile);
							 | 
						||
| 
								 | 
							
								        if (pInfo != NULL) {
							 | 
						||
| 
								 | 
							
								            if (dwMoveMethod == FILE_END) {
							 | 
						||
| 
								 | 
							
								                Print("<!-- SetFilePointerEx(END:%I64d, %le) -->\n",
							 | 
						||
| 
								 | 
							
								                      liDistanceToMove.QuadPart,
							 | 
						||
| 
								 | 
							
								                      pInfo->m_pwzPath);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            else if (dwMoveMethod == FILE_BEGIN) {
							 | 
						||
| 
								 | 
							
								                Print("<!-- SetFilePointerEx(BEG:%I64d, %le) -->\n",
							 | 
						||
| 
								 | 
							
								                      liDistanceToMove.QuadPart,
							 | 
						||
| 
								 | 
							
								                      pInfo->m_pwzPath);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            else if (dwMoveMethod == FILE_CURRENT) {
							 | 
						||
| 
								 | 
							
								                Print("<!-- SetFilePointerEx(CUR:%I64d, %le) -->\n",
							 | 
						||
| 
								 | 
							
								                      liDistanceToMove.QuadPart,
							 | 
						||
| 
								 | 
							
								                      pInfo->m_pwzPath);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								        ExitFunc();
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								    return rv;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								BOOL WINAPI Mine_ReadFile(HANDLE a0,
							 | 
						||
| 
								 | 
							
								                          LPVOID a1,
							 | 
						||
| 
								 | 
							
								                          DWORD a2,
							 | 
						||
| 
								 | 
							
								                          LPDWORD a3,
							 | 
						||
| 
								 | 
							
								                          LPOVERLAPPED a4)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    EnterFunc();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    BOOL rv = 0;
							 | 
						||
| 
								 | 
							
								    __try {
							 | 
						||
| 
								 | 
							
								        rv = Real_ReadFile(a0, a1, a2, a3, a4);
							 | 
						||
| 
								 | 
							
								    } __finally {
							 | 
						||
| 
								 | 
							
								        if (rv) {
							 | 
						||
| 
								 | 
							
								            OpenFiles::SetRead(a0, a2);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        ExitFunc();
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								    return rv;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								BOOL WINAPI Mine_ReadFileEx(HANDLE a0,
							 | 
						||
| 
								 | 
							
								                            LPVOID a1,
							 | 
						||
| 
								 | 
							
								                            DWORD a2,
							 | 
						||
| 
								 | 
							
								                            LPOVERLAPPED a3,
							 | 
						||
| 
								 | 
							
								                            LPOVERLAPPED_COMPLETION_ROUTINE a4)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    EnterFunc();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    BOOL rv = 0;
							 | 
						||
| 
								 | 
							
								    __try {
							 | 
						||
| 
								 | 
							
								        rv = Real_ReadFileEx(a0, a1, a2, a3, a4);
							 | 
						||
| 
								 | 
							
								    } __finally {
							 | 
						||
| 
								 | 
							
								        if (rv) {
							 | 
						||
| 
								 | 
							
								            OpenFiles::SetRead(a0, a2);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        ExitFunc();
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								    return rv;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								BOOL WINAPI Mine_WriteFile(HANDLE a0,
							 | 
						||
| 
								 | 
							
								                           LPCVOID a1,
							 | 
						||
| 
								 | 
							
								                           DWORD a2,
							 | 
						||
| 
								 | 
							
								                           LPDWORD a3,
							 | 
						||
| 
								 | 
							
								                           LPOVERLAPPED a4)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    EnterFunc();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    BOOL rv = 0;
							 | 
						||
| 
								 | 
							
								    __try {
							 | 
						||
| 
								 | 
							
								        rv = Real_WriteFile(a0, a1, a2, a3, a4);
							 | 
						||
| 
								 | 
							
								    } __finally {
							 | 
						||
| 
								 | 
							
								        OpenFiles::SetWrite(a0, a2);
							 | 
						||
| 
								 | 
							
								        ExitFunc();
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								    return rv;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								BOOL WINAPI Mine_WriteFileEx(HANDLE a0,
							 | 
						||
| 
								 | 
							
								                             LPCVOID a1,
							 | 
						||
| 
								 | 
							
								                             DWORD a2,
							 | 
						||
| 
								 | 
							
								                             LPOVERLAPPED a3,
							 | 
						||
| 
								 | 
							
								                             LPOVERLAPPED_COMPLETION_ROUTINE a4)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    EnterFunc();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    BOOL rv = 0;
							 | 
						||
| 
								 | 
							
								    __try {
							 | 
						||
| 
								 | 
							
								        rv = Real_WriteFileEx(a0, a1, a2, a3, a4);
							 | 
						||
| 
								 | 
							
								    } __finally {
							 | 
						||
| 
								 | 
							
								        OpenFiles::SetWrite(a0, a2);
							 | 
						||
| 
								 | 
							
								        ExitFunc();
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								    return rv;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								BOOL WINAPI Mine_WriteConsoleA(HANDLE a0,
							 | 
						||
| 
								 | 
							
								                                  const VOID* a1,
							 | 
						||
| 
								 | 
							
								                                  DWORD a2,
							 | 
						||
| 
								 | 
							
								                                  LPDWORD a3,
							 | 
						||
| 
								 | 
							
								                                  LPVOID a4)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    EnterFunc();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    BOOL rv = 0;
							 | 
						||
| 
								 | 
							
								    __try {
							 | 
						||
| 
								 | 
							
								        rv = Real_WriteConsoleA(a0, a1, a2, a3, a4);
							 | 
						||
| 
								 | 
							
								    } __finally {
							 | 
						||
| 
								 | 
							
								        OpenFiles::SetWrite(a0, a2);
							 | 
						||
| 
								 | 
							
								        ExitFunc();
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								    return rv;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								BOOL WINAPI Mine_WriteConsoleW(HANDLE a0,
							 | 
						||
| 
								 | 
							
								                                  const VOID* a1,
							 | 
						||
| 
								 | 
							
								                                  DWORD a2,
							 | 
						||
| 
								 | 
							
								                                  LPDWORD a3,
							 | 
						||
| 
								 | 
							
								                                  LPVOID a4)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    EnterFunc();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    BOOL rv = 0;
							 | 
						||
| 
								 | 
							
								    __try {
							 | 
						||
| 
								 | 
							
								        rv = Real_WriteConsoleW(a0, a1, a2, a3, a4);
							 | 
						||
| 
								 | 
							
								    } __finally {
							 | 
						||
| 
								 | 
							
								        OpenFiles::SetWrite(a0, a2);
							 | 
						||
| 
								 | 
							
								        ExitFunc();
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								    return rv;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//////////////////////////////////////////////////////////////////////////////
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								DWORD WINAPI Mine_ExpandEnvironmentStringsA(PCSTR lpSrc, PCHAR lpDst, DWORD nSize)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    EnterFunc();
							 | 
						||
| 
								 | 
							
								    DWORD rv = 0;
							 | 
						||
| 
								 | 
							
								    __try {
							 | 
						||
| 
								 | 
							
								        rv = Real_ExpandEnvironmentStringsA(lpSrc, lpDst, nSize);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    __finally {
							 | 
						||
| 
								 | 
							
								        if (rv > 0) {
							 | 
						||
| 
								 | 
							
								#if 0
							 | 
						||
| 
								 | 
							
								            Print("<!-- ExpandEnvironmentStringsA(%he) -->\n", lpSrc);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        ExitFunc();
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								    return rv;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								DWORD WINAPI Mine_ExpandEnvironmentStringsW(PCWSTR lpSrc, PWCHAR lpDst, DWORD nSize)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    EnterFunc();
							 | 
						||
| 
								 | 
							
								    DWORD rv = 0;
							 | 
						||
| 
								 | 
							
								    __try {
							 | 
						||
| 
								 | 
							
								        rv = Real_ExpandEnvironmentStringsW(lpSrc, lpDst, nSize);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    __finally {
							 | 
						||
| 
								 | 
							
								        if (rv > 0) {
							 | 
						||
| 
								 | 
							
								#if 0
							 | 
						||
| 
								 | 
							
								            Print("<!-- ExpandEnvironmentStringsW(%le) -->\n", lpSrc);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        ExitFunc();
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								    return rv;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								DWORD WINAPI Mine_GetEnvironmentVariableA(PCSTR lpName, PCHAR lpBuffer, DWORD nSize)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    EnterFunc();
							 | 
						||
| 
								 | 
							
								    DWORD rv = 0;
							 | 
						||
| 
								 | 
							
								    __try {
							 | 
						||
| 
								 | 
							
								        rv = Real_GetEnvironmentVariableA(lpName, lpBuffer, nSize);
							 | 
						||
| 
								 | 
							
								        //        if (rv > 0 && rv < nSize && lpBuffer != NULL) {
							 | 
						||
| 
								 | 
							
								        //            EnvVars::Used(lpName);
							 | 
						||
| 
								 | 
							
								        //        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    __finally {
							 | 
						||
| 
								 | 
							
								        EnvVars::Used(lpName);
							 | 
						||
| 
								 | 
							
								        ExitFunc();
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								    return rv;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								DWORD WINAPI Mine_GetEnvironmentVariableW(PCWSTR lpName, PWCHAR lpBuffer, DWORD nSize)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    EnterFunc();
							 | 
						||
| 
								 | 
							
								    DWORD rv = 0;
							 | 
						||
| 
								 | 
							
								    __try {
							 | 
						||
| 
								 | 
							
								        rv = Real_GetEnvironmentVariableW(lpName, lpBuffer, nSize);
							 | 
						||
| 
								 | 
							
								        //        if (rv > 0 && rv < nSize && lpBuffer != NULL) {
							 | 
						||
| 
								 | 
							
								        //            EnvVars::Used(lpName);
							 | 
						||
| 
								 | 
							
								        //        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    __finally {
							 | 
						||
| 
								 | 
							
								        EnvVars::Used(lpName);
							 | 
						||
| 
								 | 
							
								        ExitFunc();
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								    return rv;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								PCWSTR CDECL Mine_wgetenv(PCWSTR var)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    EnterFunc();
							 | 
						||
| 
								 | 
							
								    PCWSTR rv = 0;
							 | 
						||
| 
								 | 
							
								    __try {
							 | 
						||
| 
								 | 
							
								        rv = Real_wgetenv(var);
							 | 
						||
| 
								 | 
							
								        //        if (rv != NULL) {
							 | 
						||
| 
								 | 
							
								        //            EnvVars::Used(var);
							 | 
						||
| 
								 | 
							
								        //        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    __finally {
							 | 
						||
| 
								 | 
							
								        EnvVars::Used(var);
							 | 
						||
| 
								 | 
							
								        ExitFunc();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return rv;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								PCSTR CDECL Mine_getenv(PCSTR var)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    EnterFunc();
							 | 
						||
| 
								 | 
							
								    PCSTR rv = 0;
							 | 
						||
| 
								 | 
							
								    __try {
							 | 
						||
| 
								 | 
							
								        rv = Real_getenv(var);
							 | 
						||
| 
								 | 
							
								        //        if (rv) {
							 | 
						||
| 
								 | 
							
								        //            EnvVars::Used(var);
							 | 
						||
| 
								 | 
							
								        //        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    __finally {
							 | 
						||
| 
								 | 
							
								        EnvVars::Used(var);
							 | 
						||
| 
								 | 
							
								        ExitFunc();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return rv;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								DWORD CDECL Mine_getenv_s(DWORD *pValue, PCHAR pBuffer, DWORD cBuffer, PCSTR varname)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    EnterFunc();
							 | 
						||
| 
								 | 
							
								    DWORD rv = 0;
							 | 
						||
| 
								 | 
							
								    __try {
							 | 
						||
| 
								 | 
							
								        DWORD value;
							 | 
						||
| 
								 | 
							
								        if (pValue == NULL) {
							 | 
						||
| 
								 | 
							
								            pValue = &value;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        rv = Real_getenv_s(pValue, pBuffer, cBuffer, varname);
							 | 
						||
| 
								 | 
							
								        //        if (rv == 0 && *pValue > 0) {
							 | 
						||
| 
								 | 
							
								        //            EnvVars::Used(varname);
							 | 
						||
| 
								 | 
							
								        //        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    __finally {
							 | 
						||
| 
								 | 
							
								        EnvVars::Used(varname);
							 | 
						||
| 
								 | 
							
								        ExitFunc();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return rv;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								DWORD CDECL Mine_wgetenv_s(DWORD *pValue, PWCHAR pBuffer, DWORD cBuffer, PCWSTR varname)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    EnterFunc();
							 | 
						||
| 
								 | 
							
								    DWORD rv = 0;
							 | 
						||
| 
								 | 
							
								    __try {
							 | 
						||
| 
								 | 
							
								        DWORD value;
							 | 
						||
| 
								 | 
							
								        if (pValue == NULL) {
							 | 
						||
| 
								 | 
							
								            pValue = &value;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        rv = Real_wgetenv_s(pValue, pBuffer, cBuffer, varname);
							 | 
						||
| 
								 | 
							
								        //        if (rv == 0 && *pValue > 0) {
							 | 
						||
| 
								 | 
							
								        //            EnvVars::Used(varname);
							 | 
						||
| 
								 | 
							
								        //        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    __finally {
							 | 
						||
| 
								 | 
							
								        EnvVars::Used(varname);
							 | 
						||
| 
								 | 
							
								        ExitFunc();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return rv;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								DWORD CDECL Mine_dupenv_s(PCHAR *ppBuffer, DWORD *pcBuffer, PCSTR varname)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    EnterFunc();
							 | 
						||
| 
								 | 
							
								    DWORD rv = 0;
							 | 
						||
| 
								 | 
							
								    __try {
							 | 
						||
| 
								 | 
							
								        PCHAR pb;
							 | 
						||
| 
								 | 
							
								        DWORD cb;
							 | 
						||
| 
								 | 
							
								        if (ppBuffer == NULL) {
							 | 
						||
| 
								 | 
							
								            ppBuffer = &pb;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        if (pcBuffer == NULL) {
							 | 
						||
| 
								 | 
							
								            pcBuffer = &cb;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        rv = Real_dupenv_s(ppBuffer, pcBuffer, varname);
							 | 
						||
| 
								 | 
							
								        //        if (rv == 0 && *pcBuffer > 0 && *ppBuffer != NULL) {
							 | 
						||
| 
								 | 
							
								        //            EnvVars::Used(varname);
							 | 
						||
| 
								 | 
							
								        //        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    __finally {
							 | 
						||
| 
								 | 
							
								        EnvVars::Used(varname);
							 | 
						||
| 
								 | 
							
								        ExitFunc();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return rv;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								DWORD CDECL Mine_wdupenv_s(PWCHAR *ppBuffer, DWORD *pcBuffer, PCWSTR varname)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    EnterFunc();
							 | 
						||
| 
								 | 
							
								    DWORD rv = 0;
							 | 
						||
| 
								 | 
							
								    __try {
							 | 
						||
| 
								 | 
							
								        PWCHAR pb;
							 | 
						||
| 
								 | 
							
								        DWORD cb;
							 | 
						||
| 
								 | 
							
								        if (ppBuffer == NULL) {
							 | 
						||
| 
								 | 
							
								            ppBuffer = &pb;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        if (pcBuffer == NULL) {
							 | 
						||
| 
								 | 
							
								            pcBuffer = &cb;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        rv = Real_wdupenv_s(ppBuffer, pcBuffer, varname);
							 | 
						||
| 
								 | 
							
								        //        if (rv == 0 && *pcBuffer > 0 && *ppBuffer != NULL) {
							 | 
						||
| 
								 | 
							
								        //            EnvVars::Used(varname);
							 | 
						||
| 
								 | 
							
								        //        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    __finally {
							 | 
						||
| 
								 | 
							
								        EnvVars::Used(varname);
							 | 
						||
| 
								 | 
							
								        ExitFunc();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return rv;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/////////////////////////////////////////////////////////////
							 | 
						||
| 
								 | 
							
								// AttachDetours
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								LONG AttachDetours(VOID)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    DetourTransactionBegin();
							 | 
						||
| 
								 | 
							
								    DetourUpdateThread(GetCurrentThread());
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    DetourAttach(&(PVOID&)Real_EntryPoint, Mine_EntryPoint);
							 | 
						||
| 
								 | 
							
								    DetourAttach(&(PVOID&)Real_ExitProcess, Mine_ExitProcess);
							 | 
						||
| 
								 | 
							
								    DetourAttach(&(PVOID&)Real_CopyFileExA, Mine_CopyFileExA);
							 | 
						||
| 
								 | 
							
								    DetourAttach(&(PVOID&)Real_CopyFileExW, Mine_CopyFileExW);
							 | 
						||
| 
								 | 
							
								    DetourAttach(&(PVOID&)Real_PrivCopyFileExW, Mine_PrivCopyFileExW);
							 | 
						||
| 
								 | 
							
								    DetourAttach(&(PVOID&)Real_CreateHardLinkA, Mine_CreateHardLinkA);
							 | 
						||
| 
								 | 
							
								    DetourAttach(&(PVOID&)Real_CreateHardLinkW, Mine_CreateHardLinkW);
							 | 
						||
| 
								 | 
							
								    DetourAttach(&(PVOID&)Real_CreateDirectoryW, Mine_CreateDirectoryW);
							 | 
						||
| 
								 | 
							
								    DetourAttach(&(PVOID&)Real_CreateDirectoryExW, Mine_CreateDirectoryExW);
							 | 
						||
| 
								 | 
							
								    DetourAttach(&(PVOID&)Real_CreateFileW, Mine_CreateFileW);
							 | 
						||
| 
								 | 
							
								    DetourAttach(&(PVOID&)Real_CreatePipe, Mine_CreatePipe);
							 | 
						||
| 
								 | 
							
								    DetourAttach(&(PVOID&)Real_CreateFileMappingW, Mine_CreateFileMappingW);
							 | 
						||
| 
								 | 
							
								    DetourAttach(&(PVOID&)Real_CloseHandle, Mine_CloseHandle);
							 | 
						||
| 
								 | 
							
								    DetourAttach(&(PVOID&)Real_DuplicateHandle, Mine_DuplicateHandle);
							 | 
						||
| 
								 | 
							
								    DetourAttach(&(PVOID&)Real_CreateProcessW, Mine_CreateProcessW);
							 | 
						||
| 
								 | 
							
								    DetourAttach(&(PVOID&)Real_CreateProcessA, Mine_CreateProcessA);
							 | 
						||
| 
								 | 
							
								    DetourAttach(&(PVOID&)Real_DeleteFileW, Mine_DeleteFileW);
							 | 
						||
| 
								 | 
							
								    DetourAttach(&(PVOID&)Real_DeviceIoControl, Mine_DeviceIoControl);
							 | 
						||
| 
								 | 
							
								    DetourAttach(&(PVOID&)Real_GetFileAttributesW, Mine_GetFileAttributesW);
							 | 
						||
| 
								 | 
							
								    DetourAttach(&(PVOID&)Real_MoveFileA, Mine_MoveFileA);
							 | 
						||
| 
								 | 
							
								    DetourAttach(&(PVOID&)Real_MoveFileW, Mine_MoveFileW);
							 | 
						||
| 
								 | 
							
								    DetourAttach(&(PVOID&)Real_MoveFileExA, Mine_MoveFileExA);
							 | 
						||
| 
								 | 
							
								    DetourAttach(&(PVOID&)Real_MoveFileExW, Mine_MoveFileExW);
							 | 
						||
| 
								 | 
							
								    DetourAttach(&(PVOID&)Real_MoveFileWithProgressW, Mine_MoveFileWithProgressW);
							 | 
						||
| 
								 | 
							
								    DetourAttach(&(PVOID&)Real_SetStdHandle, Mine_SetStdHandle);
							 | 
						||
| 
								 | 
							
								    DetourAttach(&(PVOID&)Real_LoadLibraryA, Mine_LoadLibraryA);
							 | 
						||
| 
								 | 
							
								    DetourAttach(&(PVOID&)Real_LoadLibraryW, Mine_LoadLibraryW);
							 | 
						||
| 
								 | 
							
								    DetourAttach(&(PVOID&)Real_LoadLibraryExA, Mine_LoadLibraryExA);
							 | 
						||
| 
								 | 
							
								    DetourAttach(&(PVOID&)Real_LoadLibraryExW, Mine_LoadLibraryExW);
							 | 
						||
| 
								 | 
							
								    DetourAttach(&(PVOID&)Real_SetFilePointer, Mine_SetFilePointer);
							 | 
						||
| 
								 | 
							
								    DetourAttach(&(PVOID&)Real_SetFilePointerEx, Mine_SetFilePointerEx);
							 | 
						||
| 
								 | 
							
								    DetourAttach(&(PVOID&)Real_ReadFile, Mine_ReadFile);
							 | 
						||
| 
								 | 
							
								    DetourAttach(&(PVOID&)Real_ReadFileEx, Mine_ReadFileEx);
							 | 
						||
| 
								 | 
							
								    DetourAttach(&(PVOID&)Real_WriteFile, Mine_WriteFile);
							 | 
						||
| 
								 | 
							
								    DetourAttach(&(PVOID&)Real_WriteFileEx, Mine_WriteFileEx);
							 | 
						||
| 
								 | 
							
								    DetourAttach(&(PVOID&)Real_WriteConsoleA, Mine_WriteConsoleA);
							 | 
						||
| 
								 | 
							
								    DetourAttach(&(PVOID&)Real_WriteConsoleW, Mine_WriteConsoleW);
							 | 
						||
| 
								 | 
							
								    DetourAttach(&(PVOID&)Real_ExpandEnvironmentStringsA, Mine_ExpandEnvironmentStringsA);
							 | 
						||
| 
								 | 
							
								    DetourAttach(&(PVOID&)Real_ExpandEnvironmentStringsW, Mine_ExpandEnvironmentStringsW);
							 | 
						||
| 
								 | 
							
								    DetourAttach(&(PVOID&)Real_GetEnvironmentVariableA, Mine_GetEnvironmentVariableA);
							 | 
						||
| 
								 | 
							
								    DetourAttach(&(PVOID&)Real_GetEnvironmentVariableW, Mine_GetEnvironmentVariableW);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return DetourTransactionCommit();
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								LONG DetachDetours(VOID)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    DetourTransactionBegin();
							 | 
						||
| 
								 | 
							
								    DetourUpdateThread(GetCurrentThread());
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    DetourDetach(&(PVOID&)Real_EntryPoint, Mine_EntryPoint);
							 | 
						||
| 
								 | 
							
								    DetourAttach(&(PVOID&)Real_ExitProcess, Mine_ExitProcess);
							 | 
						||
| 
								 | 
							
								    DetourDetach(&(PVOID&)Real_CopyFileExA, Mine_CopyFileExA);
							 | 
						||
| 
								 | 
							
								    DetourDetach(&(PVOID&)Real_CopyFileExW, Mine_CopyFileExW);
							 | 
						||
| 
								 | 
							
								    DetourDetach(&(PVOID&)Real_PrivCopyFileExW, Mine_PrivCopyFileExW);
							 | 
						||
| 
								 | 
							
								    DetourDetach(&(PVOID&)Real_CreateHardLinkA, Mine_CreateHardLinkA);
							 | 
						||
| 
								 | 
							
								    DetourDetach(&(PVOID&)Real_CreateHardLinkW, Mine_CreateHardLinkW);
							 | 
						||
| 
								 | 
							
								    DetourDetach(&(PVOID&)Real_CreateDirectoryW, Mine_CreateDirectoryW);
							 | 
						||
| 
								 | 
							
								    DetourDetach(&(PVOID&)Real_CreateDirectoryExW, Mine_CreateDirectoryExW);
							 | 
						||
| 
								 | 
							
								    DetourDetach(&(PVOID&)Real_CreateFileW, Mine_CreateFileW);
							 | 
						||
| 
								 | 
							
								    DetourDetach(&(PVOID&)Real_CreatePipe, Mine_CreatePipe);
							 | 
						||
| 
								 | 
							
								    DetourDetach(&(PVOID&)Real_CreateFileMappingW, Mine_CreateFileMappingW);
							 | 
						||
| 
								 | 
							
								    DetourDetach(&(PVOID&)Real_CloseHandle, Mine_CloseHandle);
							 | 
						||
| 
								 | 
							
								    DetourDetach(&(PVOID&)Real_DuplicateHandle, Mine_DuplicateHandle);
							 | 
						||
| 
								 | 
							
								    DetourDetach(&(PVOID&)Real_CreateProcessW, Mine_CreateProcessW);
							 | 
						||
| 
								 | 
							
								    DetourDetach(&(PVOID&)Real_CreateProcessA, Mine_CreateProcessA);
							 | 
						||
| 
								 | 
							
								    DetourDetach(&(PVOID&)Real_DeleteFileW, Mine_DeleteFileW);
							 | 
						||
| 
								 | 
							
								    DetourDetach(&(PVOID&)Real_DeviceIoControl, Mine_DeviceIoControl);
							 | 
						||
| 
								 | 
							
								    DetourDetach(&(PVOID&)Real_GetFileAttributesW, Mine_GetFileAttributesW);
							 | 
						||
| 
								 | 
							
								    DetourDetach(&(PVOID&)Real_MoveFileA, Mine_MoveFileA);
							 | 
						||
| 
								 | 
							
								    DetourDetach(&(PVOID&)Real_MoveFileW, Mine_MoveFileW);
							 | 
						||
| 
								 | 
							
								    DetourDetach(&(PVOID&)Real_MoveFileExA, Mine_MoveFileExA);
							 | 
						||
| 
								 | 
							
								    DetourDetach(&(PVOID&)Real_MoveFileExW, Mine_MoveFileExW);
							 | 
						||
| 
								 | 
							
								    DetourDetach(&(PVOID&)Real_MoveFileWithProgressW, Mine_MoveFileWithProgressW);
							 | 
						||
| 
								 | 
							
								    DetourDetach(&(PVOID&)Real_SetStdHandle, Mine_SetStdHandle);
							 | 
						||
| 
								 | 
							
								    DetourDetach(&(PVOID&)Real_LoadLibraryA, Mine_LoadLibraryA);
							 | 
						||
| 
								 | 
							
								    DetourDetach(&(PVOID&)Real_LoadLibraryW, Mine_LoadLibraryW);
							 | 
						||
| 
								 | 
							
								    DetourDetach(&(PVOID&)Real_LoadLibraryExA, Mine_LoadLibraryExA);
							 | 
						||
| 
								 | 
							
								    DetourDetach(&(PVOID&)Real_LoadLibraryExW, Mine_LoadLibraryExW);
							 | 
						||
| 
								 | 
							
								    DetourDetach(&(PVOID&)Real_SetFilePointer, Mine_SetFilePointer);
							 | 
						||
| 
								 | 
							
								    DetourDetach(&(PVOID&)Real_SetFilePointerEx, Mine_SetFilePointerEx);
							 | 
						||
| 
								 | 
							
								    DetourDetach(&(PVOID&)Real_ReadFile, Mine_ReadFile);
							 | 
						||
| 
								 | 
							
								    DetourDetach(&(PVOID&)Real_ReadFileEx, Mine_ReadFileEx);
							 | 
						||
| 
								 | 
							
								    DetourDetach(&(PVOID&)Real_WriteFile, Mine_WriteFile);
							 | 
						||
| 
								 | 
							
								    DetourDetach(&(PVOID&)Real_WriteFileEx, Mine_WriteFileEx);
							 | 
						||
| 
								 | 
							
								    DetourDetach(&(PVOID&)Real_WriteConsoleA, Mine_WriteConsoleA);
							 | 
						||
| 
								 | 
							
								    DetourDetach(&(PVOID&)Real_WriteConsoleW, Mine_WriteConsoleW);
							 | 
						||
| 
								 | 
							
								    DetourDetach(&(PVOID&)Real_ExpandEnvironmentStringsA, Mine_ExpandEnvironmentStringsA);
							 | 
						||
| 
								 | 
							
								    DetourDetach(&(PVOID&)Real_ExpandEnvironmentStringsW, Mine_ExpandEnvironmentStringsW);
							 | 
						||
| 
								 | 
							
								    DetourDetach(&(PVOID&)Real_GetEnvironmentVariableA, Mine_GetEnvironmentVariableA);
							 | 
						||
| 
								 | 
							
								    DetourDetach(&(PVOID&)Real_GetEnvironmentVariableW, Mine_GetEnvironmentVariableW);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (Real_getenv) { DetourDetach(&(PVOID&)Real_getenv, Mine_getenv); }
							 | 
						||
| 
								 | 
							
								    if (Real_getenv_s) { DetourDetach(&(PVOID&)Real_getenv_s, Mine_getenv_s); }
							 | 
						||
| 
								 | 
							
								    if (Real_wgetenv) { DetourDetach(&(PVOID&)Real_wgetenv, Mine_wgetenv); }
							 | 
						||
| 
								 | 
							
								    if (Real_wgetenv_s) { DetourDetach(&(PVOID&)Real_wgetenv, Mine_wgetenv_s); }
							 | 
						||
| 
								 | 
							
								    if (Real_dupenv_s) { DetourDetach(&(PVOID&)Real_dupenv_s, Mine_dupenv_s); }
							 | 
						||
| 
								 | 
							
								    if (Real_wdupenv_s) { DetourDetach(&(PVOID&)Real_wdupenv_s, Mine_wdupenv_s); }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return DetourTransactionCommit();
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								//////////////////////////////////////////////////////////////////////////////
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								VOID NoteRead(PCSTR psz)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    FileInfo *pInfo = FileNames::FindPartial(psz);
							 | 
						||
| 
								 | 
							
								    pInfo->m_fRead = TRUE;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								VOID NoteRead(PCWSTR pwz)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    FileInfo *pInfo = FileNames::FindPartial(pwz);
							 | 
						||
| 
								 | 
							
								    pInfo->m_fRead = TRUE;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								VOID NoteWrite(PCSTR psz)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    FileInfo *pInfo = FileNames::FindPartial(psz);
							 | 
						||
| 
								 | 
							
								    pInfo->m_fWrite = TRUE;
							 | 
						||
| 
								 | 
							
								    if (!pInfo->m_fRead) {
							 | 
						||
| 
								 | 
							
								        pInfo->m_fCantRead = TRUE;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								VOID NoteWrite(PCWSTR pwz)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    FileInfo *pInfo = FileNames::FindPartial(pwz);
							 | 
						||
| 
								 | 
							
								    pInfo->m_fWrite = TRUE;
							 | 
						||
| 
								 | 
							
								    if (!pInfo->m_fRead) {
							 | 
						||
| 
								 | 
							
								        pInfo->m_fCantRead = TRUE;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								VOID NoteDelete(PCSTR psz)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    FileInfo *pInfo = FileNames::FindPartial(psz);
							 | 
						||
| 
								 | 
							
								    if (pInfo->m_fWrite || pInfo->m_fRead) {
							 | 
						||
| 
								 | 
							
								        pInfo->m_fCleanup = TRUE;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    else {
							 | 
						||
| 
								 | 
							
								        pInfo->m_fDelete = TRUE;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    if (!pInfo->m_fRead) {
							 | 
						||
| 
								 | 
							
								        pInfo->m_fCantRead = TRUE;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								VOID NoteDelete(PCWSTR pwz)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    FileInfo *pInfo = FileNames::FindPartial(pwz);
							 | 
						||
| 
								 | 
							
								    if (pInfo->m_fWrite || pInfo->m_fRead) {
							 | 
						||
| 
								 | 
							
								        pInfo->m_fCleanup = TRUE;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    else {
							 | 
						||
| 
								 | 
							
								        pInfo->m_fDelete = TRUE;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    if (!pInfo->m_fRead) {
							 | 
						||
| 
								 | 
							
								        pInfo->m_fCantRead = TRUE;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								VOID NoteCleanup(PCSTR psz)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    FileInfo *pInfo = FileNames::FindPartial(psz);
							 | 
						||
| 
								 | 
							
								    pInfo->m_fCleanup = TRUE;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								VOID NoteCleanup(PCWSTR pwz)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    FileInfo *pInfo = FileNames::FindPartial(pwz);
							 | 
						||
| 
								 | 
							
								    pInfo->m_fCleanup = TRUE;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								////////////////////////////////////////////////////////////// Logging System.
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								static BOOL s_bLog = 1;
							 | 
						||
| 
								 | 
							
								static LONG s_nTlsIndent = -1;
							 | 
						||
| 
								 | 
							
								static LONG s_nTlsThread = -1;
							 | 
						||
| 
								 | 
							
								static LONG s_nThreadCnt = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								LONG EnterFunc()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    DWORD dwErr = GetLastError();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    LONG nIndent = 0;
							 | 
						||
| 
								 | 
							
								    LONG nThread = 0;
							 | 
						||
| 
								 | 
							
								    if (s_nTlsIndent >= 0) {
							 | 
						||
| 
								 | 
							
								        nIndent = (LONG)(LONG_PTR)TlsGetValue(s_nTlsIndent);
							 | 
						||
| 
								 | 
							
								        TlsSetValue(s_nTlsIndent, (PVOID)(LONG_PTR)(nIndent + 1));
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    if (s_nTlsThread >= 0) {
							 | 
						||
| 
								 | 
							
								        nThread = (LONG)(LONG_PTR)TlsGetValue(s_nTlsThread);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    SetLastError(dwErr);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return nIndent;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								VOID ExitFunc()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    DWORD dwErr = GetLastError();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    LONG nIndent = 0;
							 | 
						||
| 
								 | 
							
								    LONG nThread = 0;
							 | 
						||
| 
								 | 
							
								    if (s_nTlsIndent >= 0) {
							 | 
						||
| 
								 | 
							
								        nIndent = (LONG)(LONG_PTR)TlsGetValue(s_nTlsIndent) - 1;
							 | 
						||
| 
								 | 
							
								        ASSERT(nIndent >= 0);
							 | 
						||
| 
								 | 
							
								        TlsSetValue(s_nTlsIndent, (PVOID)(LONG_PTR)nIndent);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    if (s_nTlsThread >= 0) {
							 | 
						||
| 
								 | 
							
								        nThread = (LONG)(LONG_PTR)TlsGetValue(s_nTlsThread);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    SetLastError(dwErr);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								VOID Print(const CHAR *psz, ...)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    DWORD dwErr = GetLastError();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (s_bLog && psz) {
							 | 
						||
| 
								 | 
							
								        va_list  args;
							 | 
						||
| 
								 | 
							
								        va_start(args, psz);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        TblogV(psz, args);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        va_end(args);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    SetLastError(dwErr);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								VOID AssertFailed(CONST PCHAR pszMsg, CONST PCHAR pszFile, ULONG nLine)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    Tblog("ASSERT(%hs) failed in %s, line %d.\n", pszMsg, pszFile, nLine);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//////////////////////////////////////////////////////////////////////////////
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// DLL module information
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								BOOL ThreadAttach(HMODULE hDll)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    (void)hDll;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (s_nTlsIndent >= 0) {
							 | 
						||
| 
								 | 
							
								        TlsSetValue(s_nTlsIndent, (PVOID)0);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    if (s_nTlsThread >= 0) {
							 | 
						||
| 
								 | 
							
								        LONG nThread = InterlockedIncrement(&s_nThreadCnt);
							 | 
						||
| 
								 | 
							
								        TlsSetValue(s_nTlsThread, (PVOID)(LONG_PTR)nThread);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return TRUE;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								BOOL ThreadDetach(HMODULE hDll)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    (void)hDll;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (s_nTlsIndent >= 0) {
							 | 
						||
| 
								 | 
							
								        TlsSetValue(s_nTlsIndent, (PVOID)0);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    if (s_nTlsThread >= 0) {
							 | 
						||
| 
								 | 
							
								        TlsSetValue(s_nTlsThread, (PVOID)0);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return TRUE;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								BOOL ProcessAttach(HMODULE hDll)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    InitializeCriticalSection(&s_csPipe);
							 | 
						||
| 
								 | 
							
								    InitializeCriticalSection(&s_csChildPayload);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    Procs::Initialize();
							 | 
						||
| 
								 | 
							
								    EnvVars::Initialize();
							 | 
						||
| 
								 | 
							
								    FileNames::Initialize();
							 | 
						||
| 
								 | 
							
								    OpenFiles::Initialize();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    s_bLog = FALSE;
							 | 
						||
| 
								 | 
							
								    s_nTlsIndent = TlsAlloc();
							 | 
						||
| 
								 | 
							
								    s_nTlsThread = TlsAlloc();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    s_hInst = hDll;
							 | 
						||
| 
								 | 
							
								    s_hKernel32 = NULL;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    PBYTE xCreate = (PBYTE)DetourCodeFromPointer((PVOID)Real_CreateProcessW, NULL);
							 | 
						||
| 
								 | 
							
								    PTBLOG_PAYLOAD pPayload = NULL;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    for (HMODULE hMod = NULL; (hMod = DetourEnumerateModules(hMod)) != NULL;) {
							 | 
						||
| 
								 | 
							
								        ULONG cbData;
							 | 
						||
| 
								 | 
							
								        PVOID pvData = DetourFindPayload(hMod, s_guidTrace, &cbData);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (pvData != NULL && pPayload == NULL) {
							 | 
						||
| 
								 | 
							
								            pPayload = (PTBLOG_PAYLOAD)pvData;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        ULONG cbMod = DetourGetModuleSize(hMod);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (((PBYTE)hMod) < xCreate && ((PBYTE)hMod + cbMod) > xCreate) {
							 | 
						||
| 
								 | 
							
								            s_hKernel32 = hMod;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    ZeroMemory(&s_Payload, sizeof(s_Payload));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (pPayload == NULL) {
							 | 
						||
| 
								 | 
							
								        return FALSE;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    CopyMemory(&s_Payload, pPayload, sizeof(s_Payload));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    LoadStdHandleName(STD_INPUT_HANDLE, s_Payload.wzStdin, FALSE);
							 | 
						||
| 
								 | 
							
								    LoadStdHandleName(STD_OUTPUT_HANDLE, s_Payload.wzStdout, s_Payload.fStdoutAppend);
							 | 
						||
| 
								 | 
							
								    LoadStdHandleName(STD_ERROR_HANDLE, s_Payload.wzStderr, s_Payload.fStderrAppend);
							 | 
						||
| 
								 | 
							
								    s_nTraceProcessId = s_Payload.nTraceProcessId;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    GetModuleFileNameA(s_hInst, s_szDllPath, ARRAYSIZE(s_szDllPath));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // Find hidden functions.
							 | 
						||
| 
								 | 
							
								    Real_PrivCopyFileExW =
							 | 
						||
| 
								 | 
							
								        (BOOL (WINAPI *)(LPCWSTR, LPCWSTR, LPPROGRESS_ROUTINE, LPVOID, LPBOOL, DWORD))
							 | 
						||
| 
								 | 
							
								        GetProcAddress(s_hKernel32, "PrivCopyFileExW");
							 | 
						||
| 
								 | 
							
								    if (Real_PrivCopyFileExW == NULL) {
							 | 
						||
| 
								 | 
							
								        DEBUG_BREAK();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    LONG error = AttachDetours();
							 | 
						||
| 
								 | 
							
								    if (error != NO_ERROR) {
							 | 
						||
| 
								 | 
							
								        DEBUG_BREAK();
							 | 
						||
| 
								 | 
							
								        Tblog("<!-- Error attaching detours: %d -->\n", error);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    ThreadAttach(hDll);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    s_bLog = TRUE;
							 | 
						||
| 
								 | 
							
								    return TRUE;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								BOOL ProcessDetach(HMODULE hDll)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ThreadDetach(hDll);
							 | 
						||
| 
								 | 
							
								    s_bLog = FALSE;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    LONG error = DetachDetours();
							 | 
						||
| 
								 | 
							
								    if (error != NO_ERROR) {
							 | 
						||
| 
								 | 
							
								        Tblog("<!-- Error detaching detours: %d -->\n", error);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    TblogClose();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (s_nTlsIndent >= 0) {
							 | 
						||
| 
								 | 
							
								        TlsFree(s_nTlsIndent);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    if (s_nTlsThread >= 0) {
							 | 
						||
| 
								 | 
							
								        TlsFree(s_nTlsThread);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return TRUE;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								inline VOID UpdateIfRoom(PWCHAR& pwzDst, PWCHAR pwzDstEnd, WCHAR c)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    if (pwzDst < pwzDstEnd) {
							 | 
						||
| 
								 | 
							
								        *pwzDst++ = c;  // Write character if room in buffer.
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    else {
							 | 
						||
| 
								 | 
							
								        pwzDst++;       // If no room, just advance pointer (to alloc calculation)
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static PCHAR RemoveReturns(PCHAR pszBuffer)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    PCHAR pszIn = pszBuffer;
							 | 
						||
| 
								 | 
							
								    PCHAR pszOut = pszBuffer;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    while (*pszIn) {
							 | 
						||
| 
								 | 
							
								        if (*pszIn == '\r') {
							 | 
						||
| 
								 | 
							
								            pszIn++;
							 | 
						||
| 
								 | 
							
								            continue;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        *pszOut++ = *pszIn++;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    *pszOut = '\0';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return pszBuffer;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static PWCHAR RemoveReturns(PWCHAR pwzBuffer)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    PWCHAR pwzIn = pwzBuffer;
							 | 
						||
| 
								 | 
							
								    PWCHAR pwzOut = pwzBuffer;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    while (*pwzIn) {
							 | 
						||
| 
								 | 
							
								        if (*pwzIn == '\r') {
							 | 
						||
| 
								 | 
							
								            pwzIn++;
							 | 
						||
| 
								 | 
							
								            continue;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        *pwzOut++ = *pwzIn++;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    *pwzOut = '\0';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return pwzBuffer;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								PBYTE LoadFile(HANDLE hFile, DWORD cbFile)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    PBYTE pbFile = (PBYTE)GlobalAlloc(GPTR, cbFile + 3);
							 | 
						||
| 
								 | 
							
								    if (pbFile == NULL) {
							 | 
						||
| 
								 | 
							
								        return NULL;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    DWORD cbRead = 0;
							 | 
						||
| 
								 | 
							
								    Real_SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
							 | 
						||
| 
								 | 
							
								    Real_ReadFile(hFile, pbFile, cbFile, &cbRead, NULL);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // Make sure the file is zero terminated.
							 | 
						||
| 
								 | 
							
								    pbFile[cbRead + 0] = 0;
							 | 
						||
| 
								 | 
							
								    pbFile[cbRead + 1] = 0;
							 | 
						||
| 
								 | 
							
								    pbFile[cbRead + 2] = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return pbFile;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								PWCHAR More(PCWSTR pwzPath, PWCHAR pwzDst, PWCHAR pwzDstEnd)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    HANDLE hFile = Real_CreateFileW(pwzPath, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
							 | 
						||
| 
								 | 
							
								    if (hFile == INVALID_HANDLE_VALUE) {
							 | 
						||
| 
								 | 
							
								        return NULL;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    FileInfo *pInfo = FileNames::FindPartial(pwzPath);
							 | 
						||
| 
								 | 
							
								    pInfo->m_fAbsorbed = true;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    DWORD cbFile = Real_SetFilePointer(hFile, 0, NULL, FILE_END);
							 | 
						||
| 
								 | 
							
								    DWORD cbRead = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    PCHAR pszFile = (PCHAR)GlobalAlloc(GPTR, cbFile + 2);   // 2 bytes null for Unicode or Ascii.
							 | 
						||
| 
								 | 
							
								    if (pszFile != NULL) {
							 | 
						||
| 
								 | 
							
								        Real_SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
							 | 
						||
| 
								 | 
							
								        Real_ReadFile(hFile, pszFile, cbFile, &cbRead, NULL);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (((PUCHAR)pszFile)[0] == 0xff && ((PUCHAR)pszFile)[1] == 0xfe) {
							 | 
						||
| 
								 | 
							
								            // Unicode
							 | 
						||
| 
								 | 
							
								            PWCHAR pwzFile = ((PWCHAR)pszFile) + 1;
							 | 
						||
| 
								 | 
							
								            PCWSTR pwzIn = pwzFile;
							 | 
						||
| 
								 | 
							
								            while (*pwzIn) {
							 | 
						||
| 
								 | 
							
								                if (*pwzIn == ' ' || *pwzIn == '\t' || *pwzIn == '\r' || *pwzIn == '\n') {
							 | 
						||
| 
								 | 
							
								                    UpdateIfRoom(pwzDst, pwzDstEnd, ' ');
							 | 
						||
| 
								 | 
							
								                    while (*pwzIn == ' ' || *pwzIn == '\t' || *pwzIn == '\r' || *pwzIn == '\n') {
							 | 
						||
| 
								 | 
							
								                        pwzIn++;
							 | 
						||
| 
								 | 
							
								                    }
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								                else {
							 | 
						||
| 
								 | 
							
								                    UpdateIfRoom(pwzDst, pwzDstEnd, *pwzIn++);
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        else {
							 | 
						||
| 
								 | 
							
								            PCSTR pszIn = pszFile;
							 | 
						||
| 
								 | 
							
								            while (*pszIn) {
							 | 
						||
| 
								 | 
							
								                if (*pszIn == ' ' || *pszIn == '\t' || *pszIn == '\r' || *pszIn == '\n') {
							 | 
						||
| 
								 | 
							
								                    UpdateIfRoom(pwzDst, pwzDstEnd, ' ');
							 | 
						||
| 
								 | 
							
								                    while (*pszIn == ' ' || *pszIn == '\t' || *pszIn == '\r' || *pszIn == '\n') {
							 | 
						||
| 
								 | 
							
								                        pszIn++;
							 | 
						||
| 
								 | 
							
								                    }
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								                else {
							 | 
						||
| 
								 | 
							
								                    UpdateIfRoom(pwzDst, pwzDstEnd, *pszIn++);
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        GlobalFree(pszFile);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    Real_CloseHandle(hFile);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return pwzDst;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// This function is called twice.  On the first call, pwzDstEnd <= pwzDst and
							 | 
						||
| 
								 | 
							
								// no data is copied, but pwzDst is advanced so we can see how big of a
							 | 
						||
| 
								 | 
							
								// buffer is needed to hold the command line.
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// On the second call, the command line is actually populated.
							 | 
						||
| 
								 | 
							
								PWCHAR LoadCommandLine(PCWSTR pwz, PWCHAR pwzDst, PWCHAR pwzDstEnd)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    while (*pwz) {
							 | 
						||
| 
								 | 
							
								        PCWSTR pwzArgBeg = NULL;
							 | 
						||
| 
								 | 
							
								        PCWSTR pwzArgEnd = NULL;
							 | 
						||
| 
								 | 
							
								        WCHAR cQuote = '\0';
							 | 
						||
| 
								 | 
							
								        BOOL fMore = false;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (*pwz == '@') {
							 | 
						||
| 
								 | 
							
								            fMore = true;
							 | 
						||
| 
								 | 
							
								            pwz++;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (*pwz == '\"' || *pwz == '\'') {
							 | 
						||
| 
								 | 
							
								            cQuote = *pwz++;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            pwzArgBeg = pwz;
							 | 
						||
| 
								 | 
							
								            while (*pwz != '\0' && *pwz != cQuote) {
							 | 
						||
| 
								 | 
							
								                pwz++;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            pwzArgEnd = pwz;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if (*pwz == cQuote) {
							 | 
						||
| 
								 | 
							
								                pwz++;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        else {
							 | 
						||
| 
								 | 
							
								            pwzArgBeg = pwz;
							 | 
						||
| 
								 | 
							
								            while (*pwz != '\0' && *pwz != ' ' && *pwz != '\t' && *pwz != '\n' && *pwz != '\r') {
							 | 
						||
| 
								 | 
							
								                pwz++;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            pwzArgEnd = pwz;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (fMore) {
							 | 
						||
| 
								 | 
							
								            // More arguments!
							 | 
						||
| 
								 | 
							
								            WCHAR wzPath[MAX_PATH];
							 | 
						||
| 
								 | 
							
								            PWCHAR pwzPath = wzPath;
							 | 
						||
| 
								 | 
							
								            PCWSTR pwzTmp = pwzArgBeg + 1;
							 | 
						||
| 
								 | 
							
								            while (pwzTmp < pwzArgEnd && pwzPath < wzPath + ARRAYSIZE(wzPath)-2) {
							 | 
						||
| 
								 | 
							
								                *pwzPath++ = *pwzTmp++;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            *pwzPath = '\0';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            PWCHAR pwzOut = More(wzPath, pwzDst, pwzDstEnd);
							 | 
						||
| 
								 | 
							
								            if (pwzOut != NULL) {
							 | 
						||
| 
								 | 
							
								                pwzDst = pwzOut;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                cQuote = 0;
							 | 
						||
| 
								 | 
							
								                pwzArgBeg = pwzArgEnd;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (cQuote) {
							 | 
						||
| 
								 | 
							
								            UpdateIfRoom(pwzDst, pwzDstEnd, cQuote);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        for (; pwzArgBeg < pwzArgEnd; pwzArgBeg++) {
							 | 
						||
| 
								 | 
							
								            UpdateIfRoom(pwzDst, pwzDstEnd, *pwzArgBeg);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        if (cQuote) {
							 | 
						||
| 
								 | 
							
								            UpdateIfRoom(pwzDst, pwzDstEnd, cQuote);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (*pwz) {
							 | 
						||
| 
								 | 
							
								            UpdateIfRoom(pwzDst, pwzDstEnd, ' ');
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // skip over separating spaces.
							 | 
						||
| 
								 | 
							
								        while (*pwz == ' ' || *pwz == '\t' || *pwz == '\n' || *pwz == '\r') {
							 | 
						||
| 
								 | 
							
								            pwz++;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return pwzDst;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void TestHandle(PCSTR pszName, HANDLE h)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    FileInfo *pInfo = OpenFiles::RecallFile(h);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (pInfo != NULL) {
							 | 
						||
| 
								 | 
							
								#if 1 // Ignore PIPEs.
							 | 
						||
| 
								 | 
							
								        if (FileNames::PrefixMatch(pInfo->m_pwzPath, L"\\\\.\\PIPE\\")) {
							 | 
						||
| 
								 | 
							
								            // Ignore;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        else
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								            if (FileNames::SuffixMatch(pInfo->m_pwzPath, L"\\conout$")) {
							 | 
						||
| 
								 | 
							
								            // Ignore;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        else if (FileNames::SuffixMatch(pInfo->m_pwzPath, L"\\conin$")) {
							 | 
						||
| 
								 | 
							
								            // Ignore;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        else if (FileNames::SuffixMatch(pInfo->m_pwzPath, L"\\nul")) {
							 | 
						||
| 
								 | 
							
								            // Ignore;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        else {
							 | 
						||
| 
								 | 
							
								            Tblog("<%hs%hs>%le</%hs>\n",
							 | 
						||
| 
								 | 
							
								                  pszName, pInfo->m_fAppend ? " append=\"true\"" : "", pInfo->m_pwzPath, pszName);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    else {
							 | 
						||
| 
								 | 
							
								        Tblog("<!-- hand: %hs (%x) ***Unknown*** -->\n", pszName, h);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								LONG WINAPI DetourAttachIf(PVOID *ppPointer, PVOID pDetour)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    if (*ppPointer == NULL) {
							 | 
						||
| 
								 | 
							
								        Tblog("<!-- DetourAttachIf failed: %p -->\n", pDetour);
							 | 
						||
| 
								 | 
							
								        return NO_ERROR;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    PDETOUR_TRAMPOLINE pRealTrampoline;
							 | 
						||
| 
								 | 
							
								    PVOID pRealTarget;
							 | 
						||
| 
								 | 
							
								    PVOID pRealDetour;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    LONG err = DetourAttachEx(ppPointer, pDetour, &pRealTrampoline, &pRealTarget, &pRealDetour);
							 | 
						||
| 
								 | 
							
								    if (err == NO_ERROR) {
							 | 
						||
| 
								 | 
							
								        // Tblog("<!-- DetourAttachIf %p at %p -->\n", pDetour, pRealTarget);
							 | 
						||
| 
								 | 
							
								        return NO_ERROR;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return err;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								int WINAPI Mine_EntryPoint(VOID)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    // This function is invoked instead of the process EntryPoint (Real_EntryPoint).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    TblogOpen();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    SaveEnvironment();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        CHAR szExeName[MAX_PATH];
							 | 
						||
| 
								 | 
							
								        CHAR szId[128];
							 | 
						||
| 
								 | 
							
								        CHAR szParent[128];
							 | 
						||
| 
								 | 
							
								        WCHAR wzPath[MAX_PATH];
							 | 
						||
| 
								 | 
							
								        PCHAR pszExeName = szExeName;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // Get the base command line (skipping over the executable name)
							 | 
						||
| 
								 | 
							
								        PCWSTR pwzLine = GetCommandLineW();
							 | 
						||
| 
								 | 
							
								        if (*pwzLine == '\"') {
							 | 
						||
| 
								 | 
							
								            pwzLine++;
							 | 
						||
| 
								 | 
							
								            while (*pwzLine && *pwzLine != '\"') {
							 | 
						||
| 
								 | 
							
								                pwzLine++;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            if (*pwzLine == '\"') {
							 | 
						||
| 
								 | 
							
								                pwzLine++;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        else {
							 | 
						||
| 
								 | 
							
								            while (*pwzLine && *pwzLine != ' ' && *pwzLine != '\t') {
							 | 
						||
| 
								 | 
							
								                pwzLine++;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        while (*pwzLine && (*pwzLine == ' ' || *pwzLine == '\t')) {
							 | 
						||
| 
								 | 
							
								            pwzLine++;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // Get the root executable name.
							 | 
						||
| 
								 | 
							
								        if (GetModuleFileNameA(0, szExeName, ARRAYSIZE(szExeName))) {
							 | 
						||
| 
								 | 
							
								            PCHAR psz = szExeName;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            while (*psz) {
							 | 
						||
| 
								 | 
							
								                psz++;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            while (psz > szExeName && psz[-1] != ':' && psz[-1] != '\\' && psz[-1] != '/') {
							 | 
						||
| 
								 | 
							
								                psz--;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            pszExeName = psz;
							 | 
						||
| 
								 | 
							
								            while (*psz && *psz != '.') {
							 | 
						||
| 
								 | 
							
								                psz++;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            *psz = '\0';
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        else {
							 | 
						||
| 
								 | 
							
								            szExeName[0] = '\0';
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // Start the XML process node.
							 | 
						||
| 
								 | 
							
								        Tblog("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            PCHAR pszId = szId;
							 | 
						||
| 
								 | 
							
								            PCHAR pszParent = szParent;
							 | 
						||
| 
								 | 
							
								            for (DWORD i = 0; i < s_Payload.nGeneology; i++) {
							 | 
						||
| 
								 | 
							
								                pszId = SafePrintf(pszId, 16, "%d.", s_Payload.rGeneology[i]);
							 | 
						||
| 
								 | 
							
								                if (i < s_Payload.nGeneology - 1) {
							 | 
						||
| 
								 | 
							
								                    pszParent = SafePrintf(pszParent, 16, "%d.", s_Payload.rGeneology[i]);
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            *pszId = '\0';
							 | 
						||
| 
								 | 
							
								            *pszParent = '\0';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if (szParent[0] == '\0') {
							 | 
						||
| 
								 | 
							
								                Tblog("<t:Process id=\"::%hs::\"", szId);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            else {
							 | 
						||
| 
								 | 
							
								                Tblog("<t:Process id=\"::%hs::\" parentId=\"::%hs::\"", szId, szParent);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            Tblog(" par=\"%ls\" exe=\"%hs\"", s_Payload.wzParents, pszExeName);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            BOOL drop = false;
							 | 
						||
| 
								 | 
							
								            PCWSTR pwzz = s_Payload.wzzDrop;
							 | 
						||
| 
								 | 
							
								            while (*pwzz) {
							 | 
						||
| 
								 | 
							
								                if (Compare(pwzz, pszExeName) == 0) {
							 | 
						||
| 
								 | 
							
								                    // match
							 | 
						||
| 
								 | 
							
								                    drop = true;
							 | 
						||
| 
								 | 
							
								                    break;
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								                pwzz += Size(pwzz) + 1;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            if (drop) {
							 | 
						||
| 
								 | 
							
								                Tblog(" drop=\"true\"");
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            PWCHAR pwz = s_Payload.wzParents;
							 | 
						||
| 
								 | 
							
								            while (*pwz) {
							 | 
						||
| 
								 | 
							
								                pwz++;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            *pwz++ = '/';
							 | 
						||
| 
								 | 
							
								            PCSTR psz = pszExeName;
							 | 
						||
| 
								 | 
							
								            while (*psz) {
							 | 
						||
| 
								 | 
							
								                *pwz++ = *psz++;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            *pwz = '\0';
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (HasChar(pwzLine, '|')) {
							 | 
						||
| 
								 | 
							
								            Tblog(" pipes=\"true\"");
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        if (HasChar(pwzLine, '>')) {
							 | 
						||
| 
								 | 
							
								            Tblog(" redirects=\"true\"");
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        Tblog(" xmlns:t=\"http://schemas.microsoft.com/research/tracebld/2008\">\n");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // Get the directory.
							 | 
						||
| 
								 | 
							
								        DWORD dwSize = GetCurrentDirectoryA(ARRAYSIZE(szExeName), szExeName);
							 | 
						||
| 
								 | 
							
								        if (dwSize > 0 && dwSize < ARRAYSIZE(szExeName)) {
							 | 
						||
| 
								 | 
							
								            Tblog("<t:Directory>%hs</t:Directory>\n", szExeName);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // Get the real executable name.
							 | 
						||
| 
								 | 
							
								        wzPath[0] = '\0';
							 | 
						||
| 
								 | 
							
								        if (GetModuleFileNameA(0, szExeName, ARRAYSIZE(szExeName))) {
							 | 
						||
| 
								 | 
							
								            FileInfo *pInfo = FileNames::FindPartial(szExeName);
							 | 
						||
| 
								 | 
							
								            Tblog("<t:Executable>%ls</t:Executable>\n",
							 | 
						||
| 
								 | 
							
								                  FileNames::ParameterizeName(wzPath, ARRAYSIZE(wzPath), pInfo));
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // Construct the processed command line.
							 | 
						||
| 
								 | 
							
								        PWCHAR pwzDstEnd = (PWCHAR)pwzLine;
							 | 
						||
| 
								 | 
							
								        PWCHAR pwzDst = pwzDstEnd;
							 | 
						||
| 
								 | 
							
								        pwzDst = LoadCommandLine(pwzLine, pwzDst, pwzDstEnd);
							 | 
						||
| 
								 | 
							
								        DWORD wcNew = (DWORD)((pwzDst - pwzDstEnd) + 1);
							 | 
						||
| 
								 | 
							
								        PWCHAR pwzFin = (PWCHAR)GlobalAlloc(GPTR, wcNew * sizeof(WCHAR));
							 | 
						||
| 
								 | 
							
								        pwzDst = pwzFin;
							 | 
						||
| 
								 | 
							
								        pwzDstEnd = pwzFin + wcNew;
							 | 
						||
| 
								 | 
							
								        pwzDst = LoadCommandLine(pwzLine, pwzDst, pwzDstEnd);
							 | 
						||
| 
								 | 
							
								        *pwzDst = '\0';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        FileNames::ParameterizeLine(pwzFin, pwzFin + wcNew);
							 | 
						||
| 
								 | 
							
								        if (HasSpace(wzPath)) {
							 | 
						||
| 
								 | 
							
								            Tblog("<t:Line>"%le" %le</t:Line>\n", wzPath, pwzFin);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        else {
							 | 
						||
| 
								 | 
							
								            Tblog("<t:Line>%le %le</t:Line>\n", wzPath, pwzFin);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        TestHandle("t:StdIn", GetStdHandle(STD_INPUT_HANDLE));
							 | 
						||
| 
								 | 
							
								        TestHandle("t:StdOut", GetStdHandle(STD_OUTPUT_HANDLE));
							 | 
						||
| 
								 | 
							
								        TestHandle("t:StdErr", GetStdHandle(STD_ERROR_HANDLE));
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (FindMsvcr()) {
							 | 
						||
| 
								 | 
							
								        FindProc(&(PVOID&)Real_getenv, "getenv");
							 | 
						||
| 
								 | 
							
								        FindProc(&(PVOID&)Real_wgetenv, "_wgetenv");
							 | 
						||
| 
								 | 
							
								        FindProc(&(PVOID&)Real_getenv_s, "getenv_s");
							 | 
						||
| 
								 | 
							
								        FindProc(&(PVOID&)Real_wgetenv_s, "_wgetenv_s");
							 | 
						||
| 
								 | 
							
								        FindProc(&(PVOID&)Real_dupenv_s, "_dupenv_s");
							 | 
						||
| 
								 | 
							
								        FindProc(&(PVOID&)Real_wdupenv_s, "_wdupenv_s");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        DetourTransactionBegin();
							 | 
						||
| 
								 | 
							
								        DetourUpdateThread(GetCurrentThread());
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        DetourAttachIf(&(PVOID&)Real_getenv, Mine_getenv);
							 | 
						||
| 
								 | 
							
								        DetourAttachIf(&(PVOID&)Real_getenv_s, Mine_getenv_s);
							 | 
						||
| 
								 | 
							
								        DetourAttachIf(&(PVOID&)Real_wgetenv, Mine_wgetenv);
							 | 
						||
| 
								 | 
							
								        DetourAttachIf(&(PVOID&)Real_wgetenv, Mine_wgetenv_s);
							 | 
						||
| 
								 | 
							
								        DetourAttachIf(&(PVOID&)Real_dupenv_s, Mine_dupenv_s);
							 | 
						||
| 
								 | 
							
								        DetourAttachIf(&(PVOID&)Real_wdupenv_s, Mine_wdupenv_s);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        DetourTransactionCommit();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return Real_EntryPoint();
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								VOID WINAPI Mine_ExitProcess(UINT a0)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    if (a0 & 0x80000000) {
							 | 
						||
| 
								 | 
							
								        Tblog("<t:Return>%d</t:Return>\n", -(int)a0);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    else {
							 | 
						||
| 
								 | 
							
								        Tblog("<t:Return>%d</t:Return>\n", a0);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    FileNames::Dump();
							 | 
						||
| 
								 | 
							
								    EnvVars::Dump();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    TblogClose();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    Real_ExitProcess(a0);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								BOOL APIENTRY DllMain(HINSTANCE hModule, DWORD dwReason, PVOID lpReserved)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    (void)hModule;
							 | 
						||
| 
								 | 
							
								    (void)lpReserved;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (DetourIsHelperProcess()) {
							 | 
						||
| 
								 | 
							
								        return TRUE;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (dwReason == DLL_PROCESS_ATTACH) {
							 | 
						||
| 
								 | 
							
								        DetourRestoreAfterWith();
							 | 
						||
| 
								 | 
							
								        Real_EntryPoint = (int (WINAPI *)(VOID))DetourGetEntryPoint(NULL);
							 | 
						||
| 
								 | 
							
								        return ProcessAttach(hModule);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    else if (dwReason == DLL_PROCESS_DETACH) {
							 | 
						||
| 
								 | 
							
								        return ProcessDetach(hModule);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    else if (dwReason == DLL_THREAD_ATTACH) {
							 | 
						||
| 
								 | 
							
								        return ThreadAttach(hModule);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    else if (dwReason == DLL_THREAD_DETACH) {
							 | 
						||
| 
								 | 
							
								        return ThreadDetach(hModule);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return TRUE;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								///////////////////////////////////////////////////////////////// End of File.
							 |