Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1720 lines
43 KiB

  1. #include "stdafx.h"
  2. #include "svcobjdef.h"
  3. #include "dbghelp.h"
  4. #include "Processes.h"
  5. #include "Notify.h"
  6. #include "resource.h"
  7. CEMSessionThread::CEMSessionThread
  8. (
  9. IN PEmObject pEmObj
  10. )
  11. {
  12. ATLTRACE(_T("CEMSessionThread::CEMSessionThread\n"));
  13. m_pEmSessObj = pEmObj;
  14. eDBGSessType = SessType_Automatic;
  15. m_pDBGClient = NULL;
  16. m_pDBGControl = NULL;
  17. m_pDBGSymbols = NULL;
  18. m_pASTManager = &(_Module.m_SessionManager);
  19. m_hEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
  20. m_hCDBStarted = CreateEvent ( NULL, FALSE, FALSE, NULL );
  21. //// - InitAutomaticSession..
  22. m_bRecursive = FALSE;
  23. m_bstrEcxFilePath = NULL;
  24. m_bstrNotificationString = NULL;
  25. m_bstrAltSymPath = NULL;
  26. m_bGenerateMiniDump = FALSE;
  27. m_bGenerateUserDump = FALSE;
  28. //// - InitManualSession..
  29. m_bstrUserName = NULL;
  30. m_bstrPassword = NULL;
  31. m_nPort = 0;
  32. m_bBlockIncomingIPConnections = FALSE;
  33. m_bContinueSession = TRUE;
  34. m_pEcxFile = NULL;
  35. ZeroMemory(&m_sp, sizeof(m_sp));
  36. ZeroMemory(&m_pi, sizeof(m_pi));
  37. };
  38. CEMSessionThread::~CEMSessionThread(){
  39. ATLTRACE(_T("CEMSessionThread::~CEMSessionThread\n"));
  40. if(m_bstrUserName) SysFreeString(m_bstrUserName);
  41. if(m_bstrPassword) SysFreeString(m_bstrPassword);
  42. if(m_pDBGClient) m_pDBGClient->Release();
  43. if(m_pDBGControl) m_pDBGControl->Release();
  44. if(m_pDBGSymbols) m_pDBGSymbols->Release();
  45. if(m_bstrEcxFilePath) ::SysFreeString(m_bstrEcxFilePath);
  46. if(m_bstrNotificationString) ::SysFreeString(m_bstrNotificationString );
  47. if(m_bstrAltSymPath) ::SysFreeString(m_bstrAltSymPath);
  48. CloseHandle( m_hEvent );
  49. CloseHandle( m_hCDBStarted );
  50. };
  51. DWORD
  52. CEMSessionThread::Run ( void )
  53. {
  54. ATLTRACE(_T("CEMSessionThread::Run\n"));
  55. TCHAR szConnectString[_MAX_PATH] = _T("");
  56. char *szClientConnectString = NULL;
  57. DWORD dwLastRet = -1L;
  58. HRESULT hr = E_FAIL,
  59. hrActual = E_FAIL;
  60. EmSessionStatus nStatus = STAT_SESS_NONE_STAT_NONE;
  61. UINT nPid = 0;
  62. EmObject EmObj;
  63. PEMSession pEmSess = NULL;
  64. do
  65. {
  66. do
  67. {
  68. if( m_pEmSessObj->type == EMOBJ_SERVICE ) {
  69. if( (m_pEmSessObj->nStatus == STAT_SESS_NOT_STARTED_NOTRUNNING) ||
  70. (m_pEmSessObj->nStatus & STAT_SESS_STOPPED) ) {
  71. hr = S_OK;
  72. do {
  73. dwLastRet = StartServiceAndGetPid( m_pEmSessObj->szSecName, &nPid );
  74. if( dwLastRet != ERROR_SERVICE_ALREADY_RUNNING ) {
  75. hr = HRESULT_FROM_WIN32(dwLastRet);
  76. break;
  77. }
  78. }
  79. while ( false );
  80. FAILEDHR_BREAK(hr);
  81. hr = m_pASTManager->GetSession( m_pEmSessObj->guidstream, &pEmSess );
  82. FAILEDHR_BREAK(hr);
  83. memcpy((void *)&EmObj, (void *) pEmSess->pEmObj, sizeof EmObject);
  84. EmObj.nStatus = STAT_SESS_NOT_STARTED_RUNNING;
  85. EmObj.nId = nPid;
  86. EmObj.hr = S_OK;
  87. hr = m_pASTManager->UpdateSessObject( EmObj.guidstream, &EmObj );
  88. FAILEDHR_BREAK(hr);
  89. }
  90. }
  91. //
  92. // Get server connection string and start CDB server
  93. // Ex: -server tcp:port=XXX -p YYY
  94. // -server npipe:pipe=EM_YYY -p YYY
  95. //
  96. hr = GetServerConnectString( szConnectString, _MAX_PATH );
  97. if( FAILED(hr) ) {
  98. hrActual = hr;
  99. nStatus = STAT_SESS_STOPPED_FAILED;
  100. break;
  101. }
  102. hr = StartCDBServer( szConnectString );
  103. // Indicates that the CDB server got started or failed..
  104. SetEvent(m_hCDBStarted);
  105. if( FAILED(hr) ) {
  106. hrActual = hr;
  107. hr = EMERROR_CDBSERVERSTARTFAILED;
  108. nStatus = STAT_SESS_STOPPED_FAILED;
  109. break;
  110. }
  111. #ifdef _DEBUG
  112. m_pASTManager->SetSessionStatus(
  113. m_pEmSessObj->guidstream,
  114. STAT_SESS_DEBUG_IN_PROGRESS_NONE,
  115. S_OK,
  116. L"StartCDBServer Successful"
  117. );
  118. #else
  119. m_pASTManager->SetSessionStatus(
  120. m_pEmSessObj->guidstream,
  121. STAT_SESS_DEBUG_IN_PROGRESS_NONE,
  122. S_OK,
  123. NULL
  124. );
  125. #endif
  126. //
  127. // Get client connection string and start monitoring
  128. // Ex: -remote tcp:server=ABCD,port=XXX
  129. // -remote npipe:server=ABCD,pipe=EM_YYY
  130. //
  131. hr = GetClientConnectString( szConnectString, _MAX_PATH );
  132. if( FAILED(hr) ) {
  133. hrActual = hr;
  134. hr = EMERROR_CDBSERVERSTARTFAILED;
  135. nStatus = STAT_SESS_STOPPED_FAILED;
  136. break;
  137. }
  138. size_t Len = wcstombs( NULL, szConnectString, 0 );
  139. szClientConnectString = (char *)calloc(Len+1, sizeof(char));
  140. _ASSERTE( szClientConnectString != NULL );
  141. if( szClientConnectString == NULL ) {
  142. hr = HRESULT_FROM_WIN32( GetLastError() );
  143. hrActual = hr;
  144. hr = EMERROR_CDBSERVERSTARTFAILED;
  145. nStatus = STAT_SESS_STOPPED_FAILED;
  146. break;
  147. }
  148. wcstombs( szClientConnectString, szConnectString, Len );
  149. if( eDBGSessType == SessType_Automatic ){
  150. StartAutomaticExcepMonitoring( szClientConnectString );
  151. }
  152. else{
  153. //
  154. // Need info..
  155. //
  156. StartAutomaticExcepMonitoring( szClientConnectString );
  157. // StartManualExcepMonitoring( szClientConnectString );
  158. }
  159. hr = S_OK;
  160. }
  161. while ( m_bRecursive && m_bContinueSession ); // Need to put in a way of stopping the session.
  162. }
  163. while( false );
  164. if(FAILED(hr)) {
  165. #ifdef _DEBUG
  166. m_pASTManager->SetSessionStatus(
  167. m_pEmSessObj->guidstream,
  168. STAT_SESS_STOPPED_FAILED,
  169. hrActual,
  170. L"CEMSessionThread::Run - Failed",
  171. true,
  172. true
  173. );
  174. #else
  175. m_pASTManager->SetSessionStatus(
  176. m_pEmSessObj->guidstream,
  177. STAT_SESS_STOPPED_FAILED,
  178. hrActual,
  179. NULL,
  180. true,
  181. true
  182. );
  183. #endif
  184. StopServer();
  185. }
  186. if( szClientConnectString != NULL ){
  187. free(szClientConnectString);
  188. }
  189. return hr;
  190. }
  191. HRESULT
  192. CEMSessionThread::StartAutomaticExcepMonitoring( char *pszConnectString )
  193. {
  194. ATLTRACE(_T("CEMSessionThread::StartAutomaticExcepMonitoring\n"));
  195. HRESULT hr = E_FAIL,
  196. hrActual = E_FAIL;
  197. TCHAR szUniqueFileName[_MAX_PATH+1] = _T("");
  198. char szLogFile[_MAX_PATH+1] = "";
  199. TCHAR szLogDir[_MAX_PATH+1] = _T("");
  200. char szEcxFile[_MAX_PATH+1] = "";
  201. TCHAR szEcxDir[_MAX_PATH+1] = _T("");
  202. bool bStop = FALSE;
  203. char szCmd[_MAX_PATH+1] = "";
  204. TCHAR szFileExt[_MAX_EXT+1] = _T("");
  205. DWORD dwBufSize = _MAX_PATH;
  206. char szAltSymPath[_MAX_PATH+1] = "";
  207. EmSessionStatus nStatus = STAT_SESS_NONE_STAT_NONE;
  208. bstr_t bstrStatus;
  209. do
  210. {
  211. _ASSERTE(m_bstrEcxFilePath != NULL);
  212. _Module.GetEmDirectory( EMOBJ_CMDSET, szEcxDir, dwBufSize, NULL, NULL );
  213. _stprintf(szEcxDir, _T("%s\\%s"), szEcxDir, m_bstrEcxFilePath);
  214. wcstombs( szEcxFile, szEcxDir, dwBufSize );
  215. dwBufSize = _MAX_PATH;
  216. _Module.GetEmDirectory( EMOBJ_LOGFILE, szLogDir, dwBufSize, szFileExt, _MAX_EXT );
  217. CreateDirectory( szLogDir, NULL );
  218. GetUniqueFileName( m_pEmSessObj,
  219. szUniqueFileName,
  220. _T(""),
  221. szFileExt,
  222. false
  223. );
  224. _stprintf(szLogDir, _T("%s\\%s"), szLogDir, szUniqueFileName);
  225. wcstombs( szLogFile, szLogDir, dwBufSize );
  226. hr = DebugConnect(
  227. pszConnectString,
  228. IID_IDebugClient,
  229. (void **)&m_pDBGClient
  230. );
  231. if( FAILED(hr) ) {
  232. hrActual = hr;
  233. hr = EMERROR_CONNECTIONTOSERVERFAILED;
  234. nStatus = STAT_SESS_STOPPED_FAILED;
  235. bstrStatus = L"DebugConnect failed";
  236. break;
  237. }
  238. #ifdef _DEBUG
  239. m_pASTManager->SetSessionStatus(
  240. m_pEmSessObj->guidstream,
  241. STAT_SESS_DEBUG_IN_PROGRESS_NONE,
  242. hr,
  243. L"DebugConnect Succeeded.."
  244. );
  245. #else
  246. m_pASTManager->SetSessionStatus(
  247. m_pEmSessObj->guidstream,
  248. STAT_SESS_DEBUG_IN_PROGRESS_NONE,
  249. hr,
  250. NULL
  251. );
  252. #endif
  253. hr = m_pDBGClient->QueryInterface(
  254. IID_IDebugControl,
  255. (void **)&m_pDBGControl
  256. );
  257. if( FAILED(hr) ) {
  258. nStatus = STAT_SESS_STOPPED_FAILED;
  259. bstrStatus = L"IDbgClient::QIFace ( IDbgControl ) failed";
  260. break;
  261. }
  262. hr = m_pDBGClient->QueryInterface(
  263. IID_IDebugSymbols,
  264. (void **)&m_pDBGSymbols
  265. );
  266. if( FAILED(hr) ) {
  267. nStatus = STAT_SESS_STOPPED_FAILED;
  268. bstrStatus = L"IDbgClient::QIFace ( IDebugSymbols ) failed";
  269. break;
  270. }
  271. wcstombs( szAltSymPath, m_bstrAltSymPath, dwBufSize );
  272. if( strcmp( szAltSymPath, "" ) != 0 ) {
  273. hr = m_pDBGSymbols->SetSymbolPath(szAltSymPath);
  274. if( FAILED(hr) ) {
  275. hrActual = hr;
  276. hr = EMERROR_ALTSYMPATHFAILED;
  277. nStatus = STAT_SESS_STOPPED_FAILED;
  278. bstrStatus = L"Alternate symbol path could not be set";
  279. break;
  280. }
  281. }
  282. if( eDBGSessType == SessType_Automatic ) {
  283. hr = m_pDBGControl->OpenLogFile(szLogFile, FALSE);
  284. if( FAILED(hr) ) {
  285. hrActual = hr;
  286. hr = EMERROR_UNABLETOCREATELOGFILE;
  287. nStatus = STAT_SESS_STOPPED_FAILED;
  288. bstrStatus = L"Open log file failed";
  289. break;
  290. }
  291. }
  292. /*
  293. hr = m_pDBGControl->ExecuteCommandFile(
  294. DEBUG_OUTCTL_LOG_ONLY,
  295. szEcxFile,
  296. DEBUG_EXECUTE_DEFAULT
  297. );
  298. if( FAILED(hr) ) {
  299. hrActual = hr;
  300. hr = EMERROR_ECXFILEEXECUTIONFAILED;
  301. nStatus = STAT_SESS_STOPPED_FAILED;
  302. bstrStatus = L"ExecCommandFile failed";
  303. break;
  304. }
  305. */
  306. m_EventCallbacks.m_pEMThread = this;
  307. hr = m_pDBGClient->SetEventCallbacks(&m_EventCallbacks);
  308. if( FAILED(hr) ) {
  309. hrActual = hr;
  310. hr = EMERROR_CALLBACKSCANNOTBEREGISTERED;
  311. nStatus = STAT_SESS_STOPPED_FAILED;
  312. bstrStatus = L"SetEventCallback failed";
  313. break;
  314. }
  315. ULONG ExecStatus = DEBUG_STATUS_BREAK;
  316. if( _tcscmp( m_bstrEcxFilePath, _T("") ) != 0 ) {
  317. m_pEcxFile = fopen(szEcxFile, "r");
  318. if( m_pEcxFile == NULL ) {
  319. hr = HRESULT_FROM_WIN32(GetLastError());
  320. hrActual = hr;
  321. hr = EMERROR_ECXFILEOPENFAILED;
  322. nStatus = STAT_SESS_STOPPED_FAILED;
  323. bstrStatus = L"fopen failed";
  324. break;
  325. }
  326. hr = ExecuteCommandsTillGo(NULL);
  327. }
  328. do
  329. {
  330. hr = KeepDebuggeeRunning();
  331. if( FAILED(hr) ) {
  332. nStatus = STAT_SESS_STOPPED_FAILED;
  333. bstrStatus = L"KeepDebugeeRunning failed";
  334. break;
  335. }
  336. hr = CanContinue();
  337. if( FAILED(hr) ) {
  338. nStatus = STAT_SESS_STOPPED_FAILED;
  339. bstrStatus = L"Can Continue() failed";
  340. break;
  341. }
  342. hr = m_pDBGClient->DispatchCallbacks(INFINITE); // Milli Secs..
  343. if( FAILED(hr) ) {
  344. hrActual = hr;
  345. hr = EMERROR_DISPATCHCALLBACKFAILED;
  346. nStatus = STAT_SESS_STOPPED_FAILED;
  347. bstrStatus = L"DispatchCallbacks failed";
  348. break;
  349. }
  350. //
  351. // Is this call required???
  352. //
  353. hr = CanContinue();
  354. if( hr != S_OK )
  355. {
  356. bstrStatus = L"CanContinue hr != S_OK";
  357. break;
  358. }
  359. hr = BreakIn();
  360. if( FAILED(hr) ) {
  361. bstrStatus = L"BreakIn";
  362. nStatus = STAT_SESS_STOPPED_FAILED;
  363. break;
  364. }
  365. if( strcmp( szEcxFile, "" ) != 0 ) {
  366. ExecuteCommandsTillGo(NULL);
  367. }
  368. if( eDBGServie == DBGService_HandleException ) {
  369. break;
  370. }
  371. dwBufSize = _MAX_PATH;
  372. hr = GetCmd( eDBGServie, szCmd, dwBufSize );
  373. if( FAILED(hr) ) {
  374. nStatus = STAT_SESS_STOPPED_FAILED;
  375. bstrStatus = L"GetCmd failed";
  376. break;
  377. }
  378. /*
  379. hr = BreakIn();
  380. if( FAILED(hr) ) {
  381. bstrStatus = L"BreakIn";
  382. nStatus = STAT_SESS_STOPPED_FAILED;
  383. break;
  384. }
  385. */ if( strcmp( szCmd, "q" ) == 0 ){
  386. if( eDBGSessType == SessType_Automatic ) {
  387. hr = m_pDBGControl->CloseLogFile();
  388. if( FAILED(hr) ) {
  389. bstrStatus = L"CloseLogFile";
  390. nStatus = STAT_SESS_STOPPED_FAILED;
  391. break;
  392. }
  393. }
  394. hr = m_pDBGControl->Execute( DEBUG_OUTCTL_ALL_CLIENTS,
  395. szCmd,
  396. DEBUG_EXECUTE_DEFAULT
  397. );
  398. // hr = m_pDBGControl->WaitForEvent(DEBUG_WAIT_DEFAULT, INFINITE);
  399. // hr = m_pDBGClient->EndSession(DEBUG_END_ACTIVE_TERMINATE);
  400. SetEvent( m_hEvent );
  401. break;
  402. }
  403. if( strcmp( szCmd, "qd" ) == 0 ) {
  404. if( eDBGSessType == SessType_Automatic ) {
  405. hr = m_pDBGControl->CloseLogFile();
  406. if( FAILED(hr) ) {
  407. bstrStatus = L"CloseLogFile";
  408. nStatus = STAT_SESS_STOPPED_FAILED;
  409. break;
  410. }
  411. }
  412. hr = m_pDBGControl->Execute( DEBUG_OUTCTL_ALL_CLIENTS,
  413. szCmd,
  414. DEBUG_EXECUTE_DEFAULT
  415. );
  416. /*
  417. hr = m_pDBGClient->DetachProcesses();
  418. */
  419. SetEvent( m_hEvent );
  420. break;
  421. }
  422. hr = m_pDBGControl->Execute( DEBUG_OUTCTL_ALL_CLIENTS,
  423. szCmd,
  424. DEBUG_EXECUTE_DEFAULT
  425. );
  426. if( FAILED(hr) ) {
  427. bstrStatus = L"DbgControl::Execute failed";
  428. nStatus = STAT_SESS_STOPPED_FAILED;
  429. break;
  430. }
  431. Sleep(2000);
  432. hr = m_pDBGControl->GetExecutionStatus(&ExecStatus);
  433. if( FAILED(hr) ) {
  434. bstrStatus = L"GetExecutionStatus";
  435. nStatus = STAT_SESS_STOPPED_FAILED;
  436. break;
  437. }
  438. }
  439. // Will have to terminate if either no deubuggee or
  440. // stop is requested..
  441. while( CanContinue() == S_OK );
  442. hr = m_pDBGControl->GetExecutionStatus(&ExecStatus);
  443. if( FAILED(hr) ) {
  444. bstrStatus = L"DbgControl::GetExecutionStatus failed";
  445. nStatus = STAT_SESS_STOPPED_FAILED;
  446. break;
  447. }
  448. if(ExecStatus != DEBUG_STATUS_NO_DEBUGGEE)
  449. {
  450. if( eDBGSessType == SessType_Automatic ) {
  451. m_pDBGControl->CloseLogFile();
  452. }
  453. m_pDBGClient->EndSession(DEBUG_END_PASSIVE);
  454. }
  455. }
  456. while(FALSE);
  457. if(FAILED(hr)) {
  458. #ifdef _DEBUG
  459. m_pASTManager->SetSessionStatus(
  460. m_pEmSessObj->guidstream,
  461. STAT_SESS_STOPPED_FAILED,
  462. hr,
  463. bstrStatus,
  464. true,
  465. true
  466. );
  467. #else
  468. m_pASTManager->SetSessionStatus(
  469. m_pEmSessObj->guidstream,
  470. STAT_SESS_STOPPED_FAILED,
  471. hr,
  472. NULL,
  473. true,
  474. true
  475. );
  476. #endif
  477. }
  478. //
  479. // When we are here, the debug session is guarenteed to be stopped.
  480. //
  481. {
  482. EmObject EmObj;
  483. EmObj.dateEnd = CServiceModule::GetCurrentTime();
  484. m_pASTManager->UpdateSessObject( m_pEmSessObj->guidstream,
  485. EMOBJ_FLD_DATEEND,
  486. &EmObj
  487. );
  488. }
  489. if( m_pEcxFile ) { fclose( m_pEcxFile ); m_pEcxFile = NULL; }
  490. StopServer();
  491. return hr;
  492. }
  493. HRESULT
  494. CEMSessionThread::StartManualExcepMonitoring( char *pszConnectString )
  495. {
  496. ATLTRACE(_T("CEMSessionThread::StartManualExcepMonitoring\n"));
  497. HRESULT hr = E_FAIL,
  498. hrActual = E_FAIL;
  499. char szLogFile[_MAX_PATH+1] = "";
  500. TCHAR szLogDir[_MAX_PATH+1] = _T("");
  501. char szEcxFile[_MAX_PATH+1] = "";
  502. TCHAR szEcxDir[_MAX_PATH+1] = _T("");
  503. bool bStop = FALSE;
  504. char szCmd[_MAX_PATH+1] = "";
  505. DWORD dwBufSize = _MAX_PATH;
  506. EmSessionStatus nStatus = STAT_SESS_NONE_STAT_NONE;
  507. bstr_t bstrStatus;
  508. do
  509. {
  510. _ASSERTE(m_bstrEcxFilePath != NULL);
  511. _Module.GetEmDirectory( EMOBJ_CMDSET, szEcxDir, dwBufSize, NULL, NULL );
  512. _stprintf(szEcxDir, _T("%s\\%s"), szEcxDir, m_bstrEcxFilePath);
  513. wcstombs( szEcxFile, szEcxDir, dwBufSize );
  514. dwBufSize = _MAX_PATH;
  515. _Module.GetEmDirectory( EMOBJ_LOGFILE, szLogDir, dwBufSize, NULL, NULL );
  516. _stprintf(szLogDir, _T("%s\\%s"), szLogDir, _T("EmLog.Dbl"));
  517. wcstombs( szLogFile, szLogDir, dwBufSize );
  518. hr = DebugConnect(
  519. pszConnectString,
  520. IID_IDebugClient,
  521. (void **)&m_pDBGClient
  522. );
  523. if( FAILED(hr) ) {
  524. hrActual = hr;
  525. hr = EMERROR_CONNECTIONTOSERVERFAILED;
  526. nStatus = STAT_SESS_STOPPED_FAILED;
  527. bstrStatus = L"DebugConnect failed";
  528. break;
  529. }
  530. #ifdef _DEBUG
  531. m_pASTManager->SetSessionStatus(
  532. m_pEmSessObj->guidstream,
  533. STAT_SESS_DEBUG_IN_PROGRESS_NONE,
  534. hr,
  535. L"DebugConnect Succeeded.."
  536. );
  537. #else
  538. m_pASTManager->SetSessionStatus(
  539. m_pEmSessObj->guidstream,
  540. STAT_SESS_DEBUG_IN_PROGRESS_NONE,
  541. hr,
  542. NULL
  543. );
  544. #endif
  545. hr = m_pDBGClient->QueryInterface(
  546. IID_IDebugControl,
  547. (void **)&m_pDBGControl
  548. );
  549. if( FAILED(hr) ) {
  550. nStatus = STAT_SESS_STOPPED_FAILED;
  551. bstrStatus = L"IDbgClient::QIFace ( IDbgControl ) failed";
  552. break;
  553. }
  554. hr = m_pDBGControl->OpenLogFile(szLogFile, FALSE);
  555. if( FAILED(hr) ) {
  556. hrActual = hr;
  557. hr = EMERROR_UNABLETOCREATELOGFILE;
  558. nStatus = STAT_SESS_STOPPED_FAILED;
  559. bstrStatus = L"Open log file failed";
  560. break;
  561. }
  562. hr = m_pDBGControl->ExecuteCommandFile(
  563. DEBUG_OUTCTL_LOG_ONLY,
  564. szEcxFile,
  565. DEBUG_EXECUTE_DEFAULT
  566. );
  567. if( FAILED(hr) ) {
  568. hrActual = hr;
  569. hr = EMERROR_ECXFILEEXECUTIONFAILED;
  570. nStatus = STAT_SESS_STOPPED_FAILED;
  571. bstrStatus = L"ExecCommandFile failed";
  572. break;
  573. }
  574. m_EventCallbacks.m_pEMThread = this;
  575. hr = m_pDBGClient->SetEventCallbacks(&m_EventCallbacks);
  576. if( FAILED(hr) ) {
  577. hrActual = hr;
  578. hr = EMERROR_CALLBACKSCANNOTBEREGISTERED;
  579. nStatus = STAT_SESS_STOPPED_FAILED;
  580. bstrStatus = L"SetEventCallback failed";
  581. break;
  582. }
  583. ULONG ExecStatus = DEBUG_STATUS_BREAK;
  584. // m_pDBGClient->ConnectSession(DEBUG_CONNECT_SESSION_DEFAULT);
  585. while( true ) {
  586. hr = m_pDBGClient->DispatchCallbacks(INFINITE); // Milli Secs..
  587. FAILEDHR_BREAK(hr); //DispatchCallbacks return S_FALSE if timeout expires
  588. }
  589. hr = S_OK;
  590. }
  591. while(FALSE);
  592. #ifdef _DEBUG
  593. m_pASTManager->SetSessionStatus(
  594. m_pEmSessObj->guidstream,
  595. STAT_SESS_STOPPED_SUCCESS,
  596. hr,
  597. bstrStatus
  598. );
  599. #else
  600. m_pASTManager->SetSessionStatus(
  601. m_pEmSessObj->guidstream,
  602. STAT_SESS_STOPPED_SUCCESS,
  603. hr,
  604. NULL
  605. );
  606. #endif
  607. return hr;
  608. }
  609. HRESULT
  610. CEMSessionThread::StartCDBServer
  611. (
  612. IN LPTSTR lpszConnectString
  613. )
  614. {
  615. ATLTRACE(_T("CEMSessionThread::StartCDBServer\n"));
  616. TCHAR szCdbDir[_MAX_PATH+1] = _T("");
  617. ULONG ccCdbDir = _MAX_PATH;
  618. HRESULT hr = E_FAIL;
  619. ccCdbDir = _MAX_DIR;
  620. hr = _Module.GetCDBInstallDir( szCdbDir, &ccCdbDir );
  621. if( FAILED(hr) ) return hr;
  622. _tcsncat( szCdbDir, _T("\\cdb.exe"), _MAX_DIR );
  623. BOOL bCdbCreated = CreateProcess(// This has to be obtained from the registry...
  624. szCdbDir,
  625. lpszConnectString,
  626. NULL,
  627. NULL,
  628. FALSE,
  629. CREATE_NEW_PROCESS_GROUP | CREATE_NEW_CONSOLE,
  630. NULL,
  631. NULL,
  632. &m_sp,
  633. &m_pi
  634. );
  635. if(bCdbCreated == FALSE){
  636. return HRESULT_FROM_WIN32(GetLastError());
  637. }
  638. //
  639. // Wait till CDB does some initializations..
  640. // Don't know how long to wait.. have to figure out a way..
  641. //
  642. Sleep(2000);
  643. return S_OK;
  644. }
  645. HRESULT
  646. CEMSessionThread::GetClientConnectString
  647. (
  648. IN OUT LPTSTR pszConnectString,
  649. IN DWORD dwBuffSize
  650. )
  651. {
  652. ATLTRACE(_T("CEMSessionThread::GetClientConnectString\n"));
  653. _ASSERTE(pszConnectString != NULL);
  654. _ASSERTE(dwBuffSize > 0L);
  655. HRESULT hr = E_FAIL;
  656. DWORD dwBuff = MAX_COMPUTERNAME_LENGTH;
  657. TCHAR szCompName[MAX_COMPUTERNAME_LENGTH + 1];
  658. do
  659. {
  660. if( pszConnectString == NULL ||
  661. dwBuffSize <= 0L ) break;
  662. if(GetComputerName(szCompName, &dwBuff) == FALSE){
  663. HRESULT_FROM_WIN32(GetLastError());
  664. break;
  665. }
  666. if( m_nPort != 0 ){
  667. _stprintf(pszConnectString, _T("tcp:server=%s,port=%d"), szCompName, m_nPort);
  668. }
  669. else {
  670. _stprintf(pszConnectString, _T("npipe:server=%s,pipe=EM_%d"), szCompName, m_pEmSessObj->nId);
  671. }
  672. hr = S_OK;
  673. }
  674. while( false );
  675. return hr;
  676. }
  677. HRESULT
  678. CEMSessionThread::GetServerConnectString
  679. (
  680. IN OUT LPTSTR lpszConnectString,
  681. IN DWORD dwBuffSize
  682. )
  683. {
  684. ATLTRACE(_T("CEMSessionThread::GetServerConnectString\n"));
  685. _ASSERTE(lpszConnectString != NULL);
  686. _ASSERTE(dwBuffSize > 0L);
  687. HRESULT hr = E_FAIL;
  688. do
  689. {
  690. if( lpszConnectString == NULL ||
  691. dwBuffSize <= 0L ) break;
  692. if( m_nPort != 0 ){
  693. _stprintf(lpszConnectString, _T(" -server tcp:port=%d -p %d"), m_nPort, m_pEmSessObj->nId);
  694. }
  695. else {
  696. _stprintf(lpszConnectString, _T(" -server npipe:pipe=EM_%d -p %d"), m_pEmSessObj->nId, m_pEmSessObj->nId);
  697. }
  698. hr = S_OK;
  699. }
  700. while( false );
  701. return hr;
  702. }
  703. typedef BOOL (WINAPI*PFNWR)(
  704. IN HANDLE hProcess,
  705. IN DWORD ProcessId,
  706. IN HANDLE hFile,
  707. IN MINIDUMP_TYPE DumpType,
  708. IN CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, OPTIONAL
  709. IN CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, OPTIONAL
  710. IN CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam OPTIONAL
  711. );
  712. HRESULT
  713. CEMSessionThread::CreateDumpFile( BOOL bMiniDump )
  714. {
  715. ATLTRACE(_T("CEMSessionThread::CreateDumpFile\n"));
  716. HRESULT hr = E_FAIL;
  717. HANDLE hDumpFile = INVALID_HANDLE_VALUE,
  718. hProcess = NULL;
  719. HMODULE hDbgHelp = NULL;
  720. LONG lStatus = 0L;
  721. TCHAR szDumpFile[_MAX_PATH + 1] = _T(""); // a-kjaw, bug ID: 296024/25
  722. DWORD dwBufSize = _MAX_PATH;
  723. TCHAR szCmd[_MAX_PATH + 1] = _T(""); // a-kjaw, bug ID: 296026
  724. DWORD dwLastErr = 0L;
  725. TCHAR szFileExt[_MAX_EXT + 1] = _T("");
  726. LPCTSTR lpszDbgHelpDll = _T("\\dbghelp.dll"),
  727. lpszUserDumpExe = _T("\\userdump.exe");
  728. do
  729. {
  730. hr = m_pASTManager->GetSessionStatus( m_pEmSessObj->guidstream, &lStatus );
  731. FAILEDHR_BREAK(hr);
  732. //
  733. // We cannot generate dump files if the debuggee has stopped..
  734. //
  735. if( lStatus & STAT_SESS_STOPPED ) {
  736. hr = EMERROR_INVALIDPROCESS;
  737. break;
  738. }
  739. if( bMiniDump ){
  740. _Module.GetEmDirectory( EMOBJ_MINIDUMP, szCmd, dwBufSize, szFileExt, _MAX_EXT );
  741. CreateDirectory( szCmd, NULL );
  742. GetUniqueFileName (
  743. m_pEmSessObj,
  744. szDumpFile,
  745. _T("mini"),
  746. szFileExt,
  747. false
  748. );
  749. _tcscat( szCmd, _T("\\"));
  750. _tcscat( szCmd, szDumpFile);
  751. hDumpFile = CreateFile( szCmd,
  752. GENERIC_ALL,
  753. 0,
  754. NULL, // sa
  755. CREATE_ALWAYS,
  756. FILE_ATTRIBUTE_NORMAL,
  757. NULL
  758. );
  759. if( hDumpFile == INVALID_HANDLE_VALUE ) {
  760. dwLastErr = GetLastError();
  761. hr = HRESULT_FROM_WIN32(dwLastErr);
  762. break;
  763. }
  764. dwBufSize = _MAX_DIR;
  765. hr = _Module.GetEmInstallDir( szCmd, &dwBufSize );
  766. if( FAILED(hr) ) break;
  767. _tcsncat( szCmd, lpszDbgHelpDll, _MAX_PATH );
  768. hDbgHelp = LoadLibrary(szCmd);
  769. if( hDbgHelp == NULL ) {
  770. hr = HRESULT_FROM_WIN32(GetLastError());
  771. break;
  772. }
  773. PFNWR pFunc = (PFNWR) GetProcAddress(hDbgHelp, "MiniDumpWriteDump");
  774. if(!pFunc) {
  775. hr = E_FAIL;
  776. break;
  777. }
  778. hr = HRESULT_FROM_WIN32(GetProcessHandle(m_pEmSessObj->nId, &hProcess));
  779. FAILEDHR_BREAK(hr);
  780. hr = S_FALSE;
  781. if( pFunc(hProcess, m_pEmSessObj->nId, (HANDLE)hDumpFile,
  782. MiniDumpNormal, NULL, NULL, NULL) ) {
  783. hr = S_OK;
  784. }
  785. }
  786. else{
  787. dwBufSize = _MAX_PATH;
  788. _Module.GetEmDirectory( EMOBJ_USERDUMP, szDumpFile, dwBufSize, szFileExt, _MAX_EXT );
  789. CreateDirectory( szDumpFile, NULL );
  790. _stprintf( szCmd, _T(" %d \"%s\""), m_pEmSessObj->nId, szDumpFile );
  791. GetUniqueFileName (
  792. m_pEmSessObj,
  793. szDumpFile,
  794. _T("user"),
  795. szFileExt,
  796. false
  797. );
  798. _tcscat(szCmd, _T("\\"));
  799. _tcscat(szCmd, szDumpFile);
  800. STARTUPINFO sp;
  801. PROCESS_INFORMATION pi;
  802. ZeroMemory(&sp, sizeof(sp));
  803. ZeroMemory(&pi, sizeof(pi));
  804. dwBufSize = _MAX_DIR;
  805. hr = _Module.GetEmInstallDir( szDumpFile, &dwBufSize );
  806. if( FAILED(hr) ) break;
  807. _tcsncat( szDumpFile, lpszUserDumpExe, _MAX_PATH );
  808. BOOL bRet = CreateProcess(// This has to be obtained from the registry...
  809. szDumpFile,
  810. szCmd,
  811. NULL,
  812. NULL,
  813. FALSE,
  814. CREATE_NO_WINDOW,
  815. NULL,
  816. NULL,
  817. &sp,
  818. &pi
  819. );
  820. WaitForSingleObject( pi.hProcess, INFINITE );
  821. CloseHandle(pi.hProcess);
  822. hr = S_OK;
  823. }
  824. }
  825. while(FALSE);
  826. if(hDumpFile != INVALID_HANDLE_VALUE) {
  827. CloseHandle(hDumpFile);
  828. }
  829. if(hDbgHelp) { FreeLibrary( hDbgHelp ); }
  830. if(hProcess) { CloseHandle( hProcess ); }
  831. if(hr == S_OK){
  832. lStatus |= STAT_FILECREATED_SUCCESSFULLY;
  833. }
  834. else {
  835. lStatus |= STAT_FILECREATION_FAILED;
  836. }
  837. hr = m_pASTManager->SetSessionStatus(
  838. m_pEmSessObj->guidstream,
  839. lStatus,
  840. hr,
  841. NULL
  842. );
  843. return hr;
  844. }
  845. HRESULT
  846. CEMSessionThread::StopDebugging( )
  847. {
  848. ATLTRACE(_T("CEMSessionThread::StopDebugging\n"));
  849. HRESULT hr = S_OK;
  850. IDebugClient *pDBGClntLocal = NULL;
  851. IDebugControl *pDBGCtrlLocal = NULL;
  852. do
  853. {
  854. /*
  855. // We seem to allow manual sessions to be stopped too..
  856. if( eDBGSessType == SessType_Manual ) {
  857. hr = S_OK;
  858. break;
  859. }
  860. */
  861. m_bContinueSession = FALSE;
  862. eDBGServie = DBGService_Stop;
  863. hr = m_pDBGClient->CreateClient(&pDBGClntLocal);
  864. FAILEDHR_BREAK(hr);
  865. hr = pDBGClntLocal->ExitDispatch(m_pDBGClient);
  866. FAILEDHR_BREAK(hr);
  867. WaitForSingleObject( m_hEvent, INFINITE );
  868. #ifdef _DEBUG
  869. hr = m_pASTManager->SetSessionStatus(
  870. m_pEmSessObj->guidstream,
  871. STAT_SESS_STOPPED_SUCCESS,
  872. S_OK,
  873. L"CEMSessionThread::StopDebugging - called"
  874. );
  875. #else
  876. hr = m_pASTManager->SetSessionStatus(
  877. m_pEmSessObj->guidstream,
  878. STAT_SESS_STOPPED_SUCCESS,
  879. S_OK,
  880. NULL
  881. );
  882. #endif
  883. FAILEDHR_BREAK(hr);
  884. }
  885. while(FALSE);
  886. return hr;
  887. }
  888. HRESULT
  889. CEMSessionThread::GetCmd
  890. (
  891. IN eDBGServiceRequested eDBGSvc,
  892. IN OUT char * pszCmdBuff,
  893. IN OUT DWORD &dwBufLen
  894. )
  895. {
  896. ATLTRACE(_T("CEMSessionThread::GetCmd\n"));
  897. HRESULT hr = S_OK;
  898. char szPostDebug[_MAX_PATH] = "C:\\Program Files\\Debuggers\\bin\\em\\config\\PostDebug.ecx";
  899. _ASSERTE( pszCmdBuff != NULL );
  900. _ASSERTE( dwBufLen > 0 );
  901. do
  902. {
  903. if( pszCmdBuff == NULL ||
  904. dwBufLen < 1L ){
  905. hr = E_INVALIDARG;
  906. break;
  907. }
  908. strcpy( pszCmdBuff, "" );
  909. switch( eDBGSvc )
  910. {
  911. case DBGService_Stop:
  912. case DBGService_HandleException:
  913. strncpy( pszCmdBuff, "q", dwBufLen );
  914. break;
  915. case DBGService_Cancel:
  916. strncpy( pszCmdBuff, "qd", dwBufLen ); // QD (Quit and Detach);
  917. break;
  918. case DBGService_CreateMiniDump:
  919. sprintf( pszCmdBuff, ".dump /m d:\\EMMiniDump%d.dmp", m_pEmSessObj->nId );
  920. break;
  921. case DBGService_CreateUserDump:
  922. sprintf( pszCmdBuff, ".dump d:\\EMUserDump%d.dmp", m_pEmSessObj->nId );
  923. break;
  924. case DBGService_Go:
  925. strncpy( pszCmdBuff, "g", dwBufLen );
  926. break;
  927. default:
  928. hr = E_INVALIDARG;
  929. }
  930. }
  931. while( false );
  932. dwBufLen = strlen( pszCmdBuff );
  933. return hr;
  934. }
  935. HRESULT
  936. CEMSessionThread::OnException
  937. (
  938. IN PEXCEPTION_RECORD64 pException
  939. )
  940. {
  941. ATLTRACE(_T("CEMSessionThread::OnException\n"));
  942. HRESULT hr = S_OK;
  943. IDebugClient *pDBGClntLocal = NULL;
  944. DWORD excpcd = pException->ExceptionCode;
  945. TCHAR szTemp[_MAX_PATH+1] = _T("");
  946. TCHAR szDesc[sizeof EmObject+1] = _T("");
  947. do
  948. {
  949. if(excpcd == EXCEPTION_BREAKPOINT){
  950. break;
  951. }
  952. if(m_bGenerateMiniDump) {
  953. hr = CreateDumpFile( TRUE );
  954. FAILEDHR_BREAK(hr);
  955. }
  956. if(m_bGenerateUserDump) {
  957. hr = CreateDumpFile( FALSE );
  958. FAILEDHR_BREAK(hr);
  959. }
  960. if(excpcd == EXCEPTION_ACCESS_VIOLATION){
  961. #ifdef _DEBUG
  962. m_pASTManager->SetSessionStatus(m_pEmSessObj->guidstream, STAT_SESS_STOPPED_ACCESSVIOLATION_OCCURED, S_OK, L"OnException - AV");
  963. #else
  964. m_pASTManager->SetSessionStatus(m_pEmSessObj->guidstream, STAT_SESS_STOPPED_ACCESSVIOLATION_OCCURED, S_OK, NULL);
  965. #endif
  966. ::LoadString(_Module.GetResourceInstance(), IDS_DEBUGGEE_ACCESSVIOLATION, szTemp, _MAX_PATH);
  967. GetDescriptionFromEmObj(m_pEmSessObj, szDesc, sizeof EmObject, szTemp);
  968. NotifyAdmin(szDesc);
  969. }
  970. else{ // Exception..
  971. #ifdef _DEBUG
  972. m_pASTManager->SetSessionStatus(m_pEmSessObj->guidstream, STAT_SESS_STOPPED_EXCEPTION_OCCURED, S_OK, L"OnException - Exception");
  973. #else
  974. m_pASTManager->SetSessionStatus(m_pEmSessObj->guidstream, STAT_SESS_STOPPED_EXCEPTION_OCCURED, S_OK, NULL);
  975. #endif
  976. ::LoadString(_Module.GetResourceInstance(), IDS_DEBUGGEE_EXCEPTION, szTemp, _MAX_PATH);
  977. GetDescriptionFromEmObj(m_pEmSessObj, szDesc, sizeof EmObject, szTemp);
  978. NotifyAdmin(szDesc);
  979. }
  980. hr = m_pDBGClient->CreateClient(&pDBGClntLocal);
  981. FAILEDHR_BREAK(hr);
  982. hr = pDBGClntLocal->ExitDispatch(m_pDBGClient);
  983. FAILEDHR_BREAK(hr);
  984. }
  985. while(FALSE);
  986. return hr;
  987. }
  988. HRESULT
  989. CEMSessionThread::CanContinue()
  990. {
  991. ATLTRACE(_T("CEMSessionThread::CanContinue\n"));
  992. ULONG ExecStatus = DEBUG_STATUS_BREAK;
  993. HRESULT hr = S_OK;
  994. do
  995. {
  996. hr = m_pDBGControl->GetExecutionStatus(&ExecStatus);
  997. FAILEDHR_BREAK(hr);
  998. //
  999. // We don't have anything to do if the debuggee
  1000. // has exited.
  1001. //
  1002. if( ExecStatus == DEBUG_STATUS_NO_DEBUGGEE ){
  1003. hr = S_FALSE;
  1004. break;
  1005. }
  1006. if( IsStopRequested() == TRUE ){
  1007. hr = S_FALSE;
  1008. break;
  1009. }
  1010. }
  1011. while( false );
  1012. return hr;
  1013. }
  1014. HRESULT
  1015. CEMSessionThread::KeepDebuggeeRunning()
  1016. {
  1017. ATLTRACE(_T("CEMSessionThread::KeepDebuggeeRunning\n"));
  1018. HRESULT hr = E_FAIL;
  1019. ULONG ExecStatus = DEBUG_STATUS_BREAK;
  1020. do
  1021. {
  1022. hr = m_pDBGControl->GetExecutionStatus(&ExecStatus);
  1023. FAILEDHR_BREAK(hr);
  1024. if( ExecStatus != DEBUG_STATUS_BREAK ){
  1025. break;
  1026. }
  1027. hr = BreakIn();
  1028. FAILEDHR_BREAK(hr);
  1029. hr = m_pDBGControl->Execute( DEBUG_OUTCTL_ALL_CLIENTS,
  1030. "g",
  1031. DEBUG_EXECUTE_DEFAULT
  1032. );
  1033. FAILEDHR_BREAK(hr);
  1034. }
  1035. while( false );
  1036. return hr;
  1037. }
  1038. HRESULT
  1039. CEMSessionThread::BreakIn()
  1040. {
  1041. ATLTRACE(_T("CEMSessionThread::BreakIn\n"));
  1042. HRESULT hr = E_FAIL;
  1043. ULONG ExecStatus = DEBUG_STATUS_BREAK;
  1044. do
  1045. {
  1046. hr = m_pDBGControl->GetExecutionStatus(&ExecStatus);
  1047. FAILEDHR_BREAK(hr);
  1048. if( ExecStatus == DEBUG_STATUS_GO ||
  1049. ExecStatus == DEBUG_STATUS_GO_HANDLED ||
  1050. ExecStatus == DEBUG_STATUS_GO_NOT_HANDLED ){
  1051. hr = m_pDBGControl->SetInterrupt(DEBUG_INTERRUPT_ACTIVE);
  1052. FAILEDHR_BREAK(hr);
  1053. //
  1054. // Though SetInterrupt returns immediately, it takes some time
  1055. // for the interrrupt to occur..
  1056. //
  1057. Sleep(2000);
  1058. }
  1059. }
  1060. while( false );
  1061. return hr;
  1062. }
  1063. HRESULT
  1064. CEMSessionThread::OnProcessExit
  1065. (
  1066. IN ULONG nExitCode
  1067. )
  1068. {
  1069. ATLTRACE(_T("CEMSessionThread::OnProcessExit\n"));
  1070. HRESULT hr = S_OK;
  1071. IDebugClient *pDBGClntLocal = NULL;
  1072. IDebugControl *pDBGCtrlLocal = NULL;
  1073. do
  1074. {
  1075. #ifdef _DEBUG
  1076. hr = m_pASTManager->SetSessionStatus(m_pEmSessObj->guidstream, STAT_SESS_STOPPED_DEBUGGEE_EXITED, S_OK, L"OnProcessExit");
  1077. #else
  1078. hr = m_pASTManager->SetSessionStatus(m_pEmSessObj->guidstream, STAT_SESS_STOPPED_DEBUGGEE_EXITED, S_OK, NULL);
  1079. #endif
  1080. FAILEDHR_BREAK(hr);
  1081. hr = m_pDBGClient->CreateClient(&pDBGClntLocal);
  1082. FAILEDHR_BREAK(hr);
  1083. hr = pDBGClntLocal->ExitDispatch(m_pDBGClient);
  1084. FAILEDHR_BREAK(hr);
  1085. }
  1086. while ( false );
  1087. return hr;
  1088. }
  1089. HRESULT
  1090. CEMSessionThread::Execute()
  1091. {
  1092. ATLTRACE(_T("CEMSessionThread::Execute\n"));
  1093. HRESULT hr = E_FAIL;
  1094. do
  1095. {
  1096. hr = m_pDBGControl->Execute( DEBUG_OUTCTL_ALL_CLIENTS,
  1097. "? a;g",
  1098. DEBUG_EXECUTE_DEFAULT
  1099. );
  1100. FAILEDHR_BREAK(hr);
  1101. }
  1102. while ( false );
  1103. return hr;
  1104. }
  1105. HRESULT
  1106. CEMSessionThread::InitAutomaticSession
  1107. (
  1108. IN BOOL bRecursive,
  1109. IN BSTR bstrEcxFilePath,
  1110. IN BSTR bstrNotificationString,
  1111. IN BSTR bstrAltSymPath,
  1112. IN BOOL bGenerateMiniDump,
  1113. IN BOOL bGenerateUserDump
  1114. )
  1115. {
  1116. ATLTRACE(_T("CEMSessionThread::InitAutomaticSession\n"));
  1117. _ASSERTE(bstrEcxFilePath != NULL);
  1118. if(bstrEcxFilePath == NULL) { return E_INVALIDARG; }
  1119. eDBGSessType = SessType_Automatic;
  1120. m_bRecursive = bRecursive;
  1121. m_bstrEcxFilePath = ::SysAllocString(bstrEcxFilePath);
  1122. m_bstrNotificationString = ::SysAllocString(bstrNotificationString);
  1123. m_bstrAltSymPath = ::SysAllocString(bstrAltSymPath);
  1124. m_bGenerateMiniDump = bGenerateMiniDump;
  1125. m_bGenerateUserDump = bGenerateUserDump;
  1126. return S_OK;
  1127. }
  1128. HRESULT
  1129. CEMSessionThread::InitManualSession
  1130. (
  1131. IN BSTR bstrEcxFilePath,
  1132. IN UINT nPortNumber,
  1133. IN BSTR bstrUserName,
  1134. IN BSTR bstrPassword,
  1135. IN BOOL bBlockIncomingIPConnections,
  1136. IN BSTR bstrAltSymPath
  1137. )
  1138. {
  1139. ATLTRACE(_T("CEMSessionThread::InitManualSession\n"));
  1140. _ASSERTE( nPortNumber != 0 );
  1141. _ASSERTE( bstrUserName != NULL );
  1142. _ASSERTE( bstrPassword != NULL );
  1143. HRESULT hr = E_FAIL;
  1144. do {
  1145. if( ( nPortNumber == 0 ) ||
  1146. ( bstrUserName == NULL )||
  1147. ( bstrPassword == NULL ) ) {
  1148. hr = E_INVALIDARG;
  1149. break;
  1150. }
  1151. eDBGSessType = SessType_Manual;
  1152. if(bstrEcxFilePath) m_bstrEcxFilePath = ::SysAllocString(bstrEcxFilePath);
  1153. m_nPort = nPortNumber;
  1154. m_bBlockIncomingIPConnections = bBlockIncomingIPConnections;
  1155. if(bstrUserName) m_bstrUserName = ::SysAllocString(bstrUserName);
  1156. if(bstrPassword) m_bstrPassword = ::SysAllocString(bstrPassword);
  1157. if(bstrAltSymPath) m_bstrAltSymPath = ::SysAllocString(bstrAltSymPath);
  1158. hr = S_OK;
  1159. }
  1160. while ( false );
  1161. return hr;
  1162. }
  1163. HRESULT
  1164. CEMSessionThread::StopServer()
  1165. {
  1166. ATLTRACE(_T("CEMSessionThread::StopServer\n"));
  1167. HRESULT hr = E_FAIL;
  1168. do {
  1169. if(m_pi.hProcess){
  1170. TerminateProcess(m_pi.hProcess, 0);
  1171. ZeroMemory((void *)&m_pi, sizeof PROCESS_INFORMATION);
  1172. }
  1173. }
  1174. while( false );
  1175. return hr;
  1176. }
  1177. HRESULT
  1178. CEMSessionThread::NotifyAdmin(LPCTSTR lpszData)
  1179. {
  1180. ATLTRACE(_T("CEMSessionThread::NotifyAdmin\n"));
  1181. DWORD dwLastRet = 0L;
  1182. CNotify AdminNotify(m_bstrNotificationString, lpszData);
  1183. dwLastRet = AdminNotify.Notify();
  1184. return HRESULT_FROM_WIN32(dwLastRet);
  1185. }
  1186. HRESULT
  1187. CEMSessionThread::GetDescriptionFromEmObj
  1188. (
  1189. const PEmObject pEmObj,
  1190. LPTSTR lpszDesc,
  1191. ULONG cchDesc,
  1192. LPCTSTR lpszHeader /* = NULL */
  1193. ) const
  1194. {
  1195. _ASSERTE( pEmObj != NULL );
  1196. _ASSERTE( lpszDesc != NULL );
  1197. _ASSERTE( cchDesc > 0 );
  1198. HRESULT hr = E_FAIL;
  1199. TCHAR szTemp[_MAX_PATH+1] = _T("");
  1200. int j = 0;
  1201. do
  1202. {
  1203. if( pEmObj == NULL || lpszDesc == NULL || cchDesc <= 0 ) { return E_INVALIDARG; }
  1204. /*
  1205. short type;
  1206. unsigned char guidstream[ 16 ];
  1207. LONG nId;
  1208. TCHAR szName[ 256 ];
  1209. TCHAR szSecName[ 256 ];
  1210. LONG nStatus;
  1211. DATE dateStart;
  1212. DATE dateEnd;
  1213. TCHAR szBucket1[ 64 ];
  1214. DWORD dwBucket1;
  1215. HRESULT hr;
  1216. */
  1217. j = _sntprintf(lpszDesc, cchDesc, _T("%s"), _T(""));
  1218. if( lpszHeader ) {
  1219. j += _sntprintf(lpszDesc+j, cchDesc, _T("%s -- "), lpszHeader);
  1220. }
  1221. if( pEmObj->type == EMOBJ_PROCESS ) {
  1222. ::LoadString(_Module.GetResourceInstance(), IDS_PROCESS, szTemp, _MAX_PATH);
  1223. }
  1224. else if( pEmObj->type == EMOBJ_SERVICE ) {
  1225. ::LoadString(_Module.GetResourceInstance(), IDS_SERVICE, szTemp, _MAX_PATH);
  1226. }
  1227. if(_tcscmp(szTemp, _T("")) != 0) {
  1228. j += _sntprintf(lpszDesc+j, cchDesc, _T("%s : %d - "), szTemp, pEmObj->nId);
  1229. }
  1230. if(_tcscmp(pEmObj->szName, _T("")) != 0) {
  1231. ::LoadString(_Module.GetResourceInstance(), IDS_IMAGENAME, szTemp, _MAX_PATH);
  1232. j += _sntprintf(lpszDesc+j, cchDesc, _T("%s : %s - "), szTemp, pEmObj->szName);
  1233. }
  1234. if(_tcscmp(pEmObj->szSecName, _T("")) != 0) {
  1235. ::LoadString(_Module.GetResourceInstance(), IDS_SHORTNAME, szTemp, _MAX_PATH);
  1236. j += _sntprintf(lpszDesc+j, cchDesc, _T("%s : %s - "), szTemp, pEmObj->szSecName);
  1237. }
  1238. #ifdef _DEBUG
  1239. StringFromGUID2(*(GUID*)pEmObj->guidstream, szTemp, _MAX_PATH);
  1240. if( pEmObj->guidstream && strcmp((const char*)pEmObj->guidstream, "") != 0 ) { j += _sntprintf(lpszDesc+j, cchDesc, _T("%s"), szTemp); }
  1241. #endif // _DEBUG
  1242. }
  1243. while ( false );
  1244. return hr;
  1245. }
  1246. HRESULT CEMSessionThread::CancelDebugging()
  1247. {
  1248. ATLTRACE(_T("CEMSessionThread::CancelDebugging\n"));
  1249. HRESULT hr = S_OK;
  1250. IDebugClient *pDBGClntLocal = NULL;
  1251. IDebugControl *pDBGCtrlLocal = NULL;
  1252. do
  1253. {
  1254. if( eDBGSessType == SessType_Manual ) {
  1255. hr = S_OK;
  1256. break;
  1257. }
  1258. m_bContinueSession = FALSE;
  1259. eDBGServie = DBGService_Cancel;
  1260. hr = m_pDBGClient->CreateClient(&pDBGClntLocal);
  1261. FAILEDHR_BREAK(hr);
  1262. hr = pDBGClntLocal->ExitDispatch(m_pDBGClient);
  1263. FAILEDHR_BREAK(hr);
  1264. WaitForSingleObject( m_hEvent, INFINITE );
  1265. #ifdef _DEBUG
  1266. hr = m_pASTManager->SetSessionStatus(
  1267. m_pEmSessObj->guidstream,
  1268. STAT_SESS_STOPPED_SUCCESS,
  1269. S_OK,
  1270. L"CEMSessionThread::CancelDebugging - called"
  1271. );
  1272. #else
  1273. hr = m_pASTManager->SetSessionStatus(
  1274. m_pEmSessObj->guidstream,
  1275. STAT_SESS_STOPPED_SUCCESS,
  1276. S_OK,
  1277. NULL
  1278. );
  1279. #endif
  1280. FAILEDHR_BREAK(hr);
  1281. }
  1282. while(FALSE);
  1283. return hr;
  1284. }
  1285. HRESULT
  1286. CEMSessionThread::ExecuteCommandsTillGo
  1287. (
  1288. OUT DWORD *pdwRes
  1289. )
  1290. {
  1291. _ASSERTE( m_pEcxFile != NULL );
  1292. _ASSERTE( m_pDBGControl != NULL );
  1293. HRESULT hr = E_FAIL;
  1294. char cmd[MAX_COMMAND] = "";
  1295. ULONG ExecStatus = DEBUG_STATUS_BREAK;
  1296. __try
  1297. {
  1298. if( m_pEcxFile == NULL ||
  1299. m_pDBGControl == NULL ) {
  1300. hr = E_INVALIDARG;
  1301. goto qExecuteCommandsTillGo;
  1302. }
  1303. if( pdwRes ) *pdwRes = 0L; // success
  1304. Sleep(2000); //
  1305. do
  1306. {
  1307. hr = m_pDBGControl->GetExecutionStatus(&ExecStatus);
  1308. if( FAILED(hr) ) { goto qExecuteCommandsTillGo; }
  1309. //
  1310. // we can execute commands only when the debuggee is in
  1311. // this state..
  1312. //
  1313. if( ExecStatus != DEBUG_STATUS_BREAK ) { hr = E_FAIL; goto qExecuteCommandsTillGo; }
  1314. if (fgets(cmd, MAX_COMMAND-1, m_pEcxFile))
  1315. {
  1316. cmd[strlen(cmd) - 1] = 0;
  1317. if( strcmp( cmd, "g" ) == 0 || strcmp( cmd, "G" ) == 0 ) { hr = S_OK; goto qExecuteCommandsTillGo; }
  1318. hr = m_pDBGControl->OutputPrompt(DEBUG_OUTPUT_PROMPT, "> ");
  1319. if( FAILED(hr) ) { goto qExecuteCommandsTillGo; }
  1320. hr = m_pDBGControl->Execute(
  1321. DEBUG_OUTCTL_ALL_CLIENTS,
  1322. cmd,
  1323. DEBUG_EXECUTE_ECHO
  1324. );
  1325. if( FAILED(hr) ) { goto qExecuteCommandsTillGo; }
  1326. }
  1327. else // eof reached..??
  1328. {
  1329. if( pdwRes ) { *pdwRes = GetLastError(); }
  1330. GetLastError();
  1331. hr = S_FALSE;
  1332. goto qExecuteCommandsTillGo;
  1333. }
  1334. }
  1335. while ( true );
  1336. qExecuteCommandsTillGo:
  1337. if( FAILED(hr) ) {}
  1338. }
  1339. __except ( EXCEPTION_EXECUTE_HANDLER, 1 ) {
  1340. hr = E_UNEXPECTED;
  1341. _ASSERTE( false );
  1342. }
  1343. return hr;
  1344. }