📄 remoteshell.cpp
字号:
// RemoteShell.cpp : Implementation of CRemoteShell#include "stdafx.h"#include "RemoteShellServer.h"#include "RemoteShell.h"#include "..\Common\Translate_Error.h"#include <time.h>#include <stdio.h>#include "AccessDesktop.h"/////////////////////////////////////////////////////////////////////////////// CRemoteShell// Function name : CRemoteShell::~CRemoteShell// Description : // Return type : CRemoteShell::~CRemoteShell(){ try{ if (m_hProcess) { DWORD exitCode; GetExitCodeProcess(m_hProcess, &exitCode); if (exitCode == STILL_ACTIVE) TerminateProcess(m_hProcess, 0); CloseHandle(m_hProcess); } m_hProcess = NULL; if (m_hStdoutThread != NULL) { TerminateThread(m_hStdoutThread, 0); CloseHandle(m_hStdoutThread); m_hStdoutThread = NULL; } if (m_hStderrThread != NULL) { TerminateThread(m_hStderrThread, 0); CloseHandle(m_hStderrThread); m_hStderrThread = NULL; } if (m_hOutputMutex) CloseHandle(m_hOutputMutex); m_hOutputMutex = NULL; if (m_hOutputEvent) CloseHandle(m_hOutputEvent); m_hOutputEvent = NULL; if (m_hStdoutPipeR) CloseHandle(m_hStdoutPipeR); m_hStdoutPipeR = NULL; if (m_hStderrPipeR) CloseHandle(m_hStderrPipeR); m_hStderrPipeR = NULL; if (m_hStdinPipeW) CloseHandle(m_hStdinPipeW); m_hStdinPipeW = NULL; if (m_pOutList) { ChunkNode *n; while (m_pOutList != NULL) { n = m_pOutList; m_pOutList = m_pOutList->pNext; if (n->pData != NULL) delete n->pData; delete n; } } m_pOutList = NULL; m_pOutListTail = NULL; if (m_pMapping && m_hMapping) UnmapViewOfFile(m_pMapping); if (m_hMapping) CloseHandle(m_hMapping); m_pMapping = NULL; m_hMapping = NULL; } catch(...){ LogMsg(TEXT("Exception thrown in CRemoteShell destructor.\n")); }}// Function name : RedirectStdout// Description : // Return type : void // Argument : CRemoteShell *pComvoid RedirectStdout(CRemoteShell *pCom){ unsigned char buffer[1024]; DWORD num_read = 1024; while (num_read > 0) { num_read = 1024; if (ReadFile(pCom->m_hStdoutPipeR, buffer, num_read, &num_read, NULL)) { if (num_read > 0) { DLogMsg(TEXT("RedirectStdout: %d bytes read from pipe, about to add to list.\n"), num_read); // Insert a node in the list. ChunkNode *n = new ChunkNode; n->pData = new char[num_read]; memcpy(n->pData, buffer, num_read); n->dwSize = num_read; n->pNext = NULL; n->bStdError = false; WaitForSingleObject(pCom->m_hOutputMutex, INFINITE); if (pCom->m_pOutListTail == NULL) { pCom->m_pOutList = pCom->m_pOutListTail = n; } else { pCom->m_pOutListTail->pNext = n; pCom->m_pOutListTail = n; } SetEvent(pCom->m_hOutputEvent); ReleaseMutex(pCom->m_hOutputMutex); DLogMsg(TEXT("RedirectStdout: data added to m_pOutList.\n")); } else { // ReadFile returned zero bytes so the pipes must have closed. DLogMsg(TEXT("RedirectStdout: zero bytes read from pipe.\n")); WaitForSingleObject(pCom->m_hOutputMutex, INFINITE); CloseHandle(pCom->m_hStdoutPipeR); //CloseHandle(pCom->m_hStderrPipeR); CloseHandle(pCom->m_hStdinPipeW); pCom->m_hStdoutPipeR = NULL; //pCom->m_hStderrPipeR = NULL; pCom->m_hStdinPipeW = NULL; ReleaseMutex(pCom->m_hOutputMutex); } } else { // ReadFile failed so the process must have exited. DLogMsg(TEXT("RedirectStdout: ReadFile failed.\n")); CloseHandle(pCom->m_hStdoutPipeR); //CloseHandle(pCom->m_hStderrPipeR); CloseHandle(pCom->m_hStdinPipeW); pCom->m_hStdoutPipeR = NULL; //pCom->m_hStderrPipeR = NULL; pCom->m_hStdinPipeW = NULL; break; } } // Insert a node indicating the end of the stream. DLogMsg(TEXT("RedirectStdout: inserting last node to signal no more data.\n")); ChunkNode *n = new ChunkNode; n->dwSize = 0; // <---- 0 size indicates end of stream. n->pData = NULL; // <---- NULL data indicates end of stream. n->pNext = NULL; n->bStdError = false; GetExitCodeProcess(pCom->m_hProcess, &n->dwExitCode); WaitForSingleObject(pCom->m_hOutputMutex, INFINITE); if (pCom->m_pOutListTail == NULL) pCom->m_pOutList = pCom->m_pOutListTail = n; else { pCom->m_pOutListTail->pNext = n; pCom->m_pOutListTail = n; } SetEvent(pCom->m_hOutputEvent); // Close the thread handle because the thread is about to exit. // Other threads may access this thread handle but no other thread // is checking to see when this thread exits so I close the handle here. // These two lines of code are protected by m_hOutputMutex //CloseHandle(pCom->m_hStdoutThread); //pCom->m_hStdoutThread = NULL; ReleaseMutex(pCom->m_hOutputMutex);}// Function name : RedirectStderr// Description : // Return type : void // Argument : CRemoteShell *pComvoid RedirectStderr(CRemoteShell *pCom){ unsigned char buffer[1024]; DWORD num_read = 1024; while (num_read > 0) { num_read = 1024; if (ReadFile(pCom->m_hStderrPipeR, buffer, num_read, &num_read, NULL)) { if (num_read > 0) { DLogMsg(TEXT("RedirectStdout: %d bytes read from pipe, about to add to list.\n"), num_read); // Insert a node in the list. ChunkNode *n = new ChunkNode; n->pData = new char[num_read]; memcpy(n->pData, buffer, num_read); n->dwSize = num_read; n->pNext = NULL; n->bStdError = true; WaitForSingleObject(pCom->m_hOutputMutex, INFINITE); if (pCom->m_pOutListTail == NULL) { pCom->m_pOutList = pCom->m_pOutListTail = n; } else { pCom->m_pOutListTail->pNext = n; pCom->m_pOutListTail = n; } SetEvent(pCom->m_hOutputEvent); ReleaseMutex(pCom->m_hOutputMutex); DLogMsg(TEXT("RedirectStdout: data added to m_pOutList.\n")); } else { // ReadFile returned zero bytes so the pipes must have closed. DLogMsg(TEXT("RedirectStdout: zero bytes read from pipe.\n")); WaitForSingleObject(pCom->m_hOutputMutex, INFINITE); //CloseHandle(pCom->m_hStdoutPipeR); CloseHandle(pCom->m_hStderrPipeR); CloseHandle(pCom->m_hStdinPipeW); //pCom->m_hStdoutPipeR = NULL; pCom->m_hStderrPipeR = NULL; pCom->m_hStdinPipeW = NULL; ReleaseMutex(pCom->m_hOutputMutex); } } else { // ReadFile failed so the process must have exited. DLogMsg(TEXT("RedirectStdout: ReadFile failed.\n")); //CloseHandle(pCom->m_hStdoutPipeR); CloseHandle(pCom->m_hStderrPipeR); CloseHandle(pCom->m_hStdinPipeW); //pCom->m_hStdoutPipeR = NULL; pCom->m_hStderrPipeR = NULL; pCom->m_hStdinPipeW = NULL; break; } } /* // Insert a node indicating the end of the stream. DLogMsg(TEXT("RedirectStdout: inserting last node to signal no more data.\n")); ChunkNode *n = new ChunkNode; n->dwSize = 0; // <---- 0 size indicates end of stream. n->pData = NULL; // <---- NULL data indicates end of stream. n->pNext = NULL; GetExitCodeProcess(pCom->m_hProcess, &n->dwExitCode); //*/ WaitForSingleObject(pCom->m_hOutputMutex, INFINITE); /* if (pCom->m_pOutListTail == NULL) pCom->m_pOutList = pCom->m_pOutListTail = n; else { pCom->m_pOutListTail->pNext = n; pCom->m_pOutListTail = n; } SetEvent(pCom->m_hOutputEvent); //*/ // Close the thread handle because the thread is about to exit. // Other threads may access this thread handle but no other thread // is checking to see when this thread exits so I close the handle here. // These two lines of code are protected by m_hOutputMutex //CloseHandle(pCom->m_hStderrThread); //pCom->m_hStderrThread = NULL; ReleaseMutex(pCom->m_hOutputMutex);}// Function name : SetEnvironmentVariables// Description : // Return type : void // Argument : BSTR bEnvvoid SetEnvironmentVariables(BSTR bEnv){ TCHAR name[MAX_PATH]=_T(""), value[MAX_PATH]=_T(""); WCHAR wName[MAX_PATH]=L"", wValue[MAX_PATH]=L""; WCHAR *pChar; pChar = wName; while (*bEnv != L'\0') { if (*bEnv == L'=') { *pChar = L'\0'; pChar = wValue; } else if (*bEnv == L'|') { *pChar = L'\0'; pChar = wName;#ifdef UNICODE wcscpy(name, wName); wcscpy(value, wValue);#else wcstombs(name, wName, wcslen(wName)+1); wcstombs(value, wValue, wcslen(wValue)+1);#endif SetEnvironmentVariable(name, value); } else { *pChar = *bEnv; pChar++; } bEnv++; } *pChar = L'\0';#ifdef UNICODE wcscpy(name, wName); wcscpy(value, wValue);#else wcstombs(name, wName, wcslen(wName)+1); wcstombs(value, wValue, wcslen(wValue)+1);#endif //LogWMsg(L"name: '%s', value: '%s'\n", wName, wValue); SetEnvironmentVariable(name, value);}// Function name : RemoveEnvironmentVariables// Description : // Return type : void // Argument : BSTR bEnvvoid RemoveEnvironmentVariables(BSTR bEnv){ TCHAR name[MAX_PATH]=_T(""); WCHAR wName[MAX_PATH]=L"", wValue[MAX_PATH]=L""; WCHAR *pChar; pChar = wName; while (*bEnv != L'\0') { if (*bEnv == L'=') { *pChar = L'\0'; pChar = wValue; } else if (*bEnv == L'|') { *pChar = L'\0'; pChar = wName;#ifdef UNICODE wcscpy(name, wName);#else wcstombs(name, wName, wcslen(wName)+1);#endif SetEnvironmentVariable(name, NULL); } else { *pChar = *bEnv; pChar++; } bEnv++; } *pChar = L'\0';#ifdef UNICODE wcscpy(name, wName);#else wcstombs(name, wName, wcslen(wName)+1);#endif SetEnvironmentVariable(name, NULL);}// Function name : ParseAccountDomain// Description : // Return type : void // Argument : LPCWSTR bAccount// Argument : LPTSTR tAccount// Argument : LPTSTR tDomainvoid ParseAccountDomain(LPCWSTR bAccount, LPTSTR tAccount, LPTSTR tDomain){ WCHAR wAccount[100]=L"", wDomain[100]=L"", *pwCh2; LPCWSTR pwCh; pwCh = bAccount; pwCh2 = wDomain; while ((*pwCh != L'\\') && (*pwCh != L'\0')) { *pwCh2 = *pwCh; pwCh++; pwCh2++; } if (*pwCh == L'\\') { pwCh++; wcscpy(wAccount, pwCh); *pwCh2 = L'\0'; } else { wcscpy(wAccount, bAccount); wDomain[0] = L'\0'; }#ifdef UNICODE wcscpy(tAccount, wAccount); wcscpy(tDomain, wDomain);#else wcstombs(tAccount, wAccount, wcslen(wAccount)+1); wcstombs(tDomain, wDomain, wcslen(wDomain)+1);#endif}// Function name : ParseAccountDomainW// Description : // Return type : void // Argument : LPCWSTR bAccount// Argument : LPWSTR wAccount// Argument : LPWSTR wDomainvoid ParseAccountDomainW(LPCWSTR bAccount, LPWSTR wAccount, LPWSTR wDomain){ WCHAR *pwCh2; LPCWSTR pwCh; wAccount[0] = L'\0'; wDomain[0] = L'\0'; pwCh = bAccount; pwCh2 = wDomain; while ((*pwCh != L'\\') && (*pwCh != L'\0')) { *pwCh2 = *pwCh; pwCh++; pwCh2++; } if (*pwCh == L'\\') { pwCh++; wcscpy(wAccount, pwCh); *pwCh2 = L'\0'; } else { wcscpy(wAccount, bAccount); wDomain[0] = L'\0'; }}// Function name : CRemoteShell::LaunchProcess// Description : // Return type : STDMETHODIMP // Argument : BSTR bCmdLine// Argument : BSTR bEnv// Argument : BSTR bDir// Argument : BSTR bAccount// Argument : BSTR bPassword// Argument : long *nPid// Argument : long *nError// Argument : BSTR *bErrorMsgSTDMETHODIMP CRemoteShell::LaunchProcess(BSTR bCmdLine, BSTR bEnv, BSTR bDir, BSTR bAccount, BSTR bPassword, long *nPid, long *nError, BSTR *bErrorMsg){ WCHAR error_msg[256]; BOOL bSuccess = FALSE; HANDLE hStdin, hStdout, hStderr; HANDLE hStdoutPipeW=NULL, hStderrPipeW = NULL, hStdinPipeR=NULL; HANDLE hTempPipe=NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -