Exemple #1
0
static int SysRunCommandPipe( const char *cmd, HFILE *readpipe )
{
    HFILE       pipe_input;
    HFILE       pipe_output;
    HFILE       std_output;
    HFILE       std_error;
    char        *cmdnam;
    char        *sp;
    int         rc;

    cmdnam = strdup( cmd );
    if( cmdnam == NULL )
        return( -1 );
    sp = strchr( cmdnam, ' ' );
    if( sp != NULL ) {
        *sp = '\0';
        sp++;
    }
    rc = -1;
    std_output = 1;
    std_error  = 2;
    if( DosCreatePipe( readpipe, &pipe_output, BUFSIZE ) == 0 ) {
        if( DosDupHandle( pipe_output, &std_output ) == 0 ) {
            if( DosDupHandle( pipe_output, &std_error ) == 0 ) {
                DosClose( pipe_output );
                rc = spawnl( P_NOWAIT, cmdnam, cmdnam, sp, NULL );
                DosClose( std_output );
                DosClose( std_error );
            }
        }
    }
    free( cmdnam );
    return( rc );
}
Exemple #2
0
/*
 * Save standard I/O handles prior to redirection processing.  'select'
 * is a flag mask that specifies which of the standard handles are
 * marked for safekeeping.
 */
static ELVBOOL
SaveStdIOHandles (SAVE_IO save, int select)
{
  /* Establish default values for error recovery. */
  save[0] = save[1] = save[2] = ~0;

    /*
     * Make copies of the selected standard I/O handles and mark the
     * copies so that child processes will not inherit them.
     */
  if (select & SAVE_STDIN)
    {
      if (DosDupHandle (0, &save[0]) != NO_ERROR)
        {
          goto Error;
        }
      if (DosSetFHState (save[0], OPEN_FLAGS_NOINHERIT) != NO_ERROR)
        {
          goto Error;
        }
    }

  if (select & SAVE_STDOUT)
    {
      if (DosDupHandle (1, &save[1]) != NO_ERROR)
        {
          goto Error;
        }
      if (DosSetFHState (save[1], OPEN_FLAGS_NOINHERIT) != NO_ERROR)
        {
          goto Error;
        }
    }

  if (select & SAVE_STDERR)
    {
      if (DosDupHandle (2, &save[2]) != NO_ERROR)
        {
          goto Error;
        }
      if (DosSetFHState (save[2], OPEN_FLAGS_NOINHERIT) != NO_ERROR)
        {
          goto Error;
        }
    }

  /* Success. */
  return ElvTrue;

Error:
  /* Restore any handles we have managed to save. */
  RestoreStdIOHandles (save);
  msg (MSG_ERROR, "can't save stdio handle");
  return ElvFalse;
}
static int redirect_and_run(HFILE local, HFILE remote, int stream, char* command)
{
	int rc = 0;
	HFILE save_pipe = (HFILE)-1;

	set_inherit(local, 0);
	set_inherit(stream, 1);

	do
	{
		rc = DosDupHandle(stream, &save_pipe);

		if(rc)
			break;

		set_inherit(save_pipe, 0);

		HFILE hTmp = stream;

		rc = DosDupHandle(remote, &hTmp);

		if(rc)
			break;

		rc = DosClose(remote);

		if(rc)
			break;

		rc = run(command);

		if(rc)
			break;
	}
	while(0);

	if(save_pipe != -1)
	{
		int rc = 0;
		HFILE hTmp = stream;

		rc = DosDupHandle(save_pipe, &hTmp);
		rc = DosClose(save_pipe);
	}

	return rc;
}
Exemple #4
0
_WCRTLINK int dup2( int handle1, int handle2 )
{
    APIRET  rc;

    __handle_check( handle1, -1 );

    if( handle1 == handle2 ) {
        return( handle2 );
    }
    rc = DosDupHandle( handle1, (PHFILE)&handle2 );
    if( rc != 0 ) {
        return( __set_errno_dos( rc ) );
    }
    __SetIOMode( handle2, __GetIOMode( handle1 ) );
    return( 0 );    /* indicate success */
}
Exemple #5
0
/*
 * Restore I/O handles saved by SaveStdIOHandles().
 */
static void
RestoreStdIOHandles (SAVE_IO save)
{
  HFILE fd;
  int i;

  /*
   * Restore any saved I/O handles in 'save'.  If the filesystem
   * calls fail, there's no easy way to recover.
   */
  for (i = 0; i < 3; i++)
    {
      if (save[i] != ~0)
        {
          fd = i;
          DosDupHandle (save[i], &fd);
          DosClose (save[i]);
          save[i] = ~0;
        }
    }
}
Exemple #6
0
static apr_status_t file_dup(apr_file_t **new_file, apr_file_t *old_file, apr_pool_t *p)
{
    int rv;
    apr_file_t *dup_file;

    if (*new_file == NULL) {
        dup_file = (apr_file_t *)apr_palloc(p, sizeof(apr_file_t));

        if (dup_file == NULL) {
            return APR_ENOMEM;
        }

        dup_file->filedes = -1;
    } else {
      dup_file = *new_file;
    }

    dup_file->pool = p;
    rv = DosDupHandle(old_file->filedes, &dup_file->filedes);

    if (rv) {
        return APR_FROM_OS_ERROR(rv);
    }

    dup_file->fname = apr_pstrdup(dup_file->pool, old_file->fname);
    dup_file->buffered = old_file->buffered;
    dup_file->isopen = old_file->isopen;
    dup_file->flags = old_file->flags & ~APR_INHERIT;
    dup_file->ungetchar = old_file->ungetchar;
    /* TODO - dup pipes correctly */
    dup_file->pipe = old_file->pipe;

    if (*new_file == NULL) {
        apr_pool_cleanup_register(dup_file->pool, dup_file, apr_file_cleanup,
                            apr_pool_cleanup_null);
        *new_file = dup_file;
    }

    return APR_SUCCESS;
}
Exemple #7
0
static int CreatePipeChild(PID& pid, HPIPE& hfPipe, char *Command) {
  static int PCount = 0;
  char  szPipe[32];
  char  FailBuf[256];
  char *Args;
  int   arglen = 0;
  char *Prog;
  RESULTCODES rc_code;
  ULONG ulAction;

  // ULONG ulNew;
  HPIPE hfChildPipe;
  HFILE hfNewStdOut = (HFILE)-1, hfNewStdErr = (HFILE)-1;
  HFILE hfStdOut    = 1, hfStdErr = 2;
  int   rc;

  sprintf(szPipe, "\\PIPE\\eFTE%d\\CHILD%d", getpid(), PCount);
  PCount++;

  rc = DosCreateNPipe(szPipe, &hfPipe,
                      NP_NOINHERIT | NP_ACCESS_INBOUND,
                      NP_NOWAIT | NP_TYPE_BYTE | NP_READMODE_BYTE | 1,
                      0, 4096, 0);

  if (rc != 0) return -1;

  rc = DosConnectNPipe(hfPipe);

  if ((rc != 0) && (rc != ERROR_PIPE_NOT_CONNECTED)) {
    DosClose(hfPipe);
    return -1;
  }

  rc = DosSetNPHState(hfPipe, NP_WAIT | NP_READMODE_BYTE);

  if (rc != 0) {
    DosClose(hfPipe);
    return -1;
  }

  rc = DosOpen(szPipe, &hfChildPipe, &ulAction, 0,
               FILE_NORMAL,
               OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_FAIL_IF_NEW,
               OPEN_ACCESS_WRITEONLY | OPEN_SHARE_DENYREADWRITE,
               NULL);

  if (rc != 0) {
    DosClose(hfPipe);
    return -1;
  }

  // Duplicate handles
  DosDupHandle(hfStdOut, &hfNewStdOut);
  DosDupHandle(hfStdErr, &hfNewStdErr);

  // Close existing handles for current process
  DosClose(hfStdOut);
  DosClose(hfStdErr);

  // Redirect existing handles to new file
  DosDupHandle(hfChildPipe, &hfStdOut);
  DosDupHandle(hfChildPipe, &hfStdErr);

  // Let started program inherit handles from parent

  Prog = getenv("COMSPEC");

  Args = (char *)malloc(strlen(Prog) + 1
                        + 3 + strlen(Command) + 1
                        + 1);

  if (Args == NULL) {
    DosClose(hfPipe);
    return -1;
  }

  strcpy(Args,          Prog);
  arglen = strlen(Args) + 1;
  strcpy(Args + arglen, "/c ");
  arglen += 3;
  strcpy(Args + arglen, Command);
  arglen      += strlen(Command) + 1;
  Args[arglen] = '\0';

  rc = DosExecPgm(FailBuf, sizeof(FailBuf),
                  EXEC_ASYNCRESULT, // | EXEC_BACKGROUND,
                  Args,
                  0,
                  &rc_code,
                  Prog);

  free(Args);

  // Get back original handles
    DosDupHandle(hfNewStdOut, &hfStdOut);
    DosDupHandle(hfNewStdErr, &hfStdErr);

  // Close the duplicated handles - no longer needed
    DosClose(hfNewStdOut);
    DosClose(hfNewStdErr);

    DosClose(hfChildPipe); // pipe one way, close out write end

  if (rc != 0) {
    DosClose(hfPipe);
    return -1;
  }

  pid = rc_code.codeTerminate; // get pid when successful

  return 0;
}
int main(int argc, char * argv[])
{
	int i;
	char cmdLine[CCHMAXPATH*4]={0};
	char cmdLineBuff[CCHMAXPATH*4];
	char * chrPtr;
	HWND hwndNotify;
	char exeName[CCHMAXPATH];//"g:\\projects_working\\audiocpy\\show.exe";
	char chrError[CCHMAXPATH];
	char logName[CCHMAXPATH];
	RESULTCODES resultCodes;
	ULONG rc,ulAction;
	HFILE hf,hfNew;

    if(argc<3) {
      message();
      exit(-1);
    }
	
    hwndNotify=atol(argv[1]);

	sprintf(exeName,"%s",argv[2]);
	sprintf(logName,"%s\\Logfiles\\write.log",argv[3]);
	
	sprintf(cmdLine,exeName);
	chrPtr=strrchr(cmdLine,0);
	chrPtr++;

	/* Build parameters */
    for(i=4;i<argc;i++) {
      sprintf(cmdLineBuff,"%s",chrPtr);
      sprintf(chrPtr,"%s %s",cmdLineBuff,argv[i]);
    }
    /* Replace ' with " */
    changeChar(chrPtr,'\'','\"');

    /* Replace ^ with space */
    changeChar(chrPtr,'^',' ');

	printf("HWND: %ld",hwndNotify);
	printf("\n");	
	printf("cdrecord-executable: %s",exeName);
	printf("\n");
	printf("Logname: %s\n",logName);
	printf("cdrecord parameter: %s",chrPtr);
	printf("\n");

	/* Redirect stderr */
    rc=DosOpen(logName,&hf,&ulAction,0,FILE_NORMAL,OPEN_ACTION_CREATE_IF_NEW|OPEN_ACTION_OPEN_IF_EXISTS,
               OPEN_ACCESS_WRITEONLY|OPEN_SHARE_DENYWRITE,0);
	if(!rc) {
		DosSetFilePtr(hf,0,FILE_END,&ulAction);
		hfNew=2;
		DosDupHandle(hf,&hfNew);
		
		sprintf(logName,"---------------------------------------------------------------------\n");
		write(2,logName,strlen(logName));

		sprintf(logName,"\n");
		write(2,logName,strlen(logName));	
        
		/*	time(&ltime);		
		sprintf(logName,"%s",ctime(&ltime));
		write(2,logName,strlen(logName));	
		sprintf(logName,"\n");
		write(2,logName,strlen(logName));	*/
    
		sprintf(logName,"Starting to write using %s\n",exeName);
		write(2,logName,strlen(logName));
		
		sprintf(logName,"with the following parameters: %s\n",chrPtr);
		write(2,logName,strlen(logName));
	}
	
	DosExecPgm(chrError,sizeof(chrError),EXEC_SYNC,cmdLine,0,&resultCodes,exeName);
	sprintf(logName,"Return code is: %ld\n ",resultCodes.codeResult);
	write(2,logName,strlen(logName));

    DosClose(hf);
    WinPostMsg(hwndNotify,WM_APPTERMINATENOTIFY,MPFROMLONG(ACKEY_WRITEONLY),MPFROMLONG(resultCodes.codeResult));
    return 0;
}
Exemple #9
0
/*
 * Marks the end of writing.  Returns ElvTrue if all is okay, or ElvFalse if
 * error.
 *
 * For UNIX, the temp file is closed, and the program is forked.
 * (Since this function is only called when willwrite, the program
 * wasn't forked when prgopen() was called.)  Returns ElvTrue if the
 * fork was successful, or ElvFalse if it failed.
 */
ELVBOOL 
prggo (void)
{
  HFILE r_pipe, w_pipe;  /* two ends of a pipe */
  SAVE_IO save_io;
  HFILE fd, tmp_fd;
  APIRET rc;

  /* If we weren't writing, then there's nothing to be done here */
  if (writefd < 0)
    {
      return ElvTrue;
    }

  /*
   * If we're using a temp file, close it for writing, then spawn
   * the program with its stdin redirected to come from the file.
   */
  if (command)
    {
      /* Close the temp file for writing. */
      close (writefd);
      writefd = -1;

      /* Make a pipe to use for reading stdout/stderr. */
      rc = DosCreatePipe (&r_pipe, &w_pipe, 4096);
      if (rc != NO_ERROR)
        {
          msg (MSG_ERROR, "can't create pipe");
          goto Error;
        }

      /* Save all of the standard I/O handles. */
      if (!SaveStdIOHandles (save_io, 
                             SAVE_STDIN | SAVE_STDOUT | SAVE_STDERR))
        {
          goto Error;
        }

      /*
       * Redirect standard file handles for the CHILD PROCESS.
       */

      /* Get stdin from the temporary file. */
      tmp_fd = open (tempfname, O_RDONLY);
      fd = 0;
      if (DosDupHandle (tmp_fd, &fd) != NO_ERROR)
        {
          goto DupError;
        }
      close(tmp_fd);

      /* Connect the write end of the pipe to stdout/stderr. */
      fd = 1;
      if (DosDupHandle (w_pipe, &fd) != NO_ERROR)
        {
          goto DupError;
        }
      fd = 2;
      if (DosDupHandle (w_pipe, &fd) != NO_ERROR)
        {
          goto DupError;
        }

      /*
       * Prevent the child process from inheriting the read end
       * of the pipe.  This will ensure that the pipe closes
       * cleanly when the parent process (elvis) is done with it.
       */
      if (DosSetFHState (r_pipe, OPEN_FLAGS_NOINHERIT) != NO_ERROR)
        {
          msg (MSG_ERROR, "can't set file inheritance");
          goto Error;
        }

      /* Launch the command. */
      if ((pid = RunCommand (command)) < 0)
        {
          msg (MSG_ERROR, "can't spawn");
          goto Error;
        }

      /* Restore standard file handles for the PARENT PROCESS. */
      RestoreStdIOHandles (save_io);

      /*
       * Close the write end of the pipe; the read end becomes 
       * 'readfd'.
       */
      DosClose (w_pipe);
      w_pipe = NULLHANDLE;
      readfd = r_pipe;

      /* We don't need the command string any more. */
      free (command);
    }
  else /* writing but not reading */
    {
      /* close the writefd */
      close (writefd);
      writefd = -1;
    }

  return ElvTrue;

DupError:
  msg (MSG_ERROR, "can't dup file handle");

Error:
  /* Restore standard I/O handles if necessary. */
  RestoreStdIOHandles (save_io);
  return ElvFalse;
}
Exemple #10
0
/*
 * Declares which program we'll run, and what we'll be doing with it.
 * This function should return ElvTrue if successful.  If there is an error,
 * it should issue an error message via msg(), and return ElvFalse.
 *
 * For UNIX, the behavior of this function depends on willwrite.
 * If willwrite, then the command is saved and a temporary file is
 * is created to store the data that will become the program's stdin,
 * and the function succeeds if the temp file was created successfully.
 * Else the program is forked (with stdout/stderr redirected to a pipe
 * if willread) and the function succedes if pipe() and fork()
 * succeed.
 */
ELVBOOL 
prgopen (char  *cmd,    /* command string */
         ELVBOOL  willwrite,  /* if ElvTrue, redirect command's stdin */
         ELVBOOL  willread)  /* if ElvTrue, redirect command's stdout */
{
  HFILE r_pipe, w_pipe;  /* two ends of a pipe */
  SAVE_IO save_io;
  HFILE fd;
  APIRET rc;

  /* Mark both fd's as being unused */
  writefd = readfd = -1;

  /* Next step depends on what I/O we expect to do with this program */
  if (willwrite && willread)
    {
      /* save the command */
      command = strdup (cmd);

      /* create a temporary file for feeding the program's stdin */
      sprintf (tempfname, "%s/elvis%d.tmp", TMPDIR, (int)getpid ());
      writefd = open (tempfname, O_WRONLY|O_CREAT|O_EXCL, S_IREAD|S_IWRITE);
      if (writefd < 0)
        {
          msg (MSG_ERROR, "can't make temporary file");
          free (command);
          return ElvFalse;
        }
    }
  else if (willwrite || willread) /* but not both */
    {
      /* Create a pipe. */
      rc = DosCreatePipe (&r_pipe, &w_pipe, 4096);
      if (rc != NO_ERROR)
        {
          msg(MSG_ERROR, "can't create pipe");
          goto Error;
        }

      /*
       * Redirect standard file handles for the CHILD PROCESS.
       */

      if (willwrite)
        {
          /* Save the standard input handle. */
          if (!SaveStdIOHandles (save_io, SAVE_STDIN))
            goto Error;

          /* Get standard input from the read end of the pipe. */
          fd = 0;
          if (DosDupHandle (r_pipe, &fd) != NO_ERROR)
            goto DupError;

          /*
           * Prevent the child process from inheriting the write end
           * of the pipe.  This will ensure that the pipe closes
           * cleanly when the parent process (elvis) is done with it.
           */
          if (DosSetFHState (w_pipe, OPEN_FLAGS_NOINHERIT) != NO_ERROR)
            {
              msg (MSG_ERROR, "can't set file inheritance");
              goto Error;
            }
        }
      else
        {
          /* Save the standard output and error handles. */
          if (!SaveStdIOHandles (save_io, SAVE_STDOUT | SAVE_STDERR))
            {
              goto Error;
            }

          /* Send standard output to the write end of the pipe. */
          fd = 1;
          if (DosDupHandle (w_pipe, &fd) != NO_ERROR)
            {
              goto DupError;
            }

          /* Send error output to the write end of the pipe. */
          fd = 2;
          if (DosDupHandle (w_pipe, &fd) != NO_ERROR)
            {
              goto DupError;
            }
        }

      /* Launch the command. */
      if ((pid = RunCommand (cmd)) < 0)
        {
          msg (MSG_ERROR, "can't spawn");
          goto Error;
        }

      if (willwrite)
        {
          /*
           * Close the read end of the pipe and remember the fd 
           * of the write end.
           */
          DosClose (r_pipe);
          r_pipe = NULLHANDLE;
          writefd = w_pipe;
        }
      else
        {
          /*
           * Close the write end of the pipe and remember the fd 
           * of the read end.
           */
          DosClose (w_pipe);
          w_pipe = NULLHANDLE;
          readfd = r_pipe;
        }

      /* Restore standard file handles for the PARENT PROCESS. */
      RestoreStdIOHandles (save_io);
    }
  else /* no redirection */
    {
      /* Launch the command. */
      if ((pid = RunCommand (cmd)) < 0)
        {
          msg(MSG_ERROR, "can't spawn");
          goto Error;
        }
    }

  /* if we get here, we must have succeeded */
  return ElvTrue;

DupError:
  msg(MSG_ERROR, "can't dup file handle");

Error:
  /* Restore standard I/O handles if necessary. */
  RestoreStdIOHandles (save_io);
  return ElvFalse;
}
Exemple #11
0
static void *get_log_instance()
{
  if (gLogInstance || gLogInstanceState == 2 || gInFork)
    return gLogInstance;

  /* Set a flag that we're going to init a new log instance */
  if (!__atomic_cmpxchg32(&gLogInstanceState, 1, 0))
  {
    /*
     * Another thread was faster in starting instance creation, wait for it
     * to complete in a simple spin loop (completion should be really quick).
     */
    while (gLogInstanceState == 1)
      DosSleep(1);
    return gLogInstance;
  }

  void *logInstance = NULL;
  __LIBC_LOGGROUPS *logGroups = NULL;

#if defined(TRACE_ENABLED)
  logGroups = &gLogGroups;
  __libc_LogGroupInit(&gLogGroups, "LIBCX_TRACE");
#endif

  /* Check if we are asked to log to console */
  {
    PSZ dummy;
    gLogToConsole = DosScanEnv("LIBCX_TRACE_TO_CONSOLE", &dummy) == NO_ERROR;
  }

  char buf[CCHMAXPATH + 128];

  if (gLogToConsole)
  {
    logInstance = __libc_LogInit(0, logGroups, "NUL");
    if (logInstance)
    {
      /*
       * This is a dirty hack to write logs to stdout,
       * LIBC isn't capable of it on its own (@todo fix LIBC).
       */
      typedef struct __libc_logInstance
      {
        /** Write Semaphore. */
        HMTX                    hmtx;
        /** Filehandle. */
        HFILE                   hFile;
        /** Api groups. */
        __LIBC_PLOGGROUPS       pGroups;
      } __LIBC_LOGINST, *__LIBC_PLOGINST;

      /* Sanity check (note: we use LIBC assert here to avoid recursion) */
      assert(((__LIBC_PLOGINST)logInstance)->pGroups == logGroups);

      /* Duplicate STDOUT */
      DosDupHandle(1, &((__LIBC_PLOGINST)logInstance)->hFile);
    }
  }
  else
  {
    /*
     * We don't query QSV_TIME_HIGH as it will remain 0 until 19-Jan-2038 and for
     * our purposes (generate an unique log name sorted by date) it's fine.
     */
    ULONG time;
    DosQuerySysInfo(QSV_TIME_LOW, QSV_TIME_LOW, &time, sizeof(time));

    // Get log directory (boot drive if no UNIXROOT)
    const char *path = "/var/log/libcx";
    PSZ unixroot;
    if (DosScanEnv("UNIXROOT", &unixroot) != NO_ERROR)
    {
      ULONG drv;
      DosQuerySysInfo(QSV_BOOT_DRIVE, QSV_BOOT_DRIVE, &drv, sizeof(drv));

      unixroot = "C:";
      unixroot[0] = '@' + drv;
      path = "";
    }
    else
    {
      /*
       * Make sure the directory exists (no error checks here as a failure to
       * do so will pop up later in __libc_LogInit anyway).
       */
      if (strlen(unixroot) >= CCHMAXPATH)
        return NULL;
      strcpy(buf, unixroot);
      strcat(buf, path);
      DosCreateDir(buf, NULL);
    }

    // Get program name
    char name[CCHMAXPATH];
    PPIB ppib = NULL;
    DosGetInfoBlocks(NULL, &ppib);
    if (DosQueryModuleName(ppib->pib_hmte, sizeof(name), name) != NO_ERROR)
      return NULL;
    _remext(name);

    logInstance = __libc_LogInit(0, logGroups, "%s%s/%s-%08lx-%04x.log",
                                 unixroot, path, _getname(name), time, getpid());
  }

  /* Bail out if we failed to create a log file at all */
  if (!logInstance)
  {
    gLogInstanceState = 0;
    return NULL;
  }

  if (!gLogToConsole)
  {
    // Write out LIBCx info
    strcpy(buf, "LIBCx version : " VERSION_MAJ_MIN_BLD LIBCX_DEBUG_SUFFIX LIBCX_DEV_SUFFIX "\n");
    strcat(buf, "LIBCx module  : ");
    APIRET arc = DosQueryModuleName(ghModule, CCHMAXPATH, buf + strlen(buf));
    if (arc == NO_ERROR)
      sprintf(buf + strlen(buf), " (hmod=%04lx)\n", ghModule);
    else
      sprintf(buf + strlen(buf), " <error %ld>\n", arc);
    __libc_LogRaw(logInstance, __LIBC_LOG_MSGF_FLUSH, buf, strlen(buf));
  }

  /*
   * Finish initialization by storing the instance and setting the state to 2
   * (this will unfreeze other threads that started instance creation, if any).
   */
  gLogInstance = logInstance;
  gLogInstanceState = 2;
  return gLogInstance;
}
int main(int argc, char * argv[])
{
  int rc;
  HFILE hfNew;
  HWND hwndNotify;
  char *text;
  HPIPE hpR, hpW;
  ULONG cbRead, cbWritten;
  CHAR achBuf[PIPESIZE]={0};
  CHAR szFailName[CCHMAXPATH];
  HFILE hfSave;
  RESULTCODES ChildRC= {0};
  int a;
  int iBlocks;

  rc=-1;

  if(argc<4) {
    message();
    exit(-1);
  }  

  hwndNotify=atol(argv[1]);

  /* Print the parameters in VIO window */
  printf("argc:%d\n",argc);  
  for(a=0;a<argc;a++)
    {
      printf("%d: %s\n",a,argv[a]);
    }
  printf("\n");
  memset(achBuf, 0, sizeof(achBuf));

  /*  sprintf(achBuf,"%s %s -toc -v",argv[2],argv[3]); */
  sprintf(achBuf,"%s",argv[3]);
  text=strchr(achBuf,0);
  if(!text) {
    WinPostMsg(hwndNotify,WM_APPTERMINATENOTIFY,MPFROMLONG(4),MPFROMLONG(0));    
  }
  text++;
  sprintf(text,"%s", argv[4]);
  printf("Parameters for size query: %s\n",text);
  text=achBuf; 
  printf("Path is: %s\n",text);

  /**** start  ****/
  
  /* Redirect stdout */ 
  hfSave = -1;// Get new handle
  hfNew = HF_STDOUT;
 
  if(!DosDupHandle(HF_STDOUT, &hfSave)){    /* Saves standard  handle      */
    if(!DosCreatePipe(&hpR, &hpW, PIPESIZE)){ /* Creates pipe            */

      /* If the pipe size is smaller than the output of the child the system() call blocks.
         So create the pipe big enough. */
      
      if(!DosDupHandle(hpW, &hfNew)){           /* Duplicates standard output handle */
  
        /* start CDRecord/2 */
        rc=DosExecPgm(szFailName,sizeof(szFailName),EXEC_ASYNC, text,NULL,&ChildRC, text);
        fprintf(stderr,"DosExecPgm() for dvddao returned: %d\n",rc);
        /*
          rc=system(text);
        */

        DosClose(hpW);                       /* Closes write handle to ensure     */
        /* Notification at child termination */
        DosDupHandle(hfSave, &hfNew);        /* Brings stdout back                */

        /*
         * Read from the pipe and write to the screen
         * as long as there are bytes to read.
         */
          
        do {
          BOOL bNoMedia=FALSE;

          DosRead(hpR, achBuf, sizeof(achBuf), &cbRead);
          DosWrite(HF_STDERR, achBuf, cbRead, &cbWritten);

          /* Uppercase string */
          strupr(achBuf);
          text=strstr(achBuf,"NO MEDIA");
          if(text){
            /* No DVD/CD inserted */
            iBlocks=0;
            //WinPostMsg(hwndNotify,WM_APPTERMINATENOTIFY,MPFROMLONG(4),MPFROMLONG(0));
            bNoMedia=TRUE;
            break;
          }

          text=strstr(achBuf,"MEDIA SIZE");
          if(text){
            char dummy[200];
            /* We have the size */
            sscanf(text, "%s %s %d", dummy, dummy, &iBlocks);
            break;
          }

        } while(cbRead);          
        printf("Num blocks found %d \n",iBlocks);
        DosClose(hpR);
      }
    }
  }/* if(!DosDupHandle(HF_STDERR, &hfSave)) */      

  printf("Errorcode from dvddao is: %d\n",rc);
  /* Send msg. to the notification window */
  WinPostMsg(hwndNotify,WM_APPTERMINATENOTIFY,MPFROMLONG(4),MPFROMLONG(iBlocks));
  exit(0);
}
/**
 * Implementation of VbglR3Init and VbglR3InitUser
 */
static int vbglR3Init(const char *pszDeviceName)
{
    uint32_t cInits = ASMAtomicIncU32(&g_cInits);
    Assert(cInits > 0);
    if (cInits > 1)
    {
        /*
         * This will fail if two (or more) threads race each other calling VbglR3Init.
         * However it will work fine for single threaded or otherwise serialized
         * processed calling us more than once.
         */
#ifdef RT_OS_WINDOWS
        if (g_hFile == INVALID_HANDLE_VALUE)
#elif !defined (VBOX_VBGLR3_XFREE86)
        if (g_File == NIL_RTFILE)
#else
        if (g_File == -1)
#endif
            return VERR_INTERNAL_ERROR;
        return VINF_SUCCESS;
    }
#if defined(RT_OS_WINDOWS)
    if (g_hFile != INVALID_HANDLE_VALUE)
#elif !defined(VBOX_VBGLR3_XFREE86)
    if (g_File != NIL_RTFILE)
#else
    if (g_File != -1)
#endif
        return VERR_INTERNAL_ERROR;

#if defined(RT_OS_WINDOWS)
    /*
     * Have to use CreateFile here as we want to specify FILE_FLAG_OVERLAPPED
     * and possible some other bits not available thru iprt/file.h.
     */
    HANDLE hFile = CreateFile(pszDeviceName,
                              GENERIC_READ | GENERIC_WRITE,
                              FILE_SHARE_READ | FILE_SHARE_WRITE,
                              NULL,
                              OPEN_EXISTING,
                              FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
                              NULL);

    if (hFile == INVALID_HANDLE_VALUE)
        return VERR_OPEN_FAILED;
    g_hFile = hFile;

#elif defined(RT_OS_OS2)
    /*
     * We might wish to compile this with Watcom, so stick to
     * the OS/2 APIs all the way. And in any case we have to use
     * DosDevIOCtl for the requests, why not use Dos* for everything.
     */
    HFILE hf = NULLHANDLE;
    ULONG ulAction = 0;
    APIRET rc = DosOpen((PCSZ)pszDeviceName, &hf, &ulAction, 0, FILE_NORMAL,
                        OPEN_ACTION_OPEN_IF_EXISTS,
                        OPEN_FLAGS_FAIL_ON_ERROR | OPEN_FLAGS_NOINHERIT | OPEN_SHARE_DENYNONE | OPEN_ACCESS_READWRITE,
                        NULL);
    if (rc)
        return RTErrConvertFromOS2(rc);

    if (hf < 16)
    {
        HFILE ahfs[16];
        unsigned i;
        for (i = 0; i < RT_ELEMENTS(ahfs); i++)
        {
            ahfs[i] = 0xffffffff;
            rc = DosDupHandle(hf, &ahfs[i]);
            if (rc)
                break;
        }

        if (i-- > 1)
        {
            ULONG fulState = 0;
            rc = DosQueryFHState(ahfs[i], &fulState);
            if (!rc)
            {
                fulState |= OPEN_FLAGS_NOINHERIT;
                fulState &= OPEN_FLAGS_WRITE_THROUGH | OPEN_FLAGS_FAIL_ON_ERROR | OPEN_FLAGS_NO_CACHE | OPEN_FLAGS_NOINHERIT; /* Turn off non-participating bits. */
                rc = DosSetFHState(ahfs[i], fulState);
            }
            if (!rc)
            {
                rc = DosClose(hf);
                AssertMsg(!rc, ("%ld\n", rc));
                hf = ahfs[i];
            }
            else
                i++;
            while (i-- > 0)
                DosClose(ahfs[i]);
        }
    }
    g_File = (RTFILE)hf;

#elif defined(VBOX_VBGLR3_XFREE86)
    int File = xf86open(pszDeviceName, XF86_O_RDWR);
    if (File == -1)
        return VERR_OPEN_FAILED;
    g_File = File;

#else

    /* The default implementation. (linux, solaris, freebsd) */
    RTFILE File;
    int rc = RTFileOpen(&File, pszDeviceName, RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
    if (RT_FAILURE(rc))
        return rc;
    g_File = File;

#endif

#ifndef VBOX_VBGLR3_XFREE86
    /*
     * Create release logger
     */
    PRTLOGGER pReleaseLogger;
    static const char * const s_apszGroups[] = VBOX_LOGGROUP_NAMES;
    int rc2 = RTLogCreate(&pReleaseLogger, 0, "all", "VBOX_RELEASE_LOG",
                          RT_ELEMENTS(s_apszGroups), &s_apszGroups[0], RTLOGDEST_USER, NULL);
    /* This may legitimately fail if we are using the mini-runtime. */
    if (RT_SUCCESS(rc2))
        RTLogRelSetDefaultInstance(pReleaseLogger);
#endif

    return VINF_SUCCESS;
}
Exemple #14
0
HB_FHANDLE hb_fsProcessOpen( const char * pszFileName,
                             HB_FHANDLE * phStdin, HB_FHANDLE * phStdout,
                             HB_FHANDLE * phStderr,
                             HB_BOOL fDetach, HB_ULONG * pulPID )
{
   HB_FHANDLE hPipeIn [ 2 ] = { FS_ERROR, FS_ERROR },
              hPipeOut[ 2 ] = { FS_ERROR, FS_ERROR },
              hPipeErr[ 2 ] = { FS_ERROR, FS_ERROR };
   HB_FHANDLE hResult = FS_ERROR;
   HB_ERRCODE errCode;
   HB_BOOL fError = HB_FALSE;

   HB_TRACE( HB_TR_DEBUG, ( "hb_fsProcessOpen(%s, %p, %p, %p, %d, %p)", pszFileName, phStdin, phStdout, phStderr, fDetach, pulPID ) );

   if( phStdin != NULL )
      fError = ! hb_fsPipeCreate( hPipeIn );
   if( ! fError && phStdout != NULL )
      fError = ! hb_fsPipeCreate( hPipeOut );
   if( ! fError && phStderr != NULL )
   {
      if( phStdout == phStderr )
      {
         hPipeErr[ 0 ] = hPipeOut[ 0 ];
         hPipeErr[ 1 ] = hPipeOut[ 1 ];
      }
      else
         fError = ! hb_fsPipeCreate( hPipeErr );
   }

   if( ! fError )
   {
#if defined( HB_OS_WIN )

      PROCESS_INFORMATION pi;
      STARTUPINFO si;
      DWORD dwFlags = 0;
      LPTSTR lpCommand = HB_CHARDUP( pszFileName );

#  if ! defined( HB_OS_WIN_CE )
      if( phStdin != NULL )
         SetHandleInformation( ( HANDLE ) hb_fsGetOsHandle( hPipeIn [ 1 ] ), HANDLE_FLAG_INHERIT, 0 );
      if( phStdout != NULL )
         SetHandleInformation( ( HANDLE ) hb_fsGetOsHandle( hPipeOut[ 0 ] ), HANDLE_FLAG_INHERIT, 0 );
      if( phStderr != NULL && phStdout != phStderr )
         SetHandleInformation( ( HANDLE ) hb_fsGetOsHandle( hPipeErr[ 0 ] ), HANDLE_FLAG_INHERIT, 0 );
#  endif

      memset( &pi, 0, sizeof( pi ) );
      memset( &si, 0, sizeof( si ) );
      si.cb = sizeof( si );
#  ifdef STARTF_USESTDHANDLES
      si.dwFlags = STARTF_USESTDHANDLES;
#  endif
      if( fDetach )
      {
#  ifdef STARTF_USESHOWWINDOW
         si.dwFlags |= STARTF_USESHOWWINDOW;
#  endif
         si.wShowWindow = SW_HIDE;
         si.hStdInput  = ( HANDLE ) hb_fsGetOsHandle( hPipeIn [ 0 ] );
         si.hStdOutput = ( HANDLE ) hb_fsGetOsHandle( hPipeOut[ 1 ] );
         si.hStdError  = ( HANDLE ) hb_fsGetOsHandle( hPipeErr[ 1 ] );
#  ifdef DETACHED_PROCESS
         dwFlags |= DETACHED_PROCESS;
#  endif
      }
      else
      {
         si.hStdInput  = phStdin  ? ( HANDLE ) hb_fsGetOsHandle( hPipeIn [ 0 ] ) : GetStdHandle( STD_INPUT_HANDLE );
         si.hStdOutput = phStdout ? ( HANDLE ) hb_fsGetOsHandle( hPipeOut[ 1 ] ) : GetStdHandle( STD_OUTPUT_HANDLE );
         si.hStdError  = phStderr ? ( HANDLE ) hb_fsGetOsHandle( hPipeErr[ 1 ] ) : GetStdHandle( STD_ERROR_HANDLE );
      }
      fError = ! CreateProcess( NULL,           /* lpAppName */
                                lpCommand,
                                NULL,           /* lpProcessAttr */
                                NULL,           /* lpThreadAttr */
                                TRUE,           /* bInheritHandles */
                                dwFlags,        /* dwCreationFlags */
                                NULL,           /* lpEnvironment */
                                NULL,           /* lpCurrentDirectory */
                                &si,
                                &pi );
      hb_fsSetIOError( ! fError, 0 );
      hb_xfree( lpCommand );
      if( ! fError )
      {
         if( phStdin != NULL )
         {
            *phStdin = ( HB_FHANDLE ) hPipeIn[ 1 ];
            hPipeIn[ 1 ] = FS_ERROR;
         }
         if( phStdout != NULL )
         {
            *phStdout = ( HB_FHANDLE ) hPipeOut[ 0 ];
            hPipeOut[ 0 ] = FS_ERROR;
         }
         if( phStderr != NULL )
         {
            *phStderr = ( HB_FHANDLE ) hPipeErr[ 0 ];
            hPipeErr[ 0 ] = FS_ERROR;
         }
         if( pulPID )
            *pulPID = pi.dwProcessId;
         CloseHandle( pi.hThread );
         hResult = ( HB_FHANDLE ) pi.hProcess;
      }

#elif defined( HB_OS_OS2 )

      HFILE hNull = ( HFILE ) FS_ERROR;
      ULONG ulState = 0;
      APIRET ret = NO_ERROR;
      PID pid = ( PID ) -1;
      PHB_GT pGT;

      if( fDetach && ( ! phStdin || ! phStdout || ! phStderr ) )
      {
         HB_FHANDLE hFile;

         ret = hb_fsOS2DosOpen( "NUL:", &hFile, &ulState, 0,
                                FILE_NORMAL, OPEN_ACCESS_READWRITE,
                                OPEN_ACTION_OPEN_IF_EXISTS );
         if( ret == NO_ERROR )
            hNull = ( HFILE ) hFile;
      }

      if( ret == NO_ERROR && phStdin != NULL )
      {
         ret = DosQueryFHState( hPipeIn[ 1 ], &ulState );
         if( ret == NO_ERROR && ( ulState & OPEN_FLAGS_NOINHERIT ) == 0 )
            ret = DosSetFHState( hPipeIn[ 1 ], ( ulState & 0xFF00 ) | OPEN_FLAGS_NOINHERIT );
      }
      if( ret == NO_ERROR && phStdout != NULL )
      {
         ret = DosQueryFHState( hPipeOut[ 0 ], &ulState );
         if( ret == NO_ERROR && ( ulState & OPEN_FLAGS_NOINHERIT ) == 0 )
            ret = DosSetFHState( hPipeOut[ 0 ], ( ulState & 0xFF00 ) | OPEN_FLAGS_NOINHERIT );
      }
      if( ret == NO_ERROR && phStderr != NULL && phStdout != phStderr )
      {
         ret = DosQueryFHState( hPipeErr[ 0 ], &ulState );
         if( ret == NO_ERROR && ( ulState & OPEN_FLAGS_NOINHERIT ) == 0 )
            ret = DosSetFHState( hPipeErr[ 0 ], ( ulState & 0xFF00 ) | OPEN_FLAGS_NOINHERIT );
      }

      if( ret == NO_ERROR && ( pGT = hb_gt_Base() ) != NULL )
      {
         ULONG ulStateIn, ulStateOut, ulStateErr;
         HFILE hStdIn, hStdErr, hStdOut, hDup;

         ulStateIn = ulStateOut = ulStateErr = OPEN_FLAGS_NOINHERIT;
         hStdIn  = hStdErr = hStdOut = ( HFILE ) FS_ERROR;

         if( ret == NO_ERROR && ( phStdin != NULL || fDetach ) )
         {
            hDup = 0;
            ret = DosDupHandle( hDup, &hStdIn );
            if( ret == NO_ERROR )
            {
               ret = DosQueryFHState( hStdIn, &ulStateIn );
               if( ret == NO_ERROR && ( ulStateIn & OPEN_FLAGS_NOINHERIT ) == 0 )
                  ret = DosSetFHState( hStdIn, ( ulStateIn & 0xFF00 ) | OPEN_FLAGS_NOINHERIT );
               if( ret == NO_ERROR )
                  ret = DosDupHandle( phStdin != NULL ? ( HFILE ) hPipeIn[ 0 ] : hNull, &hDup );
            }
         }

         if( ret == NO_ERROR && ( phStdout != NULL || fDetach ) )
         {
            hDup = 1;
            ret = DosDupHandle( hDup, &hStdOut );
            if( ret == NO_ERROR )
            {
               ret = DosQueryFHState( hStdOut, &ulStateOut );
               if( ret == NO_ERROR && ( ulStateOut & OPEN_FLAGS_NOINHERIT ) == 0 )
                  ret = DosSetFHState( hStdOut, ( ulStateOut & 0xFF00 ) | OPEN_FLAGS_NOINHERIT );
               if( ret == NO_ERROR )
                  ret = DosDupHandle( phStdout != NULL ? ( HFILE ) hPipeOut[ 1 ] : hNull, &hDup );
            }
         }

         if( ret == NO_ERROR && ( phStderr != NULL || fDetach ) )
         {
            hDup = 2;
            ret = DosDupHandle( hDup, &hStdErr );
            if( ret == NO_ERROR )
            {
               ret = DosQueryFHState( hStdErr, &ulStateErr );
               if( ret == NO_ERROR && ( ulStateErr & OPEN_FLAGS_NOINHERIT ) == 0 )
                  ret = DosSetFHState( hStdErr, ( ulStateErr & 0xFF00 ) | OPEN_FLAGS_NOINHERIT );
               if( ret == NO_ERROR )
                  ret = DosDupHandle( phStderr != NULL ? ( HFILE ) hPipeErr[ 1 ] : hNull, &hDup );
            }
         }

         if( ret == NO_ERROR )
         {
            char * pArgs = hb_buildArgsOS2( pszFileName, &ret );
            char uchLoadError[ CCHMAXPATH ] = { 0 };
            RESULTCODES ChildRC = { 0, 0 };

            if( pArgs )
            {
               ret = DosExecPgm( uchLoadError, sizeof( uchLoadError ),
                                 fDetach ? EXEC_BACKGROUND : EXEC_ASYNCRESULT,
                                 ( PCSZ ) pArgs, NULL /* env */,
                                 &ChildRC,
                                 ( PCSZ ) pArgs );
               if( ret == NO_ERROR )
                  pid = ChildRC.codeTerminate;
               hb_freeArgsOS2( pArgs );
            }
         }

         if( hNull != ( HFILE ) FS_ERROR )
            DosClose( hNull );

         if( hStdIn != ( HFILE ) FS_ERROR )
         {
            hDup = 0;
            DosDupHandle( hStdIn, &hDup );
            DosClose( hStdIn );
            if( ( ulStateIn & OPEN_FLAGS_NOINHERIT ) == 0 )
               DosSetFHState( hDup, ulStateIn & 0xFF00 );
         }
         if( hStdOut != ( HFILE ) FS_ERROR )
         {
            hDup = 1;
            DosDupHandle( hStdOut, &hDup );
            DosClose( hStdOut );
            if( ( ulStateOut & OPEN_FLAGS_NOINHERIT ) == 0 )
               DosSetFHState( hDup, ulStateOut & 0xFF00 );
         }
         if( hStdErr != ( HFILE ) FS_ERROR )
         {
            hDup = 2;
            DosDupHandle( hStdErr, &hDup );
            DosClose( hStdErr );
            if( ( ulStateErr & OPEN_FLAGS_NOINHERIT ) == 0 )
               DosSetFHState( hDup, ulStateErr & 0xFF00 );
         }

         hb_gt_BaseFree( pGT );
      }
      else
      {
         if( hNull != ( HFILE ) FS_ERROR )
            DosClose( hNull );
         if( ret == NO_ERROR )
            ret = ( APIRET ) FS_ERROR;
      }

      fError = ret != NO_ERROR;
      if( ! fError )
      {
         if( phStdin != NULL )
         {
            *phStdin = ( HB_FHANDLE ) hPipeIn[ 1 ];
            hPipeIn[ 1 ] = FS_ERROR;
         }
         if( phStdout != NULL )
         {
            *phStdout = ( HB_FHANDLE ) hPipeOut[ 0 ];
            hPipeOut[ 0 ] = FS_ERROR;
         }
         if( phStderr != NULL )
         {
            *phStderr = ( HB_FHANDLE ) hPipeErr[ 0 ];
            hPipeErr[ 0 ] = FS_ERROR;
         }
         if( pulPID )
            *pulPID = pid;
         hResult = ( HB_FHANDLE ) pid;
      }

      hb_fsSetError( ( HB_ERRCODE ) ret );

#elif defined( HB_OS_UNIX ) && \
      ! defined( HB_OS_VXWORKS ) && ! defined( HB_OS_SYMBIAN )

      char ** argv = hb_buildArgs( pszFileName );
      pid_t pid = fork();

      if( pid == -1 )
         fError = HB_TRUE;
      else if( pid != 0 )    /* parent process */
      {
         if( phStdin != NULL )
         {
            *phStdin = ( HB_FHANDLE ) hPipeIn[ 1 ];
            hPipeIn[ 1 ] = FS_ERROR;
         }
         if( phStdout != NULL )
         {
            *phStdout = ( HB_FHANDLE ) hPipeOut[ 0 ];
            hPipeOut[ 0 ] = FS_ERROR;
         }
         if( phStderr != NULL )
         {
            *phStderr = ( HB_FHANDLE ) hPipeErr[ 0 ];
            hPipeErr[ 0 ] = FS_ERROR;
         }
         if( pulPID )
            *pulPID = pid;
         hResult = ( HB_FHANDLE ) pid;
      }
      else                    /* child process */
      {
         if( fDetach && ( ! phStdin || ! phStdout || ! phStderr ) )
         {
            HB_FHANDLE hNull = open( "/dev/null", O_RDWR );

            if( ! phStdin )
               dup2( hNull, 0 );
            if( ! phStdout )
               dup2( hNull, 1 );
            if( ! phStderr )
               dup2( hNull, 2 );

            if( hNull != FS_ERROR )
               hb_fsClose( hNull );
         }

         if( phStdin != NULL )
         {
            dup2( hPipeIn[ 0 ], 0 );
            hb_fsClose( hPipeIn[ 1 ] );
         }
         if( phStdout != NULL )
         {
            dup2( hPipeOut[ 1 ], 1 );
            hb_fsClose( hPipeOut[ 0 ] );
         }
         if( phStderr != NULL )
         {
            dup2( hPipeErr[ 1 ], 2 );
            if( phStdout != phStderr )
               hb_fsClose( hPipeErr[ 0 ] );
         }

         /* close all non std* handles */
         {
            int iMaxFD, i;
            iMaxFD = sysconf( _SC_OPEN_MAX );
            if( iMaxFD < 3 )
               iMaxFD = 1024;
            for( i = 3; i < iMaxFD; ++i )
               hb_fsClose( i );
         }

         /* reset extended process attributes */
         if( setuid( getuid() ) == -1 ) {}
         if( setgid( getgid() ) == -1 ) {}

         /* execute command */
         {
#  if defined( __WATCOMC__ )
            execvp( argv[ 0 ], ( const char ** ) argv );
#  else
            execvp( argv[ 0 ], argv );
#  endif
            exit( -1 );
         }
      }
      hb_fsSetIOError( ! fError, 0 );

      hb_freeArgs( argv );

#elif defined( HB_OS_OS2 ) || defined( HB_OS_WIN )

      int hStdIn, hStdOut, hStdErr;
      char ** argv;
      int pid;

      hStdIn  = dup( 0 );
      hStdOut = dup( 1 );
      hStdErr = dup( 2 );

      if( fDetach && ( ! phStdin || ! phStdout || ! phStderr ) )
      {
         HB_FHANDLE hNull = open( "NUL:", O_RDWR );

         if( ! phStdin )
            dup2( hNull, 0 );
         if( ! phStdout )
            dup2( hNull, 1 );
         if( ! phStderr )
            dup2( hNull, 2 );

         if( hNull != FS_ERROR )
            close( hNull );
      }

      if( phStdin != NULL )
         dup2( hPipeIn[ 0 ], 0 );
      if( phStdout != NULL )
         dup2( hPipeOut[ 1 ], 1 );
      if( phStderr != NULL )
         dup2( hPipeErr[ 1 ], 2 );

      argv = hb_buildArgs( pszFileName );

#if defined( _MSC_VER ) || defined( __LCC__ ) || \
    defined( __XCC__ ) || defined( __POCC__ )
      pid = _spawnvp( _P_NOWAIT, argv[ 0 ], argv );
#elif defined( __MINGW32__ ) || defined( __WATCOMC__ )
      pid = spawnvp( P_NOWAIT, argv[ 0 ], ( const char * const * ) argv );
#else
      pid = spawnvp( P_NOWAIT, argv[ 0 ], ( char * const * ) argv );
#endif
      hb_freeArgs( argv );

      dup2( hStdIn,  0 );
      close( hStdIn );

      dup2( hStdOut, 1 );
      close( hStdOut );

      dup2( hStdErr, 2 );
      close( hStdErr );

      if( pid < 0 )
         fError = HB_TRUE;
      else if( pid != 0 )    /* parent process */
      {
         if( phStdin != NULL )
         {
            *phStdin = ( HB_FHANDLE ) hPipeIn[ 1 ];
            hPipeIn[ 1 ] = FS_ERROR;
         }
         if( phStdout != NULL )
         {
            *phStdout = ( HB_FHANDLE ) hPipeOut[ 0 ];
            hPipeOut[ 0 ] = FS_ERROR;
         }
         if( phStderr != NULL )
         {
            *phStderr = ( HB_FHANDLE ) hPipeErr[ 0 ];
            hPipeErr[ 0 ] = FS_ERROR;
         }
         if( pulPID )
            *pulPID = pid;
         hResult = ( HB_FHANDLE ) pid;
      }

      hb_fsSetIOError( ! fError, 0 );

#else
      int iTODO; /* TODO: for given platform */

      HB_SYMBOL_UNUSED( pszFileName );
      HB_SYMBOL_UNUSED( fDetach );
      HB_SYMBOL_UNUSED( pulPID );

      hb_fsSetError( ( HB_ERRCODE ) FS_ERROR );
#endif
   }

   errCode = hb_fsError();

   if( hPipeIn[ 0 ] != FS_ERROR )
      hb_fsClose( hPipeIn[ 0 ] );
   if( hPipeIn[ 1 ] != FS_ERROR )
      hb_fsClose( hPipeIn[ 1 ] );
   if( hPipeOut[ 0 ] != FS_ERROR )
      hb_fsClose( hPipeOut[ 0 ] );
   if( hPipeOut[ 1 ] != FS_ERROR )
      hb_fsClose( hPipeOut[ 1 ] );
   if( phStdout != phStderr )
   {
      if( hPipeErr[ 0 ] != FS_ERROR )
         hb_fsClose( hPipeErr[ 0 ] );
      if( hPipeErr[ 1 ] != FS_ERROR )
         hb_fsClose( hPipeErr[ 1 ] );
   }

   hb_fsSetError( errCode );

   return hResult;
}
Exemple #15
0
PRProcess * _PR_CreateOS2Process(
    const char *path,
    char *const *argv,
    char *const *envp,
    const PRProcessAttr *attr)
{
    PRProcess *proc = NULL;
    char *cmdLine = NULL;
    char **newEnvp = NULL;
    char *envBlock = NULL;
   
    STARTDATA startData = {0};
    APIRET    rc;
    ULONG     ulAppType = 0;
    PID       pid = 0;
    char     *pszComSpec;
    char      pszEXEName[CCHMAXPATH] = "";
    char      pszFormatString[CCHMAXPATH];
    char      pszObjectBuffer[CCHMAXPATH];
    char     *pszFormatResult = NULL;

    /*
     * Variables for DosExecPgm
     */
    char szFailed[CCHMAXPATH];
    char *pszCmdLine = NULL;
    RESULTCODES procInfo;
    HFILE hStdIn  = 0,
          hStdOut = 0,
          hStdErr = 0;
    HFILE hStdInSave  = -1,
          hStdOutSave = -1,
          hStdErrSave = -1;

    proc = PR_NEW(PRProcess);
    if (!proc) {
        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
        goto errorExit;
    }
   
    if (assembleCmdLine(argv, &cmdLine) == -1) {
        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
        goto errorExit;
    }

#ifdef MOZ_OS2_HIGH_MEMORY
    /*
     * DosQueryAppType() fails if path (the char* in the first argument) is in
     * high memory. If that is the case, the following moves it to low memory.
     */ 
    if ((ULONG)path >= 0x20000000) {
        size_t len = strlen(path) + 1;
        char *copy = (char *)alloca(len);
        memcpy(copy, path, len);
        path = copy;
    }
#endif
   
    if (envp == NULL) {
        newEnvp = NULL;
    } else {
        int i;
        int numEnv = 0;
        while (envp[numEnv]) {
            numEnv++;
        }
        newEnvp = (char **) PR_MALLOC((numEnv+1) * sizeof(char *));
        for (i = 0; i <= numEnv; i++) {
            newEnvp[i] = envp[i];
        }
        qsort((void *) newEnvp, (size_t) numEnv, sizeof(char *), compare);
    }
    if (assembleEnvBlock(newEnvp, &envBlock) == -1) {
        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
        goto errorExit;
    }
  
    rc = DosQueryAppType(path, &ulAppType);
    if (rc != NO_ERROR) {
       char *pszDot = strrchr(path, '.');
       if (pszDot) {
          /* If it is a CMD file, launch the users command processor */
          if (!stricmp(pszDot, ".cmd")) {
             rc = DosScanEnv("COMSPEC", (PSZ *)&pszComSpec);
             if (!rc) {
                strcpy(pszFormatString, "/C %s %s");
                strcpy(pszEXEName, pszComSpec);
                ulAppType = FAPPTYP_WINDOWCOMPAT;
             }
          }
       }
    }
    if (ulAppType == 0) {
       PR_SetError(PR_UNKNOWN_ERROR, 0);
       goto errorExit;
    }
 
    if ((ulAppType & FAPPTYP_WINDOWAPI) == FAPPTYP_WINDOWAPI) {
        startData.SessionType = SSF_TYPE_PM;
    }
    else if (ulAppType & FAPPTYP_WINDOWCOMPAT) {
        startData.SessionType = SSF_TYPE_WINDOWABLEVIO;
    }
    else {
        startData.SessionType = SSF_TYPE_DEFAULT;
    }
 
    if (ulAppType & (FAPPTYP_WINDOWSPROT31 | FAPPTYP_WINDOWSPROT | FAPPTYP_WINDOWSREAL))
    {
        strcpy(pszEXEName, "WINOS2.COM");
        startData.SessionType = PROG_31_STDSEAMLESSVDM;
        strcpy(pszFormatString, "/3 %s %s");
    }
 
    startData.InheritOpt = SSF_INHERTOPT_SHELL;
 
    if (pszEXEName[0]) {
        pszFormatResult = PR_MALLOC(strlen(pszFormatString)+strlen(path)+strlen(cmdLine));
        sprintf(pszFormatResult, pszFormatString, path, cmdLine);
        startData.PgmInputs = pszFormatResult;
    } else {
        strcpy(pszEXEName, path);
        startData.PgmInputs = cmdLine;
    }
    startData.PgmName = pszEXEName;
 
    startData.Length = sizeof(startData);
    startData.Related = SSF_RELATED_INDEPENDENT;
    startData.ObjectBuffer = pszObjectBuffer;
    startData.ObjectBuffLen = CCHMAXPATH;
    startData.Environment = envBlock;
 
    if (attr) {
        /* On OS/2, there is really no way to pass file handles for stdin,
         * stdout, and stderr to a new process.  Instead, we can make it
         * a child process and make the given file handles a copy of our
         * stdin, stdout, and stderr.  The child process then inherits
         * ours, and we set ours back.  Twisted and gross I know. If you
         * know a better way, please use it.
         */
        if (attr->stdinFd) {
            hStdIn = 0;
            DosDupHandle(hStdIn, &hStdInSave);
            DosDupHandle((HFILE) attr->stdinFd->secret->md.osfd, &hStdIn);
        }

        if (attr->stdoutFd) {
            hStdOut = 1;
            DosDupHandle(hStdOut, &hStdOutSave);
            DosDupHandle((HFILE) attr->stdoutFd->secret->md.osfd, &hStdOut);
        }

        if (attr->stderrFd) {
            hStdErr = 2;
            DosDupHandle(hStdErr, &hStdErrSave);
            DosDupHandle((HFILE) attr->stderrFd->secret->md.osfd, &hStdErr);
        }
        /*
         * Build up the Command Line for DosExecPgm
         */
        pszCmdLine = PR_MALLOC(strlen(pszEXEName) +
                               strlen(startData.PgmInputs) + 3);
        sprintf(pszCmdLine, "%s%c%s%c", pszEXEName, '\0',
                startData.PgmInputs, '\0');
        rc = DosExecPgm(szFailed,
                        CCHMAXPATH,
                        EXEC_ASYNCRESULT,
                        pszCmdLine,
                        envBlock,
                        &procInfo,
                        pszEXEName);
        PR_DELETE(pszCmdLine);

        /* Restore our old values.  Hope this works */
        if (hStdInSave != -1) {
            DosDupHandle(hStdInSave, &hStdIn);
            DosClose(hStdInSave);
        }

        if (hStdOutSave != -1) {
            DosDupHandle(hStdOutSave, &hStdOut);
            DosClose(hStdOutSave);
        }

        if (hStdErrSave != -1) {
            DosDupHandle(hStdErrSave, &hStdErr);
            DosClose(hStdErrSave);
        }

        if (rc != NO_ERROR) {
            /* XXX what error code? */
            PR_SetError(PR_UNKNOWN_ERROR, rc);
            goto errorExit;
        }

        proc->md.pid = procInfo.codeTerminate;
    } else {	
        /*
         * If no STDIN/STDOUT redirection is not needed, use DosStartSession
         * to create a new, independent session
         */
        rc = DosStartSession(&startData, &ulAppType, &pid);

        if ((rc != NO_ERROR) && (rc != ERROR_SMG_START_IN_BACKGROUND)) {
            PR_SetError(PR_UNKNOWN_ERROR, rc);
            goto errorExit;
        }
 
        proc->md.pid = pid;
    }

    if (pszFormatResult) {
        PR_DELETE(pszFormatResult);
    }

    PR_DELETE(cmdLine);
    if (newEnvp) {
        PR_DELETE(newEnvp);
    }
    if (envBlock) {
        PR_DELETE(envBlock);
    }
    return proc;

errorExit:
    if (cmdLine) {
        PR_DELETE(cmdLine);
    }
    if (newEnvp) {
        PR_DELETE(newEnvp);
    }
    if (envBlock) {
        PR_DELETE(envBlock);
    }
    if (proc) {
        PR_DELETE(proc);
    }
    return NULL;
}  /* _PR_CreateOS2Process */
Exemple #16
0
/**
 * Implementation of VbglR3Init and VbglR3InitUser
 */
static int vbglR3Init(const char *pszDeviceName)
{
    uint32_t cInits = ASMAtomicIncU32(&g_cInits);
    Assert(cInits > 0);
    if (cInits > 1)
    {
        /*
         * This will fail if two (or more) threads race each other calling VbglR3Init.
         * However it will work fine for single threaded or otherwise serialized
         * processed calling us more than once.
         */
#ifdef RT_OS_WINDOWS
        if (g_hFile == INVALID_HANDLE_VALUE)
#elif !defined (VBOX_VBGLR3_XSERVER)
        if (g_File == NIL_RTFILE)
#else
        if (g_File == -1)
#endif
            return VERR_INTERNAL_ERROR;
        return VINF_SUCCESS;
    }
#if defined(RT_OS_WINDOWS)
    if (g_hFile != INVALID_HANDLE_VALUE)
#elif !defined(VBOX_VBGLR3_XSERVER)
    if (g_File != NIL_RTFILE)
#else
    if (g_File != -1)
#endif
        return VERR_INTERNAL_ERROR;

#if defined(RT_OS_WINDOWS)
    /*
     * Have to use CreateFile here as we want to specify FILE_FLAG_OVERLAPPED
     * and possible some other bits not available thru iprt/file.h.
     */
    HANDLE hFile = CreateFile(pszDeviceName,
                              GENERIC_READ | GENERIC_WRITE,
                              FILE_SHARE_READ | FILE_SHARE_WRITE,
                              NULL,
                              OPEN_EXISTING,
                              FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
                              NULL);

    if (hFile == INVALID_HANDLE_VALUE)
        return VERR_OPEN_FAILED;
    g_hFile = hFile;

#elif defined(RT_OS_OS2)
    /*
     * We might wish to compile this with Watcom, so stick to
     * the OS/2 APIs all the way. And in any case we have to use
     * DosDevIOCtl for the requests, why not use Dos* for everything.
     */
    HFILE hf = NULLHANDLE;
    ULONG ulAction = 0;
    APIRET rc = DosOpen((PCSZ)pszDeviceName, &hf, &ulAction, 0, FILE_NORMAL,
                        OPEN_ACTION_OPEN_IF_EXISTS,
                        OPEN_FLAGS_FAIL_ON_ERROR | OPEN_FLAGS_NOINHERIT | OPEN_SHARE_DENYNONE | OPEN_ACCESS_READWRITE,
                        NULL);
    if (rc)
        return RTErrConvertFromOS2(rc);

    if (hf < 16)
    {
        HFILE ahfs[16];
        unsigned i;
        for (i = 0; i < RT_ELEMENTS(ahfs); i++)
        {
            ahfs[i] = 0xffffffff;
            rc = DosDupHandle(hf, &ahfs[i]);
            if (rc)
                break;
        }

        if (i-- > 1)
        {
            ULONG fulState = 0;
            rc = DosQueryFHState(ahfs[i], &fulState);
            if (!rc)
            {
                fulState |= OPEN_FLAGS_NOINHERIT;
                fulState &= OPEN_FLAGS_WRITE_THROUGH | OPEN_FLAGS_FAIL_ON_ERROR | OPEN_FLAGS_NO_CACHE | OPEN_FLAGS_NOINHERIT; /* Turn off non-participating bits. */
                rc = DosSetFHState(ahfs[i], fulState);
            }
            if (!rc)
            {
                rc = DosClose(hf);
                AssertMsg(!rc, ("%ld\n", rc));
                hf = ahfs[i];
            }
            else
                i++;
            while (i-- > 0)
                DosClose(ahfs[i]);
        }
    }
    g_File = (RTFILE)hf;

#elif defined(RT_OS_DARWIN)
    /*
     * Darwin is kind of special we need to engage the device via I/O first
     * before we open it via the BSD device node.
     */
    mach_port_t MasterPort;
    kern_return_t kr = IOMasterPort(MACH_PORT_NULL, &MasterPort);
    if (kr != kIOReturnSuccess)
        return VERR_GENERAL_FAILURE;

    CFDictionaryRef ClassToMatch = IOServiceMatching("org_virtualbox_VBoxGuest");
    if (!ClassToMatch)
        return VERR_GENERAL_FAILURE;

    io_service_t ServiceObject = IOServiceGetMatchingService(kIOMasterPortDefault, ClassToMatch);
    if (!ServiceObject)
        return VERR_NOT_FOUND;

    io_connect_t uConnection;
    kr = IOServiceOpen(ServiceObject, mach_task_self(), VBOXGUEST_DARWIN_IOSERVICE_COOKIE, &uConnection);
    IOObjectRelease(ServiceObject);
    if (kr != kIOReturnSuccess)
        return VERR_OPEN_FAILED;

    RTFILE hFile;
    int rc = RTFileOpen(&hFile, pszDeviceName, RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
    if (RT_FAILURE(rc))
    {
        IOServiceClose(uConnection);
        return rc;
    }
    g_File = hFile;
    g_uConnection = uConnection;

#elif defined(VBOX_VBGLR3_XSERVER)
    int File = xf86open(pszDeviceName, XF86_O_RDWR);
    if (File == -1)
        return VERR_OPEN_FAILED;
    g_File = File;

#else

    /* The default implementation. (linux, solaris, freebsd, haiku) */
    RTFILE File;
    int rc = RTFileOpen(&File, pszDeviceName, RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
    if (RT_FAILURE(rc))
        return rc;
    g_File = File;

#endif

#ifndef VBOX_VBGLR3_XSERVER
    /*
     * Create release logger
     */
    PRTLOGGER pReleaseLogger;
    static const char * const s_apszGroups[] = VBOX_LOGGROUP_NAMES;
    int rc2 = RTLogCreate(&pReleaseLogger, 0, "all", "VBOX_RELEASE_LOG",
                          RT_ELEMENTS(s_apszGroups), &s_apszGroups[0], RTLOGDEST_USER, NULL);
    /* This may legitimately fail if we are using the mini-runtime. */
    if (RT_SUCCESS(rc2))
        RTLogRelSetDefaultInstance(pReleaseLogger);
#endif

    return VINF_SUCCESS;
}
int main(int argc, char * argv[])
{
  char achBuf[PIPESIZE];
  char achBuf2[PIPESIZE];
  char szFailName[CCHMAXPATH];

  int rc;
  HFILE hfNew;
  HFILE hfSave;
  HPIPE hpR, hpW;

  HFILE hfNew2;
  HFILE hfSaveOutput;
  HPIPE hpR2, hpW2;


  ULONG cbRead, cbRead2, cbWritten;
  HWND hwndNotify;
  char *text;
  char *mem;
  char *ptrLocalMem;
  int a;


  UCHAR LoadError[CCHMAXPATH]= {0};
  RESULTCODES ChildRC= {0};
  PID pidChild;
  FILE* fh;
  char* pipePtr;
  char* fifoPtr;
  FILE * pipe;
  LONG writtenB=0;
  LONG delta=0;
  LONG lNoFix=0;
  int iFifo=0;
  BOOL bPriority=FALSE;
  FILE *file;

  rc=-1;

  /*
    argv[0]=progname
    argv[1]=HWND 
    argv[2]=cdrecord path
    argv[3]=installation dir
    argv[4]=Parameter filename
    argv[5]=logfilename
   */

  for(a=0;a<argc;a++)
    printf("%d:  %s\n", a, argv[a]);
    
  if(argc<6) {
    message();
    exit(-1);
  }  

  hwndNotify=atol(argv[1]);

  if((ptrLocalMem=malloc(SHAREDMEM_SIZE))==NULL){
    WinPostMsg(hwndNotify,WM_APPTERMINATENOTIFY,MPFROMLONG(ACKEY_PRINTSIZE),MPFROMLONG(0));
    exit(255);
  }
  /* Open file with parameters */
  if((file=fopen(argv[4],"rb"))==NULL){
    WinPostMsg(hwndNotify,WM_APPTERMINATENOTIFY,MPFROMLONG(ACKEY_PRINTSIZE),MPFROMLONG(0));
    exit(255);
  }
  
  /* Copy command line to local memory */
  fread(ptrLocalMem, sizeof(char), SHAREDMEM_SIZE, file);
  fclose(file);

  /* Open log file */
  snprintf(LoadError, sizeof(LoadError), "%s\\%s",argv[3], argv[5]);
  fh=fopen(LoadError,"a");

  /* Get cmd line */
  text=ptrLocalMem;
  
  /* find pipe char */
  pipePtr=strchr(text,'|');
  
  mem=strstr(text,"-print-size");
  for(a=0;a<strlen("-print-size");a++) {
    *mem=' ';
    mem++;
  }
  
  if(fh) {
    fputs("\n---------------------------------------------------------------\n",fh);
    fputs("Starting the helper \"",fh);
    fputs(argv[0],fh);
    fputs("\" with the following parameters:\n",fh);
    fputs(text,fh);
    fputs("\n\n",fh);
  }
  
  /* Find end of mkisofs path */
  mem=strchr(text,'"');
  *mem=0;
  
  if(pipePtr) {
    *pipePtr=0;
    pipePtr++;
    *pipePtr=0;
    pipePtr++;
  }
  /* pipePtr points to begin of cdrecord path */
  if(strstr(pipePtr,"-nofix"))
    lNoFix=1;
  
  /* FIFO size. Needing it to know when FIFO is filled. We raise the priority of the mkisofs
     process then.
     */
  if((fifoPtr=strstr(pipePtr,"fs="))!=NULLHANDLE) {
    fifoPtr+=3;
    iFifo=atoi(fifoPtr);
    iFifo*=1024*1024;
  }        
  
#ifdef DEBUG    
  //      DosFreeMem(pvSharedMem);
  free(ptrLocalMem);
  WinPostMsg(hwndNotify,WM_APPTERMINATENOTIFY,MPFROMLONG(ACKEY_ONTHEFLY),MPFROMSHORT(rc));
  exit(0);
#endif

  fflush(stdout);
  fflush(stderr);
  
  hfSaveOutput = -1;// Get new handle
  hfNew2 = HF_STDOUT;
  
  if(!DosDupHandle(HF_STDOUT, &hfSaveOutput)) {
        if(!DosCreatePipe(&hpR2, &hpW2, PIPESIZE)) {
          if(!DosDupHandle(hpW2, &hfNew2)){/* Duplicates standard out handle */

            /* Start mkisofs */
            rc=DosExecPgm(LoadError,sizeof(LoadError),EXEC_ASYNCRESULT, text,NULL,&ChildRC,text);
            sprintf(achBuf,"DosExecPgm() for mkisofs returned: %d\n",rc);
            if(fh)
              fputs(achBuf,fh);
            
            DosClose(hpW2);                       /* Closes write handle to ensure     */
            /* Notification at child termination */
            
            DosDupHandle(hfSaveOutput, &hfNew2);        /* Brings stdout back                */   
            /* pipePtr points to begin of cdrecord path */
            pipe=popen(pipePtr,"wb");

            /*
             * Read from the pipe and write to the screen
             * as long as there are bytes to read.
             */          
            do {
              /* Read from mkisofs */
              DosRead(hpR2, achBuf2, sizeof(achBuf2), &cbRead2);

              /* Read output of cdrecord */
              //DosRead(hpR, achBuf, sizeof(achBuf), &cbRead);
              //DosWrite(HF_STDERR, achBuf, cbRead, &cbWritten);
              //   sscanf(achBuf,"%[^=]= %ld",szFailName,&size);       

              /* Write output of mkisofs */
              if(cbRead2)
                fwrite(achBuf2,sizeof(BYTE),cbRead2,pipe);
              
              delta+=cbRead2;
              writtenB+=cbRead2;
              if(delta>=PIPESIZE*200) {
                delta=0;
                WinPostMsg(hwndNotify,WM_APPTERMINATENOTIFY,MPFROMLONG(ACKEY_MBWRITTEN),MPFROMLONG(writtenB));
              }
              if(writtenB>=iFifo && !bPriority) {
                fputs("FIFO filled, increasing priority of mkisofs process.\n", fh);
                bPriority=TRUE;
                rc=DosSetPriority(PRTYS_PROCESS,PRTYC_TIMECRITICAL,30,ChildRC.codeTerminate);
                sprintf(LoadError,"DosSetPriority() returned: %d (should be 0)\n", rc);
                fputs(LoadError,fh);
                fputs("Increasing priority of the on-the-fly helper process.\n",fh);
                // rc=DosSetPriority(PRTYS_PROCESS,PRTYC_TIMECRITICAL,20,0);
                /* Is this kind of priority setting ok? */
                rc=DosSetPriority(PRTYS_PROCESS,PRTYC_TIMECRITICAL,30,0);
                sprintf(LoadError,"DosSetPriority() returned: %d (should be 0)\n", rc);
                fputs(LoadError,fh);
              }

            } while(cbRead2);

            WinPostMsg(hwndNotify,WM_APPTERMINATENOTIFY,MPFROMLONG(ACKEY_MBWRITTEN),MPFROMLONG(writtenB));
            /*  mark EOF in pipe */        
            ungetc(EOF,pipe);
            /* Tell the PM wrapper that all the data is transfered to cdrecord */
            WinPostMsg(hwndNotify,WM_APPTERMINATENOTIFY,MPFROMLONG(ACKEY_FIXATING),MPFROMLONG(lNoFix));            
            /* Wait for cdrecord process to end */
            rc=pclose(pipe);
          
            DosClose(hpR2);
        
          }
        }
      }/* if(!DosDupHandle(HF_STDERR, &hfSave)) */
      DosWaitChild(0,DCWW_WAIT,&ChildRC,&pidChild,0);

      free(ptrLocalMem);
      //  DosFreeMem(pvSharedMem);
      if(fh) {
        sprintf(achBuf,"CDRecord returned: %d\n",rc);
        fputs(achBuf,fh);
        fclose(fh);
      }
   
  /* Send msg. to the notification window */
  WinPostMsg(hwndNotify,WM_APPTERMINATENOTIFY,MPFROMLONG(ACKEY_ONTHEFLY),MPFROMSHORT(rc));
}
Exemple #18
0
static int connect_pipe( FILE *fp, const CHAR_TYPE *command, int *handles,
                         int readOrWrite, int textOrBinary )
/************************************************************************/
{
#if defined( __NT__ )
    BOOL                rc;
    HANDLE              osHandle;
    HANDLE              oldHandle;
#elif defined( __WARP__ )
    APIRET              rc;
    HFILE               osHandle;
    HFILE               oldHandle;
#elif defined( __OS2__ )
    USHORT              rc;
    HFILE               osHandle;
    HFILE               oldHandle;
#endif

    if( readOrWrite == 'w' ) {
        /*** Change the standard input handle for process inheritance ***/
#if defined( __NT__ )
        osHandle = GetStdHandle( STD_INPUT_HANDLE );        /* get old */
        if( osHandle == INVALID_HANDLE_VALUE ) {
            return( 0 );
        }
        oldHandle = osHandle;
        rc = SetStdHandle( STD_INPUT_HANDLE,                /* set new */
                           (HANDLE)_os_handle(handles[0]) );
        if( rc == FALSE ) {
            SetStdHandle( STD_INPUT_HANDLE, oldHandle );
            return( 0 );
        }
#elif defined( __OS2__ )
        oldHandle = (HFILE)0xFFFFFFFF;      /* duplicate standard input */
        rc = DosDupHandle( STDIN_HANDLE, &oldHandle );
        if( rc != NO_ERROR )  return( 0 );
        osHandle = STDIN_HANDLE;            /* use new standard input */
        rc = DosDupHandle( (HFILE)_os_handle(handles[0]), &osHandle );
        if( rc != NO_ERROR ) {
            DosClose( oldHandle );
            return( 0 );
        }
#endif

        /*** Spawn the process and go home ***/
        if( spawn_it( fp, command ) == 0 ) {
            return( 0 );
        }
#if defined( __NT__ )
        SetStdHandle( STD_INPUT_HANDLE, oldHandle );
#elif defined( __OS2__ )
        osHandle = STDIN_HANDLE;
        rc = DosDupHandle( oldHandle, &osHandle );
#endif
        close( handles[0] );        /* parent process should close this */
    } else {
        /*** Change the standard output handle for process inheritance ***/
#if defined( __NT__ )
        osHandle = GetStdHandle( STD_OUTPUT_HANDLE );       /* get old */
        if( osHandle == INVALID_HANDLE_VALUE ) {
            return( 0 );
        }
        oldHandle = osHandle;
        rc = SetStdHandle( STD_OUTPUT_HANDLE,               /* set new */
                           (HANDLE)_os_handle(handles[1]) );
        if( rc == FALSE ) {
            SetStdHandle( STD_OUTPUT_HANDLE, oldHandle );
            return( 0 );
        }
#elif defined( __OS2__ )
        oldHandle = (HFILE)0xFFFFFFFF;      /* duplicate standard input */
        rc = DosDupHandle( STDOUT_HANDLE, &oldHandle );
        if( rc != NO_ERROR ) {
            return( 0 );
        }
        osHandle = STDOUT_HANDLE;           /* use new standard input */
        rc = DosDupHandle( (HFILE)_os_handle(handles[1]), &osHandle );
        if( rc != NO_ERROR ) {
            DosClose( oldHandle );
            return( 0 );
        }
#endif

        /*** Spawn the process and go home ***/
        if( spawn_it( fp, command ) == 0 ) {
            return( 0 );
        }
#if defined( __NT__ )
        SetStdHandle( STD_OUTPUT_HANDLE, oldHandle );
#elif defined( __OS2__ )
        osHandle = STDOUT_HANDLE;
        rc = DosDupHandle( oldHandle, &osHandle );
#endif
        close( handles[1] );        /* parent process should close this */
    }

    return( 1 );
}
int main(int argc, char * argv[])
{
	int i;
	char cmdLine[CCHMAXPATH*4]={0};
	char * chrPtr;	
    char * chrPtr2;
	HWND hwndNotify;
	char exeName[CCHMAXPATH];//="g:\\projects_working\\audiocpy\\cdrecord.exe";
	char chrError[CCHMAXPATH];
	RESULTCODES resultCodes;
	ULONG rc,ulAction;
    int a;

    char puffer[1024];

    LONG lValue1=0;
    LONG lValue2=0;

    /* Vars for check size */
  int iLeadin;
  int iLeadout;
  int size;
  HFILE hfNew;
  HFILE hfSave;
  HPIPE hpR, hpW;
  ULONG cbRead, cbWritten;
  BOOL bBreak=TRUE;
  char *text,*text2;
  CHAR achBuf[PIPESIZE]={0};
  CHAR szFailName[CCHMAXPATH];
  RESULTCODES ChildRC= {0};
  PID pidChild;
  /*
    argv[0]: progname
    argv[1]: hwnd
    argv[2]: cdrecord path
    argv[3]: dev=x,y,z
   */

    /* Have to check if argc is really 4 */
    if(argc<4) {
      message();
      exit(-1);
    }

    /* Print the parameters in VIO window */
    printf("argc:%d\n",argc);  
    for(a=0;a<argc;a++)
      {
        printf("%d: %s\n",a,argv[a]);
      }
    printf("\n");

    hwndNotify=atol(argv[1]);
    /* Error: no cdrecord options given */
    if(argc<4) {
      WinPostMsg(hwndNotify,WM_APPTERMINATENOTIFY,MPFROMLONG(lValue1),MPFROMLONG(lValue2));
      return;
    }

	/* Get input */
    sprintf(exeName,"%s",argv[2]);// cdrecord/2 path

    for(i=3;i<argc;i++) {
      /* Find 'dev=' in option string */
      chrPtr=strstr(argv[i],"dev=");
      if(chrPtr!=NULL)i=argc;
    }


    /* Build cdrecord/2 cmd-line */
    sprintf(cmdLine,"%s",exeName);
    if((chrPtr=strrchr(cmdLine, 0))==NULL) {
      WinPostMsg(hwndNotify,WM_APPTERMINATENOTIFY,MPFROMLONG(0),MPFROMLONG(0));
      return;
    }
	chrPtr++;
	sprintf(chrPtr,"%s -msinfo", argv[3]);

	if(DosCreatePipe(&hpR,&hpW,1024)) {
      WinPostMsg(hwndNotify,WM_APPTERMINATENOTIFY,MPFROMLONG(0),MPFROMLONG(0));
      return;
    }
    if((chrPtr=strrchr(cmdLine, 0))==NULL) {
      WinPostMsg(hwndNotify,WM_APPTERMINATENOTIFY,MPFROMLONG(0),MPFROMLONG(0));
      return;
    }

    /* Save stdout */
    hfSave=-1;
    if(!DosDupHandle(HF_STDOUT,&hfSave)){/* Saves standard  handle      *//* Saves standard  handle      */
      
      /* Redirect stdout */
      hfNew=HF_STDOUT;
      if(!DosDupHandle(hpW,&hfNew)) {
        
        /* start cdrecord/2 */
        rc=DosExecPgm(chrError,sizeof(chrError),EXEC_ASYNC,cmdLine,0,&resultCodes,exeName);
        fprintf(stderr,"DosExecPgm() for CDRecord/2 returned: %d\n",rc);

        DosClose(hpW);                       /* Closes write handle to ensure     */
        /* Notification at child termination */
        DosDupHandle(hfSave, &hfNew);        /* Brings stdout back                */

        /*
         * Read from the pipe and write to the screen
         * as long as there are bytes to read.
         */

        do {
          /* Retrieve output */
          rc=DosRead(hpR,puffer,sizeof(puffer),&cbRead);
          DosWrite(HF_STDERR, puffer, cbRead, &cbWritten);

          if(cbRead>2) {
            lValue1=atol(puffer);// Previous session start sector
            puffer[1023]=0; //Make sure we have a terminating zero!
            chrPtr=strchr(puffer,',');
            chrPtr++;
            lValue2=atol(chrPtr);
          }
        } while(cbRead);

        DosClose(hpR);
        bBreak=FALSE;
      }/* if(!DosDupHandle(hpW,&hfNew)) */
    }/* if(!DosDupHandle(HF_STDOUT,&hfSave)) */
    /* Get leadin and leadout */

    if(!bBreak) {
      /* Now query size */
      sprintf(achBuf,"%s",argv[2]);/* cdrecord path */
      text=strchr(achBuf,0);
      if(!text) {
        WinPostMsg(hwndNotify,WM_APPTERMINATENOTIFY,MPFROMLONG(0),MPFROMLONG(0));    
      }
      text++;
      sprintf(text,"%s -toc -v", argv[3]);
      printf("Parameters for size query: %s\n",text);
      text=achBuf; 
      printf("Cdrecord path is: %s\n",text);

      /* Redirect stdout */ 
      hfSave = -1;// Get new handle
      hfNew = HF_STDOUT;
      
      if(!DosDupHandle(HF_STDOUT, &hfSave)){    /* Saves standard  handle      */
        if(!DosCreatePipe(&hpR, &hpW, PIPESIZE)){ /* Creates pipe            */
          
          /* If the pipe size is smaller than the output of the child the system() call blocks.
             So create the pipe big enough. */
          
          if(!DosDupHandle(hpW, &hfNew)){           /* Duplicates standard output handle */
            
            /* start CDRecord/2 */
            rc=DosExecPgm(szFailName,sizeof(szFailName),EXEC_ASYNCRESULT, text,NULL,&ChildRC, text);
            fprintf(stderr,"DosExecPgm() for CDRecord/2 returned: %d\n",rc);
            /*
              rc=system(text);
              */
            
            DosClose(hpW);                       /* Closes write handle to ensure     */
            /* Notification at child termination */
            DosDupHandle(hfSave, &hfNew);        /* Brings stdout back                */
            
            /*
             * Read from the pipe and write to the screen
             * as long as there are bytes to read.
             */
            
            do {
              DosRead(hpR, achBuf, sizeof(achBuf), &cbRead);
              DosWrite(HF_STDERR, achBuf, cbRead, &cbWritten);
              
              text=strstr(achBuf,"ATIP");
              
              if(text){
                /* Check if we have a lead in section */
                text2=strstr(text,"in:");
                if(text2) {
                  /* Yes, we have a lead in. Seems to be a blank disk. Find lead out now */
                  iLeadin=0;
                  text2++;
                  text=strstr(text2,"ATIP");/* Second ATIP shows lead out of blank disk */
                  if(text)
                    sscanf(text,"%[^:]: %ld",szFailName,&iLeadout);
                }/* if(text2) */
                else {
                  /* No lead in section. It seems to be a disk with some tracks already written */
                  sscanf(text,"%[^:]: %ld",szFailName,&iLeadout); /* ATIP shows disk lead out */
                  text2=strstr(text,"lout");
                  if(!text2){/* Error */
                    iLeadin=iLeadout;/* Set disk size to zero as error */
                    break;
                  }
                  /* Lead out of track is lead in of next track */
                  sscanf(text2,"%[^:]: %ld",szFailName,&iLeadin);
                }
              }
            } while(cbRead);          
            printf("Leadin is  %d \n",iLeadin); /* We use stdout because stderr is redirected */
            printf("Leadout is  %d \n",iLeadout);
            DosClose(hpR);
          }
        }
      }/* if(!DosDupHandle(HF_STDERR, &hfSave)) */      

      DosWaitChild(DCWA_PROCESS, DCWW_WAIT,&ChildRC, &pidChild, ChildRC.codeTerminate);
      if(ChildRC.codeResult!=0) {
        WinPostMsg(hwndNotify,WM_APPTERMINATENOTIFY,MPFROMLONG(0),MPFROMLONG(0));
        exit(0);
      }

      /* Calculate free space */
      size=iLeadout-iLeadin;
      if(iLeadin) {
        /* Because iLeadin isn't zero, the disk seems to be a disk with already written session.
           11400 sectors must be substracted from the size as lead in for the next session */
        if(size<11400)
          size=0;
        else
          size-=11400;
      }
    }
    printf("1. sector: %d\n2. sector: %d\n", lValue1, lValue2);

    /* The following kombinations of leadin, out, 1. sector and 2. sector are possible:
       Open CD with previous session:  xxx,  xxx,  ???,  xxx
       Empty CD:                       0  ,  xxx,  0  ,  0
       Closed CD:                      0  ,  0  ,  0  ,  0 (???)
       Closed CD:                      xxx,  xxxx,  0  ,  0
       No CD:                          0  ,  0  ,  0  ,  0
       */
    /* Full or no CD -> Error */
    if(!lValue1 && !lValue2 && !iLeadin && !iLeadout) {
      WinPostMsg(hwndNotify,WM_APPTERMINATENOTIFY,MPFROMLONG(0),MPFROMLONG(0));
      exit(0);
    }
    if(!lValue1 && !lValue2 && iLeadin && iLeadout) {
      WinPostMsg(hwndNotify,WM_APPTERMINATENOTIFY,MPFROMLONG(0),MPFROMLONG(0));
      exit(0);
    }

    /* Empty CD. Mark it by sending 1 for the sectors */
    if(!lValue1 && !lValue2  && iLeadout) {
      WinPostMsg(hwndNotify,WM_APPTERMINATENOTIFY,MPFROMLONG(1),MPFROMLONG(1));
      exit(0);
    }

	/* Send the two values to our notification window */
    WinPostMsg(hwndNotify,WM_APPTERMINATENOTIFY,MPFROMLONG(lValue1),MPFROMLONG(lValue2));
    exit(0);
}
Exemple #20
0
int main(VOID) {



HFILE    ReadHandle     = NULLHANDLE; /* Read handle of pipe */

HFILE    WriteHandle    = NULLHANDLE; /* Write handle of pipe */

HFILE    NewReadHandle  = (HFILE) -1; /* Duplicate read handle */

HFILE    NewWriteHandle = (HFILE) 10; /* Duplicate write handle */

ULONG    PipeSize       = 42;         /* Size of pipe */

APIRET   rc             = NO_ERROR;   /* API return code */



rc = DosCreatePipe ( &ReadHandle, &WriteHandle, PipeSize );

if (rc != NO_ERROR) {

   printf("DosCreatePipe error: return code = %u\n", rc);

   return 1;

}

      /* Duplicate Read Handle of Pipe - use next available handle */



rc = DosDupHandle ( ReadHandle, &NewReadHandle );

if (rc != NO_ERROR) {

   printf("DosDupHandle error: return code = %u\n", rc);

   return 1;

}

      /* Duplicate Write Handle of Pipe - use handle 10 */



rc = DosDupHandle ( ReadHandle, &NewWriteHandle );

if (rc != NO_ERROR) {

   printf("DosDupHandle error: return code = %u\n", rc);

   return 1;

}



printf("Handles are: Read:%u  Write:%u  NewRead:%u  NewWrite:%u\n",

            ReadHandle, WriteHandle, NewReadHandle, NewWriteHandle);



return NO_ERROR;

}
Exemple #21
0
int main( void ) {

    unsigned long action;
    char buffer[32];
    struct messagequeue chtmsgq;
    struct clienthandlerthreadparameters chtp;
    unsigned long count;
    struct connectthreadparameters ctp;
    HFILE hfcon;
    HFILE hfstdout;
    struct message * msg;
    APIRET rc;
    int running;

    /*  Reopen file 1 in case the user has redirected output.  */

    DosOpen( "CON", &hfcon, &action, 0, FILE_NORMAL,
            OPEN_ACTION_FAIL_IF_NEW|OPEN_ACTION_OPEN_IF_EXISTS,
            OPEN_FLAGS_FAIL_ON_ERROR|OPEN_FLAGS_SEQUENTIAL|
                OPEN_SHARE_DENYNONE|OPEN_ACCESS_WRITEONLY,
            NULL );
    hfstdout = HFILE_STDOUT;
    DosDupHandle(hfcon,&hfstdout);

    /*  Unbuffer stdout.  */

    setbuf(stdout,NULL);

    /*  Header stuff.  */

    printf("tserver v%d.%03d Client/Server Demonstration Server\n",
            TSERVER_VERSION,TSERVER_PATCHLEVEL);

    /*  Install break handlers to catch ^C and Ctrl-Break.  */

    signal(SIGINT,sigbreak);
    signal(SIGBREAK,sigbreak);

    /*  Begin application initialization ...  */

    printf("Server is initializing - please wait ... ");

    /*  Initialize mainmsgq.  */

    DosCreateMutexSem(NULL,&mainmsgq.access,0,FALSE);
    mainmsgq.q = NULL;
    mainmsgq.qtail = &mainmsgq.q;
    DosCreateEventSem(NULL,&mainmsgq.available,0,FALSE);

    /*  Start the connect thread.  */

    DosCreateEventSem(NULL,&ctp.initialized,0,FALSE);
    ctp.maxpipes = ( unsigned char ) NP_UNLIMITED_INSTANCES;
    ctp.pipename = "\\pipe\\time";
    DosCreateEventSem(NULL,&ctp.shutdown,0,FALSE);
    ctp.msgq = &mainmsgq;
    DosCreateEventSem(NULL,&ctp.terminated,0,FALSE);

    _beginthread( connectthread, NULL, 8192, ( void * ) &ctp );
    DosWaitEventSem(ctp.initialized,SEM_INDEFINITE_WAIT);

    DosCloseEventSem(ctp.initialized);

    /*  Start the client handler thread.  */

    DosCreateMutexSem(NULL,&chtmsgq.access,0,FALSE);
    chtmsgq.q = NULL;
    chtmsgq.qtail = &chtmsgq.q;
    DosCreateEventSem(NULL,&chtmsgq.available,0,FALSE);

    DosCreateEventSem(NULL,&chtp.initialized,0,FALSE);
    chtp.inmsgq = &chtmsgq;
    chtp.outmsgq = &mainmsgq;
    DosCreateEventSem(NULL,&chtp.terminated,0,FALSE);

    _beginthread( clienthandlerthread, NULL, 8192, ( void * ) &chtp );
    DosWaitEventSem(chtp.initialized,SEM_INDEFINITE_WAIT);

    DosCloseEventSem(chtp.initialized);

    printf("completed\n\n");

    /*  Initialization completed.  */

    printf( "%s Server is running.\n", timestamp(buffer) );

    running = !0;

    while ( running ) {

        printf( "\r%s ", timestamp(buffer) );

        /*  Wait one second for a message to hit the queue.  If one      **
        **  arrives, handle it, otherwise just update the timer.         */

        rc = DosWaitEventSem(mainmsgq.available,1000);

        if ( rc != ERROR_TIMEOUT )

            /*  Loop until message queue is empty ( break below ).  */

            while ( !0 ) {

                DosRequestMutexSem(mainmsgq.access,SEM_INDEFINITE_WAIT);

                msg = mainmsgq.q;
                if ( msg != NULL ) {
                    mainmsgq.q = msg->next;
                    /*  If last message dequeued, reset tail pointer.  */
                    if ( mainmsgq.q == NULL )
                        mainmsgq.qtail = &mainmsgq.q;
                    }

                DosResetEventSem(mainmsgq.available,&count);

                DosReleaseMutexSem(mainmsgq.access);

                /*  Break out of inner loop if last message pulled.  */

                if ( msg == NULL )
                    break;

                /*  Update the timer ...  */

                printf( "\r%s ", timestamp(buffer) );

                switch ( msg->id ) {

                    case closed:
                        /*  Client disconnected.  */
                        printf("Closed pipe %lu.\n",
                                msg->data.closeddata.hpipe);
                        break;

                    case connected:
                        /*  Client connected.  Display message, then     **
                        **  pass the pipe handle to the client handler.  */
                        printf("Connected pipe %lu.\n",
                                msg->data.connecteddata.hpipe);
                        DosRequestMutexSem(chtmsgq.access,
                                SEM_INDEFINITE_WAIT);
                        *chtmsgq.qtail =
                                malloc( sizeof( struct message ) );
                        (*chtmsgq.qtail)->id = connected;
                        (*chtmsgq.qtail)->data.connecteddata.hpipe =
                                msg->data.connecteddata.hpipe;
                        (*chtmsgq.qtail)->next = NULL;
                        DosPostEventSem(chtmsgq.available);
                        DosReleaseMutexSem(chtmsgq.access);
                        break;

                    case ctclosed:
                        /*  Connect thread has shut down prematurely.    **
                        **  This will occur if there is an error in      **
                        **  that thread.                                 */
                        printf(
                                "Connect thread died - NO NEW CLIENTS MAY "
                                    "CONNECT.\n");
                        break;

                    case cterror:
                        /*  Display error message from the connect       **
                        **  thread.                                      */
                        if ( msg->data.cterrordata.ec == pipedisconnected )
                            printf("Disconnected from pipe %lu.\n",
                                    msg->data.cterrordata.hpipe);
                          else
                            printf("Error %d in connect thread.\n",
                                    msg->data.cterrordata.ec);
                        break;

                    case executing:
                        /*  Log informative message.  */
                        printf("Pipe %d executing: %s.\n",
                                msg->data.executingdata.hpipe,
                                msg->data.executingdata.cmd);
                        break;

                    case shutdownreq:
                        printf("Shutting down.\n");
                        running = 0;
                        break;

                    case breakhit:
                        printf("**** break ****\n");
                        running = 0;
                        break;

                    }

                free(msg);

                }

        }

    /*  Begin termination ...  */

    printf("\nServer is shutting down - please wait ... ");

    /*  Post shutdown message to client handler thread.  */

    DosRequestMutexSem(chtmsgq.access,SEM_INDEFINITE_WAIT);
    *chtmsgq.qtail = malloc( sizeof( struct message ) );
    (*chtmsgq.qtail)->id = shutdownreq;
    (*chtmsgq.qtail)->next = NULL;
    DosPostEventSem(chtmsgq.available);
    DosReleaseMutexSem(chtmsgq.access);

    DosWaitEventSem(chtp.terminated,SEM_INDEFINITE_WAIT);

    DosCloseEventSem(chtp.terminated);

    /*  Clear out any messages remaining in the queue.  */

    while ( chtmsgq.q != NULL ) {
        msg = chtmsgq.q;
        chtmsgq.q = msg->next;
        free(msg);
        }

    DosCloseEventSem(chtmsgq.available);
    DosCloseMutexSem(chtmsgq.access);

    /*  Post shutdown semaphore in connect thread.  */

    DosPostEventSem(ctp.shutdown);
    DosWaitEventSem(ctp.terminated,SEM_INDEFINITE_WAIT);

    DosCloseEventSem(ctp.shutdown);
    DosCloseEventSem(ctp.terminated);

    /*  All threads shut down.  Clear out the main message queue.  */

    while ( mainmsgq.q != NULL ) {
        msg = mainmsgq.q;
        mainmsgq.q = msg->next;
        free(msg);
        }

    DosCloseEventSem(mainmsgq.available);
    DosCloseMutexSem(mainmsgq.access);

    printf("completed\n");

    /*  Outta here ...  */

    return 0;

    }
Exemple #22
0
    BreakPoint( OpenFile( name, mode, flags ) );
}


static void doClose( HFILE hdl )
{
    BreakPoint( DosClose( hdl ) );
}

void DoDupFile( HFILE old, HFILE new )
{
    HFILE       new_t;
    USHORT      rc;

    new_t = new;
    rc = DosDupHandle( old, &new_t );
    if( rc != 0 ) {
        BreakPoint( NIL_DOS_HANDLE );
    } else {
        BreakPoint( new_t );
    }
}


static char stack[1024];


long TaskExecute( excfn rtn )
{
    long        retval;