/*============================================================================
  CMake - Cross Platform Makefile Generator
  Copyright 2000-2009 Kitware, Inc., Insight Software Consortium

  Distributed under the OSI-approved BSD License (the "License");
  see accompanying file Copyright.txt for details.

  This software is distributed WITHOUT ANY WARRANTY; without even the
  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  See the License for more information.
============================================================================*/
#include "cmWin32ProcessExecution.h"

#include "cmSystemTools.h"

#include <malloc.h>
#include <io.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <windows.h>

#if defined(__BORLANDC__)
#  define STRICMP stricmp
#  define TO_INTPTR(x) ((long)(x))
#endif // Borland
#if defined(_MSC_VER) // Visual studio
#  if ( _MSC_VER >= 1300 )
#    include <stddef.h>
#    define TO_INTPTR(x) ((intptr_t)(x))
#  else // Visual Studio 6
#    define TO_INTPTR(x) ((long)(x))
#  endif // Visual studio .NET
#  define STRICMP _stricmp
#endif // Visual Studio
#if defined(__MINGW32__)
# include <stdint.h>
# define TO_INTPTR(x) ((intptr_t)(x))
# define STRICMP _stricmp
#endif // MinGW

#define POPEN_1 1
#define POPEN_2 2
#define POPEN_3 3
#define POPEN_4 4

#define cmMAX(x,y) (((x)<(y))?(y):(x))

void DisplayErrorMessage()
{
  LPVOID lpMsgBuf;
  FormatMessage(
    FORMAT_MESSAGE_ALLOCATE_BUFFER |
    FORMAT_MESSAGE_FROM_SYSTEM |
    FORMAT_MESSAGE_IGNORE_INSERTS,
    NULL,
    GetLastError(),
    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
    (LPTSTR) &lpMsgBuf,
    0,
    NULL
    );
  // Process any inserts in lpMsgBuf.
  // ...
  // Display the string.
  MessageBox( NULL, (LPCTSTR)lpMsgBuf, "Error", MB_OK | MB_ICONINFORMATION );
  // Free the buffer.
  LocalFree( lpMsgBuf );
}

// Code from a Borland web site with the following explaination :
/* In this article, I will explain how to spawn a console application
 * and redirect its standard input/output using anonymous pipes. An
 * anonymous pipe is a pipe that goes only in one direction (read
 * pipe, write pipe, etc.). Maybe you are asking, "why would I ever
 * need to do this sort of thing?" One example would be a Windows
 * telnet server, where you spawn a shell and listen on a port and
 * send and receive data between the shell and the socket
 * client. (Windows does not really have a built-in remote
 * shell). First, we should talk about pipes. A pipe in Windows is
 * simply a method of communication, often between process. The SDK
 * defines a pipe as "a communication conduit with two ends;
 a process
 * with a handle to one end can communicate with a process having a
 * handle to the other end." In our case, we are using "anonymous"
 * pipes, one-way pipes that "transfer data between a parent process
 * and a child process or between two child processes of the same
 * parent process." It's easiest to imagine a pipe as its namesake. An
 * actual pipe running between processes that can carry data. We are
 * using anonymous pipes because the console app we are spawning is a
 * child process. We use the CreatePipe function which will create an
 * anonymous pipe and return a read handle and a write handle. We will
 * create two pipes, on for stdin and one for stdout. We will then
 * monitor the read end of the stdout pipe to check for display on our
 * child process. Every time there is something availabe for reading,
 * we will display it in our app. Consequently, we check for input in
 * our app and send it off to the write end of the stdin pipe. */

inline bool IsWinNT()
//check if we're running NT
{
  OSVERSIONINFO osv;
  osv.dwOSVersionInfoSize = sizeof(osv);
  GetVersionEx(&osv);
  return (osv.dwPlatformId == VER_PLATFORM_WIN32_NT);
}

//---------------------------------------------------------------------------
bool cmWin32ProcessExecution::BorlandRunCommand(
  const char* command, const char* dir,
  std::string& output, int& retVal, bool verbose, int /* timeout */,
  bool hideWindows)
{
  //verbose = true;
  //std::cerr << std::endl
  //        << "WindowsRunCommand(" << command << ")" << std::endl
  //        << std::flush;
  const int BUFFER_SIZE = 4096;
  char buf[BUFFER_SIZE];

//i/o buffer
  STARTUPINFO si;
  SECURITY_ATTRIBUTES sa;
  SECURITY_DESCRIPTOR sd;

//security information for pipes
  PROCESS_INFORMATION pi;
  HANDLE newstdin,newstdout,read_stdout,write_stdin;

//pipe handles
  if (IsWinNT())
//initialize security descriptor (Windows NT)
    {
    InitializeSecurityDescriptor(&sd,SECURITY_DESCRIPTOR_REVISION);
    SetSecurityDescriptorDacl(&sd, true, NULL, false);
    sa.lpSecurityDescriptor = &sd;

    }
  else sa.lpSecurityDescriptor = NULL;
  sa.nLength = sizeof(SECURITY_ATTRIBUTES);
  sa.bInheritHandle = true;

//allow inheritable handles
  if (!CreatePipe(&newstdin,&write_stdin,&sa,0))
//create stdin pipe
    {
    return false;
    }
  if (!CreatePipe(&read_stdout,&newstdout,&sa,0))
//create stdout pipe
    {
    CloseHandle(newstdin);
    CloseHandle(write_stdin);
    return false;

    }
  GetStartupInfo(&si);

//set startupinfo for the spawned process
  /* The dwFlags member tells CreateProcess how to make the
   * process. STARTF_USESTDHANDLES validates the hStd*
   * members. STARTF_USESHOWWINDOW validates the wShowWindow
   * member. */

  si.cb = sizeof(STARTUPINFO);
  si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
  si.hStdOutput = newstdout;
  si.hStdError = newstdout;
  si.wShowWindow = SW_SHOWDEFAULT;
  if(hideWindows)
    {
    si.wShowWindow = SW_HIDE;
    }

//set the new handles for the child process si.hStdInput = newstdin;
  char* commandAndArgs = strcpy(new char[strlen(command)+1], command);
  if (!CreateProcess(NULL,commandAndArgs,NULL,NULL,TRUE,
                     0, // CREATE_NEW_CONSOLE,
                     NULL,dir,&si,&pi))
    {
    std::cerr << "CreateProcess failed " << commandAndArgs << std::endl;
    CloseHandle(newstdin);
    CloseHandle(newstdout);
    CloseHandle(read_stdout);
    CloseHandle(write_stdin);
    delete [] commandAndArgs;
    return false;

    }
  delete [] commandAndArgs;
  unsigned long exit=0;

//process exit code unsigned
  unsigned long bread;

//bytes read unsigned
  unsigned long avail;

//bytes available
  memset(buf, 0, sizeof(buf));
  for(;;)
//main program loop
    {
    Sleep(10);
//check to see if there is any data to read from stdout
    //std::cout << "Peek for data..." << std::endl;
    PeekNamedPipe(read_stdout,buf,1023,&bread,&avail,NULL);
    if (bread != 0)
      {
      memset(buf, 0, sizeof(buf));
      if (avail > 1023)
        {
        while (bread >= 1023)
          {
          //std::cout << "Read data..." << std::endl;
          ReadFile(read_stdout,buf,1023,&bread,NULL);

          //read the stdout pipe
          memset(buf, 0, sizeof(buf));
          output += buf;
          if (verbose)
            {
            cmSystemTools::Stdout(buf);
            }
          }
        }
      else
        {
        ReadFile(read_stdout,buf,1023,&bread,NULL);
        output += buf;
        if(verbose)
          {
          cmSystemTools::Stdout(buf);
          }

        }

      }

    //std::cout << "Check for process..." << std::endl;
    GetExitCodeProcess(pi.hProcess,&exit);

//while the process is running
    if (exit != STILL_ACTIVE) break;

    }
  WaitForSingleObject(pi.hProcess, INFINITE);
  GetExitCodeProcess(pi.hProcess,&exit);
  CloseHandle(pi.hThread);
  CloseHandle(pi.hProcess);
  CloseHandle(newstdin);

//clean stuff up
  CloseHandle(newstdout);
  CloseHandle(read_stdout);
  CloseHandle(write_stdin);
  retVal = exit;
  return true;

}

bool cmWin32ProcessExecution::StartProcess(
  const char* cmd, const char* path, bool verbose)
{
  this->Initialize();
  this->Verbose = verbose;
  return this->PrivateOpen(cmd, path, _O_RDONLY | _O_TEXT, POPEN_3);
}

bool cmWin32ProcessExecution::Wait(int timeout)
{
  return this->PrivateClose(timeout);
}

static BOOL RealPopenCreateProcess(const char *cmdstring,
                                   const char *path,
                                   const char *szConsoleSpawn,
                                   HANDLE hStdin,
                                   HANDLE hStdout,
                                   HANDLE hStderr,
                                   HANDLE *hProcess,
                                   bool hideWindows,
                                   std::string& output)
{
  PROCESS_INFORMATION piProcInfo;
  STARTUPINFO siStartInfo;
  char *s1=0,*s2=0;
  const char *s3 = " /c ";
  int i = GetEnvironmentVariable("COMSPEC",NULL,0);
  if (i)
    {
    char *comshell;

    s1 = (char *)malloc(i);
    int x = GetEnvironmentVariable("COMSPEC", s1, i);
    if (!x)
      {
      free(s1);
      return x;
      }

    /* Explicitly check if we are using COMMAND.COM.  If we are
     * then use the w9xpopen hack.
     */
    comshell = s1 + x;
    while (comshell >= s1 && *comshell != '\\')
      --comshell;
    ++comshell;

    if (GetVersion() < 0x80000000 &&
        STRICMP(comshell, "command.com") != 0)
      {
      /* NT/2000 and not using command.com. */
      x = i + (int)strlen(s3) + (int)strlen(cmdstring) + 1;
      s2 = (char *)malloc(x);
      ZeroMemory(s2, x);
      //sprintf(s2, "%s%s%s", s1, s3, cmdstring);
      sprintf(s2, "%s", cmdstring);
      }
    else
      {
      /*
       * Oh gag, we're on Win9x or using COMMAND.COM. Use
       * the workaround listed in KB: Q150956
       */
      char modulepath[_MAX_PATH];
      struct stat statinfo;
      GetModuleFileName(NULL, modulepath, sizeof(modulepath));
      for (i = x = 0; modulepath[i]; i++)
        if (modulepath[i] == '\\')
          x = i+1;
      modulepath[x] = '\0';
      /* Create the full-name to w9xpopen, so we can test it exists */
      strncat(modulepath,
              szConsoleSpawn,
              (sizeof(modulepath)/sizeof(modulepath[0]))
              -strlen(modulepath));
      if (stat(modulepath, &statinfo) != 0)
        {
          /* Eeek - file-not-found - possibly an embedding
             situation - see if we can locate it in sys.prefix
          */
        strncpy(modulepath,
                ".",
                sizeof(modulepath)/sizeof(modulepath[0]));
        if (modulepath[strlen(modulepath)-1] != '\\')
          strcat(modulepath, "\\");
        strncat(modulepath,
                szConsoleSpawn,
                (sizeof(modulepath)/sizeof(modulepath[0]))
                -strlen(modulepath));
        /* No where else to look - raise an easily identifiable
           error, rather than leaving Windows to report
           "file not found" - as the user is probably blissfully
           unaware this shim EXE is used, and it will confuse them.
           (well, it confused me for a while ;-)
        */
        if (stat(modulepath, &statinfo) != 0)
          {
          std::cout
            << "Can not locate '" << modulepath
            << "' which is needed "
            "for popen to work with your shell "
            "or platform." << std::endl;
          free(s1);
          free(s2);
          return FALSE;
          }
        }
      x = i + (int)strlen(s3) + (int)strlen(cmdstring) + 1 +
        (int)strlen(modulepath) +
        (int)strlen(szConsoleSpawn) + 1;
      if(s2)
        {
        free(s2);
        }
      s2 = (char *)malloc(x);
      ZeroMemory(s2, x);
      sprintf(
        s2,
        "%s %s%s%s",
        modulepath,
        s1,
        s3,
        cmdstring);
      sprintf(
        s2,
        "%s %s",
        modulepath,
        cmdstring);
      }
    }

  /* Could be an else here to try cmd.exe / command.com in the path
     Now we'll just error out.. */
  else
    {
    std::cout << "Cannot locate a COMSPEC environment variable to "
              << "use as the shell" << std::endl;
    free(s2);
    free(s1);
    return FALSE;
    }

  ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
  siStartInfo.cb = sizeof(STARTUPINFO);
  siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
  siStartInfo.hStdInput = hStdin;
  siStartInfo.hStdOutput = hStdout;
  siStartInfo.hStdError = hStderr;
  siStartInfo.wShowWindow = SW_SHOWDEFAULT;
  if(hideWindows)
    {
    siStartInfo.wShowWindow = SW_HIDE;
    }

  //std::cout << "Create process: " << s2 << std::endl;
  if (CreateProcess(NULL,
                    s2,
                    NULL,
                    NULL,
                    TRUE,
                    0, //CREATE_NEW_CONSOLE,
                    NULL,
                    path,
                    &siStartInfo,
                    &piProcInfo) )
    {
    /* Close the handles now so anyone waiting is woken. */
    CloseHandle(piProcInfo.hThread);
    /* Return process handle */
    *hProcess = piProcInfo.hProcess;
    //std::cout << "Process created..." << std::endl;
    free(s2);
    free(s1);
    return TRUE;
    }

  output += "CreateProcessError: ";
  {
  /* Format the error message.  */
  char message[1024];
  DWORD original = GetLastError();
  DWORD length = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
                               FORMAT_MESSAGE_IGNORE_INSERTS, 0, original,
                               MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                               message, 1023, 0);
  if(length < 1)
    {
    /* FormatMessage failed.  Use a default message.  */
    _snprintf(message, 1023,
              "Process execution failed with error 0x%X.  "
              "FormatMessage failed with error 0x%X",
              original, GetLastError());
    }
  output += message;
  }
  output += "\n";
  output += "for command: ";
  output += s2;
  if(path)
    {
    output += "\nin dir: ";
    output += path;
    }
  output += "\n";
  free(s2);
  free(s1);
  return FALSE;
}

/* The following code is based off of KB: Q190351 */

bool cmWin32ProcessExecution::PrivateOpen(const char *cmdstring,
                                          const char* path,
                                          int mode,
                                          int n)
{
  HANDLE hProcess;

  SECURITY_ATTRIBUTES saAttr;
  BOOL fSuccess;
  int fd1, fd2, fd3;
  this->hChildStdinRd = 0;
  this->hChildStdinWr = 0;
  this->hChildStdoutRd = 0;
  this->hChildStdoutWr = 0;
  this->hChildStderrRd = 0;
  this->hChildStderrWr = 0;
  this->hChildStdinWrDup = 0;
  this->hChildStdoutRdDup = 0;
  this->hChildStderrRdDup = 0;

  saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
  saAttr.bInheritHandle = TRUE;
  saAttr.lpSecurityDescriptor = NULL;

  fd1 = 0;
  fd2 = 0;
  fd3 = 0;

  if (!CreatePipe(&this->hChildStdinRd, &this->hChildStdinWr, &saAttr, 0))
    {
    this->Output += "CreatePipeError\n";
    return false;
    }

  /* Create new output read handle and the input write handle. Set
   * the inheritance properties to FALSE. Otherwise, the child inherits
   * these handles; resulting in non-closeable handles to the pipes
   * being created. */
  fSuccess = DuplicateHandle(GetCurrentProcess(), this->hChildStdinWr,
                             GetCurrentProcess(), &this->hChildStdinWrDup, 0,
                             FALSE,
                             DUPLICATE_SAME_ACCESS);
  if (!fSuccess)
    {
    this->Output += "DuplicateHandleError\n";
    return false;
    }


  /* Close the inheritable version of ChildStdin
     that we're using. */
  CloseHandle(hChildStdinWr);

  if (!CreatePipe(&this->hChildStdoutRd, &this->hChildStdoutWr, &saAttr, 0))
    {
    this->Output += "CreatePipeError\n";
    return false;
    }

  fSuccess = DuplicateHandle(GetCurrentProcess(), this->hChildStdoutRd,
                             GetCurrentProcess(), &this->hChildStdoutRdDup, 0,
                             FALSE, DUPLICATE_SAME_ACCESS);
  if (!fSuccess)
    {
    this->Output += "DuplicateHandleError\n";
    return false;
    }

  /* Close the inheritable version of ChildStdout
     that we're using. */
  CloseHandle(hChildStdoutRd);

  if (n != POPEN_4)
    {
    if (!CreatePipe(&this->hChildStderrRd, &this->hChildStderrWr, &saAttr, 0))
      {
      this->Output += "CreatePipeError\n";
      return false;
      }
   fSuccess = DuplicateHandle(GetCurrentProcess(),
                              this->hChildStderrRd,
                              GetCurrentProcess(),
                              &this->hChildStderrRdDup, 0,
                              FALSE, DUPLICATE_SAME_ACCESS);
    if (!fSuccess)
      {
      this->Output += "DuplicateHandleError\n";
      return false;
      }
    /* Close the inheritable version of ChildStdErr that we're using. */
    CloseHandle(hChildStderrRd);

    }

  switch (n)
    {
    case POPEN_1:
      switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY))
        {
        case _O_WRONLY | _O_TEXT:
          /* Case for writing to child Stdin in text mode. */
          fd1 = _open_osfhandle(TO_INTPTR(this->hChildStdinWrDup), mode);
          /* We don't care about these pipes anymore,
             so close them. */
          break;

        case _O_RDONLY | _O_TEXT:
          /* Case for reading from child Stdout in text mode. */
          fd1 = _open_osfhandle(TO_INTPTR(this->hChildStdoutRdDup), mode);
          /* We don't care about these pipes anymore,
             so close them. */
          break;

        case _O_RDONLY | _O_BINARY:
          /* Case for readinig from child Stdout in
             binary mode. */
          fd1 = _open_osfhandle(TO_INTPTR(this->hChildStdoutRdDup), mode);
          /* We don't care about these pipes anymore,
             so close them. */
          break;

        case _O_WRONLY | _O_BINARY:
          /* Case for writing to child Stdin in binary mode. */
          fd1 = _open_osfhandle(TO_INTPTR(this->hChildStdinWrDup), mode);
          /* We don't care about these pipes anymore,
             so close them. */
          break;
        }
      break;

    case POPEN_2:
    case POPEN_4:
      //if ( 1 )
        {
        fd1 = _open_osfhandle(TO_INTPTR(this->hChildStdinWrDup), mode);
        fd2 = _open_osfhandle(TO_INTPTR(this->hChildStdoutRdDup), mode);
        break;
        }

    case POPEN_3:
      //if ( 1)
        {
        fd1 = _open_osfhandle(TO_INTPTR(this->hChildStdinWrDup), mode);
        fd2 = _open_osfhandle(TO_INTPTR(this->hChildStdoutRdDup), mode);
        fd3 = _open_osfhandle(TO_INTPTR(this->hChildStderrRdDup), mode);
        break;
        }
    }

  if (n == POPEN_4)
    {
    if (!RealPopenCreateProcess(cmdstring,
                                path,
                                this->ConsoleSpawn.c_str(),
                                this->hChildStdinRd,
                                this->hChildStdoutWr,
                                this->hChildStdoutWr,
                                &hProcess, this->HideWindows,
                                this->Output))
      {
      if(fd1 >= 0)
        {
        close(fd1);
        }
      if(fd2 >= 0)
        {
        close(fd2);
        }
      if(fd3 >= 0)
        {
        close(fd3);
        }
      return 0;
      }
    }
  else
    {
    if (!RealPopenCreateProcess(cmdstring,
                                path,
                                this->ConsoleSpawn.c_str(),
                                this->hChildStdinRd,
                                this->hChildStdoutWr,
                                this->hChildStderrWr,
                                &hProcess, this->HideWindows,
                                this->Output))
      {
      if(fd1 >= 0)
        {
        close(fd1);
        }
      if(fd2 >= 0)
        {
        close(fd2);
        }
      if(fd3 >= 0)
        {
        close(fd3);
        }
      return 0;
      }
    }

  /* Child is launched. Close the parents copy of those pipe
   * handles that only the child should have open.  You need to
   * make sure that no handles to the write end of the output pipe
   * are maintained in this process or else the pipe will not close
   * when the child process exits and the ReadFile will hang. */
  this->ProcessHandle = hProcess;
  if ( fd1 >= 0 )
    {
    this->pStdIn = fd1;
    }
  if ( fd2 >= 0 )
    {
    this->pStdOut = fd2;
    }
  if ( fd3 >= 0 )
    {
    this->pStdErr = fd3;
    }

  return true;
}

bool cmWin32ProcessExecution::CloseHandles()
{
  if(this->pStdErr != -1 )
    {
    // this will close this as well: this->hChildStderrRdDup
    _close(this->pStdErr);
    this->pStdErr = -1;
    this->hChildStderrRdDup = 0;
    }
  if(this->pStdIn != -1 )
    {
    // this will close this as well: this->hChildStdinWrDup
    _close(this->pStdIn);
    this->pStdIn = -1;
    this->hChildStdinWrDup = 0;
    }
  if(this->pStdOut != -1 )
    {
    // this will close this as well: this->hChildStdoutRdDup
    _close(this->pStdOut);
    this->pStdOut = -1;
    this->hChildStdoutRdDup = 0;
    }

  bool ret = true;
  if (this->hChildStdinRd && !CloseHandle(this->hChildStdinRd))
    {
    ret = false;
    }
  this->hChildStdinRd = 0;
  // now close these two
  if (this->hChildStdoutWr && !CloseHandle(this->hChildStdoutWr))
    {
    ret = false;
    }
  this->hChildStdoutWr = 0;
  if (this->hChildStderrWr && !CloseHandle(this->hChildStderrWr))
    {
    ret = false;
    }
  this->hChildStderrWr = 0;
  return ret;
}
cmWin32ProcessExecution::~cmWin32ProcessExecution()
{
  this->CloseHandles();
}

bool cmWin32ProcessExecution::PrivateClose(int /* timeout */)
{
  HANDLE hProcess = this->ProcessHandle;

  int result = -1;
  DWORD exit_code;

  std::string output = "";
  bool done = false;
  while(!done)
    {
    Sleep(10);
    bool have_some = false;
    struct _stat fsout;
    struct _stat fserr;
    int rout = _fstat(this->pStdOut, &fsout);
    int rerr = _fstat(this->pStdErr, &fserr);
    if ( rout && rerr )
      {
      break;
      }
    if (fserr.st_size > 0)
      {
      char buffer[1024];
      int len = read(this->pStdErr, buffer, 1023);
      buffer[len] = 0;
      if ( this->Verbose )
        {
        cmSystemTools::Stdout(buffer);
        }
      output += buffer;
      have_some = true;
      }
    if (fsout.st_size > 0)
      {
      char buffer[1024];
      int len = read(this->pStdOut, buffer, 1023);
      buffer[len] = 0;
      if ( this->Verbose )
        {
        cmSystemTools::Stdout(buffer);
        }
      output += buffer;
      have_some = true;
      }
    unsigned long exitCode;
    if ( ! have_some )
      {
      GetExitCodeProcess(hProcess,&exitCode);
      if (exitCode != STILL_ACTIVE)
        {
        break;
        }
      }
    }


  if (WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
      GetExitCodeProcess(hProcess, &exit_code))
    {
    result = exit_code;
    }
  else
    {
    /* Indicate failure - this will cause the file object
     * to raise an I/O error and translate the last Win32
     * error code from errno.  We do have a problem with
     * last errors that overlap the normal errno table,
     * but that's a consistent problem with the file object.
     */
    if (result != EOF)
      {
      /* If the error wasn't from the fclose(), then
       * set errno for the file object error handling.
       */
      errno = GetLastError();
      }
    result = -1;
    }

  /* Free up the native handle at this point */
  CloseHandle(hProcess);
  this->ExitValue = result;
  this->Output += output;
  bool ret = this->CloseHandles();
  if ( result < 0 || !ret)
    {
    return false;
    }
  return true;
}

int cmWin32ProcessExecution::Windows9xHack(const char* command)
{
  BOOL bRet;
  STARTUPINFO si;
  PROCESS_INFORMATION pi;
  DWORD exit_code=0;

  if (!command)
    {
    cmSystemTools::Error("Windows9xHack: Command not specified");
    return 1;
  }

  /* Make child process use this app's standard files. */
  ZeroMemory(&si, sizeof si);
  si.cb = sizeof si;
  si.dwFlags = STARTF_USESTDHANDLES;
  si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
  si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
  si.hStdError = GetStdHandle(STD_ERROR_HANDLE);


  char * app = 0;
  char* cmd = new char[ strlen(command) + 1 ];
  strcpy(cmd, command);

  bRet = CreateProcess(
    app, cmd,
    0, 0,
    TRUE, 0,
    0, 0,
    &si, &pi
    );
  delete [] cmd;

  if (bRet)
    {
    if (WaitForSingleObject(pi.hProcess, INFINITE) != WAIT_FAILED)
      {
      GetExitCodeProcess(pi.hProcess, &exit_code);
      }
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);
    return exit_code;
    }

  return 1;
}
