Merge commit 'dabc40cb19' as 'ext/detours'

This commit is contained in:
Andrzej Janik 2021-01-03 17:52:14 +01:00
commit 77523940b3
178 changed files with 102613 additions and 0 deletions

View file

@ -0,0 +1,157 @@
##############################################################################
##
## Utility to registry and file access APIs.
##
## Microsoft Research Detours Package
##
## Copyright (c) Microsoft Corporation. All rights reserved.
##
!include ..\common.mak
LIBS=$(LIBS) kernel32.lib
##############################################################################
all: dirs \
$(BIND)\trcbld$(DETOURS_BITS).dll \
$(BIND)\tracebld.exe \
\
!IF $(DETOURS_SOURCE_BROWSING)==1
$(OBJD)\trcbld$(DETOURS_BITS).bsc \
$(OBJD)\tracebld.bsc \
!ENDIF
option
##############################################################################
clean:
-del *~ test.txt log.*.xml 2>nul
-del $(BIND)\tracebld.* $(BIND)\trcbld*.* 2>nul
-rmdir /q /s $(OBJD) 2>nul
realclean: clean
-rmdir /q /s $(OBJDS) 2>nul
dirs:
@if not exist $(BIND) mkdir $(BIND) && echo. Created $(BIND)
@if not exist $(OBJD) mkdir $(OBJD) && echo. Created $(OBJD)
##############################################################################
$(OBJD)\trcbld.obj : trcbld.cpp
$(OBJD)\trcbld.res : trcbld.rc
$(BIND)\trcbld$(DETOURS_BITS).dll : $(OBJD)\trcbld.obj $(OBJD)\trcbld.res $(DEPS)
cl /LD $(CFLAGS) /Fe$@ /Fd$(@R).pdb \
$(OBJD)\trcbld.obj $(OBJD)\trcbld.res \
/link $(LINKFLAGS) /release /subsystem:console \
/export:DetourFinishHelperProcess,@1,NONAME \
$(LIBS)
$(OBJD)\trcbld$(DETOURS_BITS).bsc : $(OBJD)\trcbld.obj
bscmake /v /n /o $@ $(OBJD)\trcbld.sbr
$(OBJD)\tracebld.obj : tracebld.cpp
$(BIND)\tracebld.exe : $(OBJD)\tracebld.obj $(DEPS)
cl $(CFLAGS) /Fe$@ /Fd$(@R).pdb $(OBJD)\tracebld.obj \
/link $(LINKFLAGS) $(LIBS) \
/subsystem:console /fixed:no
$(OBJD)\tracebld.bsc : $(OBJD)\tracebld.obj
bscmake /v /n /o $@ $(OBJD)\tracebld.sbr
############################################### Install non-bit-size binaries.
!IF "$(DETOURS_OPTION_PROCESSOR)" != ""
$(OPTD)\trcbld$(DETOURS_OPTION_BITS).dll:
$(OPTD)\trcbld$(DETOURS_OPTION_BITS).pdb:
$(BIND)\trcbld$(DETOURS_OPTION_BITS).dll : $(OPTD)\trcbld$(DETOURS_OPTION_BITS).dll
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
$(BIND)\trcbld$(DETOURS_OPTION_BITS).pdb : $(OPTD)\trcbld$(DETOURS_OPTION_BITS).pdb
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
option: \
$(BIND)\trcbld$(DETOURS_OPTION_BITS).dll \
$(BIND)\trcbld$(DETOURS_OPTION_BITS).pdb \
!ELSE
option:
!ENDIF
##############################################################################
test: all
-del log.*.xml 2>nul
$(BIND)\tracebld.exe /o:log %COMSPEC% /c dir
@echo -------- Log from log.00000000 ---------------------
type log.00000000.xml
test0: all
-del log.*.xml 2>nul
$(BIND)\tracebld.exe /o:log %COMSPEC% /c xx.cmd
@echo -------- Log from log.00000000 ---------------------
type log.00000000.xml
@echo -------- Log from log.00000001 ---------------------
type log.00000001.xml
test1: all
set FooBAR=1
-del log.*.xml 2>nul
@echo -------- Logging output to log ------------
-rmdir /q /s obj 2>nul
$(BIND)\tracebld.exe /o:log nmake.exe test2
@echo -------- Log from log.00000000 ---------------------
type log.00000000.xml | findstr /c:"t:Line"
type log.00000002.xml | findstr /c:"t:Line"
test1d: all
-del log.*.xml 2>nul
@echo -------- Logging output to log ------------
-rmdir /q /s obj 2>nul
windbg -g -G -o $(BIND)\tracebld.exe /o:log nmake.exe test2
@echo -------- Log from log.00000000 ---------------------
type log.00000000.xml | findstr /c:"t:Line"
type log.00000002.xml | findstr /c:"t:Line"
test2: all
-del foo.txt
echo foo1 >> foo.txt
echo foo2 >> foo.txt
echo foo3 >> foo.txt
-del log.foo.xml
-mkdir obj
cmd.exe /c "set Foo=BAR&&cmd.exe /c echo. FOO=%Foo%"
cl /LD $(CFLAGS) /Tp<< @<<obj\response.txt > log.foo.xml
#include <windows.h>
<<
/Feobj\tbtest.exe /Fd$(@R).pdb $(DET_SRC)
/link $(LINKFLAGS) /subsystem:console
/export:DetourFinishHelperProcess,@1
<<NOKEEP
type $(BIND)\trcbld.cpp | findstr CreateFile
echo int main() { return 0; } > obj\test.cpp
cl /c /Foobj\test.obj obj\test.cpp
-del tbtest.* 2>nul
test3: all
-del log.*.xml 2>nul
@echo -------- Logging output to log ------------
-rmdir /q /s foo
$(BIND)\tracebld.exe /o:log xcopy.exe $(BIND)\trcbld.cpp foo\ /y
@echo -------- Log from log.00000000 ---------------------
type log.00000000.xml
test4: all
-del log.*.xml 2>nul
echo int main() { return 0; } > obj\test.cpp
$(BIND)\tracebld.exe /o:log cl /c /Foobj\test.obj obj\test.cpp
@echo -------- Log from log.00000000 ---------------------
type log.00000000.xml
################################################################# End of File.

View file

@ -0,0 +1,569 @@
//////////////////////////////////////////////////////////////////////////////
//
// Detours Test Program (tracebld.cpp of tracebld.exe)
//
// Microsoft Research Detours Package
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.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"
#if (_MSC_VER < 1299)
typedef ULONG * PULONG_PTR;
typedef ULONG ULONG_PTR;
typedef LONG * PLONG_PTR;
typedef LONG LONG_PTR;
#endif
//////////////////////////////////////////////////////////////////////////////
#pragma warning(disable:4127) // Many of our asserts are constants.
#define ASSERT_ALWAYS(x) \
do { \
if (!(x)) { \
AssertMessage(#x, __FILE__, __LINE__); \
DebugBreak(); \
} \
} while (0)
#ifndef NDEBUG
#define ASSERT(x) ASSERT_ALWAYS(x)
#else
#define ASSERT(x)
#endif
#define UNUSED(c) (c) = (c)
//////////////////////////////////////////////////////////////////////////////
enum {
CLIENT_AWAITING_PIPE_ACCEPT = 0x21,
CLIENT_AWAITING_PIPE_DATA = 0x22,
};
typedef struct _CLIENT : OVERLAPPED
{
HANDLE hPipe;
LONG nClient;
HANDLE hFile;
BOOL fAwaitingAccept;
PVOID Zero;
TBLOG_MESSAGE Message;
BOOL LogMessage(PTBLOG_MESSAGE pMessage, DWORD nBytes);
BOOL LogMessageV(PCHAR pszMsg, ...);
} CLIENT, *PCLIENT;
//////////////////////////////////////////////////////////////////////////////
//
CHAR s_szLogFile[MAX_PATH];
CHAR s_szPipe[MAX_PATH];
LONG s_nActiveClients = 0;
LONG s_nTotalClients = 0;
LONGLONG s_llStartTime;
BOOL s_fVerbose = FALSE;
TBLOG_PAYLOAD s_Payload;
//////////////////////////////////////////////////////////////////////////////
//
VOID MyErrExit(PCSTR pszMsg)
{
DWORD error = GetLastError();
fprintf(stderr, "TRACEBLD: Error %ld in %s.\n", error, pszMsg);
fflush(stderr);
exit(1);
}
//////////////////////////////////////////////////////////////////////////////
//
BOOL CLIENT::LogMessageV(PCHAR pszMsg, ...)
{
DWORD cbWritten = 0;
CHAR szBuf[1024];
PCHAR pcchEnd = szBuf + ARRAYSIZE(szBuf) - 2;
PCHAR pcchCur = szBuf;
HRESULT hr;
va_list args;
va_start(args, pszMsg);
hr = StringCchVPrintfExA(pcchCur, pcchEnd - pcchCur,
&pcchCur, NULL, STRSAFE_NULL_ON_FAILURE,
pszMsg, args);
va_end(args);
if (FAILED(hr)) {
goto cleanup;
}
hr = StringCchPrintfExA(pcchCur, szBuf + (ARRAYSIZE(szBuf)) - pcchCur,
&pcchCur, NULL, STRSAFE_NULL_ON_FAILURE,
"\n");
cleanup:
WriteFile(hFile, szBuf, (DWORD)(pcchCur - szBuf), &cbWritten, NULL);
return TRUE;
}
BOOL CLIENT::LogMessage(PTBLOG_MESSAGE pMessage, DWORD nBytes)
{
// Sanity check the size of the message.
//
if (nBytes > pMessage->nBytes) {
nBytes = pMessage->nBytes;
}
if (nBytes >= sizeof(*pMessage)) {
nBytes = sizeof(*pMessage) - 1;
}
// Don't log message if there isn't and message text.
//
DWORD cbWrite = nBytes - offsetof(TBLOG_MESSAGE, szMessage);
if (cbWrite <= 0 ) {
return TRUE;
}
if (s_fVerbose) {
printf("[%s]", pMessage->szMessage);
}
DWORD cbWritten = 0;
WriteFile(hFile, pMessage->szMessage, cbWrite, &cbWritten, NULL);
return TRUE;
}
BOOL CloseConnection(PCLIENT pClient)
{
InterlockedDecrement(&s_nActiveClients);
if (pClient != NULL) {
if (pClient->hPipe != INVALID_HANDLE_VALUE) {
//FlushFileBuffers(pClient->hPipe);
if (!DisconnectNamedPipe(pClient->hPipe)) {
DWORD error = GetLastError();
pClient->LogMessageV("<!-- Error %d in DisconnectNamedPipe. -->\n", error);
}
CloseHandle(pClient->hPipe);
pClient->hPipe = INVALID_HANDLE_VALUE;
}
if (pClient->hFile != INVALID_HANDLE_VALUE) {
CloseHandle(pClient->hFile);
pClient->hFile = INVALID_HANDLE_VALUE;
}
GlobalFree(pClient);
pClient = NULL;
}
return TRUE;
}
// Creates a pipe instance and initiate an accept request.
//
PCLIENT CreatePipeConnection(HANDLE hCompletionPort, LONG nClient)
{
HANDLE hPipe = CreateNamedPipeA(s_szPipe, // pipe name
PIPE_ACCESS_INBOUND | // read-only access
FILE_FLAG_OVERLAPPED, // overlapped mode
PIPE_TYPE_MESSAGE | // message-type pipe
PIPE_READMODE_MESSAGE | // message read mode
PIPE_WAIT, // blocking mode
PIPE_UNLIMITED_INSTANCES, // unlimited instances
0, // output buffer size
0, // input buffer size
20000, // client time-out
NULL); // no security attributes
if (hPipe == INVALID_HANDLE_VALUE) {
MyErrExit("CreateNamedPipe");
}
// Allocate the client data structure.
//
PCLIENT pClient = (PCLIENT) GlobalAlloc(GPTR, sizeof(CLIENT));
if (pClient == NULL) {
MyErrExit("GlobalAlloc pClient");
}
CHAR szLogFile[MAX_PATH];
StringCchPrintfA(szLogFile, ARRAYSIZE(szLogFile), "%s.%08d.xml", s_szLogFile, nClient);
ZeroMemory(pClient, sizeof(*pClient));
pClient->hPipe = hPipe;
pClient->nClient = nClient;
pClient->fAwaitingAccept = TRUE;
pClient->hFile = CreateFileA(szLogFile,
GENERIC_WRITE,
FILE_SHARE_READ,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL |
FILE_FLAG_SEQUENTIAL_SCAN,
NULL);
if (pClient->hFile == INVALID_HANDLE_VALUE) {
fprintf(stderr, "TRACEBLD: Error opening output file: %s: %ld\n\n",
szLogFile, GetLastError());
fflush(stderr);
MyErrExit("CreateFile");
}
// Associate file with our complietion port.
//
if (!CreateIoCompletionPort(pClient->hPipe, hCompletionPort, (ULONG_PTR)pClient, 0)) {
MyErrExit("CreateIoComplietionPort pClient");
}
if (!ConnectNamedPipe(hPipe, pClient)) {
DWORD error = GetLastError();
if (error == ERROR_IO_PENDING) {
return NULL;
}
if (error == ERROR_PIPE_CONNECTED) {
#if 0
pClient->LogMessageV("<!-- ConnectNamedPipe client already connected. -->");
#endif
pClient->fAwaitingAccept = FALSE;
}
else if (error != ERROR_IO_PENDING &&
error != ERROR_PIPE_LISTENING) {
MyErrExit("ConnectNamedPipe");
}
}
else {
fprintf(stderr, "*** ConnectNamedPipe accepted immediately.\n");
#if 0
pClient->LogMessageV("<!-- ConnectNamedPipe accepted immediately. -->");
#endif
pClient->fAwaitingAccept = FALSE;
}
return pClient;
}
BOOL DoRead(PCLIENT pClient)
{
SetLastError(NO_ERROR);
DWORD nBytes = 0;
BOOL b = ReadFile(pClient->hPipe, &pClient->Message, sizeof(pClient->Message),
&nBytes, pClient);
DWORD error = GetLastError();
if (b && error == NO_ERROR) {
return TRUE;
}
if (error == ERROR_BROKEN_PIPE) {
pClient->LogMessageV("<!-- **** ReadFile 002 *** ERROR_BROKEN_PIPE [%d] -->\n", nBytes);
CloseConnection(pClient);
return TRUE;
}
else if (error == ERROR_INVALID_HANDLE) {
// ?
pClient->LogMessageV("<!-- **** ReadFile 002 *** ERROR_INVALID_HANDLE -->\n");
// I have no idea why this happens. Our remedy is to drop the connection.
return TRUE;
}
else if (error != ERROR_IO_PENDING) {
if (b) {
pClient->LogMessageV("<!-- **** ReadFile 002 succeeded: %d -->\n", error);
}
else {
pClient->LogMessageV("<!-- **** ReadFile 002 failed: %d -->\n", error);
}
CloseConnection(pClient);
}
return TRUE;
}
DWORD WINAPI WorkerThread(LPVOID pvVoid)
{
PCLIENT pClient;
BOOL b;
LPOVERLAPPED lpo;
DWORD nBytes;
HANDLE hCompletionPort = (HANDLE)pvVoid;
for (BOOL fKeepLooping = TRUE; fKeepLooping;) {
pClient = NULL;
lpo = NULL;
nBytes = 0;
b = GetQueuedCompletionStatus(hCompletionPort,
&nBytes, (PULONG_PTR)&pClient, &lpo, INFINITE);
if (!b) {
if (pClient) {
if (GetLastError() == ERROR_BROKEN_PIPE) {
pClient->LogMessageV("<!-- Client closed pipe. -->");
}
else {
pClient->LogMessageV("<!-- *** GetQueuedCompletionStatus failed %d -->",
GetLastError());
}
CloseConnection(pClient);
}
continue;
}
if (pClient->fAwaitingAccept) {
BOOL fAgain = TRUE;
while (fAgain) {
LONG nClient = InterlockedIncrement(&s_nTotalClients);
InterlockedIncrement(&s_nActiveClients);
pClient->fAwaitingAccept = FALSE;
PCLIENT pNew = CreatePipeConnection(hCompletionPort, nClient);
fAgain = FALSE;
if (pNew != NULL) {
fAgain = !pNew->fAwaitingAccept;
DoRead(pNew);
}
}
}
else {
if (nBytes <= offsetof(TBLOG_MESSAGE, szMessage)) {
pClient->LogMessageV("</t:Process>\n");
CloseConnection(pClient);
continue;
}
pClient->LogMessage(&pClient->Message, nBytes);
}
DoRead(pClient);
}
return 0;
}
BOOL CreateWorkers(HANDLE hCompletionPort)
{
DWORD dwThread;
HANDLE hThread;
DWORD i;
SYSTEM_INFO SystemInfo;
GetSystemInfo(&SystemInfo);
for (i = 0; i < 1; i++) {
hThread = CreateThread(NULL, 0, WorkerThread, hCompletionPort, 0, &dwThread);
if (!hThread) {
MyErrExit("CreateThread WorkerThread");
// Unreachable: return FALSE;
}
CloseHandle(hThread);
}
return TRUE;
}
DWORD CopyEnvironment(PWCHAR pwzzOut, PCWSTR pwzzIn)
{
PCWSTR pwzzBeg = pwzzOut;
while (*pwzzIn) {
while (*pwzzIn) {
*pwzzOut++ = *pwzzIn++;
}
*pwzzOut++ = *pwzzIn++; // Copy zero.
}
*pwzzOut++ = '\0'; // Add last zero.
return (DWORD)(pwzzOut - pwzzBeg);
}
//////////////////////////////////////////////////////////////////////////////
//
DWORD main(int argc, char **argv)
{
HANDLE hCompletionPort;
BOOL fNeedHelp = FALSE;
WCHAR wzzDrop[1024] = L"build\0nmake\0";
GetSystemTimeAsFileTime((FILETIME *)&s_llStartTime);
StringCchPrintfA(s_szPipe, ARRAYSIZE(s_szPipe), "%s.%d", TBLOG_PIPE_NAME, GetCurrentProcessId());
int arg = 1;
for (; arg < argc && (argv[arg][0] == '-' || argv[arg][0] == '/'); arg++) {
CHAR *argn = argv[arg] + 1;
CHAR *argp = argn;
while (*argp && *argp != ':' && *argp != '=') {
argp++;
}
if (*argp == ':' || *argp == '=') {
*argp++ = '\0';
}
switch (argn[0]) {
case 'd': // Drop Processes
case 'D':
if (*argp) {
PWCHAR pwz = wzzDrop;
while (*argp) {
if (*argp == ';') {
*pwz++ = '\0';
}
else {
*pwz++ = *argp++;
}
}
*pwz++ = '\0';
*pwz = '\0';
}
case 'o': // Output file.
case 'O':
StringCchCopyA(s_szLogFile, ARRAYSIZE(s_szLogFile), argp);
break;
case 'v': // Verbose
case 'V':
s_fVerbose = TRUE;
break;
case '?': // Help.
fNeedHelp = TRUE;
break;
default:
fNeedHelp = TRUE;
printf("TRACEBLD: Bad argument: %s:%s\n", argn, argp);
break;
}
}
if (arg >= argc) {
fNeedHelp = TRUE;
}
if (fNeedHelp) {
printf("Usage:\n"
" tracebld [options] command {command arguments}\n"
"Options:\n"
" /o:file Log all events to the output files.\n"
" /? Display this help message.\n"
"Summary:\n"
" Runs the build commands and figures out which files have dependencies..\n"
"\n");
exit(9001);
}
// Create the completion port.
hCompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, NULL, 0);
if (hCompletionPort == NULL) {
MyErrExit("CreateIoCompletionPort");
}
// Create completion port worker threads.
//
CreateWorkers(hCompletionPort);
CreatePipeConnection(hCompletionPort, 0);
printf("TRACEBLD: Ready for clients. Press Ctrl-C to stop.\n");
/////////////////////////////////////////////////////////// Validate DLLs.
//
CHAR szTmpPath[MAX_PATH];
CHAR szExePath[MAX_PATH];
CHAR szDllPath[MAX_PATH];
PCHAR pszFilePart = NULL;
if (!GetModuleFileNameA(NULL, szTmpPath, ARRAYSIZE(szTmpPath))) {
printf("TRACEBLD: Couldn't retreive exe name.\n");
return 9002;
}
if (!GetFullPathNameA(szTmpPath, ARRAYSIZE(szExePath), szExePath, &pszFilePart) ||
pszFilePart == NULL) {
printf("TRACEBLD: Error: %s is not a valid path name..\n", szTmpPath);
return 9002;
}
StringCchCopyA(pszFilePart, szExePath + ARRAYSIZE(szExePath) - pszFilePart,
"trcbld" DETOURS_STRINGIFY(DETOURS_BITS) ".dll");
StringCchCopyA(szDllPath, ARRAYSIZE(szDllPath), szExePath);
//////////////////////////////////////////////////////////////////////////
STARTUPINFOA si;
PROCESS_INFORMATION pi;
CHAR szCommand[2048];
CHAR szExe[MAX_PATH];
CHAR szFullExe[MAX_PATH] = "\0";
PCHAR pszFileExe = NULL;
ZeroMemory(&si, sizeof(si));
ZeroMemory(&pi, sizeof(pi));
si.cb = sizeof(si);
szCommand[0] = L'\0';
StringCchCopyA(szExe, sizeof(szExe), argv[arg]);
for (; arg < argc; arg++) {
if (strchr(argv[arg], ' ') != NULL || strchr(argv[arg], '\t') != NULL) {
StringCchCatA(szCommand, sizeof(szCommand), "\"");
StringCchCatA(szCommand, sizeof(szCommand), argv[arg]);
StringCchCatA(szCommand, sizeof(szCommand), "\"");
}
else {
StringCchCatA(szCommand, sizeof(szCommand), argv[arg]);
}
if (arg + 1 < argc) {
StringCchCatA(szCommand, sizeof(szCommand), " ");
}
}
printf("TRACEBLD: Starting: `%s'\n", szCommand);
printf("TRACEBLD: with `%s'\n", szDllPath);
fflush(stdout);
DWORD dwFlags = CREATE_DEFAULT_ERROR_MODE | CREATE_SUSPENDED;
SetLastError(0);
SearchPathA(NULL, szExe, ".exe", ARRAYSIZE(szFullExe), szFullExe, &pszFileExe);
if (!DetourCreateProcessWithDllExA(szFullExe[0] ? szFullExe : NULL, szCommand,
NULL, NULL, TRUE, dwFlags, NULL, NULL,
&si, &pi, szDllPath, NULL)) {
printf("TRACEBLD: DetourCreateProcessWithDllEx failed: %ld\n", GetLastError());
ExitProcess(9007);
}
ZeroMemory(&s_Payload, sizeof(s_Payload));
s_Payload.nParentProcessId = GetCurrentProcessId();
s_Payload.nTraceProcessId = GetCurrentProcessId();
s_Payload.nGeneology = 1;
s_Payload.rGeneology[0] = 0;
StringCchCopyW(s_Payload.wzStdin, ARRAYSIZE(s_Payload.wzStdin), L"\\\\.\\CONIN$");
StringCchCopyW(s_Payload.wzStdout, ARRAYSIZE(s_Payload.wzStdout), L"\\\\.\\CONOUT$");
StringCchCopyW(s_Payload.wzStderr, ARRAYSIZE(s_Payload.wzStderr), L"\\\\.\\CONOUT$");
StringCchCopyW(s_Payload.wzParents, ARRAYSIZE(s_Payload.wzParents), L"");
CopyEnvironment(s_Payload.wzzDrop, wzzDrop);
LPWCH pwStrings = GetEnvironmentStringsW();
CopyEnvironment(s_Payload.wzzEnvironment, pwStrings);
FreeEnvironmentStringsW(pwStrings);
if (!DetourCopyPayloadToProcess(pi.hProcess, s_guidTrace,
&s_Payload, sizeof(s_Payload))) {
printf("TRACEBLD: DetourCopyPayloadToProcess failed: %ld\n", GetLastError());
ExitProcess(9008);
}
ResumeThread(pi.hThread);
WaitForSingleObject(pi.hProcess, INFINITE);
DWORD dwResult = 0;
if (!GetExitCodeProcess(pi.hProcess, &dwResult)) {
printf("TRACEBLD: GetExitCodeProcess failed: %ld\n", GetLastError());
return 9008;
}
printf("TRACEBLD: %ld processes.\n", s_nTotalClients);
return dwResult;
}
//
//////////////////////////////////////////////////////////////////////////////

View file

@ -0,0 +1,59 @@
//////////////////////////////////////////////////////////////////////////////
//
// Detours Test Program (tracebld.h of tracebld.exe)
//
// Microsoft Research Detours Package
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
#pragma once
#ifndef _TRACEBLD_H_
#define _TRACEBLD_H_
#include <stdarg.h>
//////////////////////////////////////////////////////////////////////////////
//
//
#define TBLOG_PIPE_NAMEA "\\\\.\\pipe\\tracebuild"
#define TBLOG_PIPE_NAMEW L"\\\\.\\pipe\\tracebuild"
#ifdef UNICODE
#define TBLOG_PIPE_NAME TBLOG_PIPE_NAMEW
#else
#define TBLOG_PIPE_NAME TBLOG_PIPE_NAMEA
#endif
//////////////////////////////////////////////////////////////////////////////
//
typedef struct _TBLOG_MESSAGE
{
DWORD nBytes;
CHAR szMessage[32764]; // 32768 - sizeof(nBytes)
} TBLOG_MESSAGE, *PTBLOG_MESSAGE;
typedef struct _TBLOG_PAYLOAD
{
DWORD nParentProcessId;
DWORD nTraceProcessId;
DWORD nGeneology;
DWORD rGeneology[64];
WCHAR wzParents[256];
WCHAR wzStdin[256];
WCHAR wzStdout[256];
WCHAR wzStderr[256];
BOOL fStdoutAppend;
BOOL fStderrAppend;
WCHAR wzzDrop[1024]; // Like an environment: zero terminated strings with a last zero.
WCHAR wzzEnvironment[32768];
} TBLOG_PAYLOAD, *PTBLOG_PAYLOAD;
// Shared state payload guid.
//
const GUID s_guidTrace = {
0xd8e2dc69, 0x3004, 0x453e,
{0x94, 0x15, 0x19, 0x0e, 0x79, 0xe8, 0x93, 0x52}
};
#endif // _TRACEBLD_H_
//
///////////////////////////////////////////////////////////////// End of File.

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,17 @@
//////////////////////////////////////////////////////////////////////////////
//
// Version information for trcbld.rc.
//
// Microsoft Research Detours Package
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
#include "detver.h"
#define VER_INTERNALNAME_STR "trcbld" DETOURS_STRINGIFY(DETOURS_BITS)
#define VER_ORIGINALFILENAME_STR "trcbld" DETOURS_STRINGIFY(DETOURS_BITS) ".dll"
#define VER_FILEDESCRIPTION_STR "Detours Build Tracing Module"
#define VER_COMPANYNAME_STR "Microsoft Corporation"
#include "common.ver"