Example #1
0
static void MZ_Launch( LPCSTR cmdtail, int length )
{
  TDB *pTask = GlobalLock16( GetCurrentTask() );
  BYTE *psp_start = PTR_REAL_TO_LIN( DOSVM_psp, 0 );
  DWORD rv;
  SYSLEVEL *lock;

  MZ_FillPSP(psp_start, cmdtail, length);
  pTask->flags |= TDBF_WINOLDAP;

  /* DTA is set to PSP:0080h when a program is started. */
  pTask->dta = MAKESEGPTR( DOSVM_psp, 0x80 );

  GetpWin16Lock( &lock );
  _LeaveSysLevel( lock );

  ResumeThread(dosvm_thread);
  rv = DOSVM_Loop(dosvm_thread);

  CloseHandle(dosvm_thread);
  dosvm_thread = 0; dosvm_tid = 0;
  CloseHandle(loop_thread);
  loop_thread = 0; loop_tid = 0;

  VGA_Clean();
  ExitProcess(rv);
}
Example #2
0
static DWORD MZ_Launch( LPCSTR cmdtail, int length )
{
  TDB *pTask = GlobalLock16( GetCurrentTask() );
  BYTE *psp_start = PTR_REAL_TO_LIN( DOSVM_psp, 0 );
  DWORD rv;
  SYSLEVEL *lock;
  MSG msg;

  MZ_FillPSP(psp_start, cmdtail, length);
  pTask->flags |= TDBF_WINOLDAP;

  /* DTA is set to PSP:0080h when a program is started. */
  pTask->dta = MAKESEGPTR( DOSVM_psp, 0x80 );

  GetpWin16Lock( &lock );
  _LeaveSysLevel( lock );

  /* force the message queue to be created */
  PeekMessageW(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);

  ResumeThread(dosvm_thread);
  rv = DOSVM_Loop(dosvm_thread);

  CloseHandle(dosvm_thread);
  dosvm_thread = 0; dosvm_tid = 0;
  CloseHandle(loop_thread);
  loop_thread = 0; loop_tid = 0;
  if (rv) return rv;

  VGA_Clean();
  ExitProcess(0);
}
Example #3
0
/***********************************************************************
 *		MZ_Exec
 *
 * this may only be called from existing DOS processes
 */
BOOL WINAPI MZ_Exec( CONTEXT86 *context, LPCSTR filename, BYTE func, LPVOID paramblk )
{
  DWORD binType;
  STARTUPINFOA st;
  PROCESS_INFORMATION pe;
  HANDLE hFile;

  BOOL ret = FALSE;

  if(!GetBinaryTypeA(filename, &binType))   /* determine what kind of binary this is */
  {
    return FALSE; /* binary is not an executable */
  }

  /* handle non-dos executables */
  if(binType != SCS_DOS_BINARY)
  {
    if(func == 0) /* load and execute */
    {
      LPSTR fullCmdLine;
      WORD fullCmdLength;
      LPBYTE psp_start = (LPBYTE)((DWORD)DOSVM_psp << 4);
      PDB16 *psp = (PDB16 *)psp_start;
      ExecBlock *blk = (ExecBlock *)paramblk;
      LPBYTE cmdline = PTR_REAL_TO_LIN(SELECTOROF(blk->cmdline),OFFSETOF(blk->cmdline));
      LPBYTE envblock = PTR_REAL_TO_LIN(psp->environment, 0);
      int    cmdLength = cmdline[0];

      /*
       * If cmdLength is 127, command tail is truncated and environment 
       * variable CMDLINE should contain full command line 
       * (this includes filename).
       */
      if (cmdLength == 127)
      {
          FIXME( "CMDLINE argument passing is unimplemented.\n" );
          cmdLength = 126; /* FIXME */
      }

      fullCmdLength = (strlen(filename) + 1) + cmdLength + 1; /* filename + space + cmdline + terminating null character */

      fullCmdLine = HeapAlloc(GetProcessHeap(), 0, fullCmdLength);
      if(!fullCmdLine) return FALSE; /* return false on memory alloc failure */

      /* build the full command line from the executable file and the command line being passed in */
      snprintf(fullCmdLine, fullCmdLength, "%s ", filename); /* start off with the executable filename and a space */
      memcpy(fullCmdLine + strlen(fullCmdLine), cmdline + 1, cmdLength); /* append cmdline onto the end */
      fullCmdLine[fullCmdLength - 1] = 0; /* null terminate string */

      ZeroMemory (&st, sizeof(STARTUPINFOA));
      st.cb = sizeof(STARTUPINFOA);
      ret = CreateProcessA (NULL, fullCmdLine, NULL, NULL, TRUE, 0, envblock, NULL, &st, &pe);

      /* wait for the app to finish and clean up PROCESS_INFORMATION handles */
      if(ret)
      {
        WaitForSingleObject(pe.hProcess, INFINITE);  /* wait here until the child process is complete */
        CloseHandle(pe.hProcess);
        CloseHandle(pe.hThread);
      }

      HeapFree(GetProcessHeap(), 0, fullCmdLine);  /* free the memory we allocated */
    }
    else
    {
      FIXME("EXEC type of %d not implemented for non-dos executables\n", func);
      ret = FALSE;
    }

    return ret;
  } /* if(binType != SCS_DOS_BINARY) */


  /* handle dos executables */

  hFile = CreateFileA( filename, GENERIC_READ, FILE_SHARE_READ,
			     NULL, OPEN_EXISTING, 0, 0);
  if (hFile == INVALID_HANDLE_VALUE) return FALSE;

  switch (func) {
  case 0: /* load and execute */
  case 1: /* load but don't execute */
    {
      /* save current process's return SS:SP now */
      LPBYTE psp_start = (LPBYTE)((DWORD)DOSVM_psp << 4);
      PDB16 *psp = (PDB16 *)psp_start;
      psp->saveStack = (DWORD)MAKESEGPTR(context->SegSs, LOWORD(context->Esp));
    }
    ret = MZ_DoLoadImage( hFile, filename, NULL, ((ExecBlock *)paramblk)->env_seg );
    if (ret) {
      /* MZ_LoadImage created a new PSP and loaded new values into it,
       * let's work on the new values now */
      LPBYTE psp_start = (LPBYTE)((DWORD)DOSVM_psp << 4);
      ExecBlock *blk = (ExecBlock *)paramblk;
      LPBYTE cmdline = PTR_REAL_TO_LIN(SELECTOROF(blk->cmdline),OFFSETOF(blk->cmdline));

      /* First character contains the length of the command line. */
      MZ_FillPSP(psp_start, (LPSTR)cmdline + 1, cmdline[0]);

      /* the lame MS-DOS engineers decided that the return address should be in int22 */
      DOSVM_SetRMHandler(0x22, (FARPROC16)MAKESEGPTR(context->SegCs, LOWORD(context->Eip)));
      if (func) {
	/* don't execute, just return startup state */
        /*
         * From Ralph Brown:
         *  For function 01h, the AX value to be passed to the child program 
         *  is put on top of the child's stack
         */
        LPBYTE stack;
        init_sp -= 2;
        stack = (LPBYTE) CTX_SEG_OFF_TO_LIN(context, init_ss, init_sp);
        /* FIXME: push AX correctly */
        stack[0] = 0x00;    /* push AL */
        stack[1] = 0x00;    /* push AH */
	
	blk->init_cs = init_cs;
	blk->init_ip = init_ip;
	blk->init_ss = init_ss;
	blk->init_sp = init_sp;
      } else {
	/* execute by making us return to new process */
	context->SegCs = init_cs;
	context->Eip   = init_ip;
	context->SegSs = init_ss;
	context->Esp   = init_sp;
	context->SegDs = DOSVM_psp;
	context->SegEs = DOSVM_psp;
	context->Eax   = 0;
      }
    }
    break;
  case 3: /* load overlay */
    {
      OverlayBlock *blk = (OverlayBlock *)paramblk;
      ret = MZ_DoLoadImage( hFile, filename, blk, 0);
    }
    break;
  default:
    FIXME("EXEC load type %d not implemented\n", func);
    SetLastError(ERROR_INVALID_FUNCTION);
    break;
  }
  CloseHandle(hFile);
  return ret;
}