Beispiel #1
0
HWND CDefTermHk::AllocHiddenConsole(bool bTempForVS)
{
	// функция AttachConsole есть только в WinXP и выше
	AttachConsole_t _AttachConsole = GetAttachConsoleProc();
	if (!_AttachConsole)
	{
		LogHookingStatus(L"Can't create hidden console, function does not exist");
		return NULL;
	}

	LogHookingStatus(L"AllocHiddenConsole");

	ReloadSettings();
	_ASSERTEX(isDefTermEnabled() && (gbIsNetVsHost || bTempForVS));

	if (!isDefTermEnabled())
	{
		// Disabled in settings or registry
		LogHookingStatus(L"Application skipped by settings");
		return NULL;
	}

	HANDLE hSrvProcess = NULL;
	DWORD nAttachPID = bTempForVS ? 0 : gnSelfPID;
	DWORD nSrvPID = StartConsoleServer(nAttachPID, true, &hSrvProcess);
	if (!nSrvPID)
	{
		// Failed to start process?
		return NULL;
	}
	_ASSERTEX(hSrvProcess!=NULL);

	HWND hCreatedCon = NULL;

	// Do while server process is alive
	DWORD nStart = GetTickCount(), nMaxDelta = 30000, nDelta = 0;
	DWORD nWait = WaitForSingleObject(hSrvProcess, 0);
	while (nWait != WAIT_OBJECT_0)
	{
		if (_AttachConsole(nSrvPID))
		{
			hCreatedCon = GetRealConsoleWindow();
			if (hCreatedCon)
				break;
		}

		nWait = WaitForSingleObject(hSrvProcess, 150);

		nDelta = (GetTickCount() - nStart);
		if (nDelta > nMaxDelta)
			break;
	}

	return hCreatedCon;
}
Beispiel #2
0
gboolean
GlibUtils_AttachConsole(void)
{
   typedef BOOL (WINAPI *AttachConsoleFn)(DWORD);
   gboolean ret = TRUE;
   AttachConsoleFn _AttachConsole;
   BOOL reopenStdout;
   BOOL reopenStderr;

   if (GetConsoleWindow() != NULL) {
      goto exit;
   }

   reopenStdout = !GlibUtilsIsRedirected(STD_OUTPUT_HANDLE);
   reopenStderr = !GlibUtilsIsRedirected(STD_ERROR_HANDLE);
   if (!reopenStdout && !reopenStderr) {
      goto exit;
   }

   _AttachConsole = (AttachConsoleFn) GetProcAddress(GetModuleHandleW(L"kernel32.dll"),
                                                     "AttachConsole");
   if ((_AttachConsole != NULL && _AttachConsole(ATTACH_PARENT_PROCESS)) ||
       AllocConsole()) {
      FILE *fptr;

      if (reopenStdout) {
         fptr = _wfreopen(L"CONOUT$", L"a", stdout);
         if (fptr == NULL) {
            g_warning("_wfreopen failed for stdout/CONOUT$: %d (%s)",
                      errno, strerror(errno));
            ret = FALSE;
         }
      }

      if (reopenStderr) {
         fptr = _wfreopen(L"CONOUT$", L"a", stderr);
         if (fptr == NULL) {
            g_warning("_wfreopen failed for stderr/CONOUT$: %d (%s)",
                      errno, strerror(errno));
            ret = FALSE;
         } else {
            setvbuf(fptr, NULL, _IONBF, 0);
         }
      }
   } else {
      ret = FALSE;
   }

exit:
   if (!ret) {
      g_warning("Console redirection unavailable.");
   }
   return ret;
}
Beispiel #3
0
bool AttachServerConsole()
{
	bool lbAttachRc = false;
	DWORD nErrCode;
	HWND hCurCon = GetRealConsoleWindow();
	if (hCurCon == NULL && gnServerPID != 0)
	{
		// функция есть только в WinXP и выше
		AttachConsole_t _AttachConsole = GetAttachConsoleProc();
		if (_AttachConsole)
		{
			lbAttachRc = (_AttachConsole(gnServerPID) != 0);
			if (!lbAttachRc)
			{
				nErrCode = GetLastError();
				_ASSERTE(nErrCode==0 && lbAttachRc);
			}
		}
	}
	return lbAttachRc;
}
Beispiel #4
0
void OpenConsole() 
{
	COORD csize;
	CONSOLE_SCREEN_BUFFER_INFO csbiInfo; 
	SMALL_RECT srect;
	char buf[256];

	//dont do anything if we're already attached
	if (hConsole) return;

	//attach to an existing console (if we can; this is circuitous because AttachConsole wasnt added until XP)
	//remember to abstract this late bound function notion if we end up having to do this anywhere else
	bool attached = false;
	HMODULE lib = LoadLibrary("kernel32.dll");
	if(lib)
	{
		typedef BOOL (WINAPI *_TAttachConsole)(DWORD dwProcessId);
		_TAttachConsole _AttachConsole  = (_TAttachConsole)GetProcAddress(lib,"AttachConsole");
		if(_AttachConsole)
		{
			if(_AttachConsole(-1))
				attached = true;
		}
		FreeLibrary(lib);
	}

	//if we failed to attach, then alloc a new console
	if(!attached)
	{
		AllocConsole();
	}

	hConsole = GetStdHandle(STD_OUTPUT_HANDLE);

	//redirect stdio
	long lStdHandle = (long)hConsole;
	int hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
	if(hConHandle == -1)
		return; //this fails from a visual studio command prompt
	
	FILE *fp = _fdopen( hConHandle, "w" );
	*stdout = *fp;
	//and stderr
	*stderr = *fp;

	memset(buf,0,256);
	sprintf(buf,"%s OUTPUT", DESMUME_NAME_AND_VERSION);
	SetConsoleTitle(TEXT(buf));
	csize.X = 60;
	csize.Y = 800;
	SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), csize);
	GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbiInfo);
	srect = csbiInfo.srWindow;
	srect.Right = srect.Left + 99;
	srect.Bottom = srect.Top + 64;
	SetConsoleWindowInfo(GetStdHandle(STD_OUTPUT_HANDLE), TRUE, &srect);
	SetConsoleCP(GetACP());
	SetConsoleOutputCP(GetACP());
	if(attached) printlog("\n");
	printlog("%s\n",DESMUME_NAME_AND_VERSION);
	printlog("- compiled: %s %s\n\n",__DATE__,__TIME__);


}
Beispiel #5
0
// запустить через ShellExecuteEx в скрытом режиме
// (см. шаманство с консолью)
static BOOL ExecuteHide( CPath& path, DWORD* out_exitcode, CSimpleString* strOut )
{
	HANDLE hSaveStdin = NULL;
	HANDLE hSaveStdout = NULL;
	HANDLE hChildStdoutRdDup = NULL;
	HANDLE hChildStdoutWr = NULL;
	try
	{
		// подключаем консоль
		STARTUPINFOA si = { sizeof(STARTUPINFOA) };
		si.dwFlags = STARTF_USESHOWWINDOW;
		si.wShowWindow = SW_HIDE;
		PROCESS_INFORMATION pi = { 0 };
		char command_line[] = "cmd";
		::CreateProcessA( NULL, // не используем имя файла, все в строке запуска
						  command_line, // Command line
						  NULL, // Process handle not inheritable
						  NULL, // Thread handle not inheritable
						  TRUE, // Set handle inheritance to FALSE
						  0, // No creation flags
						  NULL, // Use parent's environment block
						  NULL, // Use parent's starting directory
						  &si, // STARTUPINFO
						  &pi ); // PROCESS_INFORMATION
		// задержка чтобы консоль успела создаться
		::WaitForSingleObject( pi.hProcess, 100 );
		BOOL hResult = FALSE;
		HMODULE hLib = LoadLibraryA("Kernel32.dll");
		if ( hLib != NULL )
		{
			typedef BOOL (STDAPICALLTYPE *ATTACHCONSOLE)( DWORD dwProcessId );
			ATTACHCONSOLE _AttachConsole = NULL;
			_AttachConsole = (ATTACHCONSOLE)GetProcAddress( hLib, "AttachConsole" );
			if ( _AttachConsole ) hResult = _AttachConsole( pi.dwProcessId );
			FreeLibrary( hLib );
		}
		if ( hResult == FALSE ) AllocConsole();

		TerminateProcess( pi.hProcess, 0 );
		CloseHandle( pi.hProcess );
		CloseHandle( pi.hThread );

		HANDLE hChildStdinRd;
		HANDLE hChildStdinWr;
		HANDLE hChildStdinWrDup;
		HANDLE hChildStdoutRd;

		// Set the bInheritHandle flag so pipe handles are inherited. 
		SECURITY_ATTRIBUTES saAttr = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };
		BOOL fSuccess;

		// The steps for redirecting child process's STDOUT: 
		//     1. Save current STDOUT, to be restored later. 
		//     2. Create anonymous pipe to be STDOUT for child process. 
		//     3. Set STDOUT of the parent process to be write handle to 
		//        the pipe, so it is inherited by the child process. 
		//     4. Create a noninheritable duplicate of the read handle and
		//        close the inheritable read handle. 

		// Save the handle to the current STDOUT. 
		hSaveStdout = GetStdHandle( STD_OUTPUT_HANDLE );

		// Create a pipe for the child process's STDOUT.
		if ( !CreatePipe( &hChildStdoutRd, &hChildStdoutWr, &saAttr, 0 ) ) throw(1);

		// Set a write handle to the pipe to be STDOUT. 
		if ( !SetStdHandle( STD_OUTPUT_HANDLE, hChildStdoutWr ) ) throw(1);

		// Create noninheritable read handle and close the inheritable read 
		// handle.
		fSuccess = DuplicateHandle( GetCurrentProcess(),
									hChildStdoutRd,
									GetCurrentProcess(),
									&hChildStdoutRdDup,
									0,
									FALSE,
									DUPLICATE_SAME_ACCESS );
		if( fSuccess == FALSE ) throw(1);
		CloseHandle( hChildStdoutRd );

		// The steps for redirecting child process's STDIN: 
		//     1.  Save current STDIN, to be restored later. 
		//     2.  Create anonymous pipe to be STDIN for child process. 
		//     3.  Set STDIN of the parent to be the read handle to the 
		//         pipe, so it is inherited by the child process. 
		//     4.  Create a noninheritable duplicate of the write handle, 
		//         and close the inheritable write handle. 

		// Save the handle to the current STDIN. 
		hSaveStdin = GetStdHandle( STD_INPUT_HANDLE );

		// Create a pipe for the child process's STDIN. 
		if ( !CreatePipe( &hChildStdinRd, &hChildStdinWr, &saAttr, 0 ) ) throw(1);

		// Set a read handle to the pipe to be STDIN. 
		if ( !SetStdHandle( STD_INPUT_HANDLE, hChildStdinRd ) ) throw(1);

		// Duplicate the write handle to the pipe so it is not inherited. 
		fSuccess = DuplicateHandle( GetCurrentProcess(),
									hChildStdinWr,
									GetCurrentProcess(),
									&hChildStdinWrDup,
									0,
									FALSE,
									DUPLICATE_SAME_ACCESS );
		if ( fSuccess == FALSE ) throw(1);

		CloseHandle( hChildStdinWr );
	}
	catch (...)
	{
		return FALSE;
	}

	// Now create the child process.
	SHELLEXECUTEINFOA shinf = { sizeof(SHELLEXECUTEINFOA) };
	shinf.lpFile = path.GetPath();
	shinf.lpParameters = path.GetFileParams();
	//shinf.lpDirectory = path.GetDirectory();
	shinf.fMask = SEE_MASK_FLAG_NO_UI |
				  SEE_MASK_NO_CONSOLE |
				  SEE_MASK_FLAG_DDEWAIT |
				  SEE_MASK_NOCLOSEPROCESS;
	shinf.nShow = SW_HIDE;
	BOOL bSuccess = ::ShellExecuteExA( &shinf );
	if ( bSuccess && shinf.hInstApp <= (HINSTANCE)32 ) bSuccess = FALSE;
	HANDLE hProcess = shinf.hProcess;

	try
	{
		if ( bSuccess == FALSE || hProcess == NULL ) throw(1);

		if ( hChildStdoutWr != NULL )
		{
			CloseHandle( hChildStdoutWr );
			hChildStdoutWr = NULL;
		}

		// After process creation, restore the saved STDIN and STDOUT.
		if ( hSaveStdin != NULL )
		{
			if ( !SetStdHandle( STD_INPUT_HANDLE, hSaveStdin ) ) throw(1);
			CloseHandle( hSaveStdin );
			hSaveStdin = NULL;
		}

		if ( hSaveStdout != NULL )
		{
			if ( !SetStdHandle( STD_OUTPUT_HANDLE, hSaveStdout ) ) throw(1);
			CloseHandle( hSaveStdout );
			hSaveStdout = NULL;
		}

		if ( hChildStdoutRdDup != NULL )
		{
			// Read output from the child process, and write to parent's STDOUT.
			const int BUFSIZE = 1024;
			DWORD dwRead;
			CMemBuffer< char, BUFSIZE > bufStr; // строковой буфер
			CMemBuffer< char, BUFSIZE > bufCmdLine; // строковой буфер
			for (;;)
			{
				if( ReadFile( hChildStdoutRdDup,
							  bufCmdLine.GetBuffer(),
							  BUFSIZE,
							  &dwRead,
							  NULL ) == FALSE ||
					dwRead == 0 )
				{
					DWORD exit_code = 0;
					if ( ::GetExitCodeProcess( hProcess, &exit_code ) == FALSE ||
						 exit_code != STILL_ACTIVE )
					{
						break;
					}
					else
					{
						continue;
					}
				}
				bufCmdLine[ dwRead ] = '\0';
				::OemToAnsi( bufCmdLine.GetBuffer(), bufStr.GetBuffer() );
				strOut->Append( bufStr.GetBuffer() );
			}
			CloseHandle( hChildStdoutRdDup );
			hChildStdoutRdDup = NULL;
		}
		FreeConsole();
	}
	catch (...)
	{
		if ( hChildStdoutWr != NULL ) CloseHandle( hChildStdoutWr );
		if ( hSaveStdin != NULL ) CloseHandle( hSaveStdin );
		if ( hSaveStdout != NULL ) CloseHandle( hSaveStdout );
		if ( hChildStdoutRdDup != NULL ) CloseHandle( hChildStdoutRdDup );
		if ( bSuccess == FALSE || hProcess == NULL ) return FALSE;
	}

	::GetExitCodeProcess( hProcess, out_exitcode );
	CloseHandle( hProcess );
	return TRUE;
}