/*==LICENSE==* CyanWorlds.com Engine - MMOG client, server and tools Copyright (C) 2011 Cyan Worlds, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . You can contact Cyan Worlds, Inc. by email legal@cyan.com or by snail mail at: Cyan Worlds, Inc. 14617 N Newport Hwy Mead, WA 99021 *==LICENSE==*/ /***************************************************************************** * * $/Plasma20/Sources/Plasma/NucleusLib/pnCrashExe/Win32/pnCreMail.cpp * ***/ #include "../Pch.h" #pragma hdrstop //============================================================================ namespace Crash { //============================================================================ /***************************************************************************** * * Local functions * ***/ //============================================================================ static bool CreateInheritablePipe ( HANDLE * read, HANDLE * write, bool inheritRead ) { // create pipe for std error read/write if (!CreatePipe(read, write, (LPSECURITY_ATTRIBUTES) NULL, 0)) return false; // make the appropriate handle inheritable HANDLE hProcess = GetCurrentProcess(); HANDLE * inherit = inheritRead ? read : write; bool result = DuplicateHandle( hProcess, *inherit, hProcess, inherit, 0, true, // make inheritable DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS ); if (!result) return false; return true; } /***************************************************************************** * * Module functions * ***/ //============================================================================ void CrashSendEmail ( const char smtp[], const char sender[], const char recipients[], const char replyTo[], const char username[], const char password[], const char programName[], const char errorType[], const char logBuffer[] ) { enum { IN_CHILD, IN_PARENT, NUM_PIPES }; unsigned i; HANDLE pipes[NUM_PIPES]; for (i = 0; i < arrsize(pipes); ++i) pipes[i] = INVALID_HANDLE_VALUE; for (;;) { // create pipes for Server -> StdIn -> Client if (!CreateInheritablePipe(&pipes[IN_CHILD], &pipes[IN_PARENT], true)) break; char subject[512]; StrPrintf( subject, arrsize(subject), "\"[Crash] %s, %s\"", programName, errorType ); char cmdLine[512]; StrPrintf( cmdLine, arrsize(cmdLine), "plMail.exe -smtp %s -sender %s", smtp, sender ); if (replyTo && replyTo[0]) { StrPack(cmdLine, " -replyTo ", arrsize(cmdLine)); StrPack(cmdLine, replyTo, arrsize(cmdLine)); } if (username && username[0]) { StrPack(cmdLine, " -u ", arrsize(cmdLine)); StrPack(cmdLine, username, arrsize(cmdLine)); } if (password && password[0]) { StrPack(cmdLine, " -p ", arrsize(cmdLine)); StrPack(cmdLine, password, arrsize(cmdLine)); } StrPack(cmdLine, " ", arrsize(cmdLine)); StrPack(cmdLine, recipients, arrsize(cmdLine)); StrPack(cmdLine, " ", arrsize(cmdLine)); StrPack(cmdLine, subject, arrsize(cmdLine)); // create process STARTUPINFO si; ZERO(si); si.cb = sizeof(si); si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; si.wShowWindow = SW_HIDE; si.hStdInput = pipes[IN_CHILD]; si.hStdOutput = INVALID_HANDLE_VALUE; si.hStdError = INVALID_HANDLE_VALUE; PROCESS_INFORMATION pi; BOOL result = CreateProcess( NULL, cmdLine, (LPSECURITY_ATTRIBUTES) NULL, (LPSECURITY_ATTRIBUTES) NULL, true, // => inherit handles NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi ); if (!result) break; CloseHandle(pi.hProcess); CloseHandle(pi.hThread); // Write output data DWORD written, length = StrLen(logBuffer); WriteFile(pipes[IN_PARENT], logBuffer, length, &written, NULL); // complete break; } // cleanup pipes for (i = 0; i < arrsize(pipes); ++i) { if (pipes[i] != INVALID_HANDLE_VALUE) CloseHandle(pipes[i]); } } //============================================================================ } // namespace Crash //============================================================================