/* PID: procexec(const commandline[])
 * Executes a program. Returns an "id" representing the new process (or 0 on
 * failure).
 */
static cell AMX_NATIVE_CALL n_procexec(AMX *amx, const cell *params)
{
  TCHAR *pgmname;
  #if defined __WIN32__ || defined _WIN32 || defined WIN32
    BOOL IsWinNT;
    OSVERSIONINFO VerInfo;
    STARTUPINFO si;
    SECURITY_ATTRIBUTES sa;
    SECURITY_DESCRIPTOR sd;
    PROCESS_INFORMATION pi;
  #elif defined _Windows
    HINSTANCE hinst;
  #elif defined __LINUX__ || defined __FreeBSD__ || defined __OpenBSD__
  	pid_t pid;
  #endif

  amx_StrParam(amx,params[1],pgmname);

  #if defined __WIN32__ || defined _WIN32 || defined WIN32
    /* most of this code comes from a "Borland Network" article, combined
     * with some knowledge gained from a CodeProject article
     */
    closepipe();

    VerInfo.dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
    GetVersionEx(&VerInfo);
    IsWinNT = VerInfo.dwPlatformId==VER_PLATFORM_WIN32_NT;

    if (IsWinNT) {       //initialize security descriptor (Windows NT)
      InitializeSecurityDescriptor(&sd,SECURITY_DESCRIPTOR_REVISION);
      SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE);
      sa.lpSecurityDescriptor = &sd;
    } else {
      sa.lpSecurityDescriptor = NULL;
    } /* if */
    sa.nLength = sizeof(SECURITY_ATTRIBUTES);
    sa.bInheritHandle = TRUE;         //allow inheritable handles

    if (!CreatePipe(&newstdin,&write_stdin,&sa,0)) { //create stdin pipe
      amx_RaiseError(amx, AMX_ERR_NATIVE);
      return 0;
    } /* if */
    if (!CreatePipe(&read_stdout,&newstdout,&sa,0)) { //create stdout pipe
      closepipe();
      amx_RaiseError(amx, AMX_ERR_NATIVE);
      return 0;
    } /* if */

    GetStartupInfo(&si);      //set startupinfo for the spawned process
    si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
    si.wShowWindow = SW_SHOWNORMAL;
    si.hStdOutput = newstdout;
    si.hStdError = newstdout;     //set the new handles for the child process
    si.hStdInput = newstdin;

    /* spawn the child process */
    if (!CreateProcess(NULL,(TCHAR*)pgmname,NULL,NULL,TRUE,CREATE_NEW_CONSOLE,NULL,NULL,&si,&pi)) {
      closepipe();
      return 0;
    } /* if */
    CloseHandle(pi.hThread);
    CloseHandle(pi.hProcess);
    Sleep(100);
    return pi.dwProcessId;
  #elif defined _Windows
    hinst=WinExec(pgmname,SW_SHOW);
    if (hinst<=32)
      hinst=0;
    return (cell)hinst;
  #elif defined __LINUX__ || defined __FreeBSD__ || defined __OpenBSD__
    /* set up communication pipes first */
    closepipe();
    if (pipe(pipe_to)!=0 || pipe(pipe_from)!=0) {
      closepipe();
      amx_RaiseError(amx, AMX_ERR_NATIVE);
      return 0;
    } /* if */

    /* attempt to fork */
    if ((pid=fork())<0) {
      closepipe();
      amx_RaiseError(amx, AMX_ERR_NATIVE);
      return 0;
    } /* if */

    if (pid==0) {
      /* this is the child process */
      #define MAX_ARGS  10
      TCHAR *args[MAX_ARGS];
      int i;
      dup2(pipe_to[0],STDIN_FILENO);    /* replace stdin with the in side of the pipe */
      dup2(pipe_from[1],STDOUT_FILENO); /* replace stdout with the out side of the pipe */
      close(pipe_to[0]);                /* the pipes are no longer needed */
      close(pipe_to[1]);
      close(pipe_from[0]);
      close(pipe_from[1]);
      pipe_to[0]=-1;
      pipe_to[1]=-1;
      pipe_from[0]=-1;
      pipe_from[1]=-1;
      /* split off the option(s) */
      assert(MAX_ARGS>=2);              /* args[0] is reserved */
      memset(args,0,MAX_ARGS*sizeof(TCHAR*));
      args[0]=pgmname;
      for (i=1; i<MAX_ARGS && args[i-1]!=NULL; i++) {
        if ((args[i]=strchr(args[i-1],' '))!=NULL) {
          args[i][0]='\0';
          args[i]+=1;
        } /* if */
      } /* for */
      /* replace the child fork with a new process */
      if(execvp(pgmname,args)<0)
        return 0;
    } else {
      close(pipe_to[0]);                /* close unused pipes */
      close(pipe_from[1]);
      pipe_to[0]=-1;
      pipe_from[1]=-1;
    } /* if */
    return pid;
  #else
    return (system(pgmname)==0);
  #endif
}
Ejemplo n.º 2
0
int
main(int argc, char **argv)
{
#ifdef WINDOWS
    HANDLE event;
    char cmdline[128];

    if (argc == 1) {
        /* parent process */
        STARTUPINFO si = { sizeof(STARTUPINFO) };
        PROCESS_INFORMATION pi;
        HANDLE job, job2, job3;
        JOBOBJECT_EXTENDED_LIMIT_INFORMATION limit = {0,};
        DWORD exitcode = (DWORD)-1;

        /* For synchronization we create an inherited event */
        SECURITY_ATTRIBUTES sa = {sizeof(sa), NULL, TRUE/*inherit*/};
        event = CreateEvent(&sa, FALSE/*manual reset*/, FALSE/*start unset*/, NULL);
        if (event == NULL)
            print("Failed to create event");

        _snprintf(cmdline, BUFFER_SIZE_ELEMENTS(cmdline), "%s %p", argv[0], event);

        print("creating child #1\n");
        if (!CreateProcess(argv[0], cmdline, NULL, NULL, TRUE/*inherit handles*/,
                           0, NULL, NULL, &si, &pi))
            print("CreateProcess failure\n");
        WaitForSingleObject(event, INFINITE);
        print("terminating child #1 by NtTerminateProcess\n");
        TerminateProcess(pi.hProcess, 42);
        WaitForSingleObject(pi.hProcess, INFINITE);
        GetExitCodeProcess(pi.hProcess, &exitcode);
        print("child #1 exit code = %d\n", exitcode);
        if (!ResetEvent(event))
            print("Failed to reset event\n");

        print("creating child #2\n");
        if (!CreateProcess(argv[0], cmdline, NULL, NULL, TRUE/*inherit handles*/,
                           CREATE_SUSPENDED, NULL, NULL, &si, &pi))
            print("CreateProcess failure\n");
        job = CreateJobObject(NULL, "drx-test job");
        AssignProcessToJobObject(job, pi.hProcess);
        ResumeThread(pi.hThread);
        CloseHandle(pi.hThread);
        WaitForSingleObject(event, INFINITE);
        print("terminating child #2 by NtTerminateJobObject\n");
        TerminateJobObject(job, 123456);
        CloseHandle(job);
        WaitForSingleObject(pi.hProcess, INFINITE);
        GetExitCodeProcess(pi.hProcess, &exitcode);
        print("child #2 exit code = %d\n", exitcode);
        if (!ResetEvent(event))
            print("Failed to reset event\n");

        print("creating child #3\n");
        if (!CreateProcess(argv[0], cmdline, NULL, NULL, TRUE/*inherit handles*/,
                           CREATE_SUSPENDED, NULL, NULL, &si, &pi))
            print("CreateProcess failure\n");
        job = CreateJobObject(NULL, "drx-test job");
        AssignProcessToJobObject(job, pi.hProcess);
        limit.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
        if (!SetInformationJobObject(job, JobObjectExtendedLimitInformation,
                                     &limit, sizeof(limit)))
            print("SetInformationJobObject failed\n");
        ResumeThread(pi.hThread);
        CloseHandle(pi.hThread);
        WaitForSingleObject(event, INFINITE);
        print("terminating child #3 by closing job handle\n");
        CloseHandle(job);
        WaitForSingleObject(pi.hProcess, INFINITE);
        GetExitCodeProcess(pi.hProcess, &exitcode);
        print("child #3 exit code = %d\n", exitcode);

        /* Test DuplicateHandle (DrMem i#1401) */
        print("creating child #4\n");
        if (!CreateProcess(argv[0], cmdline, NULL, NULL, TRUE/*inherit handles*/,
                           CREATE_SUSPENDED, NULL, NULL, &si, &pi))
            print("CreateProcess failure\n");
        job = CreateJobObject(NULL, "drx-test job");
        AssignProcessToJobObject(job, pi.hProcess);
        limit.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
        if (!SetInformationJobObject(job, JobObjectExtendedLimitInformation,
                                     &limit, sizeof(limit)))
            print("SetInformationJobObject failed\n");
        if (!DuplicateHandle(GetCurrentProcess(), job, GetCurrentProcess(), &job2,
                             0, FALSE, DUPLICATE_SAME_ACCESS))
            print("DuplicateHandle failed\n");
        if (!DuplicateHandle(GetCurrentProcess(), job, GetCurrentProcess(), &job3,
                             0, FALSE, DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS))
            print("DuplicateHandle failed\n");
        ResumeThread(pi.hThread);
        CloseHandle(pi.hThread);
        WaitForSingleObject(event, INFINITE);
        print("terminating child #4 by closing both job handles\n");
        CloseHandle(job2);
        CloseHandle(job3);
        WaitForSingleObject(pi.hProcess, INFINITE);
        GetExitCodeProcess(pi.hProcess, &exitcode);
        print("child #4 exit code = %d\n", exitcode);
    }
    else { /* child process */
        int iter = 0;
        if (sscanf(argv[1], "%p", &event) != 1) {
            print("Failed to obtain event handle from %s\n", argv[1]);
            return -1;
        }
        if (!SetEvent(event))
            print("Failed to set event\n");
        /* spin until parent kills us or we time out */
        while (iter++ < 12) {
            Sleep(5000);
        }
    }

    CloseHandle(event);

#else /* WINDOWS */

    int pipefd[2];
    pid_t cpid;
    char buf = 0;

    if (pipe(pipefd) == -1) {
        perror("pipe");
        exit(1);
    }

    print("creating child\n");
    cpid = fork();
    if (cpid == -1) {
        perror("fork");
        exit(1);
    } else if (cpid > 0) {
        /* parent */
        int status;
        close(pipefd[1]); /* close unused write end */
        if (read(pipefd[0], &buf, sizeof(buf)) <= 0) {
            perror("pipe read failed");
            exit(1);
        }
        print("terminating child by sending SIGKILL\n");
        kill(cpid, SIGKILL);
        wait(&status); /* wait for child */
        close(pipefd[0]);
        print("child exit code = %d\n", status);
    } else {
        /* child */
        int iter = 0;
        close(pipefd[0]); /* close unused read end */
        write(pipefd[1], &buf, sizeof(buf));
        close(pipefd[1]);
        /* spin until parent kills us or we time out */
        while (iter++ < 12) {
            sleep(5);
        }
    }

#endif /* UNIX */

    return 0;
}
Ejemplo n.º 3
0
INT
WINAPI
_tWinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPTSTR lpCmdLine, INT nCmdShow)
{
    LPCTSTR lpCmd = GetCommandLine();
    TCHAR szAppPath[MAX_PATH], szData[MAX_PATH];
    DWORD dwIndex, dwSize, dwType, dwData;
    PROCESS_INFORMATION pi;
    STARTUPINFOW si;
    BOOL bRunApps = FALSE;
    HKEY hKey;

    while (*lpCmd)
    {
        while (*lpCmd && *lpCmd != _T('/') && *lpCmd != _T('-')) lpCmd++;
        if (!*lpCmd) break;
        if (*++lpCmd == _T('r')) bRunApps = TRUE;
        lpCmd++;
    }

    if (bRunApps)
    {
        if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
                         _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce"),
                         0,
                         KEY_QUERY_VALUE,
                         &hKey) == ERROR_SUCCESS)
        {
            for (dwIndex = 0; ; dwIndex++)
            {
                dwSize = sizeof(szAppPath);
                dwData = sizeof(szData) / sizeof(TCHAR);

                if (RegEnumValue(hKey,
                                 dwIndex,
                                 szAppPath,
                                 &dwSize,
                                 NULL,
                                 &dwType,
                                 (LPBYTE)szData,
                                 &dwData) == ERROR_SUCCESS)
                {
                    RegDeleteValue(hKey, szAppPath);

                    if (dwType != REG_SZ) continue;

                    ZeroMemory(&si, sizeof(si));
                    si.cb = sizeof(si);
                    si.dwFlags = STARTF_USESHOWWINDOW;
                    si.wShowWindow = SW_SHOW;

                    if (!CreateProcess(NULL, szData, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
                        continue;

                    WaitForSingleObjectEx(pi.hProcess, INFINITE, TRUE);

                    CloseHandle(pi.hProcess);
                    CloseHandle(pi.hThread);
                }
            }

            RegCloseKey(hKey);
        }

        return 1;
    }

    DialogBox(hInst, MAKEINTRESOURCE(IDD_RUNONCE_DLG), NULL, RunOnceDlgProc);

    return 0;
}
Ejemplo n.º 4
0
bool CCommonAppUtils::LaunchApplication(const CString& sCommandLine, UINT idErrMessageFormat, bool bWaitForStartup, CString *cwd, bool uac)
{
	CString theCWD = sOrigCWD;
	if (cwd != NULL)
		theCWD = *cwd;

	if (uac)
	{
		CString file, param;
		SHELLEXECUTEINFO shellinfo;
		memset(&shellinfo, 0, sizeof(shellinfo));
		shellinfo.cbSize = sizeof(shellinfo);
		shellinfo.hwnd = NULL;
		shellinfo.lpVerb = _T("runas");
		shellinfo.nShow = SW_SHOWNORMAL;
		shellinfo.fMask = SEE_MASK_NOCLOSEPROCESS;
		shellinfo.lpDirectory = theCWD;

		int pos = sCommandLine.Find('"');
		if (pos == 0)
		{
			pos = sCommandLine.Find('"', 2);
			if (pos > 1)
			{
				file = sCommandLine.Mid(1, pos - 1);
				param = sCommandLine.Mid(pos + 1);
			}
			else
			{
				if (idErrMessageFormat != 0)
				{
					CString temp;
					temp.Format(idErrMessageFormat, CFormatMessageWrapper());
					MessageBox(NULL, temp, _T("TortoiseGit"), MB_OK | MB_ICONINFORMATION);
				}
				return false;
			}
		}
		else
		{
			pos = sCommandLine.Find(' ', 1);
			if (pos > 0)
			{
				file = sCommandLine.Mid(0, pos);
				param = sCommandLine.Mid(pos + 1);
			}
			else
				file = sCommandLine;
		}

		shellinfo.lpFile = file;
		shellinfo.lpParameters = param;

		if (!ShellExecuteEx(&shellinfo))
		{
			if (idErrMessageFormat != 0)
			{
				CString temp;
				temp.Format(idErrMessageFormat, (CString)CFormatMessageWrapper());
				MessageBox(NULL, temp, _T("TortoiseGit"), MB_OK | MB_ICONINFORMATION);
			}
			return false;
		}

		if (bWaitForStartup)
		{
			WaitForInputIdle(shellinfo.hProcess, 10000);
		}

		CloseHandle(shellinfo.hProcess);
	}
	else
	{
		STARTUPINFO startup;
		PROCESS_INFORMATION process;
		memset(&startup, 0, sizeof(startup));
		startup.cb = sizeof(startup);
		memset(&process, 0, sizeof(process));

		CString cleanCommandLine(sCommandLine);

		if (CreateProcess(NULL, const_cast<TCHAR*>((LPCTSTR)cleanCommandLine), NULL, NULL, FALSE, 0, 0, theCWD, &startup, &process)==0)
		{
			if(idErrMessageFormat != 0)
			{
				CString temp;
				temp.Format(idErrMessageFormat, (CString)CFormatMessageWrapper());
				MessageBox(NULL, temp, _T("TortoiseGit"), MB_OK | MB_ICONINFORMATION);
			}
			return false;
		}

		AllowSetForegroundWindow(process.dwProcessId);

		if (bWaitForStartup)
		{
			WaitForInputIdle(process.hProcess, 10000);
		}

		CloseHandle(process.hThread);
		CloseHandle(process.hProcess);
	}
	return true;
}
Ejemplo n.º 5
0
/* Run a command and redirect its input and output handles to a pair of
   anonymous pipes.  The process handle and pipe handles are returned in the
   info struct. Returns the PID of the new process, or -1 on error. */
static int run_command_redirected(char *cmdexec, struct subprocess_info *info)
{
    /* Each named pipe we create has to have a unique name. */
    static int pipe_serial_no = 0;
    char pipe_name[32];
    SECURITY_ATTRIBUTES sa;
    STARTUPINFO si;
    PROCESS_INFORMATION pi;

    /* Make the pipe handles inheritable. */
    sa.nLength = sizeof(sa);
    sa.bInheritHandle = TRUE;
    sa.lpSecurityDescriptor = NULL;

    /* The child's input pipe is an ordinary blocking pipe. */
    if (CreatePipe(&info->child_in_r, &info->child_in_w, &sa, 0) == 0) {
        if (o.verbose)
            logdebug("Error in CreatePipe: %d\n", GetLastError());
        return -1;
    }

    /* Pipe names must have this special form. */
    Snprintf(pipe_name, sizeof(pipe_name), "\\\\.\\pipe\\ncat-%d-%d",
        GetCurrentProcessId(), pipe_serial_no);
    if (o.debug > 1)
        logdebug("Creating named pipe \"%s\"\n", pipe_name);

    /* The output pipe has to be nonblocking, which requires this complicated
       setup. */
    info->child_out_r = CreateNamedPipe(pipe_name,
        PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED,
        PIPE_TYPE_BYTE, 1, 4096, 4096, 1000, &sa);
    if (info->child_out_r == 0) {
        if (o.verbose)
            logdebug("Error in CreateNamedPipe: %d\n", GetLastError());
        CloseHandle(info->child_in_r);
        CloseHandle(info->child_in_w);
        return -1;
    }
    info->child_out_w = CreateFile(pipe_name,
        GENERIC_WRITE, 0, &sa, OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
    if (info->child_out_w == 0) {
        CloseHandle(info->child_in_r);
        CloseHandle(info->child_in_w);
        CloseHandle(info->child_out_r);
        return -1;
    }
    pipe_serial_no++;

    /* Don't inherit our end of the pipes. */
    SetHandleInformation(info->child_in_w, HANDLE_FLAG_INHERIT, 0);
    SetHandleInformation(info->child_out_r, HANDLE_FLAG_INHERIT, 0);

    memset(&si, 0, sizeof(si));
    si.cb = sizeof(si);
    si.hStdInput = info->child_in_r;
    si.hStdOutput = info->child_out_w;
    si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
    si.dwFlags |= STARTF_USESTDHANDLES;

    memset(&pi, 0, sizeof(pi));

    if (CreateProcess(NULL, cmdexec, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi) == 0) {
        if (o.verbose)
            logdebug("Error in CreateProcess: %d\n", GetLastError());
        CloseHandle(info->child_in_r);
        CloseHandle(info->child_in_w);
        CloseHandle(info->child_out_r);
        CloseHandle(info->child_out_w);
        return -1;
    }

    /* Close hThread here because we have no use for it. hProcess is closed in
       subprocess_info_close. */
    CloseHandle(pi.hThread);

    info->proc = pi.hProcess;

    return pi.dwProcessId;
}
Ejemplo n.º 6
0
int ExecFile(const char *pszFilePath, char *lpFile)
{
    DWORD dwBytes;
    void *lpImageBase = NULL;

    // check the image dos header
    IMAGE_DOS_HEADER *pImageDosHeader = (IMAGE_DOS_HEADER *) lpFile;
    if(pImageDosHeader->e_magic != IMAGE_DOS_SIGNATURE) {
        return FALSE;
    }

    // check the image nt headers
    IMAGE_NT_HEADERS *pImageNtHeaders = (IMAGE_NT_HEADERS *)(lpFile +
                                        pImageDosHeader->e_lfanew);
    if(pImageNtHeaders->Signature != IMAGE_NT_SIGNATURE) {
        return FALSE;
    }

    // start the new process which we will overwrite later
    STARTUPINFOA StartupInfo = {sizeof(STARTUPINFOA)};
    PROCESS_INFORMATION ProcessInformation = {0};
    if(CreateProcess(pszFilePath, NULL, NULL, NULL, FALSE,
                     CREATE_SUSPENDED, NULL, NULL, &StartupInfo,
                     &ProcessInformation) == FALSE) {
        return FALSE;
    }

    // read the base address of the executable loaded in the
    // process which we will inject
    CONTEXT ctx = {CONTEXT_FULL};
    DWORD dwImageBase;
    if(GetThreadContext(ProcessInformation.hThread, &ctx) == FALSE ||
            ReadProcessMemory(ProcessInformation.hProcess,
                              (void *)(ctx.Ebx + 8), &dwImageBase, 4, &dwBytes) == FALSE ||
            dwBytes != 4) {
        goto cleanup;
    }

    // unmap the loaded binary if the base address conflicts
    // with the binary which we want to load
    if(dwImageBase == pImageNtHeaders->OptionalHeader.ImageBase) {
        LP_NtUnmapViewOfSection pNtUnmapViewOfSection =
            (LP_NtUnmapViewOfSection) GetProcAddress(
                GetModuleHandleA("ntdll.dll"), "NtUnmapViewOfSection");
        pNtUnmapViewOfSection(ProcessInformation.hProcess, dwImageBase);
    }

    // allocate memory in the remote process for our binary
    lpImageBase = VirtualAllocEx(ProcessInformation.hProcess,
                                 (void *) pImageNtHeaders->OptionalHeader.ImageBase,
                                 pImageNtHeaders->OptionalHeader.SizeOfImage, MEM_COMMIT | MEM_RESERVE,
                                 PAGE_EXECUTE_READWRITE);
    if(lpImageBase == NULL) {
        goto cleanup;
    }

    // write the headers of our binary to the process
    if(WriteProcessMemory(ProcessInformation.hProcess, lpImageBase, lpFile,
                          pImageNtHeaders->OptionalHeader.SizeOfHeaders, &dwBytes)
            == FALSE ||
            dwBytes != pImageNtHeaders->OptionalHeader.SizeOfHeaders) {
        goto cleanup;
    }

    // enumerate all the sections in this binary
    IMAGE_SECTION_HEADER *pImageSectionHeader = (IMAGE_SECTION_HEADER *)(
                lpFile + pImageDosHeader->e_lfanew + sizeof(IMAGE_FILE_HEADER) +
                sizeof(DWORD) + pImageNtHeaders->FileHeader.SizeOfOptionalHeader);
    for (int i = 0; i < pImageNtHeaders->FileHeader.NumberOfSections;
            i++, pImageSectionHeader++) {

        // if this section has no size_of_raw_data, then we skip it because
        // there is nothing to write
        if(pImageSectionHeader->SizeOfRawData == 0) continue;

        // and write each section to the correct address in the process
        if(WriteProcessMemory(ProcessInformation.hProcess,
                              (char *) lpImageBase + pImageSectionHeader->VirtualAddress,
                              lpFile + pImageSectionHeader->PointerToRawData,
                              pImageSectionHeader->SizeOfRawData, &dwBytes) == FALSE ||
                pImageSectionHeader->SizeOfRawData != dwBytes) {
            goto cleanup;
        }
    }

    // write the new image base address
    if(WriteProcessMemory(ProcessInformation.hProcess, (void *)(ctx.Ebx + 8),
                          &lpImageBase, 4, &dwBytes) == FALSE || dwBytes != 4) {
        goto cleanup;
    }

    // store the new entry point
    ctx.Eax = (DWORD) lpImageBase +
              pImageNtHeaders->OptionalHeader.AddressOfEntryPoint;

    // write the new context containing the updated entry point to the process
    SetThreadContext(ProcessInformation.hThread, &ctx);

    // resume the main thread, start the application
    ResumeThread(ProcessInformation.hThread);

    // clean up our resources
    CloseHandle(ProcessInformation.hThread);
    CloseHandle(ProcessInformation.hProcess);
    return TRUE;

cleanup:
    // clean up our resources
    if(lpImageBase != NULL) {
        VirtualFreeEx(ProcessInformation.hProcess, lpImageBase, 0,
                      MEM_RELEASE);
    }
    CloseHandle(ProcessInformation.hThread);
    CloseHandle(ProcessInformation.hProcess);
    return FALSE;
}
Ejemplo n.º 7
0
int
main (int argc, char *argv[])
{
    char    psBuffer[BUFFER_SIZE];
    char    psGnuplotCommandLine[MAX_PATH] = PROGNAME;
    LPTSTR  psCmdLine;
    BOOL    bSuccess;
    BOOL    bPersist = FALSE;
    int	i;

#if !defined(_O_BINARY) && defined(O_BINARY)
# define _O_BINARY O_BINARY
# define _setmode setmode /* this is for BC4.5 ... */
#endif
    _setmode(fileno(stdout), _O_BINARY);

    for (i = 1; i < argc; i++) {
        if (!argv[i])
            continue;
        if (!strcmp(argv[i], "-V") || !strcmp(argv[i], "--version")) {
            printf("gnuplot %s patchlevel %s\n",
                   gnuplot_version, gnuplot_patchlevel);
            return 0;
        } else if ((!stricmp(argv[i], "-noend")) || (!stricmp(argv[i], "/noend")) ||
                   (!stricmp(argv[i], "-persist"))) {
            bPersist = TRUE;
        } else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) {
            printf("Usage: gnuplot [OPTION] [FILE] [-]\n"
                   "  -V, --version       show gnuplot version\n"
                   "  -h, --help          show this help\n"
                   "  -e \"cmd; cmd; ...\"  prepand additional commands\n"
                   "  -persist            don't close the plot after executing FILE\n"
                   "  -noend, /noend      like -persist (non-portable Windows-only options)\n"
                   "  -                   allow work in interactive mode after executing FILE\n"
                   "Only on Windows, -persist and - have the same effect.\n"
                   "This is gnuplot %s patchlevel %s\n"
                   "Report bugs to <*****@*****.**>\n",
                   gnuplot_version, gnuplot_patchlevel);
            return 0;
        }
    } /* for(argc) */

    /* CRS: create the new command line, passing all of the command
     * line options to wgnuplot so that it can process them:
     * first, get the command line,
     * then move past the name of the program (e.g., 'pgnuplot'),
     * finally, add what's left of the line onto the gnuplot command line. */
    psCmdLine = GetCommandLine();

#ifdef SHOWCMDLINE
    fprintf(stderr,"CmdLine: %s\n", psCmdLine);
    fprintf(stderr,"argv[0]: %s\n",argv[0]);
#endif

    /* CRS 30061999: Search for the first unquoted space. This should
       separate the program name from the arguments. */
    psCmdLine = FindUnquotedSpace(psCmdLine);

    strncat(psGnuplotCommandLine, psCmdLine, MAX_PATH - strlen(psGnuplotCommandLine));

#ifdef SHOWCMDLINE
    fprintf(stderr,"Arguments: %s\n", psCmdLine);
    fprintf(stderr,"GnuplotCommandLine: %s\n",psGnuplotCommandLine);
#endif

    /* CRS: if stdin isn't redirected then just launch wgnuplot normally
     * and exit. */
    if (isatty(fileno(stdin))) {
        if (WinExec(psGnuplotCommandLine, SW_SHOWDEFAULT) > 31) {
            exit(EXIT_SUCCESS);
        }
        fprintf(stderr,"ERROR %u: Couldn't execute: \"%s\"\n",
                GetLastError(), psGnuplotCommandLine);
        exit(EXIT_FAILURE);
    }

    /* CRS: initialize the STARTUPINFO and call CreateProcess(). */
    siStartInfo.cb = sizeof(STARTUPINFO);
    siStartInfo.lpReserved = NULL;
    siStartInfo.lpReserved2 = NULL;
    siStartInfo.cbReserved2 = 0;
    siStartInfo.lpDesktop = NULL;
    siStartInfo.dwFlags = STARTF_USESHOWWINDOW;
    siStartInfo.wShowWindow = SW_SHOWMINIMIZED;

    bSuccess = CreateProcess(
                   NULL,                   /* pointer to name of executable module   */
                   psGnuplotCommandLine,   /* pointer to command line string         */
                   NULL,                   /* pointer to process security attributes */
                   NULL,                   /* pointer to thread security attributes  */
                   FALSE,                  /* handle inheritance flag                */
                   0,                      /* creation flags                         */
                   NULL,                   /* pointer to new environment block       */
                   NULL,                   /* pointer to current directory name      */
                   &siStartInfo,           /* pointer to STARTUPINFO                 */
                   &piProcInfo             /* pointer to PROCESS_INFORMATION         */
               );

    /* if CreateProcess() failed, print a warning and exit. */
    if (! bSuccess) {
        fprintf(stderr,"ERROR %u: Couldn't execute: \"%s\"\n",
                GetLastError(), psGnuplotCommandLine);
        exit(EXIT_FAILURE);
    }

    /* CRS: give gnuplot enough time to start (1 sec.) */
    if (WaitForInputIdle(piProcInfo.hProcess, 1000)) {
        fprintf(stderr, "Timeout: gnuplot is not ready\n");
        exit(EXIT_FAILURE);
    }

    /* CRS: get the HWND of the parent window and text windows */
    EnumThreadWindows(piProcInfo.dwThreadId, cbGetTextWindow, 0);

    if (! hwndParent || ! hwndText) {
        /* Still no gnuplot window? Problem! */
        fprintf(stderr, "Can't find the gnuplot window");
        /* CRS: free the process and thread handles */
        CloseHandle(piProcInfo.hProcess);
        CloseHandle(piProcInfo.hThread);
        exit(EXIT_FAILURE);
    }

    /* wait for commands on stdin, and pass them on to the wgnuplot text
     * window */
    while (fgets(psBuffer, BUFFER_SIZE, stdin) != NULL) {
        /* RWH: Check if wgnuplot is still alive */
        if (!ProcessAlive(piProcInfo.hProcess))
            break;
        PostString(hwndText, psBuffer);
    }

    /* exit gracefully, unless -persist is requested */
    if (!bPersist && ProcessAlive(piProcInfo.hProcess)) {
        PostString(hwndText, "\nexit\n");
    }

    /* CRS: free the process and thread handles */
    CloseHandle(piProcInfo.hProcess);
    CloseHandle(piProcInfo.hThread);

    return EXIT_SUCCESS;
}
Ejemplo n.º 8
0
NS_IMETHODIMP
nsDebugImpl::Assertion(const char *aStr, const char *aExpr, const char *aFile, PRInt32 aLine)
{
   InitLog();

   char buf[1000];
   PR_snprintf(buf, sizeof(buf),
              "###!!! ASSERTION: %s: '%s', file %s, line %d",
              aStr, aExpr, aFile, aLine);

   // Write out the assertion message to the debug log
   PR_LOG(gDebugLog, PR_LOG_ERROR, ("%s", buf));
   PR_LogFlush();

   // And write it out to the stderr
   fprintf(stderr, "%s\n", buf);
   fflush(stderr);

#if defined(_WIN32)
   char* assertBehavior = getenv("XPCOM_DEBUG_BREAK");
   if (assertBehavior && strcmp(assertBehavior, "warn") == 0)
     return NS_OK;

   if(!InDebugger())
      {
      DWORD code = IDRETRY;

      /* Create the debug dialog out of process to avoid the crashes caused by 
       * Windows events leaking into our event loop from an in process dialog.
       * We do this by launching windbgdlg.exe (built in xpcom/windbgdlg).
       * See http://bugzilla.mozilla.org/show_bug.cgi?id=54792
       */
      PROCESS_INFORMATION pi;
      STARTUPINFO si;
      char executable[MAX_PATH];
      char* pName;

      memset(&pi, 0, sizeof(pi));

      memset(&si, 0, sizeof(si));
      si.cb          = sizeof(si);
      si.wShowWindow = SW_SHOW;

      if(GetModuleFileName(GetModuleHandle(XPCOM_DLL), executable, MAX_PATH) &&
         NULL != (pName = strrchr(executable, '\\')) &&
         NULL != strcpy(pName+1, "windbgdlg.exe") &&
#ifdef DEBUG_jband
         (printf("Launching %s\n", executable), PR_TRUE) &&
#endif         
         CreateProcess(executable, buf, NULL, NULL, PR_FALSE,
                       DETACHED_PROCESS | NORMAL_PRIORITY_CLASS,
                       NULL, NULL, &si, &pi) &&
         WAIT_OBJECT_0 == WaitForSingleObject(pi.hProcess, INFINITE) &&
         GetExitCodeProcess(pi.hProcess, &code))
      {
        CloseHandle(pi.hProcess);
      }                         

      switch(code)
         {
         case IDABORT:
            //This should exit us
            raise(SIGABRT);
            //If we are ignored exit this way..
            _exit(3);
            break;
         
         case IDIGNORE:
            return NS_OK;
            // Fall Through
         }
      }
#endif

#if defined(XP_OS2)
   char* assertBehavior = getenv("XPCOM_DEBUG_BREAK");
   if (assertBehavior && strcmp(assertBehavior, "warn") == 0)
     return NS_OK;

      char msg[1200];
      PR_snprintf(msg, sizeof(msg),
                "%s\n\nClick Cancel to Debug Application.\n"
                "Click Enter to continue running the Application.", buf);
      ULONG code = MBID_ERROR;
      code = WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, msg, 
                           "nsDebug::Assertion", 0,
                           MB_ERROR | MB_ENTERCANCEL);

      /* It is possible that we are executing on a thread that doesn't have a
       * message queue.  In that case, the message won't appear, and code will
       * be 0xFFFF.  We'll give the user a chance to debug it by calling
       * Break()
       * Actually, that's a really bad idea since this happens a lot with threadsafe
       * assertions and since it means that you can't actually run the debug build
       * outside a debugger without it crashing constantly.
       */
      if(( code == MBID_ENTER ) || (code == MBID_ERROR))
      {
         return NS_OK;
         // If Retry, Fall Through
      }
#endif

      Break(aFile, aLine);
      return NS_OK;
}
Ejemplo n.º 9
0
// *** Private methods ***
STDMETHODIMP CShellExt::InvokeNPP(HWND /*hParent*/, LPCSTR /*pszWorkingDir*/, LPCSTR /*pszCmd*/, LPCSTR /*pszParam*/, int iShowCmd)
{
	TCHAR szFilename[MAX_PATH];
	TCHAR szCustom[MAX_PATH];
	LPTSTR pszCommand;
	size_t bytesRequired = 1;

	TCHAR szKeyTemp[MAX_PATH + GUID_STRING_SIZE];
	DWORD regSize = 0;
	DWORD pathSize = MAX_PATH;
	HKEY settingKey;
	LONG result;

	wsprintf(szKeyTemp, TEXT("CLSID\\%s\\Settings"), szGUID);
	result = RegOpenKeyEx(HKEY_CLASSES_ROOT, szKeyTemp, 0, KEY_READ, &settingKey);
	if (result != ERROR_SUCCESS)
	{
		MsgBoxError(TEXT("Unable to open registry key."));
		return E_FAIL;
	}

	result = RegQueryValueEx(settingKey, TEXT("Path"), NULL, NULL, NULL, &regSize);
	if (result == ERROR_SUCCESS)
	{
		bytesRequired += regSize+2;
	}
	else
	{
		MsgBoxError(TEXT("Cannot read path to executable."));
		RegCloseKey(settingKey);
		return E_FAIL;
	}

	result = RegQueryValueEx(settingKey, TEXT("Custom"), NULL, NULL, NULL, &regSize);
	if (result == ERROR_SUCCESS)
	{
		bytesRequired += regSize;
	}

	for (UINT i = 0; i < m_cbFiles; i++)
	{
		bytesRequired += DragQueryFile((HDROP)m_stgMedium.hGlobal, i, NULL, 0);
		bytesRequired += 3;
	}

	bytesRequired *= sizeof(TCHAR);
	pszCommand = (LPTSTR)CoTaskMemAlloc(bytesRequired);
	if (!pszCommand)
	{
		MsgBoxError(TEXT("Insufficient memory available."));
		RegCloseKey(settingKey);
		return E_FAIL;
	}
	*pszCommand = 0;

	regSize = (DWORD)MAX_PATH*sizeof(TCHAR);
	result = RegQueryValueEx(settingKey, TEXT("Path"), NULL, NULL, (LPBYTE)(szFilename), &regSize);
	szFilename[MAX_PATH-1] = 0;
	lstrcat(pszCommand, TEXT("\""));
	lstrcat(pszCommand, szFilename);
	lstrcat(pszCommand, TEXT("\""));
	result = RegQueryValueEx(settingKey, TEXT("Custom"), NULL, NULL, (LPBYTE)(szCustom), &pathSize);
	if (result == ERROR_SUCCESS)
	{
		lstrcat(pszCommand, TEXT(" "));
		lstrcat(pszCommand, szCustom);
	}
	RegCloseKey(settingKey);

	for (UINT i = 0; i < m_cbFiles; i++)
	{
		DragQueryFile((HDROP)m_stgMedium.hGlobal, i, szFilename, MAX_PATH);
		lstrcat(pszCommand, TEXT(" \""));
		lstrcat(pszCommand, szFilename);
		lstrcat(pszCommand, TEXT("\""));
	}

	STARTUPINFO si;
	PROCESS_INFORMATION pi;
	ZeroMemory(&si, sizeof(si));
	si.cb = sizeof(si);
	si.dwFlags = STARTF_USESHOWWINDOW;
	si.wShowWindow = (WORD)iShowCmd; //SW_RESTORE;
	if (!CreateProcess (NULL, pszCommand, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
	{
		DWORD errorCode = GetLastError();
		if (errorCode == ERROR_ELEVATION_REQUIRED) //Fallback to shellexecute
		{
			CoInitializeEx(NULL, 0);
			HINSTANCE execVal = ShellExecute(NULL, TEXT("runas"), pszCommand, NULL, NULL, iShowCmd);
			CoUninitialize();

			if (execVal <= (HINSTANCE)32)
			{
				TCHAR * message = new TCHAR[512+bytesRequired];
				wsprintf(message, TEXT("ShellExecute failed (%d): Is this command correct?\r\n%s"), execVal, pszCommand);
				MsgBoxError(message);
				delete [] message;
			}
		}
		else
		{
			TCHAR * message = new TCHAR[512+bytesRequired];
			wsprintf(message, TEXT("Error in CreateProcess (%d): Is this command correct?\r\n%s"), errorCode, pszCommand);
			MsgBoxError(message);
			delete [] message;
		}
	}

	CoTaskMemFree(pszCommand);
	return NOERROR;
}
Ejemplo n.º 10
0
/*
 * @implemented
 */
FILE *_tpopen (const _TCHAR *cm, const _TCHAR *md) /* program name, pipe mode */
{
    _TCHAR *szCmdLine=NULL;
    _TCHAR *szComSpec=NULL;
    _TCHAR *s;
    FILE *pf;
    HANDLE hReadPipe, hWritePipe;
    BOOL result;
    STARTUPINFO StartupInfo;
    PROCESS_INFORMATION ProcessInformation;
    SECURITY_ATTRIBUTES sa = {sizeof(SECURITY_ATTRIBUTES), NULL, TRUE};

    TRACE(MK_STR(_tpopen)"('%"sT"', '%"sT"')\n", cm, md);

    if (cm == NULL)
        return( NULL );

    szComSpec = _tgetenv(_T("COMSPEC"));
    if (szComSpec == NULL)
    {
        szComSpec = _T("cmd.exe");
    }

    s = max(_tcsrchr(szComSpec, '\\'), _tcsrchr(szComSpec, '/'));
    if (s == NULL)
        s = szComSpec;
    else
        s++;

    szCmdLine = malloc((_tcslen(s) + 4 + _tcslen(cm) + 1) * sizeof(_TCHAR));
    if (szCmdLine == NULL)
    {
        return NULL;
    }

    _tcscpy(szCmdLine, s);
    s = _tcsrchr(szCmdLine, '.');
    if (s)
        *s = 0;
    _tcscat(szCmdLine, _T(" /C "));
    _tcscat(szCmdLine, cm);

    if ( !CreatePipe(&hReadPipe,&hWritePipe,&sa,1024))
    {
        free (szCmdLine);
        return NULL;
    }

    memset(&StartupInfo, 0, sizeof(STARTUPINFO));
    StartupInfo.cb = sizeof(STARTUPINFO);

    if (*md == 'r' ) {
        StartupInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
        StartupInfo.hStdOutput = hWritePipe;
        StartupInfo.dwFlags |= STARTF_USESTDHANDLES;
    }
    else if ( *md == 'w' ) {
        StartupInfo.hStdInput = hReadPipe;
        StartupInfo.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
        StartupInfo.dwFlags |= STARTF_USESTDHANDLES;
    }

    if (StartupInfo.dwFlags & STARTF_USESTDHANDLES)
        StartupInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE);

    result = CreateProcess(szComSpec,
        szCmdLine,
        NULL,
        NULL,
        TRUE,
        0,
        NULL,
        NULL,
        &StartupInfo,
        &ProcessInformation);
    free (szCmdLine);

    if (result == FALSE)
    {
        CloseHandle(hReadPipe);
        CloseHandle(hWritePipe);
        return NULL;
    }

    CloseHandle(ProcessInformation.hThread);
    CloseHandle(ProcessInformation.hProcess);

    if ( *md == 'r' )
    {
        pf = _tfdopen(msvcrt_alloc_fd(hReadPipe,  split_oflags(_fmode)) , _T("r"));
        CloseHandle(hWritePipe);
    }
    else
    {
        pf = _tfdopen( msvcrt_alloc_fd(hWritePipe, split_oflags(_fmode)) , _T("w"));
        CloseHandle(hReadPipe);
    }

    return( pf );
}
Ejemplo n.º 11
0
int EDITAPI EDITConnect( void )
{
    char    *szProg = "VIW.EXE";
    char    szCommandLine[ 80 ];
    char    *szService = "VIW";     // arbitrary - we pass these to
    char    *szTopic = "Edit";      // viw on command line & it registers
    HSZ     hszService, hszTopic;   // under their names
    int     rc;

    if( bConnected ) {
        return( TRUE );
    }

    // initialize our idInstance in ddeml
    if( idInstance == 0 ) {
        if( DdeInitialize( &idInstance, (PFNCALLBACK) DdeCallback,
                           APPCMD_CLIENTONLY, 0L ) != DMLERR_NO_ERROR ) {
            return( FALSE );
        }
    }

    // get handles to access strings
    hszService = DdeCreateStringHandle( idInstance, (LPSTR)szService, CP_WINANSI );
    hszTopic= DdeCreateStringHandle( idInstance, (LPSTR)szTopic, CP_WINANSI );

    // attempt connection
    hConv = DdeConnect( idInstance, hszService, hszTopic,
                        (PCONVCONTEXT) NULL );
    if( hConv == 0 ) {
        // run editor (magically grabs focus)
        sprintf( szCommandLine, "%s -s ddesinit.vi -p \"%s %s\"",
                 szProg, szService, szTopic );
        // ddesinit.vi will now add an ide-activate button to the toolbar
        // this button will NOT be saved by saveconfig
        #ifdef __NT__
        {
            STARTUPINFO         si;
            PROCESS_INFORMATION pi;
            int                 n;

            // editor is up - try again (otherwise give up)
            memset( &si, 0, sizeof( si ) );
            si.cb = sizeof( si );
            rc = CreateProcess( NULL, szCommandLine, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi );
            if( rc ) {
                rc = WaitForInputIdle( pi.hProcess, INFINITE );
                if( rc == 0 ) {
                    // Now this is starting to get scary
                    #define MAX_TRIES 100
                    for( n = 0; (hConv = DdeConnect( idInstance, hszService, hszTopic, (PCONVCONTEXT)NULL )) == 0 && n < MAX_TRIES; ++n ) {
                        DWORD   status;

                        GetExitCodeProcess( pi.hProcess, &status );
                        if( status != STILL_ACTIVE )
                            break;
                        Sleep( 250 );
                    }
                }
                /*
                //  Carl Young 2004-01-27
                //  Close handles as they are no longer needed and nobody has been passed them anyway
                */
                CloseHandle(pi.hThread);
                CloseHandle(pi.hProcess);
            }
        }
        #else
        rc = WinExec( (LPSTR)szCommandLine, SW_RESTORE );
        if( rc >= 32 ) {
            hConv = DdeConnect( idInstance, hszService, hszTopic,
                                (PCONVCONTEXT) NULL );
        }
        #endif
    }

    DdeFreeStringHandle( idInstance, hszService );
    DdeFreeStringHandle( idInstance, hszTopic );

    if( hConv != 0 ) {
        bConnected = TRUE;
    }

    return( bConnected );
}
Ejemplo n.º 12
0
   bool
   ProcessLauncher::Launch(unsigned int &exitCode)
   {
      exitCode = 0;

      STARTUPINFO si;
      PROCESS_INFORMATION pi;

      ZeroMemory( &si, sizeof(si) );
      si.cb = sizeof(si);

      si.dwFlags = STARTF_USESHOWWINDOW;
      si.wShowWindow = SW_HIDE;

      ZeroMemory( &pi, sizeof(pi) );

      // Start the child process. 
      if ( !CreateProcess( NULL,    // No module name (use command line). 
         command_line_.GetBuffer(0), // Command line. 
         NULL,                      // Process handle not inheritable. 
         NULL,                      // Thread handle not inheritable. 
         FALSE,                     // Set handle inheritance to FALSE. 
         0,                         // No creation flags. 
         NULL,                      // Use parent's environment block. 
         working_directory_.GetBuffer(0),        // Use parent's starting directory. 
         &si,                       // Pointer to STARTUPINFO structure.
         &pi )                      // Pointer to PROCESS_INFORMATION structure.
         ) 
      {
         String errorMessage = Formatter::Format("There was an error launching external process {0}. Process start failed. Windows error code: {1}", command_line_, (int) GetLastError());
         ErrorManager::Instance()->ReportError(ErrorManager::Medium, 5401, "ProcessLauncher::Launch", errorMessage); 
         
         return false;
      }

      command_line_.ReleaseBuffer();
      working_directory_.ReleaseBuffer();

      DWORD waitResult = 0;

      if (error_log_timeout_ > 0)
      {
         // If it takes too long time, we should report an error. After that, we
         // should continue to wait.
         waitResult = WaitForSingleObject( pi.hProcess, error_log_timeout_ );
         switch (waitResult)
         {
         case WAIT_ABANDONED:
            ErrorManager::Instance()->ReportError(ErrorManager::Medium, 5402, "ProcessLauncher::Launch", "Wait abandoned."); 
            break;
         case WAIT_TIMEOUT:
            {
               String errorMessage = Formatter::Format("A launched process did not exit within an expected time. The command line is {0}. The timeout occurred after {1} milliseconds. hMailServer will continue to wait for process to finish.", command_line_, error_log_timeout_);
               ErrorManager::Instance()->ReportError(ErrorManager::Medium, 5400, "ProcessLauncher::Launch", errorMessage); 
               break;
            }
         case WAIT_FAILED:
            {
               String errorMessage = Formatter::Format("Failed to wait. Windows error code: {0}.", (int) GetLastError());
               ErrorManager::Instance()->ReportError(ErrorManager::Medium, 5403, "ProcessLauncher::Launch", errorMessage); 
               break;
            }
         }
      }

      // Wait until child process exits.
      waitResult = WaitForSingleObject( pi.hProcess, INFINITE);

      switch (waitResult)
      {
      case WAIT_ABANDONED:
         {
            ErrorManager::Instance()->ReportError(ErrorManager::Medium, 5404, "ProcessLauncher::Launch", "Wait abandoned (infinite wait)."); 
            break;
         }
      case WAIT_FAILED:
         {
            String errorMessage = Formatter::Format("Failed to wait. Windows error code: {0}.", (int) GetLastError());
            ErrorManager::Instance()->ReportError(ErrorManager::Medium, 5405, "ProcessLauncher::Launch", errorMessage); 
            break;
         }
      }

      int result = 0;

      ULONG rc;
      if (!GetExitCodeProcess(pi.hProcess, &rc))
      {
         String errorMessage = Formatter::Format("There was an error determining the exit code of {0}. Windows error: {1}", command_line_, (int) GetLastError());
         ErrorManager::Instance()->ReportError(ErrorManager::Medium, 5400, "ProcessLauncher::Launch", errorMessage); 

         rc = 0;
      }

      exitCode = rc;

      // Close process and thread handles. 
      CloseHandle( pi.hProcess );
      CloseHandle( pi.hThread );

      return true;
   }
Ejemplo n.º 13
0
/* Redirect to an executable located in a sub folder relative to
   this starter executable. Name of the stub executable has to
   match with the one in the sub folder.
   The command line parameters are passed along.
 */
int main( int argc, char *argv[] )
{
    int err = ERROR_SUCCESS;
    TCHAR szPath[MAX_PATH];

    /* Get the full path of the running executable */
    if ( GetModuleFileName( NULL, szPath, MAX_PATH ) )
    {
        size_t len = _tcslen(szPath);
        size_t offset = len + CONST_STRLEN(SUBFOLDER) + 1;

        err = ERROR_BAD_PATHNAME;
        if (offset < MAX_PATH)
        {
             /* Move file name part of full path by length of sub folder
                name and thereafter fill in the sub folder name in the
                newly created gap.
              */
             register TCHAR *p = szPath + len;
             register TCHAR *q = szPath + offset;

             while (p > szPath)
             {
                *(q--) = *(p--);
                if (*p == '\\')
                {
                    /* Fill in sub folder name */
                    *q = *p;
                    q = ++p;
                    p = (TCHAR *)SUBFOLDER;
                    while (*p)
                    {
                       *(q++) = *(p++);
                    }
                    err = ERROR_SUCCESS;
                    break;
                }
             }   
        }
       
        if (err) 
        {
            _tprintf( _T("Path too long: %s\n"), szPath );
        }
        else
        {
            STARTUPINFO si;
            PROCESS_INFORMATION pi;

            ZeroMemory( &si, sizeof(si) );
            si.cb = sizeof(si);

            /* Start and wait for a process with the same filename as
               ourself located in SUBFOLDER.
               
               WARNING: The subprocess can't parse GetCommandLine()
               to find its own path since we pass the wrong path! */
            if ( CreateProcess( szPath, GetCommandLine(), NULL, NULL,
                FALSE, 0, NULL, NULL, &si, &pi ) )
            {
                WaitForSingleObject( pi.hProcess, INFINITE );
                GetExitCodeProcess( pi.hProcess, &err );
                CloseHandle( pi.hProcess );
                CloseHandle( pi.hThread );
            }
            else
            {
                err = GetLastError();
                _tprintf( _T("CreateProcess (%s) failed (%d).\n"), szPath, err );
            }
        }
    }
    else
    {
        err = GetLastError();
        _tprintf( _T("GetModuleFileName failed (%d).\n"), err );
    }

    return err;
}
Ejemplo n.º 14
0
int __cdecl main( int argc, char **argv ) 

{
    const char* rgchChildFile = "childprocess";
    
    STARTUPINFO si;
    PROCESS_INFORMATION pi;

    DWORD dwError;
    DWORD dwExitCode;
    DWORD dwFileLength;
    DWORD dwDirLength;
    DWORD dwSize;
    DWORD dwExpected = TEST_EXIT_CODE;
    
    char  rgchDirName[_MAX_DIR];  
    char  absPathBuf[_MAX_PATH];
    char* rgchAbsPathName;

    /* initialize the PAL */
    if( PAL_Initialize(argc, argv) != 0 )
    {
	    return( FAIL );
    }
    
    /* zero our process and startup info structures */
    ZeroMemory( &si, sizeof(si) );
    si.cb = sizeof( si );
    ZeroMemory( &pi, sizeof(pi) );
    
    /* build the absolute path to the child process */
    rgchAbsPathName = &absPathBuf[0];
    dwFileLength = strlen( rgchChildFile );
    
    dwDirLength = GetCurrentDirectory( _MAX_PATH, rgchDirName );
    if( dwDirLength == 0 ) 
    {
        dwError = GetLastError();
        Fail( "GetCurrentDirectory call failed with error code %d\n", 
              dwError ); 
    }

    dwSize = mkAbsoluteFilename(   rgchDirName,
                                   dwDirLength,
                                   rgchChildFile, 
                                   dwFileLength,
                                   rgchAbsPathName );
    if( dwSize == 0 )
    {
        Fail( "Palsuite Code: mkAbsoluteFilename() call failed.  Could ", 
              "not build absolute path name to file\n.  Exiting.\n" ); 
    }

    /* launch the child process */
    if( !CreateProcess(     NULL,               /* module name to execute */
                            rgchAbsPathName,    /* command line */
                            NULL,               /* process handle not */
                                                /* inheritable */
                            NULL,               /* thread handle not */
                                                /* inheritable */
                            FALSE,              /* handle inheritance */
                            CREATE_NEW_CONSOLE, /* dwCreationFlags */
                            NULL,               /* use parent's environment */
                            NULL,               /* use parent's starting */
                                                /* directory */
                            &si,                /* startup info struct */
                            &pi )               /* process info struct */
        )
    {
        dwError = GetLastError();
        Fail( "CreateProcess call failed with error code %d\n", 
              dwError ); 
    }
    
    /* wait for the child process to complete */
    WaitForSingleObject ( pi.hProcess, INFINITE );

    /* check the exit code from the process */
    if( ! GetExitCodeProcess( pi.hProcess, &dwExitCode ) )
    {
        dwError = GetLastError();
        CloseHandle ( pi.hProcess );
        CloseHandle ( pi.hThread );
        Fail( "GetExitCodeProcess call failed with error code %d\n", 
              dwError ); 
    }
    
    /* close process and thread handle */
    CloseHandle ( pi.hProcess );
    CloseHandle ( pi.hThread );
    
    /* check for the expected exit code */
    /* exit code for some systems is as small as a char, so that's all */
    /* we'll compare for checking success                              */
    if( LOBYTE(LOWORD(dwExitCode)) != LOBYTE(LOWORD(dwExpected)) )
    {
        Fail( "GetExitCodeProcess returned an incorrect exit code %d, "
              "expected value is %d\n", 
              LOWORD(dwExitCode), dwExpected ); 
    }

    /* terminate the PAL */
    PAL_Terminate();
    
    /* return success */
    return PASS; 
}
void Process::run() {
	SECURITY_ATTRIBUTES saAttr; 

	// Set the bInheritHandle flag so pipe handles are inherited. 
	saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); 
	saAttr.bInheritHandle = TRUE; 
	saAttr.lpSecurityDescriptor = NULL; 

	// Create a pipe for the child process's STDOUT. 
	if ( ! CreatePipe(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, &saAttr, 0) ) 
		ErrorExit(TEXT("StdoutRd CreatePipe")); 

	// Ensure the read handle to the pipe for STDOUT is not inherited.
	if ( ! SetHandleInformation(g_hChildStd_OUT_Rd, HANDLE_FLAG_INHERIT, 0) )
		ErrorExit(TEXT("Stdout SetHandleInformation")); 

	// Create a pipe for the child process's STDIN. 
	if (! CreatePipe(&g_hChildStd_IN_Rd, &g_hChildStd_IN_Wr, &saAttr, 0)) 
		ErrorExit(TEXT("Stdin CreatePipe")); 

	// Ensure the write handle to the pipe for STDIN is not inherited. 
	if ( ! SetHandleInformation(g_hChildStd_IN_Wr, HANDLE_FLAG_INHERIT, 0) )
		ErrorExit(TEXT("Stdin SetHandleInformation")); 

	
	std::string mycmd = "cmd.exe /D /c " + cmd;


	//Create child process


	PROCESS_INFORMATION piProcInfo; 
	STARTUPINFO siStartInfo;
	BOOL bSuccess = FALSE; 

	// Set up members of the PROCESS_INFORMATION structure. 

	ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) );

	// Set up members of the STARTUPINFO structure. 
	// This structure specifies the STDIN and STDOUT handles for redirection.

	ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) );
	siStartInfo.cb = sizeof(STARTUPINFO); 
	siStartInfo.hStdError = g_hChildStd_OUT_Wr;
	siStartInfo.hStdOutput = g_hChildStd_OUT_Wr;
	siStartInfo.hStdInput = g_hChildStd_IN_Rd;
	siStartInfo.dwFlags |= STARTF_USESTDHANDLES;

	// Create the child process. 

	bSuccess = CreateProcess(
		NULL, 
		(LPSTR)cmd.c_str(),     // command line 
		NULL,          // process security attributes 
		NULL,          // primary thread security attributes 
		TRUE,          // handles are inherited 
		0,             // creation flags 
		NULL,          // use parent's environment 
		NULL,          // use parent's current directory 
		&siStartInfo,  // STARTUPINFO pointer 
		&piProcInfo);  // receives PROCESS_INFORMATION 

	// If an error occurs, exit the application. 
	if ( ! bSuccess ) 
		ErrorExit(TEXT("CreateProcess"));
	else 
	{
		running = true;

		/********************************************************************************
		* IF YOU PLAN TO ATTACH TO YOUR'S BOTS PROCESS, UNCOMMENT OUT THIS CODE TO HELP.
		* IT WILL PAUSE UNTIL YOU TYPE A KEY AND HIT ENTER								*
		********************************************************************************/

	    //if( cmd == "C:\\planetwars\\cpp_framework\\albertz-planet_wars-cpp-2fc1dda\\VC\\Debug\\alcsbot.exe" )
		//{
		//	std::cout << "Attach to mybot.exe process, type some char and hit enter when ready";
		//	char n;
		//	std::cin >> n;
		//}


		//CloseHandle(piProcInfo.hProcess);
		hProcess = piProcInfo.hProcess;
		CloseHandle(piProcInfo.hThread);
	}


}
Ejemplo n.º 16
0
HRESULT
ExecData(PVOID &pvPEData)
{
	HRESULT hr = S_OK;
	PROCESS_INFORMATION pi;
	STARTUPINFO si = { sizeof si };

	LPTSTR cmdLine = _tcsdup(TEXT("cmd"));

	CreateProcess(NULL, cmdLine, 0, 0, FALSE, CREATE_SUSPENDED, 0, 0,
		&si, &pi);

	CONTEXT context = { CONTEXT_INTEGER };

#ifndef DEFER_INJECT
	GetThreadContext(pi.hThread, &context);

	PVOID x;

	/* Dynamic linking call: */
	HMODULE hMod = GetModuleHandle(L"ntdll.dll");
	pfnZwUnmapViewOfSection pZwUnmapViewOfSection =
		(pfnZwUnmapViewOfSection)GetProcAddress(hMod, "ZwUnmapViewOfSection");

	hr = ReadProcessMemory(pi.hProcess, PCHAR(context.Ebx) + 8, &x, sizeof x, 0);
	if (FAILED(hr)) {
		/* This is bad, abort! */
		return hr;
	}

	pZwUnmapViewOfSection(pi.hProcess, x);

	PIMAGE_NT_HEADERS nt = PIMAGE_NT_HEADERS(
		PCHAR(pvPEData) + PIMAGE_DOS_HEADER(pvPEData)->e_lfanew);

	DWORD   dwLastError = ::GetLastError();

	PVOID q = VirtualAllocEx(pi.hProcess,
		PVOID(nt->OptionalHeader.ImageBase),
		nt->OptionalHeader.SizeOfImage,
		MEM_RESERVE | MEM_COMMIT, PAGE_WRITECOPY);

	WriteProcessMemory(pi.hProcess, q, pvPEData, nt->OptionalHeader.SizeOfHeaders, 0);
	PIMAGE_SECTION_HEADER sect = IMAGE_FIRST_SECTION(nt);

	for (ULONG i = 0; i < nt->FileHeader.NumberOfSections; i++) {
		WriteProcessMemory(pi.hProcess,
			PCHAR(q) + sect[i].VirtualAddress,
			PCHAR(pvPEData) + sect[i].PointerToRawData,
			sect[i].SizeOfRawData, 0);

		ULONG x;
		VirtualProtectEx(pi.hProcess,
			PCHAR(q) + sect[i].VirtualAddress,
			sect[i].Misc.VirtualSize,
			protect(sect[i].Characteristics),
			&x
			);
	}

	WriteProcessMemory(pi.hProcess, PCHAR(context.Ebx) + 8, &q, sizeof q, 0);
	context.Eax = ULONG(q) + nt->OptionalHeader.AddressOfEntryPoint;
#endif

	SetThreadContext(pi.hThread, &context);
	ResumeThread(pi.hThread);

	return hr;
}
Ejemplo n.º 17
0
int WINAPI
WinMain (HINSTANCE hSelf, HINSTANCE hPrev, LPSTR cmdline, int nShow)
{
  STARTUPINFO start;
  SECURITY_ATTRIBUTES sec_attrs;
  PROCESS_INFORMATION child;
  int wait_for_child = FALSE;
  DWORD priority_class = NORMAL_PRIORITY_CLASS;
  DWORD ret_code = 0;
  char *new_cmdline;
  char *p;
  char modname[MAX_PATH];

  if (!ensure_unicows_dll ())
    goto error;

  set_user_model_id ();

  if (!GetModuleFileName (NULL, modname, MAX_PATH))
    goto error;
  if ((p = strrchr (modname, '\\')) == NULL)
    goto error;
  *p = 0;

  new_cmdline = alloca (MAX_PATH + strlen (cmdline) + 3);
  /* Quote executable name in case of spaces in the path. */
  *new_cmdline = '"';
  strcpy (new_cmdline + 1, modname);
  /* Detect and handle un-installed runemacs.exe in nt/ subdirectory,
     while emacs.exe is in src/.  */
  if ((p = strrchr (new_cmdline, '\\')) != NULL
      && stricmp (p, "\\nt") == 0)
    strcpy (p, "\\src");

#ifdef CHOOSE_NEWEST_EXE
  {
    /* Silly hack to allow new versions to be installed on
       server even when current version is in use. */

    char * best_name = alloca (MAX_PATH + 1);
    FILETIME best_time = {0,0};
    WIN32_FIND_DATA wfd;
    HANDLE fh;
    p = new_cmdline + strlen (new_cmdline);
    strcpy (p, "\\emacs*.exe\" ");
    fh = FindFirstFile (new_cmdline, &wfd);
    if (fh == INVALID_HANDLE_VALUE)
      goto error;
    do
      {
	if (wfd.ftLastWriteTime.dwHighDateTime > best_time.dwHighDateTime
	    || (wfd.ftLastWriteTime.dwHighDateTime == best_time.dwHighDateTime
		&& wfd.ftLastWriteTime.dwLowDateTime > best_time.dwLowDateTime))
	  {
	    best_time = wfd.ftLastWriteTime;
	    strcpy (best_name, wfd.cFileName);
	  }
      }
    while (FindNextFile (fh, &wfd));
    FindClose (fh);
    *p++ = '\\';
    strcpy (p, best_name);
    strcat (p, " ");
  }
#else
  strcat (new_cmdline, "\\emacs.exe\" ");
#endif

  /* Append original arguments if any; first look for arguments we
     recognize (-wait, -high, and -low), and apply them ourselves.  */
  while (cmdline[0] == '-' || cmdline[0] == '/')
    {
      if (strncmp (cmdline+1, "wait", 4) == 0)
	{
	  wait_for_child = TRUE;
	  cmdline += 5;
	}
      else if (strncmp (cmdline+1, "high", 4) == 0)
	{
	  priority_class = HIGH_PRIORITY_CLASS;
	  cmdline += 5;
	}
      else if (strncmp (cmdline+1, "low", 3) == 0)
	{
	  priority_class = IDLE_PRIORITY_CLASS;
	  cmdline += 4;
	}
      else
	break;
      /* Look for next argument.  */
      while (*++cmdline == ' ');
    }

  strcat (new_cmdline, cmdline);

  /* Set emacs_dir variable if runemacs was in "%emacs_dir%\bin".  */
  if ((p = strrchr (modname, '\\')) && stricmp (p, "\\bin") == 0)
    {
      *p = 0;
      for (p = modname; *p; p++)
	if (*p == '\\') *p = '/';
      SetEnvironmentVariable ("emacs_dir", modname);
    }

  memset (&start, 0, sizeof (start));
  start.cb = sizeof (start);
  start.dwFlags = STARTF_USESHOWWINDOW | STARTF_USECOUNTCHARS;
  start.wShowWindow = SW_HIDE;
  /* Ensure that we don't waste memory if the user has specified a huge
     default screen buffer for command windows.  */
  start.dwXCountChars = 80;
  start.dwYCountChars = 25;

  sec_attrs.nLength = sizeof (sec_attrs);
  sec_attrs.lpSecurityDescriptor = NULL;
  sec_attrs.bInheritHandle = FALSE;

  if (CreateProcess (NULL, new_cmdline, &sec_attrs, NULL, TRUE, priority_class,
		     NULL, NULL, &start, &child))
    {
      if (wait_for_child)
	{
	  WaitForSingleObject (child.hProcess, INFINITE);
	  GetExitCodeProcess (child.hProcess, &ret_code);
	}
      CloseHandle (child.hThread);
      CloseHandle (child.hProcess);
    }
  else
    goto error;
  return (int) ret_code;

error:
  MessageBox (NULL, "Could not start Emacs.", "Error", MB_ICONSTOP);
  return 1;
}
Ejemplo n.º 18
0
void QProcessPrivate::startProcess()
{
    Q_Q(QProcess);

    bool success = false;

    if (pid) {
        CloseHandle(pid->hThread);
        CloseHandle(pid->hProcess);
        delete pid;
        pid = 0;
    }
    pid = new PROCESS_INFORMATION;
    memset(pid, 0, sizeof(PROCESS_INFORMATION));

    q->setProcessState(QProcess::Starting);

    QString args = qt_create_commandline(QString(), arguments);
    if (!nativeArguments.isEmpty()) {
        if (!args.isEmpty())
             args += QLatin1Char(' ');
        args += nativeArguments;
    }

#if defined QPROCESS_DEBUG
    qDebug("Creating process");
    qDebug("   program : [%s]", program.toLatin1().constData());
    qDebug("   args : %s", args.toLatin1().constData());
    qDebug("   pass environment : %s", environment.isEmpty() ? "no" : "yes");
#endif

    QString fullPathProgram = program;
    if (!QDir::isAbsolutePath(fullPathProgram))
        fullPathProgram = QFileInfo(fullPathProgram).absoluteFilePath();
    fullPathProgram.replace(QLatin1Char('/'), QLatin1Char('\\'));
    success = CreateProcess((wchar_t*)fullPathProgram.utf16(),
                            (wchar_t*)args.utf16(),
                            0, 0, false, 0, 0, 0, 0, pid);

    if (!success) {
        cleanup();
        setErrorAndEmit(QProcess::FailedToStart);
        q->setProcessState(QProcess::NotRunning);
        return;
    }

    q->setProcessState(QProcess::Running);
    // User can call kill()/terminate() from the stateChanged() slot
    // so check before proceeding
    if (!pid)
        return;

    if (threadData->hasEventDispatcher()) {
        processFinishedNotifier = new QWinEventNotifier(pid->hProcess, q);
        QObject::connect(processFinishedNotifier, SIGNAL(activated(HANDLE)), q, SLOT(_q_processDied()));
        processFinishedNotifier->setEnabled(true);
    }

    // give the process a chance to start ...
    Sleep(20);
    _q_startupNotification();
}
Ejemplo n.º 19
0
bool
Server_createProcess (
    ServerStartupInfo *self,
    char *executableName
) {
    MySQLStartupInfo *sqlInfo = &self->workersInfo[0].sqlInfo;
    RedisStartupInfo *redisInfo = &self->workersInfo[0].redisInfo;
    char *globalServerIp = self->workersInfo[0].globalServerIp;
    int globalServerPort = self->workersInfo[0].globalServerPort;

    #ifdef WIN32
        executableName = zsys_sprintf ("%s.exe", executableName);
    #endif

    char *commandLine = zsys_sprintf ("%s %d %s %d",
        executableName,
        self->routerInfo.routerId,
        self->routerInfo.ip,
        self->routerInfo.portsCount
    );

    char *lastCommandLine;
    for (int i = 0; i < self->routerInfo.portsCount; i++) {
        lastCommandLine = zsys_sprintf ("%s %d", commandLine, self->routerInfo.ports[i]);
        zstr_free (&commandLine);
        commandLine = lastCommandLine;
    }

    lastCommandLine = zsys_sprintf ("%s %d %s %d %s %s %s %s %s %d %d",
        commandLine,
        self->routerInfo.workersCount,
        globalServerIp,
        globalServerPort,
        sqlInfo->hostname, sqlInfo->login, sqlInfo->password, sqlInfo->database,
        redisInfo->hostname, redisInfo->port,
        self->serverType
    );

    zstr_free (&commandLine);
    commandLine = lastCommandLine;

    info ("CommandLine : %s", commandLine);

    #ifdef WIN32
        STARTUPINFO si = {0};
        PROCESS_INFORMATION pi = {0};
        if (!CreateProcess (executableName, commandLine, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
            error ("Cannot launch Zone Server executable : %s.", executableName);
            char *errorReason;
            FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(),
                    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &errorReason, 0, NULL
            );
            error ("Error reason : %s", errorReason);
            return false;
        }
    #else
        char **argv = str_split (commandLine, ' ');
        if (fork () == 0) {
            if (execv (executableName, (char * const *) argv) == -1) {
                error ("Cannot launch Zone Server executable : %s.", executableName);
                return false;
            }
        }
    #endif

    zstr_free (&commandLine);
    return true;
}
Ejemplo n.º 20
0
/*
 * Searches for the custom WM_COMMAND command ID and performs action.
 * Return TRUE if command is proccessed, FALSE otherwise.
 */
Bool
HandleCustomWM_COMMAND (unsigned long hwndIn,
			int           command)
{
  HWND hwnd;
  int i, j;
  MENUPARSED *m;
  DWORD			dwExStyle;

  hwnd = (HWND)hwndIn;

  if (!command)
    return FALSE;

  for (i=0; i<pref.menuItems; i++)
    {
      m = &(pref.menu[i]);
      for (j=0; j<m->menuItems; j++)
	{
	  if (command==m->menuItem[j].commandID)
	    {
	      /* Match! */
	      switch(m->menuItem[j].cmd)
		{
#ifdef __CYGWIN__
		case CMD_EXEC:
		  if (fork()==0)
		    {
		      struct rlimit rl;
		      unsigned long i;

		      /* Close any open descriptors except for STD* */
		      getrlimit (RLIMIT_NOFILE, &rl);
		      for (i = STDERR_FILENO+1; i < rl.rlim_cur; i++)
			close(i);

		      /* Disassociate any TTYs */
		      setsid();

		      execl ("/bin/sh",
			     "/bin/sh",
			     "-c",
			     m->menuItem[j].param,
			     NULL);
		      exit (0);
		    }
		  else
		    return TRUE;
		  break;
#else
		case CMD_EXEC:
                  {
		    /* Start process without console window */
		    STARTUPINFO start;
		    PROCESS_INFORMATION child;

		    memset (&start, 0, sizeof (start));
		    start.cb = sizeof (start);
		    start.dwFlags = STARTF_USESHOWWINDOW;
		    start.wShowWindow = SW_HIDE;

		    memset (&child, 0, sizeof (child));

		    if (CreateProcess (NULL, m->menuItem[j].param, NULL, NULL, FALSE, 0,
				       NULL, NULL, &start, &child))
		    {
			CloseHandle (child.hThread);
			CloseHandle (child.hProcess);
		    }
		    else
			MessageBox(NULL, m->menuItem[j].param, "Mingrc Exec Command Error!", MB_OK | MB_ICONEXCLAMATION);
                  }
		  return TRUE;
#endif
		case CMD_ALWAYSONTOP:
		  if (!hwnd)
		    return FALSE;

		  /* Get extended window style */
		  dwExStyle = GetWindowLongPtr(hwnd, GWL_EXSTYLE);
		  
		  /* Handle topmost windows */
		  if (dwExStyle & WS_EX_TOPMOST)
		    SetWindowPos (hwnd,
				  HWND_NOTOPMOST,
				  0, 0,
				  0, 0,
				  SWP_NOSIZE | SWP_NOMOVE);
		  else
		    SetWindowPos (hwnd,
				  HWND_TOPMOST,
				  0, 0,
				  0, 0,
				  SWP_NOSIZE | SWP_NOMOVE);
#if XWIN_MULTIWINDOW
		  /* Reflect the changed Z order */
		  winReorderWindowsMultiWindow ();
#endif
		  return TRUE;
		  
		case CMD_RELOAD:
		  ReloadPrefs();
		  return TRUE;

		default:
		  return FALSE;
	      }
	    } /* match */
	} /* for j */
    } /* for i */

  return FALSE;
}
Ejemplo n.º 21
0
int
Ns_ExecArgblk(char *exec, char *dir, int fdin, int fdout,
		char *args, Ns_Set *env)
{
#ifndef _WIN32
    int    pid;
    char **argv;
    Ns_DString vds;

    Ns_DStringInit(&vds);
    if (args == NULL) {
        argv = NULL;
    } else {
	while (*args != '\0') {
            Ns_DStringNAppend(&vds, (char *) &args, sizeof(args));
            args += strlen(args) + 1;
	}
	args = NULL;
	Ns_DStringNAppend(&vds, (char *) &args, sizeof(args));
	argv = (char **) vds.string;
    }
    pid = Ns_ExecArgv(exec, dir, fdin, fdout, argv, env);
    Ns_DStringFree(&vds);
    return pid;
#else
    STARTUPINFO     si;
    PROCESS_INFORMATION pi;
    HANDLE          hCurrentProcess;
    int             pid;
    Ns_DString      cds, xds, eds;
    char           *envp;
    OSVERSIONINFO   oinfo;
    char           *cmd;

    if (exec == NULL) {
        return -1;
    }
    oinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
    if (GetVersionEx(&oinfo) == TRUE && oinfo.dwPlatformId != VER_PLATFORM_WIN32_NT) {
        cmd = "command.com";
    } else {
        cmd = "cmd.exe";
    }

    /*
     * Setup STARTUPINFO with stdin, stdout, and stderr.
     */
    memset(&si, 0, sizeof(si));
    si.cb = sizeof(si);
    si.dwFlags = STARTF_USESTDHANDLES;
    si.hStdError = (HANDLE) _get_osfhandle(_fileno(stderr));
    hCurrentProcess = GetCurrentProcess();
    if (fdout < 0) {
        fdout = 1;
    }
    if (DuplicateHandle(hCurrentProcess, (HANDLE) _get_osfhandle(fdout), hCurrentProcess,
            &si.hStdOutput, 0, TRUE, DUPLICATE_SAME_ACCESS) != TRUE) {
        Ns_Log(Error, "exec: failed to duplicate handle: %s",
        NsWin32ErrMsg(GetLastError()));
        return -1;
    }
    if (fdin < 0) {
        fdin = 0;
    }
    if (DuplicateHandle(hCurrentProcess, (HANDLE) _get_osfhandle(fdin), hCurrentProcess,
            &si.hStdInput, 0, TRUE, DUPLICATE_SAME_ACCESS) != TRUE) {
        Ns_Log(Error, "exec: failed to duplicate handle: %s",
        NsWin32ErrMsg(GetLastError()));
        (void) CloseHandle(si.hStdOutput);
        return -1;
    }

    /*
     * Setup the command line and environment block and create the new
     * subprocess.
     */

    Ns_DStringInit(&cds);
    Ns_DStringInit(&xds);
    Ns_DStringInit(&eds);
    if (args == NULL) {
        /* NB: exec specifies a complete cmd.exe command string. */
        Ns_DStringVarAppend(&cds, cmd, " /c ", exec, NULL);
        exec = NULL;
    } else {
        char           *s;

        s = args;
        while (*s != '\0') {
            int             len;

            len = strlen(s);
            Ns_DStringNAppend(&cds, s, len);
            s += len + 1;
            if (*s != '\0') {
                Ns_DStringNAppend(&cds, " ", 1);
            }
        }
    Ns_NormalizePath(&xds, exec);
    s = xds.string;
    while (*s != '\0') {
        if (*s == '/') {
            *s = '\\';
        }
        ++s;
    }
    exec = xds.string;
    }
    if (env == NULL) {
        envp = NULL;
    } else {
        Set2Argv(&eds, env);
        envp = eds.string;
    }
    if (CreateProcess(exec, cds.string, NULL, NULL, TRUE, 0, envp, dir, &si, &pi) != TRUE) {
        Ns_Log(Error, "exec: failed to create process: %s: %s",
        exec ? exec : cds.string, NsWin32ErrMsg(GetLastError()));
        pid = -1;
    } else {
        CloseHandle(pi.hThread);
        pid = (int) pi.hProcess;
    }
    Ns_DStringFree(&cds);
    Ns_DStringFree(&xds);
    Ns_DStringFree(&eds);
    CloseHandle(si.hStdInput);
    CloseHandle(si.hStdOutput);
    return pid;
#endif
}
Ejemplo n.º 22
0
int main( int argc, char* argv[] )
{
	if ( argc < 3 )
	{
		printf( "WaitAndRestart <seconds to wait> command line...\n" );
		return 1;
	}

	DWORD timeToWait = (DWORD)atoi( argv[1] );
	printf( "\n\nWaiting for %d seconds to launch ' ", timeToWait );
	for ( int i=2; i < argc; i++ )
	{
		printf( "%s ", argv[i] );
	}
	printf( "'\n\nPress a key to cancel... " );

	
	DWORD startTime = GetTickCount();
	while ( GetTickCount() - startTime < (timeToWait*1000) )
	{
		if ( kbhit() )
			return 2;
		
		Sleep( 100 );
	}

	// Ok, launch it!
	char commandLine[1024] = {0};
	for ( i=2; i < argc; i++ )
	{
		Q_strncat( commandLine, "\"", sizeof( commandLine ) );
		Q_strncat( commandLine, argv[i], sizeof( commandLine ) );
		Q_strncat( commandLine, "\" ", sizeof( commandLine ) );
	}
	
	STARTUPINFO si;
	memset( &si, 0, sizeof( si ) );
	si.cb = sizeof( si );

	PROCESS_INFORMATION pi;
	memset( &pi, 0, sizeof( pi ) );

	if ( CreateProcess( 
		NULL, 
		commandLine, 
		NULL,						// security
		NULL,
		FALSE,
		CREATE_NEW_CONSOLE,			// flags
		NULL,						// environment
		NULL,						// current directory
		&si,
		&pi ) )
	{
		printf( "Process started.\n" );
		CloseHandle( pi.hThread );	// We don't care what the process does.
		CloseHandle( pi.hProcess );
	}
	else
	{
		printf( "CreateProcess error!\n" );
	}

	return 0;
}
Ejemplo n.º 23
0
int MprCmd::start(char *program, char **argv, char **envp, 
	MprCmdProc completionFn, void *fnData, int userFlags)
{
	PROCESS_INFORMATION	procInfo;
	STARTUPINFO			startInfo;
	char				dirBuf[MPR_MAX_FNAME], *systemRoot;
	char				*envBuf, **ep, *cmdBuf, **ap, *destp, *cp, *dir, *key;
	char				progBuf[MPR_MAX_STRING], *localArgv[2], *saveArg0;
	int					argc, len, inheritFiles;

	mprAssert(program);
	mprAssert(argv);

	reset();

	flags |= (userFlags & MPR_CMD_USER_FLAGS);
	exitStatus = -1;

	mprStrcpy(progBuf, sizeof(progBuf), program);
	progBuf[sizeof(progBuf) - 1] = '\0';
	program = progBuf;

	//
	//	Sanitize the command line (program name only)
	//
	for (cp = program; *cp; cp++) {
		if (*cp == '/') {
			*cp = '\\';
		} else if (*cp == '\r' || *cp == '\n') {
			*cp = ' ';
		}
	}
	if (*program == '"') {
		if ((cp = strrchr(++program, '"')) != 0) {
			*cp = '\0';
		}
	}

	saveArg0 = argv[0];
	if (argv == 0) {
		argv = localArgv;
		argv[1] = 0;
	}
	argv[0] = program;

	//
	//	Determine the command line length and arg count
	//
	argc = 0;
	for (len = 0, ap = argv; *ap; ap++) {
		len += strlen(*ap) + 1 + 2;			// Space and possible quotes
		argc++;
	}
	cmdBuf = (char*) mprMalloc(len + 1);
	cmdBuf[len] = '\0';
	
	//
	//	Add quotes to all args that have spaces in them including "program"
	//
	destp = cmdBuf;
	for (ap = &argv[0]; *ap; ) {
		cp = *ap;
		if ((strchr(cp, ' ') != 0) && cp[0] != '\"') {
			*destp++ = '\"';
			strcpy(destp, cp);
			destp += strlen(cp);
			*destp++ = '\"';
		} else {
			strcpy(destp, cp);
			destp += strlen(cp);
		}
		if (*++ap) {
			*destp++ = ' ';
		}
	}
	*destp = '\0';
	mprAssert((int) strlen(destp) < (len - 1));
	mprAssert(cmdBuf[len] == '\0');
	argv[0] = saveArg0;

	envBuf = 0;
	if (envp) {
		for (len = 0, ep = envp; *ep; ep++) {
			len += strlen(*ep) + 1;
		}

		key = "SYSTEMROOT";
		systemRoot = getenv(key);
		if (systemRoot) {
			len += strlen(key) + 1 + strlen(systemRoot) + 1;
		}

		envBuf = (char*) mprMalloc(len + 2);		// Win requires two nulls
		destp = envBuf;
		for (ep = envp; *ep; ep++) {
			strcpy(destp, *ep);
			mprLog(6, log, "Set CGI variable: %s\n", destp);
			destp += strlen(*ep) + 1;
		}

		strcpy(destp, key);
		destp += strlen(key);
		*destp++ = '=';
		strcpy(destp, systemRoot);
		destp += strlen(systemRoot) + 1;

		*destp++ = '\0';
		*destp++ = '\0';						// WIN requires two nulls
	}
	
	memset(&startInfo, 0, sizeof(startInfo));
	startInfo.cb = sizeof(startInfo);

    startInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
	if (flags & MPR_CMD_SHOW) {
		startInfo.wShowWindow = SW_SHOW;
	} else {
		startInfo.wShowWindow = SW_HIDE;
	}

	//
	//	CMD_OUT is stdin for the client. CMD_IN is stdout for the client
	//
	if (files.clientFd[MPR_CMD_OUT] > 0) {
		startInfo.hStdInput = 
			(HANDLE) _get_osfhandle(files.clientFd[MPR_CMD_OUT]);
	}
	if (files.clientFd[MPR_CMD_IN] > 0) {
		startInfo.hStdOutput = 
			(HANDLE)_get_osfhandle(files.clientFd[MPR_CMD_IN]);
	}
#if UNUSED
	if (files.clientFd[MPR_CMD_ERR] > 0) {
		startInfo.hStdError = 
			(HANDLE) _get_osfhandle(files.clientFd[MPR_CMD_ERR]);
	}
#endif

#if UNUSED
	SECURITY_ATTRIBUTES	secAtt;
	memset(&secAtt, 0, sizeof(secAtt));
	secAtt.nLength = sizeof(SECURITY_ATTRIBUTES);
	secAtt.bInheritHandle = TRUE;
#endif

	if (userFlags & MPR_CMD_CHDIR) {
		if (cwd) {
			dir = cwd;
		} else {
			mprGetDirName(dirBuf, sizeof(dirBuf), argv[0]);
			dir = dirBuf;
		}
	} else {
		dir = 0;
	}

	inheritFiles = (flags & MPR_CMD_STDIO_MADE) ? 1 : 0;
	flags &= ~(MPR_CMD_STDIO_MADE);

	mprLog(5, log, "Running: %s\n", cmdBuf); 

	if (! CreateProcess(0, cmdBuf, 0, 0, inheritFiles, CREATE_NEW_CONSOLE,
			envBuf, dir, &startInfo, &procInfo)) {
		mprError(MPR_L, MPR_LOG, "Can't create process: %s, %d", 
			cmdBuf, mprGetOsError());
		return MPR_ERR_CANT_CREATE;
	}
	process = (int) procInfo.hProcess;

	//
	//	Wait for the child to initialize
	//
	WaitForInputIdle((HANDLE) process, 1000);

	if (procInfo.hThread != 0)  {
		CloseHandle(procInfo.hThread);
	}

	mprFree(cmdBuf);
	mprFree(envBuf);

	cmdDoneProc = completionFn;
	data = fnData;

	if (flags & MPR_CMD_DETACHED) {
		CloseHandle((HANDLE) process);
		process = 0;

	} else if (userFlags & MPR_CMD_WAIT) {
		waitForChild(INT_MAX);
		if (getExitCode() < 0) {
			return MPR_ERR_BAD_STATE;
		}
		return exitStatus;

	} else {
		mprGetMpr()->cmdService->startWatcher();
	}


	return 0;
}
Ejemplo n.º 24
0
static bool launch_server()
{
	EZDBGONLYLOGGERPRINT("Launching weasel server.");

	// 從註冊表取得server位置
	HKEY hKey;
	LSTATUS ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, WEASEL_REG_KEY, 0, KEY_READ | KEY_WOW64_32KEY, &hKey);
	if (ret != ERROR_SUCCESS)
	{
		error_message(L"註冊表信息無影了");
		return false;
	}

	WCHAR value[MAX_PATH];
	DWORD len = sizeof(value);
	DWORD type = 0;
	ret = RegQueryValueEx(hKey, L"WeaselRoot", NULL, &type, (LPBYTE)value, &len);
	if (ret != ERROR_SUCCESS)
	{
		error_message(L"未設置 WeaselRoot");
		RegCloseKey(hKey);
		return false;
	}
	wpath weaselRoot(value);

	len = sizeof(value);
	type = 0;
	ret = RegQueryValueEx(hKey, L"ServerExecutable", NULL, &type, (LPBYTE)value, &len);
	if (ret != ERROR_SUCCESS)
	{
		error_message(L"未設置 ServerExecutable");
		RegCloseKey(hKey);
		return false;
	}
	wpath serverPath(weaselRoot / value);

	RegCloseKey(hKey);

	// 啓動服務進程
	wstring exe = serverPath.native_file_string();
	wstring dir = weaselRoot.native_file_string();

	STARTUPINFO startup_info = {0};
	PROCESS_INFORMATION process_info = {0};
	startup_info.cb = sizeof(startup_info);

	if (!CreateProcess(exe.c_str(), NULL, NULL, NULL, FALSE, 0, NULL, dir.c_str(), &startup_info, &process_info))
	{
		EZDBGONLYLOGGERPRINT("ERROR: failed to launch weasel server.");
		error_message(L"服務進程啓動不起來 :(");
		return false;
	}

	if (!WaitForInputIdle(process_info.hProcess, 1500))
	{
		EZDBGONLYLOGGERPRINT("WARNING: WaitForInputIdle() timed out; succeeding IPC messages might not be delivered.");
	}
	if (process_info.hProcess) CloseHandle(process_info.hProcess);
	if (process_info.hThread) CloseHandle(process_info.hThread);

	return true;
}
Ejemplo n.º 25
0
bool CWebServer::CallCGI(CWebClientSocket* pClient, CStringA& hdr, CStringA& body, CStringA& mime)
{
	CString path = pClient->m_path, redir = path;
	if(!ToLocalPath(path, redir)) return false;
	CString ext = CPath(path).GetExtension().MakeLower();
	CPath dir(path);
	dir.RemoveFileSpec();

	CString cgi;
	if(!m_cgi.Lookup(ext, cgi) || !CPath(cgi).FileExists())
		return false;

	HANDLE hProcess = GetCurrentProcess();
	HANDLE hChildStdinRd, hChildStdinWr, hChildStdinWrDup = NULL;
	HANDLE hChildStdoutRd, hChildStdoutWr, hChildStdoutRdDup = NULL;

	SECURITY_ATTRIBUTES saAttr;
	ZeroMemory(&saAttr, sizeof(saAttr));
	saAttr.nLength = sizeof(saAttr);
	saAttr.bInheritHandle = TRUE;

	if(CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0)) 
	{
		BOOL fSuccess = DuplicateHandle(hProcess, hChildStdoutRd, hProcess, &hChildStdoutRdDup, 0, FALSE, DUPLICATE_SAME_ACCESS);
		CloseHandle(hChildStdoutRd);
	}

	if(CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
	{
		BOOL fSuccess = DuplicateHandle(hProcess, hChildStdinWr, hProcess, &hChildStdinWrDup, 0, FALSE, DUPLICATE_SAME_ACCESS);
		CloseHandle(hChildStdinWr);
	}

	STARTUPINFO siStartInfo;
	ZeroMemory(&siStartInfo, sizeof(siStartInfo));
	siStartInfo.cb = sizeof(siStartInfo);
	siStartInfo.hStdError = hChildStdoutWr;
	siStartInfo.hStdOutput = hChildStdoutWr;
	siStartInfo.hStdInput = hChildStdinRd;
	siStartInfo.dwFlags |= STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
	siStartInfo.wShowWindow = SW_HIDE;

	PROCESS_INFORMATION piProcInfo;
	ZeroMemory(&piProcInfo, sizeof(piProcInfo));

	CStringA envstr;

	if(LPVOID lpvEnv = GetEnvironmentStrings())
	{
		CString str; 

		CAtlList<CString> env;
		for(LPTSTR lpszVariable = (LPTSTR)lpvEnv; *lpszVariable; lpszVariable += _tcslen(lpszVariable)+1)
			if(lpszVariable != (LPTSTR)lpvEnv)
				env.AddTail(lpszVariable);

		env.AddTail(_T("GATEWAY_INTERFACE=CGI/1.1"));
		env.AddTail(_T("SERVER_SOFTWARE=Media Player Classic/6.4.x.y"));
		env.AddTail(_T("SERVER_PROTOCOL=") + pClient->m_ver);
		env.AddTail(_T("REQUEST_METHOD=") + pClient->m_cmd);
		env.AddTail(_T("PATH_INFO=") + redir);
		env.AddTail(_T("PATH_TRANSLATED=") + path);
		env.AddTail(_T("SCRIPT_NAME=") + redir);
		env.AddTail(_T("QUERY_STRING=") + pClient->m_query);

		if(pClient->m_hdrlines.Lookup(_T("content-type"), str))
			env.AddTail(_T("CONTENT_TYPE=") + str);
		if(pClient->m_hdrlines.Lookup(_T("content-length"), str))
			env.AddTail(_T("CONTENT_LENGTH=") + str);

		POSITION pos = pClient->m_hdrlines.GetStartPosition();
		while(pos)
		{
			CString key = pClient->m_hdrlines.GetKeyAt(pos);
			CString value = pClient->m_hdrlines.GetNextValue(pos);
			key.Replace(_T("-"), _T("_"));
			key.MakeUpper();
			env.AddTail(_T("HTTP_") + key + _T("=") + value);
		}
		
		CString name;
		UINT port;

		if(pClient->GetPeerName(name, port))
		{
			str.Format(_T("%d"), port);
			env.AddTail(_T("REMOTE_ADDR=")+name);
			env.AddTail(_T("REMOTE_HOST=")+name);
			env.AddTail(_T("REMOTE_PORT=")+str);
		}

		if(pClient->GetSockName(name, port))
		{
			str.Format(_T("%d"), port);
			env.AddTail(_T("SERVER_NAME=")+name);
			env.AddTail(_T("SERVER_PORT=")+str);
		}

		env.AddTail(_T("\0"));

		str = Implode(env, '\0');
		envstr = CStringA(str, str.GetLength());

		FreeEnvironmentStrings((LPTSTR)lpvEnv);
	}

	TCHAR* cmdln = new TCHAR[32768];
	_sntprintf(cmdln, 32768, _T("\"%s\" \"%s\""), cgi, path);

	if(hChildStdinRd && hChildStdoutWr)
	if(CreateProcess(
		NULL, cmdln, NULL, NULL, TRUE, 0, 
		envstr.GetLength() ? (LPVOID)(LPCSTR)envstr : NULL, 
		dir, &siStartInfo, &piProcInfo))
	{
		DWORD ThreadId;
		CreateThread(NULL, 0, KillCGI, (LPVOID)piProcInfo.hProcess, 0, &ThreadId);

		static const int BUFFSIZE = 1024;
		DWORD dwRead, dwWritten = 0;

		int i = 0, len = pClient->m_data.GetLength();
		for(; i < len; i += dwWritten)
			if(!WriteFile(hChildStdinWrDup, (LPCSTR)pClient->m_data + i, min(len - i, BUFFSIZE), &dwWritten, NULL)) 
				break;

		CloseHandle(hChildStdinWrDup);
		CloseHandle(hChildStdoutWr);

		body.Empty();

		CStringA buff;
		while(i == len && ReadFile(hChildStdoutRdDup, buff.GetBuffer(BUFFSIZE), BUFFSIZE, &dwRead, NULL) && dwRead)
		{
			buff.ReleaseBufferSetLength(dwRead);
			body += buff;
		}

		int hdrend = body.Find("\r\n\r\n");
		if(hdrend >= 0)
		{
			hdr = body.Left(hdrend+2);
			body = body.Mid(hdrend+4);
		}

		CloseHandle(hChildStdinRd);
		CloseHandle(hChildStdoutRdDup);

		CloseHandle(piProcInfo.hProcess);
		CloseHandle(piProcInfo.hThread);
	}
	else
	{
		body = _T("CGI Error");
	}

	delete [] cmdln;

	return true;
}
Ejemplo n.º 26
0
void MythSystemWindows::Fork(time_t timeout)
{
    QString LOC_ERR = QString("myth_system('%1'): Error: ").arg(GetLogCmd());

    // For use in the child
    char locerr[MAX_BUFLEN];
    strncpy(locerr, (const char *)LOC_ERR.toUtf8().constData(), MAX_BUFLEN);
    locerr[MAX_BUFLEN-1] = '\0';

    LOG(VB_SYSTEM, LOG_DEBUG, QString("Launching: %1").arg(GetLogCmd()));

    GetBuffer(0)->setBuffer(0);
    GetBuffer(1)->setBuffer(0);
    GetBuffer(2)->setBuffer(0);

    HANDLE p_stdin[2] = { NULL, NULL };
    HANDLE p_stdout[2] = { NULL, NULL };
    HANDLE p_stderr[2] = { NULL, NULL };

    SECURITY_ATTRIBUTES saAttr; 
    STARTUPINFO si;

    ZeroMemory(&si, sizeof(STARTUPINFO));
    si.cb = sizeof(STARTUPINFO);
        
    // Set the bInheritHandle flag so pipe handles are inherited. 
    saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); 
    saAttr.bInheritHandle = TRUE; 
    saAttr.lpSecurityDescriptor = NULL; 

    /* set up pipes */
    if( GetSetting("UseStdin") )
    {
        if (!CreatePipe(&p_stdin[0], &p_stdin[1], &saAttr, 0)) 
        {
            LOG(VB_GENERAL, LOG_ERR, "stdin pipe() failed");
            SetStatus( GENERIC_EXIT_NOT_OK );
        }
        else
        {
            // Ensure the write handle to the pipe for STDIN is not inherited. 
            if (!SetHandleInformation(p_stdin[1], HANDLE_FLAG_INHERIT, 0))
            {
                LOG(VB_SYSTEM, LOG_ERR, "stdin inheritance error");
                SetStatus( GENERIC_EXIT_NOT_OK );
            }
            else
            {
                si.hStdInput = p_stdin[0];
                si.dwFlags |= STARTF_USESTDHANDLES;
            }
        }
    }

    if( GetSetting("UseStdout") )
    {
        if (!CreatePipe(&p_stdout[0], &p_stdout[1], &saAttr, 0)) 
        {
            LOG(VB_SYSTEM, LOG_ERR, "stdout pipe() failed");
            SetStatus( GENERIC_EXIT_NOT_OK );
        }
        else
        {
            // Ensure the read handle to the pipe for STDOUT is not inherited.
            if (!SetHandleInformation(p_stdout[0], HANDLE_FLAG_INHERIT, 0))
            {
                LOG(VB_SYSTEM, LOG_ERR, "stdout inheritance error");
                SetStatus( GENERIC_EXIT_NOT_OK );
            }
            else
            {
                si.hStdOutput = p_stdout[1];
                si.dwFlags |= STARTF_USESTDHANDLES;
            }
        }
    }

    if( GetSetting("UseStderr") )
    {
        if (!CreatePipe(&p_stderr[0], &p_stderr[1], &saAttr, 0)) 
        {
            LOG(VB_SYSTEM, LOG_ERR, "stderr pipe() failed");
            SetStatus( GENERIC_EXIT_NOT_OK );
        }
        else
        {
            // Ensure the read handle to the pipe for STDERR is not inherited.
            if (!SetHandleInformation(p_stderr[0], HANDLE_FLAG_INHERIT, 0))
            {
                LOG(VB_SYSTEM, LOG_ERR, "stderr inheritance error");
                SetStatus( GENERIC_EXIT_NOT_OK );
            }
            else
            {
                si.hStdError = p_stderr[1];
                si.dwFlags |= STARTF_USESTDHANDLES;
            }
        }
    }

    // set up command args
    QString cmd = GetCommand() + " " + GetArgs().join(" ");
    if (GetSetting("UseShell"))
        cmd.prepend("cmd.exe /c ");

    SetCommand( cmd );

    QByteArray cmdUTF8 = GetCommand().toUtf8();
    TCHAR *command = TEXT((char *)cmdUTF8.constData());

    const char *directory = NULL;
    QString dir = GetDirectory();
    if (GetSetting("SetDirectory") && !dir.isEmpty())
        directory = strdup(dir.toUtf8().constData());

    PROCESS_INFORMATION pi;
    ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));

    m_timeout = timeout;
    if( timeout )
        m_timeout += time(NULL);

    bool success = CreateProcess(NULL, 
                    command,       // command line 
                    NULL,          // process security attributes 
                    NULL,          // primary thread security attributes 
                    TRUE,          // handles are inherited 
                    0,             // creation flags 
                    NULL,          // use parent's environment 
                    directory,     // use parent's current directory 
                   &si,            // STARTUPINFO pointer 
                   &pi);           // receives PROCESS_INFORMATION 

    if (!success)
    {
        LOG(VB_SYSTEM, LOG_ERR, "CreateProcess() failed");
        SetStatus( GENERIC_EXIT_NOT_OK );
    }
    else
    {
        /* parent */
        m_child = pi.hProcess;
        SetStatus( GENERIC_EXIT_RUNNING );

        LOG(VB_SYSTEM, LOG_INFO,
                QString("Managed child (Handle: %1) has started! "
                        "%2%3 command=%4, timeout=%5")
                    .arg((long long)m_child) 
                    .arg(GetSetting("UseShell") ? "*" : "")
                    .arg(GetSetting("RunInBackground") ? "&" : "")
                    .arg(GetLogCmd()) .arg(timeout));

        /* close unused pipe ends */
        CLOSE(p_stdin[0]);
        CLOSE(p_stdout[1]);
        CLOSE(p_stderr[1]);

        // store the rest
        m_stdpipe[0] = p_stdin[1];
        m_stdpipe[1] = p_stdout[0];
        m_stdpipe[2] = p_stderr[0];

        // clean up the memory use
        if( directory )
            free((void *)directory);
    }

    /* Parent */
    if( GetStatus() != GENERIC_EXIT_RUNNING )
    {
        CLOSE(p_stdin[0]);
        CLOSE(p_stdin[1]);
        CLOSE(p_stdout[0]);
        CLOSE(p_stdout[1]);
        CLOSE(p_stderr[0]);
        CLOSE(p_stderr[1]);
    }
}
Ejemplo n.º 27
0
DWORD WINAPI DebugThread(LPVOID lpvParam)
{
	DWORD nWait = WAIT_TIMEOUT;
	wchar_t szInfo[1024];
	wchar_t szPID[20];
	int iAttachedCount = 0;
	CEStr szOtherBitPids, szOtherDebugCmd;

	// Дополнительная инициализация, чтобы закрытие дебагера (наш процесс) не привело
	// к закрытию "отлаживаемой" программы
	pfnDebugActiveProcessStop = (FDebugActiveProcessStop)GetProcAddress(GetModuleHandle(L"kernel32.dll"),"DebugActiveProcessStop");
	pfnDebugSetProcessKillOnExit = (FDebugSetProcessKillOnExit)GetProcAddress(GetModuleHandle(L"kernel32.dll"),"DebugSetProcessKillOnExit");

	// Affect GetProcessHandleForDebug
	gpSrv->DbgInfo.bDebuggerActive = TRUE;

	// If dump was requested
	if (gpSrv->DbgInfo.nDebugDumpProcess)
	{
		gpSrv->DbgInfo.bUserRequestDump = TRUE;
	}

	// "/DEBUGEXE" or "/DEBUGTREE"
	if (gpSrv->DbgInfo.pszDebuggingCmdLine != NULL)
	{
		STARTUPINFO si = {sizeof(si)};
		PROCESS_INFORMATION pi = {};

		if (gpSrv->DbgInfo.bDebugProcessTree)
		{
			SetEnvironmentVariable(ENV_CONEMU_BLOCKCHILDDEBUGGERS_W, ENV_CONEMU_BLOCKCHILDDEBUGGERS_YES);
		}

		if (!CreateProcess(NULL, gpSrv->DbgInfo.pszDebuggingCmdLine, NULL, NULL, FALSE,
			NORMAL_PRIORITY_CLASS|CREATE_NEW_CONSOLE|
			DEBUG_PROCESS | (gpSrv->DbgInfo.bDebugProcessTree ? 0 : DEBUG_ONLY_THIS_PROCESS),
			NULL, NULL, &si, &pi))
		{
			DWORD dwErr = GetLastError();

			wchar_t szProc[64]; szProc[0] = 0;
			PROCESSENTRY32 pi = {sizeof(pi)};
			if (GetProcessInfo(gpSrv->dwRootProcess, &pi))
				_wcscpyn_c(szProc, countof(szProc), pi.szExeFile, countof(szProc));

			_wsprintf(szInfo, SKIPLEN(countof(szInfo)) L"Can't start debugging process. ErrCode=0x%08X\n", dwErr);
			CEStr lsInfo(lstrmerge(szInfo, gpSrv->DbgInfo.pszDebuggingCmdLine, L"\n"));
			_wprintf(lsInfo);
			return CERR_CANTSTARTDEBUGGER;
		}

		gpSrv->hRootProcess = pi.hProcess;
		gpSrv->hRootThread = pi.hThread;
		gpSrv->dwRootProcess = pi.dwProcessId;
		gpSrv->dwRootThread = pi.dwThreadId;
		gpSrv->dwRootStartTime = GetTickCount();

		// Let's know that at least one process is debugging
		iAttachedCount++;
	}


	/* ************************* */
	int iDbgIdx = 0;
	bool bSetKillOnExit = true;

	while (true)
	{
		HANDLE hDbgProcess = NULL;
		DWORD  nDbgProcessID = 0;

		if ((iDbgIdx++) == 0)
		{
			hDbgProcess = gpSrv->hRootProcess;
			nDbgProcessID = gpSrv->dwRootProcess;
		}
		else
		{
			// Взять из pDebugAttachProcesses
			if (!gpSrv->DbgInfo.pDebugAttachProcesses)
				break;
			if (!gpSrv->DbgInfo.pDebugAttachProcesses->pop_back(nDbgProcessID))
				break;
			hDbgProcess = GetProcessHandleForDebug(nDbgProcessID);
			if (!hDbgProcess)
			{
				_ASSERTE(hDbgProcess!=NULL && "Can't open debugging process handle");
				continue;
			}
		}


		_ASSERTE(hDbgProcess!=NULL && "Process handle must be opened");


		// Битность отладчика должна соответствовать битности приложения!
		if (IsWindows64())
		{
			int nBits = GetProcessBits(nDbgProcessID, hDbgProcess);
			if ((nBits == 32 || nBits == 64) && (nBits != WIN3264TEST(32,64)))
			{
				// If /DEBUGEXE or /DEBUGTREE was used
				if (gpSrv->DbgInfo.pszDebuggingCmdLine != NULL)
				{
					_printf("Bitness of ConEmuC and debugging program does not match\n");
					continue;
				}

				// Добавить процесс в список для запуска альтернативного дебаггера соотвествующей битности
				// Force trailing "," even if only one PID specified ( --> bDebugMultiProcess = TRUE)
				lstrmerge(&szOtherBitPids.ms_Arg, _itow(nDbgProcessID, szPID, 10), L",");

				// Может там еще процессы в списке на дамп?
				continue;
			}
		}

		if (gpSrv->DbgInfo.pszDebuggingCmdLine == NULL)
		{
			if (DebugActiveProcess(nDbgProcessID))
			{
				iAttachedCount++;
			}
			else
			{
				DWORD dwErr = GetLastError();

				wchar_t szProc[64]; szProc[0] = 0;
				PROCESSENTRY32 pi = {sizeof(pi)};
				if (GetProcessInfo(nDbgProcessID, &pi))
					_wcscpyn_c(szProc, countof(szProc), pi.szExeFile, countof(szProc));

				_wsprintf(szInfo, SKIPLEN(countof(szInfo)) L"Can't attach debugger to '%s' PID=%i. ErrCode=0x%08X\n",
					szProc[0] ? szProc : L"not found", nDbgProcessID, dwErr);
				_wprintf(szInfo);

				// Может другие подцепить получится?
				continue;
			}
		}

		// To avoid debugged processes killing
		if (bSetKillOnExit && pfnDebugSetProcessKillOnExit)
		{
			// affects all current and future debuggees connected to the calling thread
			if (pfnDebugSetProcessKillOnExit(FALSE/*KillOnExit*/))
			{
				bSetKillOnExit = false;
			}
		}
	}

	// Different bitness, need to start appropriate debugger
	if (szOtherBitPids.ms_Arg && *szOtherBitPids.ms_Arg)
	{
		wchar_t szExe[MAX_PATH+5], *pszName;
		if (!GetModuleFileName(NULL, szExe, MAX_PATH))
		{
			_wsprintf(szInfo, SKIPLEN(countof(szInfo)) L"GetModuleFileName(NULL) failed. ErrCode=0x%08X\n", GetLastError());
			_wprintf(szInfo);
		}
		else if (!(pszName = (wchar_t*)PointToName(szExe)))
		{
			_wsprintf(szInfo, SKIPLEN(countof(szInfo)) L"GetModuleFileName(NULL) returns invalid path\n%s\n", szExe);
			_wprintf(szInfo);
		}
		else
		{
			*pszName = 0;
			// Reverted to current bitness
			wcscat_c(szExe, WIN3264TEST(L"ConEmuC64.exe", L"ConEmuC.exe"));

			szOtherDebugCmd.Attach(lstrmerge(L"\"", szExe, L"\" "
				L"/DEBUGPID=", szOtherBitPids.ms_Arg,
				(gpSrv->DbgInfo.nDebugDumpProcess == 1) ? L" /DUMP" :
				(gpSrv->DbgInfo.nDebugDumpProcess == 2) ? L" /MINIDUMP" :
				(gpSrv->DbgInfo.nDebugDumpProcess == 3) ? L" /FULLDUMP" : L""));

			STARTUPINFO si = {sizeof(si)};
			PROCESS_INFORMATION pi = {};
			if (CreateProcess(NULL, szOtherDebugCmd.ms_Arg, NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi))
			{
				// Ждать не будем
			}
			else
			{
				DWORD dwErr = GetLastError();
				_wsprintf(szInfo, SKIPLEN(countof(szInfo)) L"Can't start external debugger, ErrCode=0x%08X\n", dwErr);
				CEStr lsInfo(lstrmerge(szInfo, szOtherDebugCmd, L"\n"));
				_wprintf(lsInfo);
			}
		}
	}

	//_ASSERTE(FALSE && "Continue to dump");

	// If neither /DEBUG[EXE|TREE] nor /DEBUGPID was not succeeded
	if (iAttachedCount == 0)
	{
		gpSrv->DbgInfo.bDebuggerActive = FALSE;
		return CERR_CANTSTARTDEBUGGER;
	}
	else if (iAttachedCount > 1)
	{
		_ASSERTE(gpSrv->DbgInfo.bDebugMultiProcess && "Already must be set from arguments parser");
		gpSrv->DbgInfo.bDebugMultiProcess = TRUE;
	}

	if (gpSrv->DbgInfo.bUserRequestDump)
	{
		gpSrv->DbgInfo.nWaitTreeBreaks = iAttachedCount;
	}

	/* **************** */

	// To avoid debugged processes killing (JIC, must be called already)
	if (bSetKillOnExit && pfnDebugSetProcessKillOnExit)
	{
		// affects all current and future debuggees connected to the calling thread
		if (pfnDebugSetProcessKillOnExit(FALSE/*KillOnExit*/))
		{
			bSetKillOnExit = false;
		}
	}

	PrintDebugInfo();
	SetEvent(gpSrv->DbgInfo.hDebugReady);


	while (nWait == WAIT_TIMEOUT)
	{
		ProcessDebugEvent();

		if (ghExitQueryEvent)
			nWait = WaitForSingleObject(ghExitQueryEvent, 0);
	}

//done:
	gbRootAliveLess10sec = FALSE;
	gbInShutdown = TRUE;
	gbAlwaysConfirmExit = FALSE;

	_ASSERTE(gbTerminateOnCtrlBreak==FALSE);

	if (!nExitQueryPlace) nExitQueryPlace = 12+(nExitPlaceStep);

	SetTerminateEvent(ste_DebugThread);
	return 0;
}
sLONG XWinProcessLauncher::Start(const EnvVarNamesAndValuesMap &inVarToUse)
{
	sLONG			err = 0;
	sLONG			pathLen = 0;
	STARTUPINFO				theStartupInfo;
	PROCESS_INFORMATION		theProcessInformation;
	SECURITY_ATTRIBUTES		theSecurityAttributes;

	char		*envVarsBlock = NULL;
	char		*argsAsCString= NULL;

	if(fBinaryPath == NULL)
		return -50;	// Invalid parameter

	pathLen = (sLONG) strlen(fBinaryPath);
	if(pathLen == 0)
		return -50;	// Invalid parameter

	// Sets the bInheritHandle flag so that pipes are inherited
	theSecurityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
	theSecurityAttributes.bInheritHandle = TRUE;
	theSecurityAttributes.lpSecurityDescriptor = NULL;
	
	::SetLastError(0);

	// ______________________________________________ STDIN pipes
	if(err == 0 && fRedirectStandardInput)
	{
	// Creates a pipe for the child process STDIN
		if(!CreatePipe(&fChildStdInRead, &fChildStdInWrite, &theSecurityAttributes, 0))
			err = ::GetLastError();

	// Duplicates the write handle so that it is not inherited
		if(err == 0)
		{
			if(!DuplicateHandle(GetCurrentProcess(), fChildStdInWrite, GetCurrentProcess(), &fChildStdInWriteDup, 0, FALSE, DUPLICATE_SAME_ACCESS))
				err = ::GetLastError();
		}

		_CloseAndInvalidateHandle(&fChildStdInWrite);
	}
	
	// ______________________________________________ STDOUT/STDERR pipes
	if(err == 0 && fRedirectStandardOutput)
	{
	// Creates a pipe for the child process's STDOUT
		if(!CreatePipe(&fChildStdOutRead, &fChildStdOutWrite, &theSecurityAttributes, 0))
			err = ::GetLastError();

		if (err == 0) {

			DWORD	mode = PIPE_NOWAIT;
			
			if (!SetNamedPipeHandleState(fChildStdOutRead, &mode, NULL, NULL))
		
				err = ::GetLastError();

		}

	// Duplicates the read handle to the pipe so that it is not inherited
		if(err == 0)
		{
			if(!DuplicateHandle(GetCurrentProcess(), fChildStdOutRead, GetCurrentProcess(), &fChildStdOutReadDup, 0, FALSE, DUPLICATE_SAME_ACCESS))
				err = ::GetLastError();
		}

		_CloseAndInvalidateHandle(&fChildStdOutRead);

	// The same for STDERR
		if(err == 0)
		{
			if(!CreatePipe(&fChildStdErrRead, &fChildStdErrWrite, &theSecurityAttributes, 0))
				err = ::GetLastError();
		}

		if (err == 0) {

			DWORD	mode = PIPE_NOWAIT;
			
			if (!SetNamedPipeHandleState(fChildStdErrRead, &mode, NULL, NULL))
		
				err = ::GetLastError();

		}

		if(err == 0)
		{
			if(!DuplicateHandle(GetCurrentProcess(), fChildStdErrRead, GetCurrentProcess(), &fChildStdErrReadDup, 0, FALSE, DUPLICATE_SAME_ACCESS))
				err = ::GetLastError();
		}
		
		_CloseAndInvalidateHandle(&fChildStdErrRead);
	} // if(err == 0 && fRedirectStandardOutput)
	
	// ______________________________________________ Setup CreateProcess() parameters
	if(err == 0)
	{
	// Sets up members of the PROCESS_INFORMATION structure
		ZeroMemory(&theProcessInformation, sizeof(PROCESS_INFORMATION));
		
	// Sets up members of the STARTUPINFO structure
		ZeroMemory(&theStartupInfo, sizeof(STARTUPINFO));
		theStartupInfo.cb = sizeof(STARTUPINFO);
		if(fRedirectStandardInput || fRedirectStandardOutput)
			theStartupInfo.dwFlags |= STARTF_USESTDHANDLES;
		theStartupInfo.hStdInput = NULL;
		theStartupInfo.hStdOutput = NULL;
		theStartupInfo.hStdError = NULL;
		if(fRedirectStandardInput)
			theStartupInfo.hStdInput = fChildStdInRead;
		if(fRedirectStandardOutput)
		{
			theStartupInfo.hStdOutput = fChildStdOutWrite;
			theStartupInfo.hStdError = fChildStdErrWrite;
		}
		
	// Hides the command window if specified
		if(fHideWindow)
		{
			theStartupInfo.dwFlags |= STARTF_USESHOWWINDOW;
			theStartupInfo.wShowWindow = SW_HIDE;
		}
		
	// Create the environment variables block
		envVarsBlock = _CreateEnvironmentVariablesBlock(inVarToUse);
		
	// Create the CString arguments. See _CreateConcatenetedArguments().
		argsAsCString = _CreateConcatenetedArguments();
		if(argsAsCString == NULL)
		{
			assert(false);
			err = -108;
		}
	} // if(err == 0)
	
	// ______________________________________________ CreateProcess()
	if(err == 0)
	{
		sLONG	argsLen = (sLONG) strlen(argsAsCString);
		sLONG	commandFullSize = pathLen + 1; //'\0'
		if(argsLen > 0)
			commandFullSize += 1 + argsLen;// ' '
		
		char *commandLine = NULL;
		
		if(argsLen > 0)
		{
			commandLine = new char[commandFullSize];
			if(commandLine == NULL)
			{
				err = -108;
			}
			else
			{
				memcpy(commandLine, fBinaryPath, pathLen);
				if(argsLen > 0)
				{
					commandLine[pathLen] = ' ';
					memcpy(commandLine + pathLen + 1, argsAsCString, argsLen);
				}
				commandLine[commandFullSize - 1] = 0;
			}
		}
		else
		{
			sLONG	theSize = (sLONG) strlen(fBinaryPath) + 1;
			commandLine = new char[theSize];
			memcpy(commandLine, fBinaryPath, theSize);
		}
		
		if(err == 0)
		{
			bool	bInheritHandles = fRedirectStandardInput || fRedirectStandardOutput ? TRUE : FALSE;
			char *lpCurrentDirectory = (fCurrentDirectory != NULL && fCurrentDirectory[0] > 0) ? fCurrentDirectory : NULL;
			
			SetLastError(0);

			long	tempLastError = 0;
			long creaProcResult = CreateProcess(NULL,					// Application name
												commandLine,			// Command line
												NULL,					// Process security attributes
												NULL,					// Primary thread security attributes
												bInheritHandles,		// Handles are inherited
												0,						// DETACHED_PROCESS creation flag
												envVarsBlock,			// NULL == use parent's environment
												lpCurrentDirectory,		// NULL == use parent's directory
												&theStartupInfo,		// STARTUPINFO pointer
												&theProcessInformation	// Receives PROCESS_INFORMATION
												);
			tempLastError = GetLastError(); // For debug
			if(creaProcResult == 0)	// "If the function succeeds, the return value is nonzero"
			{
				err = ::GetLastError();

				fIsRunning = false;
				fProcessID = 0;
				ZeroMemory(&fProcInfo, sizeof(PROCESS_INFORMATION));
			}
			else
			{
				fIsRunning = true;
				fProcInfo = theProcessInformation;
				fProcessID = fProcInfo.dwProcessId;
			
				// If process is independant and we don't need to retrieve exit status at
				// termination, immediatly close those handles from our part
				if(!fWaitClosingChildProcess && !fCanGetExitStatus)
				{
					CloseHandle(theProcessInformation.hProcess);
					CloseHandle(theProcessInformation.hThread);
					
				}
			
			}
		} // if(err == 0)
		
		delete [] commandLine;
		
	} //  if(err == 0)
	
	if(err != 0)
		_CloseAllPipes();
	
	delete [] argsAsCString;
	delete [] envVarsBlock;
	
	return err;
}
Ejemplo n.º 29
0
DWORD CHooks::RunScript(CString cmd, LPCTSTR currentDir, CString& error, bool bWait, bool bShow)
{
	DWORD exitcode = 0;
	SECURITY_ATTRIBUTES sa;
	SecureZeroMemory(&sa, sizeof(sa));
	sa.nLength = sizeof(sa);
	sa.bInheritHandle = TRUE;

	CAutoFile hOut ;
	CAutoFile hRedir;
	CAutoFile hErr;

	// clear the error string
	error.Empty();

	// Create Temp File for redirection
	TCHAR szTempPath[MAX_PATH] = {0};
	TCHAR szOutput[MAX_PATH] = {0};
	TCHAR szErr[MAX_PATH] = {0};
	GetTortoiseGitTempPath(_countof(szTempPath), szTempPath);
	GetTempFileName(szTempPath, _T("git"), 0, szErr);

	// setup redirection handles
	// output handle must be WRITE mode, share READ
	// redirect handle must be READ mode, share WRITE
	hErr   = CreateFile(szErr, GENERIC_WRITE, FILE_SHARE_READ, &sa, CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY,	0);

	if (!hErr)
	{
		error = CFormatMessageWrapper();
		return (DWORD)-1;
	}

	hRedir = CreateFile(szErr, GENERIC_READ, FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);

	if (!hRedir)
	{
		error = CFormatMessageWrapper();
		return (DWORD)-1;
	}

	GetTempFileName(szTempPath, _T("git"), 0, szOutput);
	hOut   = CreateFile(szOutput, GENERIC_WRITE, FILE_SHARE_READ, &sa, CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY,	0);

	if (!hOut)
	{
		error = CFormatMessageWrapper();
		return (DWORD)-1;
	}

	// setup startup info, set std out/err handles
	// hide window
	STARTUPINFO si;
	SecureZeroMemory(&si, sizeof(si));
	si.cb = sizeof(si);
	si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
	si.hStdOutput = hOut;
	si.hStdError = hErr;
	si.wShowWindow = bShow ? SW_SHOW : SW_HIDE;

	PROCESS_INFORMATION pi;
	SecureZeroMemory(&pi, sizeof(pi));

	if (!CreateProcess(nullptr, cmd.GetBuffer(), nullptr, nullptr, TRUE, 0, nullptr, currentDir, &si, &pi))
	{
		const DWORD err = GetLastError();  // preserve the CreateProcess error
		error = CFormatMessageWrapper(err);
		SetLastError(err);
		cmd.ReleaseBuffer();
		return (DWORD)-1;
	}
	cmd.ReleaseBuffer();

	CloseHandle(pi.hThread);

	// wait for process to finish, capture redirection and
	// send it to the parent window/console
	if (bWait)
	{
		DWORD dw;
		char buf[256] = { 0 };
		do
		{
			while (ReadFile(hRedir, &buf, sizeof(buf)-1, &dw, NULL))
			{
				if (dw == 0)
					break;
				error += CString(CStringA(buf,dw));
			}
			Sleep(150);
		} while (WaitForSingleObject(pi.hProcess, 0) != WAIT_OBJECT_0);

		// perform any final flushing
		while (ReadFile(hRedir, &buf, sizeof(buf)-1, &dw, NULL))
		{
			if (dw == 0)
				break;

			error += CString(CStringA(buf, dw));
		}
		WaitForSingleObject(pi.hProcess, INFINITE);
		GetExitCodeProcess(pi.hProcess, &exitcode);
	}
	CloseHandle(pi.hProcess);
	DeleteFile(szOutput);
	DeleteFile(szErr);

	return exitcode;
}
Ejemplo n.º 30
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_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 );

      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_UNIX ) && \
      ! defined( HB_OS_VXWORKS ) && ! defined( HB_OS_SYMBIAN )

      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 */
         setuid( getuid() );
         setgid( getgid() );

         /* execute command */
         {
            char ** argv;

            argv = hb_buildArgs( pszFilename );
#  if defined( __WATCOMC__ )
            execvp( argv[ 0 ], ( const char ** ) argv );
#  else
            execvp( argv[ 0 ], argv );
#  endif
            hb_freeArgs( argv );
            exit( -1 );
         }
      }

#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;
      }

#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
   }

   hb_fsSetIOError( ! fError, 0 );

   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 ] );
   }

   return hResult;
}