⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 remoteshell.cpp

📁 MPICH是MPI的重要研究,提供了一系列的接口函数,为并行计算的实现提供了编程环境.
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	HANDLE hUser = NULL;	STARTUPINFO saInfo;	PROCESS_INFORMATION psInfo;	void *pEnv=NULL;	TCHAR tCmdLine[MAX_PATH];	TCHAR tSavedPath[MAX_PATH] = TEXT(".");	TCHAR tAccount[256], tPassword[256], tDomain[256], *psztDomain;	HANDLE hImpersonatedToken;	HRESULT hr;	try{	DLogMsg(TEXT("LaunchProcess called: %u\n"), this);	DLogWMsg(L"\n     Launching:\n        %s\n        %s\n\n", bCmdLine, bEnv);#ifdef UNICODE	wcscpy(tCmdLine, bCmdLine);	//swprintf(tCmdLine, L"cmd.exe /c %s", bCmdLine);#else	wcstombs(tCmdLine, bCmdLine, wcslen(bCmdLine)+1);	//char sTempBuffer[256];	//wcstombs(sTempBuffer, bCmdLine, wcslen(bCmdLine)+1);	//sprintf(tCmdLine, "cmd.exe /c %s", sTempBuffer);#endif	// Launching of the client processes must be synchronized because	// stdin,out,err are redirected for the entire process, not just this thread.	if (WaitForSingleObject(g_hLaunchSyncMutex, g_nLaunchTimeout) == WAIT_TIMEOUT)	{		*nError = 1;		SysReAllocString(bErrorMsg, L"LaunchProcess: Timeout while waiting for syncronization object.\n");		LogMsg(TEXT("LaunchProcess: Timeout while waiting for syncronization object.\n"));		return S_OK;	}	// Don't handle errors, just let the process die.	// In the future this will be configurable to allow various debugging options.	SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);	// Save stdin, stdout, and stderr	hStdin = GetStdHandle(STD_INPUT_HANDLE);	hStdout = GetStdHandle(STD_OUTPUT_HANDLE);	hStderr = GetStdHandle(STD_ERROR_HANDLE);	if (hStdin == INVALID_HANDLE_VALUE || hStdout == INVALID_HANDLE_VALUE  || hStderr == INVALID_HANDLE_VALUE)	{		*nError = GetLastError();		SysReAllocString(bErrorMsg, L"LaunchProcess: Unable to get standard handles.\n");		ReleaseMutex(g_hLaunchSyncMutex);		return S_OK;	}	// Set the security attributes to allow handles to be inherited	SECURITY_ATTRIBUTES saAttr;	saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);	saAttr.lpSecurityDescriptor = NULL;	saAttr.bInheritHandle = TRUE;	// Create pipes for stdin, stdout, and stderr	// Stdout	if (!CreatePipe(&hTempPipe, &hStdoutPipeW, &saAttr, 0))	{		*nError = GetLastError();		Translate_Error(*nError, error_msg, L"LaunchProcess:CreatePipe failed ");		SysReAllocString(bErrorMsg, error_msg);		goto CLEANUP;	}	// Make the read end of the stdout pipe not inheritable	if (!DuplicateHandle(GetCurrentProcess(), hTempPipe, 		GetCurrentProcess(), &m_hStdoutPipeR, 		0, FALSE, DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS))	{		*nError = GetLastError();		Translate_Error(*nError, error_msg, L"LaunchProcess:DuplicateHandle(StdoutPipeR) failed ");		SysReAllocString(bErrorMsg, error_msg);		goto CLEANUP;	}	// Stderr	if (!CreatePipe(&hTempPipe, &hStderrPipeW, &saAttr, 0))	{		*nError = GetLastError();		Translate_Error(*nError, error_msg, L"LaunchProcess:CreatePipe failed ");		SysReAllocString(bErrorMsg, error_msg);		goto CLEANUP;	}	// Make the read end of the stderr pipe not inheritable	if (!DuplicateHandle(GetCurrentProcess(), hTempPipe, 		GetCurrentProcess(), &m_hStderrPipeR, 		0, FALSE, DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS))	{		*nError = GetLastError();		Translate_Error(*nError, error_msg, L"LaunchProcess:DuplicateHandle(StderrPipeR) failed ");		SysReAllocString(bErrorMsg, error_msg);		goto CLEANUP;	}	// Stdin	if (!CreatePipe(&hStdinPipeR, &hTempPipe, &saAttr, 0))	{		*nError = GetLastError();		Translate_Error(*nError, error_msg, L"LaunchProcess:CreatePipe failed");		SysReAllocString(bErrorMsg, error_msg);		goto CLEANUP;	}	// Make the write end of the stdin pipe not inheritable	if (!DuplicateHandle(GetCurrentProcess(), hTempPipe, 		GetCurrentProcess(), &m_hStdinPipeW, 		0, FALSE, DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS))	{		*nError = GetLastError();		Translate_Error(*nError, error_msg, L"LaunchProcess:DuplicateHandle(StdoutPipeR) failed ");		SysReAllocString(bErrorMsg, error_msg);		goto CLEANUP;	}	// Set stdin, stdout, and stderr to the ends of the pipe the created process will use	if (!SetStdHandle(STD_INPUT_HANDLE, hStdinPipeR))	{		*nError = GetLastError();		Translate_Error(*nError, error_msg, L"LaunchProcess:SetStdHandle(Input) failed ");		SysReAllocString(bErrorMsg, error_msg);		goto CLEANUP;	}	if (!SetStdHandle(STD_OUTPUT_HANDLE, hStdoutPipeW))	{		*nError = GetLastError();		Translate_Error(*nError, error_msg, L"LaunchProcess:SetStdHandle(Output) failed ");		SysReAllocString(bErrorMsg, error_msg);		goto RESTORE_CLEANUP;	}	if (!SetStdHandle(STD_ERROR_HANDLE, hStderrPipeW))	{		*nError = GetLastError();		Translate_Error(*nError, error_msg, L"LaunchProcess:SetStdHandle(Error) failed ");		SysReAllocString(bErrorMsg, error_msg);		goto RESTORE_CLEANUP;	}	// Set up the STARTINFO structure	memset(&saInfo, 0, sizeof(STARTUPINFO));	saInfo.cb         = sizeof(STARTUPINFO);	saInfo.hStdInput  = hStdinPipeR;	saInfo.hStdOutput = hStdoutPipeW;	saInfo.hStdError  = hStderrPipeW;	saInfo.dwFlags    = STARTF_USESTDHANDLES;	if (m_bLaunchOnDesktop)		saInfo.lpDesktop  = TEXT("WinSta0\\Default");	// Set the environment variables	SetEnvironmentVariables(bEnv);	pEnv = GetEnvironmentStrings();	// Get a handle to the user token either by logging in or impersonating the user.	if (wcslen(bAccount))	{		// An account was passed in so use it to get the user token.		ParseAccountDomain(bAccount, tAccount, tDomain);		if (_tcslen(tDomain) < 1)			psztDomain = NULL;		else			psztDomain = tDomain;#ifdef UNICODE		wcscpy(tPassword, bPassword);#else		wcstombs(tPassword, bPassword, wcslen(bPassword)+1);#endif		if (!LogonUser(			tAccount,			psztDomain, 			tPassword,			LOGON32_LOGON_INTERACTIVE, 			LOGON32_PROVIDER_DEFAULT, 			&hUser))		{			*nError = GetLastError();			Translate_Error(*nError, error_msg, L"LaunchProcess:LogonUser failed ");			SysReAllocString(bErrorMsg, error_msg);			LogWMsg(L"LaunchProcess: LogonUser failed: %d, %s\n", *nError, error_msg);			goto RESTORE_CLEANUP;		}	}	else	{		// No account was passed in so impersonate the client to get a user token		hr = CoImpersonateClient();		if (FAILED(hr))			LogMsg(TEXT("LaunchProcess:CoImpersonateClient failed - launching process with process token"));		//if (!OpenThreadToken(GetCurrentThread(), TOKEN_ALL_ACCESS, TRUE, &hImpersonatedToken))		if (!OpenThreadToken(GetCurrentThread(), MAXIMUM_ALLOWED, TRUE, &hImpersonatedToken))		{			*nError = GetLastError();			Translate_Error(*nError, error_msg, L"LaunchProcess:OpenThreadToken failed: ");			SysReAllocString(bErrorMsg, error_msg);			LogWMsg(L"LaunchProcess:OpenThreadToken failed: %d, %s\n", *nError, error_msg);			goto RESTORE_CLEANUP;		}		CoRevertToSelf();		//if (!DuplicateTokenEx(hImpersonatedToken, TOKEN_ALL_ACCESS, NULL, SecurityImpersonation, TokenPrimary, &hUser))		if (!DuplicateTokenEx(hImpersonatedToken, MAXIMUM_ALLOWED, NULL, SecurityImpersonation, TokenPrimary, &hUser))		{			*nError = GetLastError();			Translate_Error(*nError, error_msg, L"LaunchProcess:DuplicateTokenEx failed: ");			SysReAllocString(bErrorMsg, error_msg);			LogWMsg(L"LaunchProcess:DuplicateTokenEx failed: %d, %s\n", *nError, error_msg);			goto RESTORE_CLEANUP;		}	}	// Create the process	//LogMsg(TEXT("impersonating user\n"));	if (ImpersonateLoggedOnUser(hUser))	{		// Attempt to change into the directory passed into the function		GetCurrentDirectory(MAX_PATH, tSavedPath);		if (!SetCurrentDirectoryW(bDir))		{			int terror = GetLastError();			char terror_msg[256];			Translate_Error(terror, terror_msg, "LaunchProcess:SetCurrentDirectory failed ");			LogMsg(terror_msg);		}		//LogMsg(TEXT("LaunchInteractiveProcess: about to launch %s.\n"), tCmdLine);		if (CreateProcessAsUser(			hUser,			NULL,			tCmdLine,			NULL, NULL, TRUE,			//DETACHED_PROCESS | IDLE_PRIORITY_CLASS, 			//CREATE_NO_WINDOW | IDLE_PRIORITY_CLASS,			CREATE_NO_WINDOW | IDLE_PRIORITY_CLASS | CREATE_NEW_PROCESS_GROUP,			//DETACHED_PROCESS | IDLE_PRIORITY_CLASS | CREATE_NEW_PROCESS_GROUP,			//CREATE_NO_WINDOW | IDLE_PRIORITY_CLASS | CREATE_SUSPENDED, 			pEnv,			NULL,			&saInfo, &psInfo))		{			m_hProcess = psInfo.hProcess;			//ResumeThread(psInfo.hThread);			CloseHandle(psInfo.hThread);			LogMsg(TEXT("LaunchProcess: launched '%s'"), tCmdLine);			bSuccess = TRUE;			*nPid = psInfo.dwProcessId;			m_dwProcessId = psInfo.dwProcessId;			SysReAllocString(bErrorMsg, L"success");			*nError = 0;		}		else		{			*nError = GetLastError();			Translate_Error(*nError, error_msg, L"LaunchProcess:CreateProcessAsUser failed: ");			SysReAllocString(bErrorMsg, error_msg);			LogWMsg(L"LaunchProcess: CreateProcessAsUser failed: error %d, %s", *nError, error_msg);			LogMsg("LaunchProcess: failed to launch '%s'", tCmdLine);		}		RevertToSelf();	}	else	{		*nError = GetLastError();		Translate_Error(*nError, error_msg, L"LaunchProcess:ImpersonateLoggedOnUser failed ");		SysReAllocString(bErrorMsg, error_msg);		LogWMsg(L"LaunchProcess: ImpersonateLoggedOnUser failed: %d, %s\n", *nError, error_msg);	}	CloseHandle(hUser);	FreeEnvironmentStrings((TCHAR*)pEnv);	SetCurrentDirectory(tSavedPath);	RemoveEnvironmentVariables(bEnv);RESTORE_CLEANUP:	// Restore stdin, stdout, stderr	if (!SetStdHandle(STD_INPUT_HANDLE, hStdin))	{		*nError = GetLastError();		Translate_Error(*nError, error_msg, L"LaunchProcess:SetStdHandle(restore Input) failed ");		SysReAllocString(bErrorMsg, error_msg);	}	if (!SetStdHandle(STD_OUTPUT_HANDLE, hStdout))	{		*nError = GetLastError();		Translate_Error(*nError, error_msg, L"LaunchProcess:SetStdHandle(restore Output) failed ");		SysReAllocString(bErrorMsg, error_msg);	}	if (!SetStdHandle(STD_ERROR_HANDLE, hStderr))	{		*nError = GetLastError();		Translate_Error(*nError, error_msg, L"LaunchProcess:SetStdHandle(restore Error) failed ");		SysReAllocString(bErrorMsg, error_msg);	}	if (bSuccess)	{		// start threads to monitor output of pipes		DWORD dwThreadID;		m_hStdoutThread = CreateThread(			NULL, 0, (LPTHREAD_START_ROUTINE)RedirectStdout,			this, 0, &dwThreadID);				if (m_hStdoutThread == NULL)			SysReAllocString(bErrorMsg, L"Unable to create a thread to redirect standard out.\n");		m_hStderrThread = CreateThread(			NULL, 0, (LPTHREAD_START_ROUTINE)RedirectStderr,			this, 0, &dwThreadID);		if (m_hStderrThread == NULL)			SysReAllocString(bErrorMsg, L"Unable to create a thread to redirect standard error.\n");	}CLEANUP:	ReleaseMutex(g_hLaunchSyncMutex);	CloseHandle(hStdoutPipeW);	CloseHandle(hStderrPipeW);	CloseHandle(hStdinPipeR);	}catch(...){		*nError = 1;		ReleaseMutex(g_hLaunchSyncMutex);		SysReAllocString(bErrorMsg, L"LaunchProcess:Exception thrown");		LogWMsg(L"Exception thrown in LaunchProcess");	}	return S_OK;}// Function name	: CRemoteShell::GetProcessOutput// Description	    : // Return type		: STDMETHODIMP // Argument         : VARIANT *vOutput// Argument         : long *nState// Argument         : long *nError// Argument         : BSTR *bErrorMsgSTDMETHODIMP CRemoteShell::GetProcessOutput(VARIANT *vOutput, long *nState, long *nError, BSTR *bErrorMsg){	SAFEARRAYBOUND bound;	void *pBuf;	ChunkNode *node;	try{	VariantClear(vOutput);	vOutput->vt = VT_UI1 | VT_ARRAY;	// It may be worthy to put a timeout value here but as is, this would allow a user to leave	// a session open for days without timing out.	WaitForSingleObject(m_hOutputMutex, INFINITE);	// After this block, m_pOutList is valid.	if (m_pOutList == NULL)	{		// Nothing in the list so release the mutex and wait for something to be added to the list.		// Release the mutex		ReleaseMutex(m_hOutputMutex);		// Wait for the event signalling new data has been added to the list		WaitForSingleObject(m_hOutputEvent, INFINITE);		// Wait for the mutex to syncronize access to the list		WaitForSingleObject(m_hOutputMutex, INFINITE);	}	bound.lLbound = 0;	bound.cElements = m_pOutList->dwSize;	// Create an array to return the data in.	vOutput->parray = SafeArrayCreate(VT_UI1, 1, &bound);	// Copy the data in the list to the array	if (m_pOutList->dwSize > 0)	{		SafeArrayAccessData(vOutput->parray, &pBuf);		memcpy(pBuf, m_pOutList->pData, m_pOutList->dwSize);		SafeArrayUnaccessData(vOutput->parray);	}	// Remove the node that has just been copied and signal whether there is potentially more data to come.	node = m_pOutList;	m_pOutList = m_pOutList->pNext;	if (m_pOutList == NULL)	{		m_pOutListTail = NULL;		ResetEvent(m_hOutputEvent);	}	if (node->bStdError)		*nState = RSH_OUTPUT_STDERR;	else		*nState = RSH_OUTPUT_STDOUT;	if (node->dwSize > 0)	{		delete node->pData;		*nState = (*nState) | RSH_OUTPUT_MORE;	}	else	{	    if (WaitForSingleObject(m_hStdoutThread, 5000) != WAIT_OBJECT_0)		TerminateThread(m_hStdoutThread, 0);	    if (WaitForSingleObject(m_hStderrThread, 5000) != WAIT_OBJECT_0)		TerminateThread(m_hStderrThread, 0);	    CloseHandle(m_hStdoutThread);	    CloseHandle(m_hStderrThread);	    m_hStdoutThread = NULL;	    m_hStderrThread = NULL;	}	m_dwExitCode = node->dwExitCode;	delete node;	ReleaseMutex(m_hOutputMutex);	}catch(...){		*nError = 1;		SysReAllocString(bErrorMsg, L"GetInteractiveOutput:Exception thrown");		LogWMsg(L"Exception thrown in GetInteractiveOutput.\n");	}	return S_OK;}// Function name	: CRemoteShell::PutProcessInput// Description	    : // Return type		: STDMETHODIMP // Argument         : VARIANT vInput// Argument         : long *nError// Argument         : BSTR *bErrorMsgSTDMETHODIMP CRemoteShell::PutProcessInput(VARIANT vInput, long *nError, BSTR *bErrorMsg){	LPVOID pBuf;	DWORD size, num_written;	if (vInput.vt == (VT_UI1 | VT_ARRAY))	{		size = vInput.parray->rgsabound->cElements;		SafeArrayAccessData(vInput.parray, &pBuf);		WriteFile(m_hStdinPipeW, pBuf, size, &num_written, NULL);		SafeArrayUnaccessData(vInput.parray);	}	return S_OK;}// Function name	: CRemoteShell::Abort// Description	    : // Return type		: STDMETHODIMP // Argument         : long *nError// Argument         : BSTR *bErrorMsgSTDMETHODIMP CRemoteShell::Abort(long *nError, BSTR *bErrorMsg){	if (m_hProcess != NULL)	{		*nError = 1;		if (GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, m_dwProcessId))		{			if (WaitForSingleObject(m_hProcess, 500) == WAIT_OBJECT_0)				*nError = 0;		}		if (*nError)		{			if (TerminateProcess(m_hProcess, 1))				*nError = 0;			else			{				*nError = GetLastError();				WCHAR error_msg[256];				Translate_Error(*nError, error_msg, L"Abort:TerminateProcess failed ");				SysReAllocString(bErrorMsg, error_msg);				LogWMsg(L"%d, %s", *nError, error_msg);			}		}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -