Example #1
1
//
// pszCmd should be less than 1024 bytes.
//
U32 CProcessUtil_i::RunSilentProcess(LPCTSTR pszCmd, LPCTSTR pAppCmd, DWORD dwTimeOut)
{
  HANDLE hProcess = 0;
  HANDLE hThread = 0;
  STARTUPINFO si;
  PROCESS_INFORMATION pi;
  TCHAR szCmd[1024] = {0,};
 
  if(pszCmd)
  {
    lstrcpyn(szCmd, pszCmd, sizeof(szCmd)-1);
  }
  
  ZeroMemory( &si, sizeof(si) );
  si.cb = sizeof(si); //si.cb = sizeof(STARTUPINFO);
  //si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
  si.hStdOutput = NULL;
  si.hStdInput  = NULL;
  si.hStdError  = NULL;
  // Use this if you want to show the child.
  si.wShowWindow = SW_HIDE;
  
  ZeroMemory( &pi, sizeof(pi) );
  
  //SetCurrentDirectory(pszCurPath);

  //WinExec(pszCmd, SW_SHOW);
  //return FALSE;

  // Start the child process.
  if( !CreateProcess(pAppCmd , // the app line
    szCmd, //           "C:\\pclint\\tst.bat" Command line. , bat  or cmd.exe /k ....
    NULL,             // Process handle not inheritable. 
    NULL,             // Thread handle not inheritable. 
    FALSE,            // Set handle inheritance to FALSE. 
    CREATE_NO_WINDOW, // creation flags.CREATE_NEW_CONSOLE CREATE_NO_WINDOW
    NULL,             // Use parent's environment block. 
    NULL,             // Use parent's starting directory. 
    &si,              // Pointer to STARTUPINFO structure.
    &pi )             // Pointer to PROCESS_INFORMATION structure.
    ) 
  {
    return ERR_WIN32_ERROR_I; 
  }
  
  hProcess = pi.hProcess;
  hThread  = pi.hThread;

  if (hProcess == NULL)
  {
    OutputDbgStr(_T("Error: Internal error. \n"));
    return ERR_WIN32_ERROR_I;
  }
  else
  {
    switch (::WaitForSingleObject(hProcess, dwTimeOut)) // WaitForSingleObject( pi.hProcess,  );
    {
    case WAIT_OBJECT_0:
      break;
    case WAIT_TIMEOUT:
      break;
    default:
      break;
    }
  }
  
  DWORD dwExitCode = 0;
  GetExitCodeProcess(hProcess, &dwExitCode);
  
  // Close process and thread handles. 
  CloseHandle( hProcess );
  CloseHandle( hThread );
  
  return dwExitCode;
}
Example #2
0
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
#endif
{
	hInst = hInstance;
	isWin64 = IsWindows64();
	
	GetVersionEx(&gOSVer);
	
	int nInstallVer = 0;
	
	wsprintf(gsTitle, L"ConEmu %s installer", CONEMUVERL);
	lstrcpyn(gsRunAsAdm, L"Run installer as administrator", countof(gsRunAsAdm));

	wchar_t szArg[MAX_PATH+1];
	LPCWSTR pszCmdToken = GetCommandLine();
	LPCWSTR pszCmdLineW = pszCmdToken;
	
	gsTempFolder[0] = 0;
	
	while (0 == NextArg(&pszCmdToken, szArg))
	{
		if (lstrcmp(szArg, L"/?") == 0 || lstrcmp(szArg, L"-?") == 0 || lstrcmp(szArg, L"-h") == 0
			|| lstrcmp(szArg, L"-help") == 0 || lstrcmp(szArg, L"--help") == 0)
		{
			MessageBox(NULL,
				L"Usage:\n"
				L"   ConEmuSetup [/p:x86[,adm] | /p:x64[,adm]] [<msi args>]\n"
				L"   ConEmuSetup [/e[:<extract path>]] [/p:x86 | /p:x64]\n"
				L"Example (run x64 auto update as administrator):\n"
				L"   ConEmuSetup /p:x64,adm /qr",
				gsTitle, MB_ICONINFORMATION);
			return 1;
		}
		
		if (*szArg == L'/')
		{
			if (szArg[1] == L'e' || szArg[1] == L'E')
			{
				gbExtractOnly = true;
				if (szArg[2] == L':' && szArg[3])
				{
					lstrcpyn(gsTempFolder, (szArg[3]==L'"') ? (szArg+4) : (szArg+3), countof(gsTempFolder));
				}
				continue;
			}
		
		    if (memcmp(szArg, L"/p:x", 4*sizeof(*szArg)) == 0)
		    {
		    	gbAlreadyAdmin = IsUserAdmin();
				if (lstrcmpi(szArg+4, L"86") == 0)
				{
					nInstallVer = Ver86;
				}
				else if (lstrcmpi(szArg+4, L"86,adm") == 0)
				{
					nInstallVer = Ver86;
					gbUseElevation = !gbAlreadyAdmin;
				}
				else if (lstrcmpi(szArg+4, L"64") == 0)
				{
					nInstallVer = Ver64;
				}
				else if (lstrcmpi(szArg+4, L"64,adm") == 0)
				{
					nInstallVer = Ver64;
					gbUseElevation = !gbAlreadyAdmin;
				}
			}
			else
				pszCmdToken = pszCmdLineW;
			break;
		}
		else if (*szArg == L'-')
		{
			pszCmdToken = pszCmdLineW;
			break;
		}
			
		pszCmdLineW = pszCmdToken;
	}
	

	if (!gbExtractOnly)
	{
		wchar_t szInstallPath[MAX_PATH+32];
		bool bInstalled;
		HKEY hk;
	
		lstrcpyn(gsMessage, L"Choose version to install", countof(gsMessage));
		
			szInstallPath[0] = 0; bInstalled = false;
			struct {HKEY hk; LPCWSTR path; LPCWSTR name; bool our;}
				Keys[] = {
					{HKEY_LOCAL_MACHINE,L"SOFTWARE\\ConEmu",L"InstallDir",true},
					{HKEY_LOCAL_MACHINE,L"SOFTWARE\\Far Manager",L"InstallDir"},
					{HKEY_LOCAL_MACHINE,L"SOFTWARE\\Far2",L"InstallDir"},
					{HKEY_LOCAL_MACHINE,L"SOFTWARE\\Far",L"InstallDir"},
				};
			for (size_t s = 0; s < countof(Keys); s++)
			{
				if (!RegOpenKeyEx(Keys[s].hk, Keys[s].path, 0, KEY_READ, &hk)
					|| !RegOpenKeyEx(Keys[s].hk, Keys[s].path, 0, KEY_READ|KEY_WOW64_32KEY, &hk))
				{
					wchar_t szPath[MAX_PATH+1] = {}; DWORD cbSize = sizeof(szPath)-2;
					LONG lRc = RegQueryValueEx(hk, Keys[s].name, NULL, NULL, (LPBYTE)szPath, &cbSize);
					RegCloseKey(hk);
					if (!lRc && *szPath)
					{
						bInstalled = Keys[s].our;
						lstrcpy(szInstallPath, szPath);
						cbSize = lstrlen(szInstallPath);
						if (szInstallPath[cbSize-1] == L'\\') szInstallPath[cbSize-1] = 0;
						break;
					}
				}
			}
			if (szInstallPath[0] == 0)
			{
				GetEnvironmentVariable(L"ProgramFiles", szInstallPath, MAX_PATH);
				int nLen = lstrlen(szInstallPath);
				lstrcat(szInstallPath, (nLen > 0 && szInstallPath[nLen-1] != L'\\') ? L"\\ConEmu" : L"ConEmu");
			}
			wsprintf(gsVer86, L"%s x86\n%s installation folder is\n%s", CONEMUVERL, bInstalled ? L"Current" : L"Default", szInstallPath);

			
		if (isWin64)
		{
			
				szInstallPath[0] = 0; bInstalled = false;
				struct {HKEY hk; LPCWSTR path; LPCWSTR name; bool our;}
					Keys[] = {
						{HKEY_LOCAL_MACHINE,L"SOFTWARE\\ConEmu",L"InstallDir_x64",true},
						{HKEY_LOCAL_MACHINE,L"SOFTWARE\\Far Manager",L"InstallDir_x64"},
						{HKEY_LOCAL_MACHINE,L"SOFTWARE\\Far2",L"InstallDir_x64"},
						{HKEY_LOCAL_MACHINE,L"SOFTWARE\\Far",L"InstallDir_x64"},
					};
				for (size_t s = 0; s < countof(Keys); s++)
				{
					if (!RegOpenKeyEx(Keys[s].hk, Keys[s].path, 0, KEY_READ|KEY_WOW64_64KEY, &hk))
					{
						wchar_t szPath[MAX_PATH+1] = {}; DWORD cbSize = sizeof(szPath)-2;
						LONG lRc = RegQueryValueEx(hk, Keys[s].name, NULL, NULL, (LPBYTE)szPath, &cbSize);
						RegCloseKey(hk);
						if (!lRc && *szPath)
						{
							bInstalled = Keys[s].our;
							lstrcpy(szInstallPath, szPath);
							cbSize = lstrlen(szInstallPath);
							if (szInstallPath[cbSize-1] == L'\\') szInstallPath[cbSize-1] = 0;
							break;
						}
					}
				}
				if (szInstallPath[0] == 0)
				{
					GetEnvironmentVariable(L"ProgramW6432", szInstallPath, MAX_PATH);
					int nLen = lstrlen(szInstallPath);
					lstrcat(szInstallPath, (nLen > 0 && szInstallPath[nLen-1] != L'\\') ? L"\\ConEmu" : L"ConEmu");
				}
				wsprintf(gsVer64, L"%s x64\n%s installation folder is\n%s", CONEMUVERL, bInstalled ? L"Current" : L"Default", szInstallPath);

			wsprintf(gsFull, L"%s\n\nPress `Yes` to install x64 version\nPress `No` to install x86 version", gsMessage);
		}
		else
		{
			gsVer64[0] = 0;
		}
	}
	else
	{
		wchar_t szPath[MAX_PATH+1];
		if (*gsTempFolder)
		{
			lstrcpy(szPath, gsTempFolder);
		}
		else
		{
			GetTempPath(countof(szPath) - 14, szPath);
			wchar_t* pszSubDir = szPath+lstrlen(szPath);
			lstrcpy(pszSubDir, L"ConEmu");
			pszSubDir += 6;
			lstrcpy(pszSubDir, CONEMUVERL);
		}
		
		lstrcpyn(gsMessage, L"Choose version to extract", countof(gsMessage));
		wsprintf(gsVer86, L"%s x86\nExtract installation files to\n%s", CONEMUVERL, szPath);
		wsprintf(gsVer64, L"%s x64\nExtract installation files to\n%s", CONEMUVERL, szPath);
		wsprintf(gsFull, L"%s\n\nPress `Yes` to extract x64 version\nPress `No` to extract x86 version\n\n%s", gsMessage, szPath);
	}
	
	if (nInstallVer == 0)
		nInstallVer = ChooseVersion(); // IDCANCEL/Ver86/Ver64
		
	if (nInstallVer != Ver86 && nInstallVer != Ver64)
		return 1;
	
	if (gbExtractOnly && *gsTempFolder)
	{
		CreateDirectory(gsTempFolder, NULL);
	}
	else
	{
		GetTempPath(countof(gsTempFolder) - 14, gsTempFolder);
		
		wchar_t* pszSubDir = gsTempFolder+lstrlen(gsTempFolder);
		lstrcpy(pszSubDir, L"ConEmu");
		pszSubDir += 6;
		lstrcpy(pszSubDir, CONEMUVERL);
		pszSubDir += lstrlen(pszSubDir);
		if (!CreateDirectory(gsTempFolder, NULL))
		{
			bool lbCreated = false;
			SYSTEMTIME st = {}; GetLocalTime(&st);
			for (int i = 0; i < 100; i++)
			{
				wsprintf(pszSubDir, L"_%02i%02i%02i%i", st.wHour, st.wMinute, st.wSecond, i);
				if (CreateDirectory(gsTempFolder, NULL))
				{
					lbCreated = true;
					break;
				}
			}
			if (!lbCreated)
			{
				return ReportError(10, L"Can't create temp folder\n%s", gsTempFolder);
			}
		}
	}

	wsprintf(gsMsiFile, L"%s\\ConEmu.%s.%s.msi", gsTempFolder, CONEMUVERL, (nInstallVer == Ver86) ? L"x86" : L"x64");
	wsprintf(gsCabFile, L"%s\\ConEmu.cab", gsTempFolder);
	
	bool lbNeedExe = false;
	if (!gbExtractOnly && gOSVer.dwMajorVersion >= 6)
		lbNeedExe = true;

	if (!lbNeedExe)
		gsExeFile[0] = 0;
	else
		wsprintf(gsExeFile, L"%s\\ConEmuSetup.exe", gsTempFolder);
	
	int iExpMsi = ExportFile(nInstallVer, gsMsiFile);
	int iExpCab = (iExpMsi == 0) ? ExportFile(CABFILE, gsCabFile) : -1;
	int iExpExe = (!lbNeedExe) ? 0 : (iExpCab == 0) ? ExportFile(EXEFILE, gsExeFile) : -1;
	if (iExpMsi != 0 || iExpCab != 0 || iExpExe != 0)
	{
		DeleteFile(gsMsiFile);
		DeleteFile(gsCabFile);
		if (*gsExeFile)
			DeleteFile(gsExeFile);
		RemoveDirectory(gsTempFolder);
		return (iExpMsi != 0) ? iExpMsi : iExpCab;
	}
	
	if (gbExtractOnly)
	{
		wchar_t szMessage[MAX_PATH*2];
		wsprintf(szMessage, L"Installation files was extracted successfully\n%s", gsTempFolder);
		MessageBox(NULL, szMessage, gsTitle, MB_ICONINFORMATION);
		return 0;
	}

	int iInstRc = 0;
	SHELLEXECUTEINFO sei = {sizeof(sei)};
	wchar_t* pszParms = NULL;
	sei.fMask = SEE_MASK_NOCLOSEPROCESS|/*SEE_MASK_NOASYNC*/0x00000100; //|/*SEE_MASK_NOZONECHECKS*/0x00800000;
	sei.lpVerb = L"open";
	if (gOSVer.dwMajorVersion<=5 || !gbUseElevation)
	{
		sei.lpFile = gsMsiFile;
		sei.lpParameters = pszCmdToken;
	}
	else
	{
		sei.lpFile = gsExeFile;
		int nMaxLen = lstrlen(gsMsiFile) + (pszCmdToken ? lstrlen(pszCmdToken) : 0) + 64;
		pszParms = (wchar_t*)malloc(nMaxLen*sizeof(wchar_t));
		wsprintf(pszParms, L"/i \"%s\" %s", gsMsiFile, pszCmdToken ? pszCmdToken : L"");
		sei.lpParameters = pszParms;
	}
	sei.lpDirectory = gsTempFolder;
	sei.nShow = SW_SHOWNORMAL;
	
	BOOL lbExecute = ShellExecuteEx(&sei);
	
	#if 0
	if (!lbExecute && lbNeedExe)
	{
		DWORD nErr = GetLastError();
		if (nErr == 1223)
		{
			// Отмена пользователем UAC, или правов не хватило?
			sei.fMask = SEE_MASK_NOCLOSEPROCESS|/*SEE_MASK_NOASYNC*/0x00000100; //|/*SEE_MASK_NOZONECHECKS*/0x00800000;
			sei.lpVerb = L"open";
			sei.lpFile = gsMsiFile;
			sei.lpParameters = pszCmdToken;
			sei.lpDirectory = gsTempFolder;
			sei.nShow = SW_SHOWNORMAL;
			
			lbExecute = ShellExecuteEx(&sei);
		}
	}
	#endif
	
	if (!lbExecute)
	{
		iInstRc = ReportError(20, L"Installer failed\n%s", gsMsiFile);
	}
	else
	{
		if (!sei.hProcess)
		{
			iInstRc = ReportError(21, L"Installer failed\n%s", gsMsiFile);
		}
		else
		{
			WaitForSingleObject(sei.hProcess, INFINITE);
			DWORD nCode = 0;
			SetLastError(0);
			//1602 - это похоже "Отмена" пользователем
			if (!GetExitCodeProcess(sei.hProcess, &nCode) || (nCode != 0 && nCode != 1602))
			{
				wchar_t szFormat[128]; wsprintf(szFormat, L"Installer failed\n%%s\nExitCode=%u", nCode);
				iInstRc = ReportError(100+nCode, szFormat, gsMsiFile);
			}
		}
	}
	
	DeleteFile(gsMsiFile);
	DeleteFile(gsCabFile);
	if (*gsExeFile)
		DeleteFile(gsExeFile);
	RemoveDirectory(gsTempFolder);
	
	return iInstRc;
}
Example #3
0
    BOOL GetExitCode( DWORD* pdwExitCode )
	{ return GetExitCodeProcess( ph, pdwExitCode ); }
/*
 * Wrapper for fclose() to use for popen* files, so we can retrieve the
 * exit code for the child process and return as a result of the close.
 *
 * This function uses the _PyPopenProcs dictionary in order to map the
 * input file pointer to information about the process that was
 * originally created by the popen* call that created the file pointer.
 * The dictionary uses the file pointer as a key (with one entry
 * inserted for each file returned by the original popen* call) and a
 * single list object as the value for all files from a single call.
 * The list object contains the Win32 process handle at [0], and a file
 * count at [1], which is initialized to the total number of file
 * handles using that list.
 *
 * This function closes whichever handle it is passed, and decrements
 * the file count in the dictionary for the process handle pointed to
 * by this file.  On the last close (when the file count reaches zero),
 * this function will wait for the child process and then return its
 * exit code as the result of the close() operation.  This permits the
 * files to be closed in any order - it is always the close() of the
 * final handle that will return the exit code.
 */
static int _PyPclose(FILE *file)
{
	int result;
	DWORD exit_code;
	HANDLE hProcess;
	PyObject *procObj, *hProcessObj, *intObj, *fileObj;
	long file_count;
   
	/* Close the file handle first, to ensure it can't block the
	 * child from exiting if it's the last handle.
	 */
	result = fclose(file);

	if (_PyPopenProcs) {
		CEnterLeavePython _celp;
		if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
		    (procObj = PyDict_GetItem(_PyPopenProcs,
					      fileObj)) != NULL &&
		    (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
		    (intObj = PyList_GetItem(procObj,1)) != NULL) {

			hProcess = PyLong_AsVoidPtr(hProcessObj);
			file_count = PyInt_AsLong(intObj);

			if (file_count > 1) {
				/* Still other files referencing process */
				file_count--;
				PyList_SetItem(procObj,1,
					       PyInt_FromLong(file_count));
			} else {
				Py_BEGIN_ALLOW_THREADS
				/* Last file for this process */
				if (result != EOF &&
				    WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
				    GetExitCodeProcess(hProcess, &exit_code)) {
					/* Possible truncation here in 16-bit environments, but
					 * real exit codes are just the lower byte in any event.
					 */
					result = exit_code;
				} else {
					/* Indicate failure - this will cause the file object
					 * to raise an I/O error and translate the last Win32
					 * error code from errno.  We do have a problem with
					 * last errors that overlap the normal errno table,
					 * but that's a consistent problem with the file object.
					 */
					if (result != EOF) {
						/* If the error wasn't from the fclose(), then
						 * set errno for the file object error handling.
						 */
						errno = GetLastError();
					}
					result = -1;
				}
				/* Free up the native handle at this point */
				CloseHandle(hProcess);
				Py_END_ALLOW_THREADS
			}

			/* Remove this file pointer from dictionary */
			PyDict_DelItem(_PyPopenProcs, fileObj);

			if (PyDict_Size(_PyPopenProcs) == 0) {
				Py_DECREF(_PyPopenProcs);
				_PyPopenProcs = NULL;
			}

		} /* if object retrieval ok */

		Py_XDECREF(fileObj);
	} /* if _PyPopenProcs */
bool processIsStillRunning(HANDLE hndl)
{
   DWORD exitCode = 0;
   GetExitCodeProcess(hndl, &exitCode);
   return (exitCode==STILL_ACTIVE);
}
Example #6
0
DWORD JobbedProcessManager::return_code() {
	DWORD out;
	if (!GetExitCodeProcess(hProcess, &out))
		throw WindowsException("GetExitCodeProcess");
	return out;
}
Example #7
0
int nt_execve(const char *prog, const char *const *args, const char *const *envir)
{
	STARTUPINFO si;
	PROCESS_INFORMATION pi;
	enum {none, directex, shellex} execmode;
	DWORD exitcode;
	DWORD dwCreationflags;
	int priority;
	char *argv0;
	char *cmdstr, *cmdend;
	unsigned int cmdsize;
	size_t prognamelen, cmdlen;
	int hasext;
	char extension[_MAX_FNAME];
	const char *begin, *end, *extptr;
	static char exts[MAX_PATH];

	UNREFERENCED_PARAMETER(envir);

	/* get default PATHEXT or use empty exts */
	if (!*exts) {
		DWORD rc;
		/* not initialized */
		rc = GetEnvironmentVariable("PATHEXT", exts, sizeof(exts));
		if ((rc == 0) || (rc >= sizeof(exts)))
			/* if error or PATHEXT too big will retry at the next call */
			*exts = 0;
	}

	/* if prog has an extension initialize begin end to skip PATHEXT search */
	prognamelen = strlen(prog);
	extptr = prog + prognamelen - 1;
	hasext = 0;
	while (extptr > prog && !ISPATHSEP(*extptr)) {
		if (*extptr == '.' && *(extptr - 1) != ':' && !ISPATHSEP(*(extptr - 1))) {
			hasext++;
			break;
		}
		extptr--;
	}
	if (hasext) {
		begin = ".";
		end = "";
		strcpy(extension, extptr);
	} else {
		begin = exts;
		end = exts;
		*extension = '\0';
	}

	argv0 = (char *)heap_alloc(MAX_PATH);
	/* (prognamelen + 1) does not really matter, argv0 is '\0' filled */
	memcpy(argv0, prog, prognamelen + 1);

	errno = 0;
	execmode = none;
	/* NOTE: loops over PATHEXT if no extension found */
	while (*begin) {
		size_t extlen;
		if (GetBinaryType(argv0, &exitcode)) {
			/* exists and is executable
			   NOTE: an "xxx.exe" without a correct PE header (i.e. a text file)
			   has type "DOS binary", but execution will generate a WOW error */
			execmode = directex;
			break;
		}
		if (GetLastError() == ERROR_BAD_EXE_FORMAT) {
			/* exists but is not "executable" */
			execmode = shellex;
			break;
		}
		if (hasext)
			break;
		/* get next PATHEXT extension */
		while (*begin && (*begin != '.'))
			begin++;
		while (*end && (*end != ';'))
			end++;
		if (!*begin)
			break;
		extlen = end - begin;
		if (extlen < sizeof(extension)) {
			memcpy(extension, begin, extlen);
			extension[extlen] = '\0';
			/* prognamelen ignores the last '\r' if present */
			memcpy(argv0, prog, prognamelen);
			/* update argv0 adding the extension to prog */
			memcpy(argv0 + prognamelen, extension, extlen + 1);
		}
		begin = end;
		/* skip sequences of ';' */
		while (*end && *end == ';')
			end++;
	};

	cmdstr = (char *)heap_alloc(MAX_PATH << 2);
	cmdsize = MAX_PATH << 2;
	cmdlen = 0;
	cmdend = cmdstr;

	dbgprintf(PR_VERBOSE, "%s(): execute [%s] extension=[%s] mode=%d hasext=%d\n", __FUNCTION__, argv0, extension, execmode, hasext);
	/* skip over program name */
	args++;

	/* the file (after PATHEXT search) exists, but it's not "executable" */
	if (execmode == shellex) {
		/* if prog had no extension or has the extension associated to shell scripts */
		if ((hasext == 0 && *extension == '\0') || is_shell_script(extension)) {
			int res = process_shebang(argv0, (const char *const *)&cmdstr, &cmdlen, &cmdend, &cmdsize);
			if (res < 0) {
				execmode = none;
			} else if (res == 0) {
				char *newargv[2];
				cmdlen = copy_quote_and_fix_slashes(gModuleName, cmdstr);
				cmdend = cmdstr + cmdlen;
				newargv[0] = path_to_slash(argv0);
				newargv[1] = NULL;
				concat_args_and_quote((const char *const *)newargv, &cmdstr, &cmdlen, &cmdend, &cmdsize);
				*cmdend = 0;
				argv0 = gModuleName;
				execmode = directex;
			} else {
				cmdend = cmdstr + cmdlen;
				execmode = directex;
			}
		} else {
			unsigned long shflags = 0L;
			/* if the file extension is in pathext, use the same console
			   and wait for child. StrStrI() is from shlwapi */
			if (StrStrI(exts, extension))
				shflags = SEE_MASK_NO_CONSOLE | SEE_MASK_NOCLOSEPROCESS;
			if (try_shell_ex(argv0, args, shflags, &cmdstr, &cmdsize))
				return (0);
			/* ShellExecute failed, the file has an unknown extension, but it
			    may be a shell script with a shebang */
			if (process_shebang(argv0, (const char *const *)&cmdstr, &cmdlen, &cmdend, &cmdsize) > 0) {
				cmdend = cmdstr + cmdlen;
				execmode = directex;
			} else {
				/* the file extension is NOT known and the file has NO shebang:
				   returns EPERM, see NOTES */
				errno = EPERM;
				return (-1);
			}
		}
	} else if (execmode == directex) {
		cmdlen = copy_quote_and_fix_slashes(prog, cmdstr);
		cmdend = cmdstr + cmdlen;
	}
	if (execmode == none) {
		/* error: prog not found even after trying PATHEXT extensions */
		errno = ENOENT;
		return (-1);
	}

	concat_args_and_quote(args, &cmdstr, &cmdlen, &cmdend, &cmdsize);
	if (*cmdstr == ' ') {
		/* if we left a ' ' for the quote and there is no quote */
		cmdstr++;
		cmdlen--;
	}
	*cmdend = 0;

	init_startupinfo(&si);
	dwCreationflags = GetPriorityClass(GetCurrentProcess());
	priority = GetThreadPriority(GetCurrentThread());

#if defined(W32DEBUG)
	/* DebugView output is very difficult to read with overlong lines */
	if (cmdlen < 128)
		dbgprintf(PR_EXEC, "%s(): CreateProcess(%s, ..) cmdstr=[%s]\n", __FUNCTION__, argv0, cmdstr);
	else {
		char shortbuf[128+4];
		memcpy(shortbuf, cmdstr, 128);
		memcpy(shortbuf + 128, "...", 4);
		dbgprintf(PR_EXEC, "nt_execve(): CreateProcess(%s, ..) cmdstr=[%s]\n", argv0, shortbuf);
	}
#endif
	if (!CreateProcess(argv0, cmdstr, NULL, NULL,
			   TRUE, // need this for redirecting std handles
			   dwCreationflags | CREATE_SUSPENDED,
			   NULL, NULL, &si, &pi)) {
                exitcode = GetLastError();
		if (exitcode == ERROR_BAD_EXE_FORMAT) {
			dbgprintf(PR_ERROR, "!!! CreateProcess(%s, ..) error BAD_EXE_FORMAT in %s\n", argv0, __FUNCTION__);
			errno  = ENOEXEC;
		} else if (exitcode == ERROR_INVALID_PARAMETER) {
			dbgprintf(PR_ERROR, "!!! CreateProcess(%s, ..) error INVALID_PARAMETER in %s, cmdstr len=%u\n", argv0, __FUNCTION__, strlen(cmdstr));
			/* exceeded command line */
			/* return NOT found, ENAMETOOLONG is correct but not understood by
			   the shell that will retry with another path ... */
			errno = ENOENT;
		} else {
			dbgprintf(PR_ERROR, "!!! CreateProcess(%s, ..) error %ld in %s\n", argv0, exitcode, __FUNCTION__);
			errno = ENOENT;
		}
		goto fail_return;
	} else {
		exitcode = 0;
		if (!SetThreadPriority(pi.hThread, priority))
			dbgprintf(PR_ERROR, "!!! SetThreadPriority(0x%p) failed, error %ld\n", pi.hThread, GetLastError());
		ResumeThread(pi.hThread);
		if (!is_gui(argv0)) {
			if (WaitForSingleObject(pi.hProcess, INFINITE) != WAIT_OBJECT_0)
				dbgprintf(PR_ERROR, "!!! error %ld waiting for process %ld\n", GetLastError(), pi.dwProcessId);
			if (!GetExitCodeProcess(pi.hProcess, &exitcode))
				dbgprintf(PR_ERROR, "!!! GetExitCodeProcess(0x%p, ..) error %ld in %s\n", pi.hProcess, GetLastError(), __FUNCTION__);
		}
		CloseHandle(pi.hProcess);
		CloseHandle(pi.hThread);
		close_si_handles();
		/* @@@@ should wait for the clipboard ?
		if (is_dev_clipboard_active) {
			CloseHandle((HANDLE)_get_osfhandle(0));
			CloseHandle((HANDLE)_get_osfhandle(1));
			CloseHandle((HANDLE)_get_osfhandle(2));
			...
			WaitForSingleObject(ghdevclipthread,60*1000);
			}
		*/
		dbgprintf(PR_ALL, "--- %s(): Exec'd process %ld terminated with exitcode %ld\n", __FUNCTION__, pi.dwProcessId, exitcode);
		exec_exit((int)exitcode);
	}

fail_return:
        heap_free(cmdstr);
	close_si_handles();
	exec_exit(-1);
	return (-1);
}
Example #8
0
// Launches tests as another process
int fork()
{
  DWORD dwExitCode = 1;
  CString sWorkingFolder;
  CString sCmdLine;
  CString sExeFolder;        
    
  sWorkingFolder = Utility::GetModulePath(NULL);
  sExeFolder = Utility::GetModulePath(NULL);

  if(g_bRunningFromUNICODEFolder)
  {
    CString sAppDataFolder;
    
    Utility::GetSpecialFolder(CSIDL_LOCAL_APPDATA, sAppDataFolder);
    sWorkingFolder = sAppDataFolder+_T("\\CrashRpt UNICODE 应用程序名称");
    BOOL bCreate = Utility::CreateFolder(sWorkingFolder);
    if(!bCreate)
      return 1;
    
    /* Copy all required files to temporary directory. */
    
    

  #ifdef _DEBUG
    BOOL bCopy = CopyFile(sExeFolder+_T("\\CrashRptd.dll"), sWorkingFolder+_T("\\CrashRptd.dll"), TRUE);
    if(!bCopy)
      goto cleanup;
    BOOL bCopy5 = CopyFile(sExeFolder+_T("\\CrashRptProbed.dll"), sWorkingFolder+_T("\\CrashRptProbed.dll"), TRUE);
    if(!bCopy5)
      goto cleanup;  
    BOOL bCopy2 = CopyFile(sExeFolder+_T("\\CrashSenderd.exe"), sWorkingFolder+_T("\\CrashSenderd.exe"), TRUE);
    if(!bCopy2)
      goto cleanup;
    BOOL bCopy4 = CopyFile(sExeFolder+_T("\\Testsd.exe"), sWorkingFolder+_T("\\Testsd.exe"), TRUE);
    if(!bCopy4)
      goto cleanup;  
  #else
  #ifndef CRASHRPT_LIB
    BOOL bCopy = CopyFile(sExeFolder+_T("\\CrashRpt.dll"), sWorkingFolder+_T("\\CrashRpt.dll"), TRUE);
    if(!bCopy)
      goto cleanup;
    BOOL bCopy5 = CopyFile(sExeFolder+_T("\\CrashRptProbe.dll"), sWorkingFolder+_T("\\CrashRptProbe.dll"), TRUE);
    if(!bCopy5)
      goto cleanup;
  #endif //!CRASHRPT_LIB
    BOOL bCopy2 = CopyFile(sExeFolder+_T("\\CrashSender.exe"), sWorkingFolder+_T("\\CrashSender.exe"), TRUE);
    if(!bCopy2)
      goto cleanup;
    BOOL bCopy4 = CopyFile(sExeFolder+_T("\\Tests.exe"), sWorkingFolder+_T("\\Tests.exe"), TRUE);
    if(!bCopy4)
      goto cleanup;  
  #endif

    BOOL bCopy3 = CopyFile(sExeFolder+_T("\\crashrpt_lang.ini"), sWorkingFolder+_T("\\crashrpt_lang.ini"), TRUE);
    if(!bCopy3)
      goto cleanup;

    BOOL bCopy6 = CopyFile(sExeFolder+_T("\\dummy.ini"), sWorkingFolder+_T("\\dummy.ini"), TRUE);
    if(!bCopy6)
      goto cleanup;

    BOOL bCopy7 = CopyFile(sExeFolder+_T("\\dummy.log"), sWorkingFolder+_T("\\dummy.log"), TRUE);
    if(!bCopy7)
      goto cleanup;

    BOOL bCopy8 = CopyFile(sExeFolder+_T("\\dbghelp.dll"), sWorkingFolder+_T("\\dbghelp.dll"), TRUE);
    if(!bCopy8)
      goto cleanup;
  }

  /* Create new process */

#ifdef _DEBUG
  sCmdLine = _T("\"") + sWorkingFolder+_T("\\Testsd.exe") + _T("\"");
#else
  sCmdLine = _T("\"") + sWorkingFolder+_T("\\Tests.exe") + _T("\"");
#endif    

  if(g_bRunningFromUNICODEFolder)
    sCmdLine += _T(" /unicode");

  HANDLE hProcess = NULL;

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

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

  BOOL bCreateProcess = CreateProcess(NULL, sCmdLine.GetBuffer(0),
      NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
  if(!bCreateProcess)
  {    
    _tprintf(_T("Error creating process! Press any key to exit.\n."));  
	_getch();
    goto cleanup;
  }

  hProcess = pi.hProcess;

  // Wait until process exits.
  WaitForSingleObject(hProcess, INFINITE);
  
  GetExitCodeProcess(hProcess, &dwExitCode);

cleanup:

  // Clean up  
  if(g_bRunningFromUNICODEFolder)
    Utility::RecycleFile(sWorkingFolder, TRUE);

  return dwExitCode;
}
Example #9
0
// This routine creates a binding with the server.
HRESULT
JITManager::CreateBinding(
    __in HANDLE serverProcessHandle,
    __in_opt void * serverSecurityDescriptor,
    __in UUID * connectionUuid,
    __out RPC_BINDING_HANDLE * bindingHandle)
{
    Assert(IsOOPJITEnabled());

    RPC_STATUS status;
    DWORD attemptCount = 0;
    DWORD sleepInterval = 100; // in milliseconds
    RPC_BINDING_HANDLE localBindingHandle;
    RPC_BINDING_HANDLE_TEMPLATE_V1 bindingTemplate;
    RPC_BINDING_HANDLE_SECURITY_V1_W bindingSecurity;

#ifndef NTBUILD
    RPC_SECURITY_QOS_V4 securityQOS;
    ZeroMemory(&securityQOS, sizeof(RPC_SECURITY_QOS_V4));
    securityQOS.Capabilities = RPC_C_QOS_CAPABILITIES_DEFAULT;
    securityQOS.IdentityTracking = RPC_C_QOS_IDENTITY_DYNAMIC;
    securityQOS.ImpersonationType = RPC_C_IMP_LEVEL_IDENTIFY;
    securityQOS.Version = 4;
#else
    RPC_SECURITY_QOS_V5 securityQOS;
    ZeroMemory(&securityQOS, sizeof(RPC_SECURITY_QOS_V5));
    securityQOS.Capabilities = RPC_C_QOS_CAPABILITIES_DEFAULT;
    securityQOS.IdentityTracking = RPC_C_QOS_IDENTITY_DYNAMIC;
    securityQOS.ImpersonationType = RPC_C_IMP_LEVEL_IDENTIFY;
    securityQOS.Version = 5;
    securityQOS.ServerSecurityDescriptor = serverSecurityDescriptor;
#endif // NTBUILD

    ZeroMemory(&bindingTemplate, sizeof(bindingTemplate));
    bindingTemplate.Version = 1;
    bindingTemplate.ProtocolSequence = RPC_PROTSEQ_LRPC;
    bindingTemplate.StringEndpoint = NULL;
    memcpy_s(&bindingTemplate.ObjectUuid, sizeof(UUID), connectionUuid, sizeof(UUID));
    bindingTemplate.Flags |= RPC_BHT_OBJECT_UUID_VALID;

    ZeroMemory(&bindingSecurity, sizeof(bindingSecurity));
    bindingSecurity.Version = 1;
    bindingSecurity.AuthnLevel = RPC_C_AUTHN_LEVEL_PKT_PRIVACY;
    bindingSecurity.AuthnSvc = RPC_C_AUTHN_KERNEL;
    bindingSecurity.SecurityQos = (RPC_SECURITY_QOS*)&securityQOS;

    status = RpcBindingCreate(&bindingTemplate, &bindingSecurity, NULL, &localBindingHandle);
    if (status != RPC_S_OK)
    {
        return HRESULT_FROM_WIN32(status);
    }

    // We keep attempting to connect to the server with increasing wait intervals in between.
    // This will wait close to 5 minutes before it finally gives up.
    do
    {
        DWORD waitStatus;

        status = RpcBindingBind(NULL, localBindingHandle, ClientIChakraJIT_v0_0_c_ifspec);
        if (status == RPC_S_OK)
        {
            break;
        }
        else if (status == EPT_S_NOT_REGISTERED)
        {
            // The Server side has not finished registering the RPC Server yet.
            // We should only breakout if we have reached the max attempt count.
            if (attemptCount > 600)
            {
                break;
            }
        }
        else
        {
            // Some unknown error occurred. We are not going to retry for arbitrary errors.
            break;
        }

        // When we come to this point, it means the server has not finished registration yet.
        // We should wait for a while and then reattempt to bind.
        waitStatus = WaitForSingleObject(serverProcessHandle, sleepInterval);
        if (waitStatus == WAIT_OBJECT_0)
        {
            DWORD exitCode = (DWORD)-1;

            // The server process died for some reason. No need to reattempt.
            // We use -1 as the exit code if GetExitCodeProcess fails.
            Assert(GetExitCodeProcess(serverProcessHandle, &exitCode));
            status = RPC_S_SERVER_UNAVAILABLE;
            break;
        }
        else if (waitStatus == WAIT_TIMEOUT)
        {
            // Not an error. the server is still alive and we should reattempt.
        }
        else
        {
            // wait operation failed for an unknown reason.
            Assert(false);
            status = HRESULT_FROM_WIN32(waitStatus);
            break;
        }

        attemptCount++;
        if (sleepInterval < 500)
        {
            sleepInterval += 100;
        }
    } while (status != RPC_S_OK); // redundant check, but compiler would not allow true here.

    if (status != RPC_S_OK)
    {
        RpcBindingFree(&localBindingHandle);
        return HRESULT_FROM_WIN32(status);
    }

    *bindingHandle = localBindingHandle;
    return S_OK;
}
Example #10
0
static int try_shell_ex(char *argv0, const char *const *argv, unsigned long shellexflags, char **cmdstr, unsigned int *cmdsize)
{
	char *cmdend;
	size_t cmdlen;
	SHELLEXECUTEINFO shinfo;
	BOOL nocmd = 0;

	path_to_backslash(argv0);

	/* @@@@ is this code really needed ? when ? */
	if ((!*argv) && (argv0[0] == '\\') && (argv0[1] == '\\')) {
		shellexflags |= SEE_MASK_CONNECTNETDRV;
		nocmd = 1;
		goto noargs;
	}

	cmdend = *cmdstr;
	cmdlen = 0;
	concat_args_and_quote(argv, cmdstr, &cmdlen, &cmdend, cmdsize);
	*cmdend = '\0';

noargs:
	dbgprintf(PR_EXEC, "ShellExecute(%s, ..) with cmdstr [%s]\n", argv0, *cmdstr);
	memset(&shinfo, 0, sizeof(shinfo));
	shinfo.cbSize = sizeof(shinfo);
	shinfo.fMask = SEE_MASK_FLAG_NO_UI | SEE_MASK_FLAG_DDEWAIT | shellexflags;
	shinfo.hwnd = NULL;
	shinfo.lpVerb = NULL;
	shinfo.lpFile = argv0;
	shinfo.lpParameters = nocmd ? NULL : *cmdstr;
	shinfo.lpDirectory = 0;
	shinfo.nShow = SW_SHOWDEFAULT;

	if (ShellExecuteEx(&shinfo)) {
		DWORD retval = 255;
		dbgprintf(PR_EXEC, "ShellExecute() created process handle 0x%p\n", shinfo.hProcess);
		/* may happen if "executing" a file associated to a running program, i.e.
		   "execute" a .html file with an already opened browser window */
		if (shinfo.hProcess != (HANDLE)0) {
			if (shellexflags & SEE_MASK_NOCLOSEPROCESS) {
				if ((intptr_t)(shinfo.hInstApp) > 32) {
					if (WaitForSingleObject(shinfo.hProcess, INFINITE) == WAIT_OBJECT_0) {
						/* try to get the return value */
						GetExitCodeProcess(shinfo.hProcess, &retval);
					} else {
						dbgprintf(PR_ERROR, "!!! ShellExecute() [%s] WaitForSingleObject() error %ld\n", argv0, GetLastError());
					}
				} else {
					dbgprintf(PR_ERROR, "!!! ShellExecute() [%s] error %p\n", argv0, shinfo.hInstApp);
				}
			}
			/* try to close, it may fail but .. what else could we do */
			CloseHandle(shinfo.hProcess);
		}
		dbgprintf(PR_ALL, "--- %s(): ShellExecute() OK, exiting with code %ld\n", __FUNCTION__, retval);
		exec_exit((int)retval);
	} else {
		dbgprintf(PR_EXEC, "ShellExecute() failed\n");
	}
       	return (0);
}
Example #11
0
int
main()
{
    DWORD dwRead, dwWrite;
    char *cmdLine;
    HANDLE hStdInput, hStdOutput, hStdError;
    HANDLE hFileInput, hFileOutput, hFileError;
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    char buf[8192];
    DWORD result;

    hFileInput = INVALID_HANDLE_VALUE;
    hFileOutput = INVALID_HANDLE_VALUE;
    hFileError = INVALID_HANDLE_VALUE;
    result = 1;

    /*
     * Don't get command line from argc, argv, because the command line
     * tokenizer will have stripped off all the escape sequences needed
     * for quotes and backslashes, and then we'd have to put them all
     * back in again.  Get the raw command line and parse off what we
     * want ourselves.  The command line should be of the form:
     *
     * stub16.exe program arg1 arg2 ...
     */

    cmdLine = strchr(GetCommandLine(), ' ');
    if (cmdLine == NULL) {
	return 1;
    }
    cmdLine++;

    hStdInput = GetStdHandle(STD_INPUT_HANDLE);
    hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
    hStdError = GetStdHandle(STD_ERROR_HANDLE);

    if (GetFileType(hStdInput) == FILE_TYPE_PIPE) {
	hFileInput = CreateTempFile();
	if (hFileInput == INVALID_HANDLE_VALUE) {
	    goto cleanup;
	}
	while (ReadFile(hStdInput, buf, sizeof(buf), &dwRead, NULL) != FALSE) {
	    if (dwRead == 0) {
		break;
	    }
	    if (WriteFile(hFileInput, buf, dwRead, &dwWrite, NULL) == FALSE) {
		goto cleanup;
	    }
	}
	SetFilePointer(hFileInput, 0, 0, FILE_BEGIN);
	SetStdHandle(STD_INPUT_HANDLE, hFileInput);
    }
    if (GetFileType(hStdOutput) == FILE_TYPE_PIPE) {
	hFileOutput = CreateTempFile();
	if (hFileOutput == INVALID_HANDLE_VALUE) {
	    goto cleanup;
	}
	SetStdHandle(STD_OUTPUT_HANDLE, hFileOutput);
    }
    if (GetFileType(hStdError) == FILE_TYPE_PIPE) {
	hFileError = CreateTempFile();
	if (hFileError == INVALID_HANDLE_VALUE) {
	    goto cleanup;
	}
	SetStdHandle(STD_ERROR_HANDLE, hFileError);
    }

    ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si);
    if (CreateProcess(NULL, cmdLine, NULL, NULL, TRUE, 0, NULL, NULL, &si, 
	    &pi) == FALSE) {
	goto cleanup;
    }

    WaitForInputIdle(pi.hProcess, 5000);
    WaitForSingleObject(pi.hProcess, INFINITE);
    GetExitCodeProcess(pi.hProcess, &result);
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);

    if (hFileOutput != INVALID_HANDLE_VALUE) {
	SetFilePointer(hFileOutput, 0, 0, FILE_BEGIN);
	while (ReadFile(hFileOutput, buf, sizeof(buf), &dwRead, NULL) != FALSE) {
	    if (dwRead == 0) {
		break;
	    }
	    if (WriteFile(hStdOutput, buf, dwRead, &dwWrite, NULL) == FALSE) {
		break;
	    }
	}
    }
    if (hFileError != INVALID_HANDLE_VALUE) {
	SetFilePointer(hFileError, 0, 0, FILE_BEGIN);
	while (ReadFile(hFileError, buf, sizeof(buf), &dwRead, NULL) != FALSE) {
	    if (dwRead == 0) {
		break;
	    }
	    if (WriteFile(hStdError, buf, dwRead, &dwWrite, NULL) == FALSE) {
		break;
	    }
	}
    }

cleanup:
    if (hFileInput != INVALID_HANDLE_VALUE) {
	CloseHandle(hFileInput);
    }
    if (hFileOutput != INVALID_HANDLE_VALUE) {
	CloseHandle(hFileOutput);
    }
    if (hFileError != INVALID_HANDLE_VALUE) {
	CloseHandle(hFileError);
    }
    CloseHandle(hStdInput);
    CloseHandle(hStdOutput);
    CloseHandle(hStdError);
    ExitProcess(result);
    return 1;
}
Example #12
0
DWORD ExecCreateProcess(const char* command_str, char** result)
{
    PROCESS_INFORMATION pi;
    STARTUPINFO si;
    //HANDLE hStdout;
    SECURITY_ATTRIBUTES sa;
    HANDLE hRead,hWrite;
    char buffer[4096] = {0};
    DWORD bytesRead;
    DWORD ExitCode = ERROR;
	char* runcmd;

    sa.nLength = sizeof(SECURITY_ATTRIBUTES);
    sa.lpSecurityDescriptor = NULL;
    sa.bInheritHandle = TRUE;
    if (!CreatePipe(&hRead,&hWrite,&sa,0))
	{
        printf("Error On CreatePipe()");
        return ERROR;
    }

	runcmd=StringInit();
	runcmd=StringSet(runcmd, command_str);
	//runcmd=StringInsert (runcmd,"c://windows//system32//cmd.exe /c ",0);

    //hStdout = GetStdHandle(STD_OUTPUT_HANDLE);

    ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si);
    si.wShowWindow = SW_SHOW;
    si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
	si.hStdOutput = hWrite;
	si.hStdError = hWrite;

    if (CreateProcess(NULL, runcmd, NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi))
    {
		printf("Excuting \"%s\"\n", runcmd);
        WaitForSingleObject(pi.hProcess, INFINITE);
        GetExitCodeProcess(pi.hProcess, &ExitCode);
        CloseHandle(pi.hThread);
        CloseHandle(pi.hProcess);
    }
    else
    {
        //MessageBox(NULL, "The process could not be started...", NULL, MB_OK);
		printf("The process could not be started.\n");
		CloseHandle(hWrite);
		free(runcmd);
		return 0;
    }
    CloseHandle(hWrite);
	*result = StringInit();

    while (TRUE) 
    {
        if (ReadFile(hRead, buffer, 4095, &bytesRead, NULL) == FALSE)
        {
            break;
        }
		
		*result = StringAppent(*result, buffer);
		memset(buffer,0,4096);
		//printf(buffer);
    }

    return ExitCode;
}
Example #13
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];
	TCHAR szOutput[MAX_PATH];
	TCHAR szErr[MAX_PATH];
	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)
		return (DWORD)-1;

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

	if (!hRedir)
		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)
		return (DWORD)-1;

	// setup startup info, set std out/err handles
	// hide window
	STARTUPINFO si;
	SecureZeroMemory(&si, sizeof(si));
	si.cb = sizeof(si);
	if (hOut  != INVALID_HANDLE_VALUE)
	{
		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));

	DWORD dwFlags = 0;

	if (!CreateProcess(NULL, cmd.GetBuffer(), NULL, NULL, TRUE, dwFlags, NULL, currentDir, &si, &pi))
	{
			int 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];
		do
		{
			SecureZeroMemory(&buf,sizeof(buf));
			while (ReadFile(hRedir, &buf, sizeof(buf)-1, &dw, NULL))
			{
				if (dw == 0)
					break;
				error += CString(CStringA(buf,dw));
				SecureZeroMemory(&buf,sizeof(buf));
			}
		} 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));
			SecureZeroMemory(&buf,sizeof(buf));
		}
		WaitForSingleObject(pi.hProcess, INFINITE);
		GetExitCodeProcess(pi.hProcess, &exitcode);
	}
	CloseHandle(pi.hProcess);
	DeleteFile(szOutput);
	DeleteFile(szErr);

	return exitcode;
}
Example #14
-1
//
// Tries to call where.exe to find the location of dotnet.exe.
// Will check that the bitness of dotnet matches the current
// worker process bitness.
// Returns true if a valid dotnet was found, else false.R
//
std::optional<fs::path>
HOSTFXR_UTILITY::InvokeWhereToFindDotnet()
{
    HRESULT             hr = S_OK;
    // Arguments to call where.exe
    STARTUPINFOW        startupInfo = { 0 };
    PROCESS_INFORMATION processInformation = { 0 };
    SECURITY_ATTRIBUTES securityAttributes;

    CHAR                pzFileContents[READ_BUFFER_SIZE];
    HandleWrapper<InvalidHandleTraits>     hStdOutReadPipe;
    HandleWrapper<InvalidHandleTraits>     hStdOutWritePipe;
    HandleWrapper<InvalidHandleTraits>     hProcess;
    HandleWrapper<InvalidHandleTraits>     hThread;
    CComBSTR            pwzDotnetName = NULL;
    DWORD               dwFilePointer;
    BOOL                fIsWow64Process;
    BOOL                fIsCurrentProcess64Bit;
    DWORD               dwExitCode;
    STRU                struDotnetSubstring;
    STRU                struDotnetLocationsString;
    DWORD               dwNumBytesRead;
    DWORD               dwBinaryType;
    INT                 index = 0;
    INT                 prevIndex = 0;
    std::optional<fs::path> result;

    // Set the security attributes for the read/write pipe
    securityAttributes.nLength = sizeof(securityAttributes);
    securityAttributes.lpSecurityDescriptor = NULL;
    securityAttributes.bInheritHandle = TRUE;

    LOG_INFO(L"Invoking where.exe to find dotnet.exe");

    // Create a read/write pipe that will be used for reading the result of where.exe
    FINISHED_LAST_ERROR_IF(!CreatePipe(&hStdOutReadPipe, &hStdOutWritePipe, &securityAttributes, 0));
    FINISHED_LAST_ERROR_IF(!SetHandleInformation(hStdOutReadPipe, HANDLE_FLAG_INHERIT, 0));

    // Set the stdout and err pipe to the write pipes.
    startupInfo.cb = sizeof(startupInfo);
    startupInfo.dwFlags |= STARTF_USESTDHANDLES;
    startupInfo.hStdOutput = hStdOutWritePipe;
    startupInfo.hStdError = hStdOutWritePipe;

    // CreateProcess requires a mutable string to be passed to commandline
    // See https://blogs.msdn.microsoft.com/oldnewthing/20090601-00/?p=18083/
    pwzDotnetName = L"\"where.exe\" dotnet.exe";

    // Create a process to invoke where.exe
    FINISHED_LAST_ERROR_IF(!CreateProcessW(NULL,
        pwzDotnetName,
        NULL,
        NULL,
        TRUE,
        CREATE_NO_WINDOW,
        NULL,
        NULL,
        &startupInfo,
        &processInformation
    ));

    // Store handles into wrapper so they get closed automatically
    hProcess = processInformation.hProcess;
    hThread = processInformation.hThread;

    // Wait for where.exe to return
    WaitForSingleObject(processInformation.hProcess, INFINITE);

    //
    // where.exe will return 0 on success, 1 if the file is not found
    // and 2 if there was an error. Check if the exit code is 1 and set
    // a new hr result saying it couldn't find dotnet.exe
    //
    FINISHED_LAST_ERROR_IF (!GetExitCodeProcess(processInformation.hProcess, &dwExitCode));

    //
    // In this block, if anything fails, we will goto our fallback of
    // looking in C:/Program Files/
    //
    if (dwExitCode != 0)
    {
        FINISHED_IF_FAILED(E_FAIL);
    }

    // Where succeeded.
    // Reset file pointer to the beginning of the file.
    dwFilePointer = SetFilePointer(hStdOutReadPipe, 0, NULL, FILE_BEGIN);
    if (dwFilePointer == INVALID_SET_FILE_POINTER)
    {
        FINISHED_IF_FAILED(E_FAIL);
    }

    //
    // As the call to where.exe succeeded (dotnet.exe was found), ReadFile should not hang.
    // TODO consider putting ReadFile in a separate thread with a timeout to guarantee it doesn't block.
    //
    FINISHED_LAST_ERROR_IF (!ReadFile(hStdOutReadPipe, pzFileContents, READ_BUFFER_SIZE, &dwNumBytesRead, NULL));

    if (dwNumBytesRead >= READ_BUFFER_SIZE)
    {
        // This shouldn't ever be this large. We could continue to call ReadFile in a loop,
        // however if someone had this many dotnet.exes on their machine.
        FINISHED_IF_FAILED(E_FAIL);
    }

    FINISHED_IF_FAILED(struDotnetLocationsString.CopyA(pzFileContents, dwNumBytesRead));

    LOG_INFOF(L"where.exe invocation returned: '%ls'", struDotnetLocationsString.QueryStr());

    // Check the bitness of the currently running process
    // matches the dotnet.exe found.
    FINISHED_LAST_ERROR_IF (!IsWow64Process(GetCurrentProcess(), &fIsWow64Process));

    if (fIsWow64Process)
    {
        // 32 bit mode
        fIsCurrentProcess64Bit = FALSE;
    }
    else
    {
        // Check the SystemInfo to see if we are currently 32 or 64 bit.
        SYSTEM_INFO systemInfo;
        GetNativeSystemInfo(&systemInfo);
        fIsCurrentProcess64Bit = systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64;
    }

    LOG_INFOF(L"Current process bitness type detected as isX64=%d", fIsCurrentProcess64Bit);

    while (TRUE)
    {
        index = struDotnetLocationsString.IndexOf(L"\r\n", prevIndex);
        if (index == -1)
        {
            break;
        }

        FINISHED_IF_FAILED(struDotnetSubstring.Copy(&struDotnetLocationsString.QueryStr()[prevIndex], index - prevIndex));
        // \r\n is two wchars, so add 2 here.
        prevIndex = index + 2;

        LOG_INFOF(L"Processing entry '%ls'", struDotnetSubstring.QueryStr());

        if (LOG_LAST_ERROR_IF(!GetBinaryTypeW(struDotnetSubstring.QueryStr(), &dwBinaryType)))
        {
            continue;
        }

        LOG_INFOF(L"Binary type %d", dwBinaryType);

        if (fIsCurrentProcess64Bit == (dwBinaryType == SCS_64BIT_BINARY))
        {
            // The bitness of dotnet matched with the current worker process bitness.
            return std::make_optional(struDotnetSubstring.QueryStr());
        }
    }

    Finished:
    return result;
}
Example #15
-1
int main( int argc, char *argv[] )
{
    extern HANDLE CDECL __wine_make_process_system(void);
    static const WCHAR RunW[] = {'R','u','n',0};
    static const WCHAR RunOnceW[] = {'R','u','n','O','n','c','e',0};
    static const WCHAR RunServicesW[] = {'R','u','n','S','e','r','v','i','c','e','s',0};
    static const WCHAR RunServicesOnceW[] = {'R','u','n','S','e','r','v','i','c','e','s','O','n','c','e',0};
    static const WCHAR wineboot_eventW[] = {'_','_','w','i','n','e','b','o','o','t','_','e','v','e','n','t',0};

    /* First, set the current directory to SystemRoot */
    int optc;
    BOOL end_session, force, init, kill, restart, shutdown, update;
    HANDLE event;
    SECURITY_ATTRIBUTES sa;
    BOOL is_wow64;

    end_session = force = init = kill = restart = shutdown = update = FALSE;
    GetWindowsDirectoryW( windowsdir, MAX_PATH );
    if( !SetCurrentDirectoryW( windowsdir ) )
        WINE_ERR("Cannot set the dir to %s (%d)\n", wine_dbgstr_w(windowsdir), GetLastError() );

    if (IsWow64Process( GetCurrentProcess(), &is_wow64 ) && is_wow64)
    {
        STARTUPINFOW si;
        PROCESS_INFORMATION pi;
        WCHAR filename[MAX_PATH];
        void *redir;
        DWORD exit_code;

        memset( &si, 0, sizeof(si) );
        si.cb = sizeof(si);
        GetModuleFileNameW( 0, filename, MAX_PATH );

        Wow64DisableWow64FsRedirection( &redir );
        if (CreateProcessW( filename, GetCommandLineW(), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi ))
        {
            WINE_TRACE( "restarting %s\n", wine_dbgstr_w(filename) );
            WaitForSingleObject( pi.hProcess, INFINITE );
            GetExitCodeProcess( pi.hProcess, &exit_code );
            ExitProcess( exit_code );
        }
        else WINE_ERR( "failed to restart 64-bit %s, err %d\n", wine_dbgstr_w(filename), GetLastError() );
        Wow64RevertWow64FsRedirection( redir );
    }

    while ((optc = getopt_long(argc, argv, short_options, long_options, NULL )) != -1)
    {
        switch(optc)
        {
        case 'e': end_session = TRUE; break;
        case 'f': force = TRUE; break;
        case 'i': init = TRUE; break;
        case 'k': kill = TRUE; break;
        case 'r': restart = TRUE; break;
        case 's': shutdown = TRUE; break;
        case 'u': update = TRUE; break;
        case 'h': usage(); return 0;
        case '?': usage(); return 1;
        }
    }

    if (end_session)
    {
        if (kill)
        {
            if (!shutdown_all_desktops( force )) return 1;
        }
        else if (!shutdown_close_windows( force )) return 1;
    }

    if (kill) kill_processes( shutdown );

    if (shutdown) return 0;

    sa.nLength = sizeof(sa);
    sa.lpSecurityDescriptor = NULL;
    sa.bInheritHandle = TRUE;  /* so that services.exe inherits it */
    event = CreateEventW( &sa, TRUE, FALSE, wineboot_eventW );

    ResetEvent( event );  /* in case this is a restart */

    create_hardware_registry_keys();
    create_dynamic_registry_keys();
    create_environment_registry_keys();
    wininit();
    pendingRename();

    ProcessWindowsFileProtection();
    ProcessRunKeys( HKEY_LOCAL_MACHINE, RunServicesOnceW, TRUE, FALSE );

    if (init || (kill && !restart))
    {
        ProcessRunKeys( HKEY_LOCAL_MACHINE, RunServicesW, FALSE, FALSE );
        start_services_process();
    }
    if (init || update) update_wineprefix( update );

    create_volatile_environment_registry_key();

    ProcessRunKeys( HKEY_LOCAL_MACHINE, RunOnceW, TRUE, TRUE );

    if (!init && !restart)
    {
        ProcessRunKeys( HKEY_LOCAL_MACHINE, RunW, FALSE, FALSE );
        ProcessRunKeys( HKEY_CURRENT_USER, RunW, FALSE, FALSE );
        ProcessStartupItems();
    }

    WINE_TRACE("Operation done\n");

    SetEvent( event );
    return 0;
}
Example #16
-31
bool execute(const char* command, std::string currentDir, DWORD& retCode, std::string& output) {
	HANDLE outWR;

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

	TCHAR lpTempPathBuffer[BUFSIZE];
	TCHAR szTempFileName[MAX_PATH];
	DWORD ret = GetTempPath(BUFSIZE, lpTempPathBuffer);
	if (ret > BUFSIZE || ret == 0) {
		MessageBox(	NULL, "Error GetTempPath", "Error", MB_OK );
		return false;
	}

	ret = GetTempFileName(lpTempPathBuffer, "svn", 0, szTempFileName);
	if (ret == 0) {
		MessageBox(	NULL, "Error GetTempFileName", "Error", MB_OK );
		return false;
	}

	outWR = CreateFile(szTempFileName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, &sa, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
	if (outWR == INVALID_HANDLE_VALUE) {
		MessageBox(	NULL, "Error create file", "Error", MB_OK );
		return false;
	}

	PROCESS_INFORMATION processInfomation;
	STARTUPINFO startupInfo;
	memset(&processInfomation, 0, sizeof(processInfomation));
	memset(&startupInfo, 0, sizeof(startupInfo));
	startupInfo.cb = sizeof(startupInfo);
	startupInfo.hStdError = outWR;
	startupInfo.hStdOutput = outWR;
	startupInfo.dwFlags |= STARTF_USESTDHANDLES;
	startupInfo.wShowWindow = SW_HIDE;

	BOOL result = CreateProcess(
		NULL,
		(char*) command,
		NULL,
		NULL,
		TRUE,
		0,
		NULL,
		currentDir.c_str(),
		&startupInfo,
		&processInfomation);

	if (!result) {
		MessageBox(	NULL, "Can't CreateProcess", "Error", MB_OK );
		CloseHandle(outWR);
		return false;
	} else {
		WaitForSingleObject(processInfomation.hProcess, INFINITE);
		GetExitCodeProcess(processInfomation.hProcess, &retCode);
		CloseHandle(processInfomation.hProcess);
		CloseHandle(processInfomation.hThread);

		// read from stdout
		if (!CloseHandle(outWR)) {
			MessageBox(	NULL, "Can't CloseHandle", "Error", MB_OK );
			return false;
		}

		outWR = CreateFile(szTempFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
		if (outWR == INVALID_HANDLE_VALUE) {
			MessageBox(	NULL, "Error open file", "Error", MB_OK );
			return false;
		}

		CHAR buf[BUFSIZE];
		DWORD dwRead;
		DWORD totalSize = 0;
		std::vector<char*> allBufs;
		std::vector<DWORD> lens;
		while (true) {
			result = ReadFile(outWR, buf, BUFSIZE, &dwRead, NULL);
			if (!result || dwRead == 0) break;
			totalSize += dwRead;
			char* content = new char[dwRead];
			memcpy(content, buf, dwRead);
			allBufs.push_back(content);
			lens.push_back(dwRead);
		}
		char* content = new char[totalSize + 1];
		char* currentPtr = content;
		for (std::size_t i = 0; i < allBufs.size(); i++) {
			memcpy(currentPtr, allBufs[i], lens[i]);
			currentPtr += lens[i];
		}
		content[totalSize] = 0;
		for (std::size_t i = 0; i < allBufs.size(); i++) {
			delete[] allBufs[i];
		}
		output.swap(std::string(content));
		delete[] content;

		CloseHandle(outWR);
		return true;
	}
}