Cloned library of VTK-5.0.0 with extra build files for internal package management.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

171 lines
4.9 KiB

/*=========================================================================
Program: Visualization Toolkit
Module: $RCSfile: vtkWin32ProcessOutputWindow.cxx,v $
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
#include "vtkWin32ProcessOutputWindow.h"
#include "vtkObjectFactory.h"
#include "vtkWindows.h"
#include <vtkstd/string>
#ifndef _MAX_FNAME
# define _MAX_FNAME 4096
#endif
#ifndef _MAX_PATH
# define _MAX_PATH 4096
#endif
vtkCxxRevisionMacro(vtkWin32ProcessOutputWindow, "$Revision: 1.5 $");
vtkStandardNewMacro(vtkWin32ProcessOutputWindow);
extern "C" int vtkEncodedArrayWin32OutputWindowProcessWrite(const char* fname);
//----------------------------------------------------------------------------
vtkWin32ProcessOutputWindow::vtkWin32ProcessOutputWindow()
{
this->OutputPipe = 0;
this->Broken = 0;
this->Count = 0;
}
//----------------------------------------------------------------------------
vtkWin32ProcessOutputWindow::~vtkWin32ProcessOutputWindow()
{
if(this->OutputPipe)
{
CloseHandle(this->OutputPipe);
}
}
//----------------------------------------------------------------------------
void vtkWin32ProcessOutputWindow::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os, indent);
}
//----------------------------------------------------------------------------
void vtkWin32ProcessOutputWindow::DisplayText(const char* text)
{
// Display the text if the pipe has not been broken.
if(!this->Broken && text)
{
const char* begin = text;
while(const char* end = strchr(begin, '\n'))
{
this->Write(begin, end-begin);
this->Write("\r\n", 2);
begin = end+1;
}
this->Write(begin, strlen(begin));
}
}
//----------------------------------------------------------------------------
int vtkWin32ProcessOutputWindow::Initialize()
{
// Write the executable as a temporary file. It will delete itself.
char exeName[_MAX_FNAME+1] = "";
char tempDir[_MAX_PATH+1] = "";
// We will try putting the executable in the system temp directory.
// Note that the returned path already has a trailing slash.
DWORD length = GetTempPath(_MAX_PATH+1, tempDir);
if(length <= 0 || length > _MAX_PATH)
{
return 0;
}
// Construct the executable name from the process id, pointer to
// this output window instance, and a count. This should be unique.
sprintf(exeName, "vtkWin32OWP_%u_%p_%u.exe",
GetCurrentProcessId(), this, this->Count++);
// Allocate a buffer to hold the executable path.
size_t tdlen = strlen(tempDir);
char* exeFullPath = (char*)malloc(tdlen + strlen(exeName) + 2);
if(!exeFullPath)
{
return 0;
}
// Construct the full path to the executable.
sprintf(exeFullPath, "%s%s", tempDir, exeName);
// Try to write the executable to disk.
if(!vtkEncodedArrayWin32OutputWindowProcessWrite(exeFullPath))
{
free(exeFullPath);
return 0;
}
// Create a process and a pipe connected to its stdin.
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
si.dwFlags |= STARTF_USESHOWWINDOW;
si.dwFlags |= STARTF_USESTDHANDLES;
si.wShowWindow = SW_SHOWDEFAULT;
// Create a pipe with an inherited read end.
if(!CreatePipe(&si.hStdInput, &this->OutputPipe, 0, 0) ||
!DuplicateHandle(GetCurrentProcess(), si.hStdInput,
GetCurrentProcess(), &si.hStdInput,
0, TRUE, DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE))
{
DeleteFile(exeFullPath);
free(exeFullPath);
return 0;
}
// Create the child process.
if(!CreateProcess(0, exeFullPath, 0, 0, TRUE,
NORMAL_PRIORITY_CLASS, 0, 0, &si, &pi))
{
DeleteFile(exeFullPath);
free(exeFullPath);
CloseHandle(si.hStdInput);
return 0;
}
// We only need to keep the pipe write end. Close all other handles.
CloseHandle(si.hStdInput);
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
free(exeFullPath);
return 1;
}
//----------------------------------------------------------------------------
void vtkWin32ProcessOutputWindow::Write(const char* data, int length)
{
if(data && length)
{
// Initialize the output pipe the first time.
if(this->Broken || !this->OutputPipe && !this->Initialize())
{
this->Broken = 1;
return;
}
// Write the data to the pipe. If it breaks, close the pipe.
DWORD nWritten;
if(!WriteFile(this->OutputPipe, data, length, &nWritten, 0))
{
this->Broken = 1;
CloseHandle(this->OutputPipe);
this->OutputPipe = 0;
}
}
}