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.

1230 lines
28 KiB

  1. // EmManager.cpp : Implementation of CEmManager
  2. #include "stdafx.h"
  3. #include "Emsvc.h"
  4. #include "EmManager.h"
  5. #include "Processes.h"
  6. #include "sahlp.h"
  7. #include "EmDebugSession.h"
  8. #include "EmFile.h"
  9. /////////////////////////////////////////////////////////////////////////////
  10. // CEmManager
  11. STDMETHODIMP CEmManager::InterfaceSupportsErrorInfo(REFIID riid)
  12. {
  13. static const IID* arr[] =
  14. {
  15. &IID_IEmManager
  16. };
  17. for (int i=0; i < sizeof(arr) / sizeof(arr[0]); i++)
  18. {
  19. if (::InlineIsEqualGUID(*arr[i],riid))
  20. return S_OK;
  21. }
  22. return S_FALSE;
  23. }
  24. BOOL CALLBACK
  25. CallbackFunc
  26. (
  27. IN long lPID,
  28. IN LPCTSTR lpszImagePath,
  29. IN LPCTSTR lpszShortName,
  30. IN LPCTSTR lpszDescription,
  31. IN LPARAM lParam,
  32. IN LONG lItem
  33. )
  34. {
  35. HRESULT hr = E_FAIL;
  36. CEmManager *pEMMgr = (CEmManager *)lParam;
  37. VARIANT *pVariant = (VARIANT *)(pEMMgr->m_lpVariant);
  38. EmObject item;
  39. BSTR bstrVal = NULL,
  40. bstrTemp = NULL;
  41. PEmObject pEmObj = NULL;
  42. BOOL bSessPresent = FALSE;
  43. PEMSession pEmSess = NULL;
  44. do
  45. {
  46. ZeroMemory((PVOID)&item, sizeof EmObject);
  47. item.hr = E_FAIL;
  48. if(lPID != INVALID_PID) {
  49. item.nId = lPID;
  50. item.nStatus = pEMMgr->m_nStatus;
  51. item.type = (short)pEMMgr->m_nType;
  52. if(lpszImagePath) {
  53. _tcsncpy(item.szName, lpszImagePath, sizeof item.szName / sizeof TCHAR);
  54. }
  55. if(lpszShortName) {
  56. _tcsncpy(item.szSecName, lpszShortName, sizeof item.szSecName / sizeof TCHAR);
  57. }
  58. if(lpszDescription) {
  59. _tcsncpy(item.szBucket1, lpszDescription, sizeof item.szBucket1 / sizeof TCHAR);
  60. }
  61. bstrTemp = CopyBSTR((LPBYTE)item.szName, _tcslen(item.szName) * sizeof TCHAR);
  62. _ASSERTE(bstrTemp != NULL);
  63. if( bstrTemp == NULL ) { hr = E_OUTOFMEMORY; break; }
  64. item.hr = S_OK;
  65. hr = pEMMgr->m_pASTManager->GetSession(item.nId, bstrTemp, &pEmSess);
  66. FAILEDHR_BREAK(hr);
  67. if( bstrTemp ){ ::SysFreeString ( bstrTemp ); bstrTemp = NULL; }
  68. bSessPresent = (hr == S_OK);
  69. }
  70. if( bSessPresent && // We will point to this only if it present in the
  71. // AST and the state is "BEING DEBUGGED"
  72. pEmSess->pEmObj->nStatus & STAT_SESS_DEBUG_IN_PROGRESS )
  73. {
  74. pEmObj = pEmSess->pEmObj;
  75. }
  76. else
  77. {
  78. pEmObj = &item;
  79. }
  80. bstrVal = CopyBSTR ( (LPBYTE)pEmObj, sizeof EmObject );
  81. if( bstrVal == NULL ) { hr = E_OUTOFMEMORY; break; }
  82. hr = ::SafeArrayPutElement ( pVariant->parray, &lItem, bstrVal );
  83. FAILEDHR_BREAK(hr);
  84. if( bstrVal ) { ::SysFreeString ( bstrVal ); bstrVal = NULL; }
  85. }
  86. while ( false );
  87. if( bstrVal ) { ::SysFreeString ( bstrVal ); bstrVal = NULL; }
  88. if( bstrTemp ) { ::SysFreeString( bstrTemp ); bstrTemp = NULL; }
  89. if( FAILED(hr) ){ return FALSE; }
  90. return TRUE;
  91. }
  92. STDMETHODIMP
  93. CEmManager::EnumObjects
  94. (
  95. IN EmObjectType eObjectType,
  96. OUT VARIANT *lpVariant
  97. )
  98. {
  99. ATLTRACE(_T("CEmManager::EnumObjects\n"));
  100. _ASSERTE( lpVariant != NULL );
  101. HRESULT hr = E_FAIL;
  102. m_pcs->WriteLock();
  103. __try {
  104. do
  105. {
  106. if( lpVariant == NULL ){
  107. hr = E_INVALIDARG;
  108. break;
  109. }
  110. switch( eObjectType )
  111. {
  112. case EMOBJ_SERVICE:
  113. m_lpVariant = lpVariant;
  114. hr = EnumSrvcs();
  115. break;
  116. case EMOBJ_PROCESS:
  117. m_lpVariant = lpVariant;
  118. hr = EnumProcs();
  119. hr = S_OK;
  120. break;
  121. case EMOBJ_LOGFILE:
  122. hr = EnumLogFiles ( lpVariant );
  123. break;
  124. case EMOBJ_MINIDUMP:
  125. case EMOBJ_USERDUMP:
  126. hr = EnumDumpFiles ( lpVariant );
  127. break;
  128. case EMOBJ_CMDSET:
  129. hr = EnumCmdSets ( lpVariant );
  130. break;
  131. case EMOBJ_MSINFO:
  132. hr = EnumMsInfoFiles( lpVariant );
  133. break;
  134. default:
  135. hr = E_INVALIDARG;
  136. }
  137. }
  138. while( false );
  139. }
  140. __except ( EXCEPTION_EXECUTE_HANDLER, 1 ) {
  141. hr = E_UNEXPECTED;
  142. _ASSERTE( false );
  143. }
  144. m_pcs->WriteUnlock();
  145. return hr;
  146. }
  147. HRESULT
  148. CEmManager::EnumProcs()
  149. {
  150. ATLTRACE(_T("CEmManager::EnumProcs\n"));
  151. _ASSERTE( m_lpVariant != NULL );
  152. USES_CONVERSION;
  153. HRESULT hr = E_FAIL;
  154. DWORD dwLastRet = 0L;
  155. DWORD dwNumbProcs = 0L,
  156. dwNumbStpSess = 0L;
  157. POSITION pos = NULL;
  158. BSTR bstrVal = NULL;
  159. LONG lItem = 0L;
  160. PEMSession pEmSess = NULL;
  161. BOOL bSACreated = FALSE;
  162. EmObject TempEmObj;
  163. m_pcs->WriteLock();
  164. __try {
  165. do
  166. {
  167. if( m_lpVariant == NULL ){
  168. hr = E_UNEXPECTED;
  169. break;
  170. }
  171. dwLastRet = GetNumberOfRunningApps( &dwNumbProcs );
  172. FAILEDDW_BREAK(dwLastRet);
  173. hr = m_pASTManager->GetNumberOfStoppedSessions(&dwNumbStpSess);
  174. FAILEDHR_BREAK(hr);
  175. hr = Variant_CreateOneDim ( m_lpVariant, (dwNumbProcs + dwNumbStpSess), VT_BSTR );
  176. FAILEDHR_BREAK(hr);
  177. bSACreated = TRUE;
  178. m_nStatus = STAT_SESS_NOT_STARTED_RUNNING;
  179. m_nType = EMOBJ_PROCESS;
  180. dwLastRet = EnumRunningProcesses( CallbackFunc, (LPARAM)this );
  181. if(dwLastRet != 0){
  182. hr = HRESULT_FROM_WIN32( dwLastRet );
  183. }
  184. hr = m_pASTManager->GetFirstStoppedSession(&pos, NULL, &pEmSess);
  185. lItem = dwNumbProcs;
  186. ZeroMemory( (void *)&TempEmObj, sizeof EmObject );
  187. TempEmObj.hr = E_FAIL;
  188. while( dwNumbStpSess ){
  189. if( pEmSess->pEmObj->type & EMOBJ_PROCESS ){
  190. bstrVal = CopyBSTR ( (LPBYTE)pEmSess->pEmObj, sizeof EmObject );
  191. }
  192. else {
  193. bstrVal = CopyBSTR ( (LPBYTE)&TempEmObj, sizeof EmObject );
  194. }
  195. if( bstrVal == NULL ){
  196. hr = E_OUTOFMEMORY;
  197. break;
  198. }
  199. hr = ::SafeArrayPutElement ( m_lpVariant->parray, &lItem, bstrVal );
  200. FAILEDHR_BREAK(hr);
  201. if( bstrVal ){
  202. ::SysFreeString ( bstrVal );
  203. bstrVal = NULL;
  204. }
  205. ++lItem;
  206. --dwNumbStpSess;
  207. m_pASTManager->GetNextStoppedSession(&pos, NULL, &pEmSess);
  208. }
  209. }
  210. while ( false );
  211. if( FAILED(hr) ) {
  212. Variant_DestroyOneDim(m_lpVariant);
  213. bSACreated = FALSE;
  214. }
  215. if( bstrVal ){
  216. ::SysFreeString ( bstrVal );
  217. }
  218. }
  219. __except ( EXCEPTION_EXECUTE_HANDLER, 1 ) {
  220. hr = E_UNEXPECTED;
  221. if(bSACreated) {
  222. Variant_DestroyOneDim(m_lpVariant);
  223. bSACreated = FALSE;
  224. }
  225. if( bstrVal ){
  226. ::SysFreeString ( bstrVal );
  227. bstrVal = NULL;
  228. }
  229. _ASSERTE( false );
  230. }
  231. m_pcs->WriteUnlock();
  232. return hr;
  233. }
  234. HRESULT
  235. CEmManager::EnumSrvcs()
  236. {
  237. ATLTRACE(_T("CEmManager::EnumSrvcs\n"));
  238. _ASSERTE( m_lpVariant != NULL );
  239. USES_CONVERSION;
  240. HRESULT hr = E_FAIL;
  241. DWORD dwLastRet = 0L;
  242. DWORD dwNumbSrvcs = 0L,
  243. dwNumbStoppedSrvcs = 0L;
  244. BOOL bSACreated = FALSE;
  245. DWORD dwNumbStpSess = 0L;
  246. POSITION pos = NULL;
  247. BSTR bstrVal = NULL;
  248. LONG lItem = 0L;
  249. PEMSession pEmSess = NULL;
  250. EmObject TempEmObj;
  251. m_pcs->WriteLock();
  252. __try {
  253. do
  254. {
  255. if( m_lpVariant == NULL ){
  256. hr = E_INVALIDARG;
  257. break;
  258. }
  259. m_nType = EMOBJ_SERVICE;
  260. dwLastRet = GetNumberOfServices( &dwNumbStoppedSrvcs, SERVICE_WIN32, SERVICE_INACTIVE );
  261. FAILEDDW_BREAK(dwLastRet);
  262. dwLastRet = GetNumberOfServices( &dwNumbSrvcs, SERVICE_WIN32, SERVICE_ACTIVE );
  263. FAILEDDW_BREAK(dwLastRet);
  264. hr = m_pASTManager->GetNumberOfStoppedSessions(&dwNumbStpSess);
  265. FAILEDHR_BREAK(hr);
  266. hr = Variant_CreateOneDim ( m_lpVariant, dwNumbSrvcs + dwNumbStoppedSrvcs + dwNumbStpSess, VT_BSTR );
  267. FAILEDHR_BREAK(hr);
  268. bSACreated = TRUE;
  269. m_nStatus = STAT_SESS_NOT_STARTED_RUNNING;
  270. dwLastRet = EnumServices( CallbackFunc, (LPARAM)this, SERVICE_ACTIVE, 0L );
  271. m_nStatus = STAT_SESS_NOT_STARTED_NOTRUNNING;
  272. dwLastRet = EnumServices( CallbackFunc, (LPARAM)this, SERVICE_INACTIVE, dwNumbSrvcs );
  273. hr = m_pASTManager->GetFirstStoppedSession(&pos, NULL, &pEmSess);
  274. lItem = dwNumbSrvcs + dwNumbStoppedSrvcs;
  275. ZeroMemory( (void *)&TempEmObj, sizeof EmObject );
  276. TempEmObj.hr = E_FAIL;
  277. while( dwNumbStpSess ){
  278. if( pEmSess->pEmObj->type & EMOBJ_SERVICE ){
  279. bstrVal = CopyBSTR ( (LPBYTE)pEmSess->pEmObj, sizeof EmObject );
  280. }
  281. else {
  282. bstrVal = CopyBSTR ( (LPBYTE)&TempEmObj, sizeof EmObject );
  283. }
  284. if( bstrVal == NULL ){
  285. hr = E_OUTOFMEMORY;
  286. break;
  287. }
  288. hr = ::SafeArrayPutElement ( m_lpVariant->parray, &lItem, bstrVal );
  289. FAILEDHR_BREAK(hr);
  290. if( bstrVal ){
  291. ::SysFreeString ( bstrVal );
  292. bstrVal = NULL;
  293. }
  294. ++lItem;
  295. --dwNumbStpSess;
  296. m_pASTManager->GetNextStoppedSession(&pos, NULL, &pEmSess);
  297. }
  298. if(dwLastRet == FALSE){ // The callback returned false.. otherwise we would
  299. // get the error value (GetLastError())
  300. hr = S_FALSE;
  301. }
  302. else {
  303. hr = HRESULT_FROM_WIN32( dwLastRet );
  304. }
  305. }
  306. while ( false );
  307. if(FAILED(hr)) {
  308. if( bSACreated ) Variant_DestroyOneDim(m_lpVariant);
  309. bSACreated = FALSE;
  310. }
  311. }
  312. __except ( EXCEPTION_EXECUTE_HANDLER, 1 ) {
  313. hr = E_UNEXPECTED;
  314. if(bSACreated) {
  315. Variant_DestroyOneDim(m_lpVariant);
  316. bSACreated = FALSE;
  317. }
  318. _ASSERTE( false );
  319. }
  320. m_pcs->WriteUnlock();
  321. return hr;
  322. }
  323. STDMETHODIMP
  324. CEmManager::OpenSession
  325. (
  326. IN OUT BSTR bstrEmObj,
  327. OUT IEmDebugSession **ppEmDebugSession
  328. )
  329. {
  330. ATLTRACE(_T("CEmManager::OpenSession\n"));
  331. _ASSERTE(bstrEmObj != NULL);
  332. _ASSERTE(ppEmDebugSession != NULL);
  333. HRESULT hr = E_FAIL;
  334. PEmObject pEmNewSessObj = NULL;
  335. PEMSession pNewEmSess = NULL;
  336. BOOL bBeingDebugged = FALSE;
  337. PEmObject pEmObj = NULL;
  338. CComObject<CEmDebugSession> *pEmDbgSess = NULL;
  339. m_pcs->WriteLock();
  340. __try {
  341. do
  342. {
  343. if( bstrEmObj == NULL ||
  344. ppEmDebugSession == NULL ){
  345. hr = E_INVALIDARG;
  346. break;
  347. }
  348. pEmObj = GetEmObj(bstrEmObj);
  349. //
  350. // Check the session table if it is already being debugged
  351. //
  352. // hr = m_pASTManager->IsAlreadyBeingDebugged(pEmObj);
  353. // if( FAILED(hr) && hr != EMERROR_INVALIDPROCESS ) break;
  354. hr = CheckIfCanOpenSession( pEmObj );
  355. FAILEDHR_BREAK(hr);
  356. bBeingDebugged = (hr == S_FALSE);
  357. hr = CComObject<CEmDebugSession>::CreateInstance(&pEmDbgSess);
  358. FAILEDHR_BREAK(hr);
  359. pEmDbgSess->AddRef();
  360. if( bBeingDebugged == FALSE ){ // it is not being debugged already.
  361. hr = m_pASTManager->AddSession(pEmObj, &pNewEmSess);
  362. FAILEDHR_BREAK(hr);
  363. hr = S_OK;
  364. }
  365. else{ // it is already being debugged
  366. //
  367. // This will get the updated status too..
  368. //
  369. hr = m_pASTManager->GetSession(pEmObj->nId, pEmObj->szName, &pNewEmSess);
  370. FAILEDHR_BREAK(hr);
  371. hr = S_FALSE;
  372. /**********
  373. hr = m_pASTManager->IsSessionOrphaned(pNewEmSess->pEmObj->guidstream);
  374. FAILEDHR_BREAK(hr);
  375. if( hr == S_OK ) {} // session is orphaned..
  376. else if( hr == S_FALSE ) {} // session is not orphaned..
  377. ***********/
  378. }
  379. pEmNewSessObj = pNewEmSess->pEmObj;
  380. pEmDbgSess->m_pEmObj = pEmNewSessObj;
  381. pEmDbgSess->m_pEmSessThrd = (CEMSessionThread *)pNewEmSess->pThread;
  382. }
  383. while( false );
  384. if(FAILED(hr)){
  385. if(pEmDbgSess){
  386. pEmDbgSess->Release();
  387. pEmDbgSess = NULL;
  388. }
  389. }
  390. else{
  391. //
  392. // This will update all the fields of EmObject..
  393. //
  394. ::SysFreeString(bstrEmObj);
  395. bstrEmObj = CopyBSTR((LPBYTE)pNewEmSess->pEmObj, sizeof EmObject);
  396. *ppEmDebugSession = pEmDbgSess; // Client will take care of Release.
  397. }
  398. } // __try
  399. __except ( EXCEPTION_EXECUTE_HANDLER, 1 ) {
  400. hr = E_UNEXPECTED;
  401. if(pEmDbgSess){
  402. pEmDbgSess->Release();
  403. pEmDbgSess = NULL;
  404. }
  405. _ASSERTE( false );
  406. }
  407. m_pcs->WriteUnlock();
  408. return hr;
  409. }
  410. STDMETHODIMP CEmManager::DeleteSession(BSTR bstrEmObj)
  411. {
  412. ATLTRACE(_T("CEmManager::CloseSession\n"));
  413. _ASSERTE(bstrEmObj != NULL);
  414. HRESULT hr = E_FAIL;
  415. PEmObject pEmObj = NULL;
  416. m_pcs->ReadLock();
  417. __try {
  418. if(bstrEmObj == NULL){
  419. hr = E_INVALIDARG;
  420. }
  421. else {
  422. pEmObj = GetEmObj(bstrEmObj);
  423. hr = m_pASTManager->RemoveSession(pEmObj->guidstream);
  424. }
  425. }
  426. __except ( EXCEPTION_EXECUTE_HANDLER, 1 ) {
  427. hr = E_UNEXPECTED;
  428. _ASSERTE( false );
  429. }
  430. m_pcs->ReadUnlock();
  431. return hr;
  432. }
  433. STDMETHODIMP CEmManager::EnumObjectsEx(BSTR bstrEmObj, VARIANT *lpVariant)
  434. {
  435. ATLTRACE(_T("CEmManager::EnumObjectsEx\n"));
  436. _ASSERTE( lpVariant != NULL );
  437. _ASSERTE( bstrEmObj != NULL );
  438. HRESULT hr = E_FAIL;
  439. PEmObject pEmObj = NULL;
  440. TCHAR szSearchString[_MAX_PATH + 1] = _T("");
  441. TCHAR szEmDir[_MAX_PATH+1] = _T("");
  442. TCHAR szEmFileExt[_MAX_EXT+1] = _T("");
  443. m_pcs->WriteLock();
  444. __try {
  445. do
  446. {
  447. if( bstrEmObj == NULL ||
  448. lpVariant == NULL ) {
  449. hr = E_INVALIDARG;
  450. break;
  451. }
  452. pEmObj = GetEmObj(bstrEmObj);
  453. _ASSERTE(pEmObj != NULL);
  454. switch( pEmObj->type )
  455. {
  456. case EMOBJ_SERVICE:
  457. break;
  458. case EMOBJ_PROCESS:
  459. if( pEmObj->nStatus & STAT_SESS_STOPPED ) {
  460. hr = EnumSessions( pEmObj, lpVariant );
  461. }
  462. break;
  463. case EMOBJ_LOGFILE:
  464. _Module.GetEmDirectory( EMOBJ_LOGFILE, szEmDir, _MAX_PATH, szEmFileExt, _MAX_EXT );
  465. GetUniqueFileName(
  466. pEmObj,
  467. szSearchString,
  468. NULL,
  469. szEmFileExt,
  470. true
  471. );
  472. _tcsncat( szEmDir, _T("\\"), _MAX_PATH );
  473. _tcsncat( szEmDir, szSearchString, _MAX_PATH );
  474. hr = EnumLogFiles ( lpVariant, szEmDir );
  475. break;
  476. case EMOBJ_MINIDUMP:
  477. case EMOBJ_USERDUMP:
  478. _Module.GetEmDirectory( EMOBJ_MINIDUMP, szEmDir, _MAX_PATH, szEmFileExt, _MAX_EXT );
  479. GetUniqueFileName(
  480. pEmObj,
  481. szSearchString,
  482. NULL,
  483. szEmFileExt,
  484. true
  485. );
  486. _tcsncat( szEmDir, _T("\\"), _MAX_PATH );
  487. _tcsncat( szEmDir, szSearchString, _MAX_PATH );
  488. hr = EnumDumpFiles ( lpVariant, szEmDir );
  489. break;
  490. case EMOBJ_MSINFO:
  491. _Module.GetEmDirectory( EMOBJ_MSINFO, szEmDir, _MAX_PATH, szEmFileExt, _MAX_EXT );
  492. GetUniqueFileName(
  493. pEmObj,
  494. szSearchString,
  495. NULL,
  496. szEmFileExt,
  497. true
  498. );
  499. _tcsncat( szEmDir, _T("\\"), _MAX_PATH );
  500. _tcsncat( szEmDir, szSearchString, _MAX_PATH );
  501. hr = EnumMsInfoFiles( lpVariant, szEmDir );
  502. break;
  503. case EMOBJ_CMDSET:
  504. hr = EnumCmdSets ( lpVariant );
  505. break;
  506. default:
  507. hr = E_INVALIDARG;
  508. }
  509. }
  510. while( false );
  511. }
  512. __except ( EXCEPTION_EXECUTE_HANDLER, 1 ) {
  513. hr = E_UNEXPECTED;
  514. _ASSERTE( false );
  515. }
  516. m_pcs->WriteUnlock();
  517. return hr;
  518. }
  519. HRESULT
  520. CEmManager::EnumSessions
  521. (
  522. IN PEmObject pEmObj,
  523. OUT VARIANT *lpVariant
  524. )
  525. {
  526. ATLTRACE(_T("CEmManager::EnumSessions\n"));
  527. _ASSERTE( pEmObj != NULL );
  528. _ASSERTE( lpVariant != NULL );
  529. HRESULT hr = E_FAIL;
  530. DWORD dwNumbSess = 0L;
  531. long lItem = 0L;
  532. PEMSession pEmSess = NULL;
  533. POSITION pos = NULL;
  534. BSTR bstrVal = NULL;
  535. bool bVariantCreated = false;
  536. EmObject TempEmObj;
  537. m_pcs->WriteLock();
  538. __try {
  539. if( pEmObj == NULL ||
  540. lpVariant == NULL ) {
  541. hr = E_INVALIDARG;
  542. goto qEnumSessions;
  543. }
  544. hr = m_pASTManager->GetNumberOfSessions(&dwNumbSess);
  545. if(hr != S_OK) goto qEnumSessions; // S_FALSE => no sessions.
  546. hr = Variant_CreateOneDim ( lpVariant, dwNumbSess, VT_BSTR );
  547. if(FAILED(hr)) goto qEnumSessions;
  548. bVariantCreated = true;
  549. hr = m_pASTManager->GetFirstSession(&pos, &pEmSess);
  550. lItem = 0L;
  551. ZeroMemory( (void *)&TempEmObj, sizeof EmObject );
  552. TempEmObj.hr = E_FAIL;
  553. while( dwNumbSess ){
  554. if( HIWORD(pEmSess->pEmObj->nStatus) & HIWORD(pEmObj->nStatus) ) {
  555. bstrVal = CopyBSTR ( (LPBYTE)pEmSess->pEmObj, sizeof EmObject );
  556. }
  557. else {
  558. bstrVal = CopyBSTR ( (LPBYTE)&TempEmObj, sizeof EmObject );
  559. }
  560. if( bstrVal == NULL ) { hr = E_OUTOFMEMORY; goto qEnumSessions; }
  561. hr = ::SafeArrayPutElement ( lpVariant->parray, &lItem, bstrVal );
  562. if(FAILED(hr)) goto qEnumSessions;
  563. if( bstrVal ){
  564. ::SysFreeString ( bstrVal );
  565. bstrVal = NULL;
  566. }
  567. ++lItem;
  568. --dwNumbSess;
  569. m_pASTManager->GetNextSession(&pos, &pEmSess);
  570. }
  571. qEnumSessions:
  572. if( FAILED(hr) ) {
  573. if( bVariantCreated == true ) Variant_DestroyOneDim(lpVariant);
  574. }
  575. }
  576. __except ( EXCEPTION_EXECUTE_HANDLER, 1 ) {
  577. if( bVariantCreated == true ) Variant_DestroyOneDim(lpVariant);
  578. hr = E_UNEXPECTED;
  579. _ASSERTE( false );
  580. }
  581. m_pcs->WriteUnlock();
  582. return hr;
  583. }
  584. STDMETHODIMP CEmManager::GetEmFileInterface(BSTR bstrEmObj, IStream **ppstrm)
  585. {
  586. _ASSERTE( bstrEmObj != NULL );
  587. _ASSERTE( ppstrm != NULL );
  588. HRESULT hr = E_FAIL;
  589. PEmObject pEmObj = NULL;
  590. TCHAR szEmDir[_MAX_PATH+1] = _T("");
  591. CComObject<CEmFile> *pEmFile = NULL;
  592. m_pcs->WriteLock();
  593. __try
  594. {
  595. if( bstrEmObj == NULL || ppstrm == NULL ) {
  596. hr = E_INVALIDARG; goto qGetEmFileInterface;
  597. }
  598. pEmObj = GetEmObj(bstrEmObj);
  599. *ppstrm = NULL;
  600. hr = CComObject<CEmFile>::CreateInstance(&pEmFile);
  601. if( FAILED(hr) ) { goto qGetEmFileInterface; }
  602. pEmFile->AddRef();
  603. hr = _Module.GetEmDirectory( (EmObjectType)pEmObj->type, szEmDir, _MAX_PATH, NULL, 0L );
  604. if( FAILED(hr) ) { goto qGetEmFileInterface; }
  605. _tcsncat( szEmDir, _T("\\"), _MAX_PATH );
  606. _tcsncat( szEmDir, pEmObj->szName, _MAX_PATH );
  607. hr = pEmFile->InitFile( szEmDir );
  608. if( FAILED(hr) ) { goto qGetEmFileInterface; }
  609. *ppstrm = pEmFile;
  610. hr = S_OK;
  611. qGetEmFileInterface:
  612. if( FAILED(hr) ) {
  613. if( pEmFile ) { pEmFile->Release(); }
  614. }
  615. }
  616. __except ( EXCEPTION_EXECUTE_HANDLER, 1 ) {
  617. hr = E_UNEXPECTED;
  618. _ASSERTE( false );
  619. }
  620. m_pcs->WriteUnlock();
  621. return hr;
  622. }
  623. STDMETHODIMP
  624. CEmManager::GenerateDumpFile
  625. (
  626. IN BSTR bstrEmObj,
  627. IN UINT nDumpType
  628. )
  629. {
  630. _ASSERTE( bstrEmObj != NULL );
  631. HRESULT hr = E_FAIL;
  632. IEmDebugSession *pIEmDbgSess = NULL;
  633. bool bCallDeleteSess = false;
  634. m_pcs->ReadLock();
  635. __try
  636. {
  637. if( bstrEmObj == NULL ) { hr = E_INVALIDARG; goto qGenerateDumpFile; }
  638. hr = OpenSession( bstrEmObj, &pIEmDbgSess );
  639. bCallDeleteSess = (hr == S_OK);
  640. if( pIEmDbgSess ) {
  641. hr = pIEmDbgSess->GenerateDumpFile( nDumpType );
  642. }
  643. qGenerateDumpFile:
  644. if( FAILED(hr) ) {
  645. if( pIEmDbgSess ) { pIEmDbgSess->Release(); pIEmDbgSess = NULL; }
  646. }
  647. // if( bCallDeleteSess ) { DeleteSession( bstrEmObj ); }
  648. }
  649. __except ( EXCEPTION_EXECUTE_HANDLER, 1 ) {
  650. hr = E_UNEXPECTED;
  651. if( pIEmDbgSess ) { pIEmDbgSess->Release(); pIEmDbgSess = NULL; }
  652. // if( bCallDeleteSess ) { DeleteSession( bstrEmObj ); }
  653. _ASSERTE( false );
  654. }
  655. m_pcs->ReadUnlock();
  656. return hr;
  657. }
  658. HRESULT
  659. CEmManager::CheckIfCanOpenSession
  660. (
  661. IN PEmObject pEmObj
  662. )
  663. {
  664. HRESULT hr = E_FAIL,
  665. hrTemp = E_FAIL;
  666. DWORD dwLastRet = 0L;
  667. bool bValidImage = false;
  668. PEMSession pEmSess = NULL;
  669. POSITION pos = NULL;
  670. m_pcs->ReadLock();
  671. __try
  672. {
  673. if( pEmObj->type != EMOBJ_SERVICE && pEmObj->type != EMOBJ_PROCESS ) {
  674. hr = E_INVALIDARG;
  675. goto qCheckIfCanOpenSession;
  676. }
  677. if( pEmObj->type == EMOBJ_PROCESS ) {
  678. IsValidProcess( pEmObj->nId, pEmObj->szName, &bValidImage );
  679. hrTemp = m_pASTManager->GetSession(
  680. pEmObj->nId,
  681. pEmObj->szName,
  682. &pEmSess
  683. );
  684. if( !bValidImage ) { // pid and image name does not match.. :(
  685. if( hrTemp == S_FALSE ) { // Not present in the AST, as well.
  686. hr = EMERROR_INVALIDPROCESS;
  687. }
  688. else { // is present in the AST..
  689. hr = S_FALSE;
  690. }
  691. goto qCheckIfCanOpenSession;
  692. }
  693. if( bValidImage ) { // pid and image name match..
  694. if( hrTemp == S_FALSE ) { // not present in the AST, so it can be added..
  695. hr = S_OK;
  696. }
  697. else { // present in the AST..
  698. if( HIWORD(pEmSess->pEmObj->nStatus) >= HIWORD(STAT_SESS_DEBUG_IN_PROGRESS) )
  699. hr = S_FALSE;
  700. else
  701. hr = S_OK;
  702. }
  703. goto qCheckIfCanOpenSession;
  704. }
  705. }
  706. if( pEmObj->type == EMOBJ_SERVICE ) {
  707. hr = m_pASTManager->GetNumberOfSessions( &dwLastRet );
  708. if( FAILED(hr) ) { goto qCheckIfCanOpenSession; }
  709. hr = m_pASTManager->GetFirstSession(&pos, &pEmSess);
  710. if( FAILED(hr) ) { goto qCheckIfCanOpenSession; }
  711. hr = S_OK;
  712. while( dwLastRet ) {
  713. if( _tcsicmp( pEmObj->szName, pEmSess->pEmObj->szName ) == 0 &&
  714. _tcsicmp( pEmObj->szSecName, pEmSess->pEmObj->szSecName ) == 0 ) {
  715. hr = S_FALSE;
  716. goto qCheckIfCanOpenSession;
  717. }
  718. --dwLastRet;
  719. m_pASTManager->GetNextSession(&pos, &pEmSess);
  720. }
  721. }
  722. qCheckIfCanOpenSession:
  723. if(FAILED(hr)){}
  724. }
  725. __except ( EXCEPTION_EXECUTE_HANDLER, 1 ) {
  726. hr = E_UNEXPECTED;
  727. _ASSERTE( false );
  728. }
  729. m_pcs->ReadUnlock();
  730. return hr;
  731. }
  732. STDMETHODIMP CEmManager::DeleteFile(BSTR bstrEmObj)
  733. {
  734. _ASSERTE( bstrEmObj != NULL );
  735. HRESULT hr = E_FAIL;
  736. LPTSTR lpszFullFileName = NULL;
  737. PEmObject pEmObj = NULL;
  738. ULONG lStrLen = 0L;
  739. m_pcs->ReadLock();
  740. __try
  741. {
  742. if( bstrEmObj == NULL ) {
  743. hr = E_INVALIDARG;
  744. goto qDeleteFile;
  745. }
  746. pEmObj = GetEmObj(bstrEmObj);
  747. if( pEmObj->type != EMOBJ_LOGFILE &&
  748. pEmObj->type != EMOBJ_MINIDUMP &&
  749. pEmObj->type != EMOBJ_USERDUMP &&
  750. pEmObj->type != EMOBJ_MSINFO
  751. ) {
  752. hr = E_INVALIDARG;
  753. goto qDeleteFile;
  754. }
  755. lStrLen = _tcslen(pEmObj->szName);
  756. lStrLen += _tcslen(pEmObj->szSecName) + 1;
  757. lpszFullFileName = new TCHAR[lStrLen + 1];
  758. if( !lpszFullFileName ) {
  759. hr = HRESULT_FROM_WIN32(GetLastError());
  760. goto qDeleteFile;
  761. }
  762. _stprintf( lpszFullFileName, _T("%s\\%s"), pEmObj->szSecName, pEmObj->szName );
  763. if(!::DeleteFile( lpszFullFileName )) {
  764. hr = HRESULT_FROM_WIN32(GetLastError());
  765. goto qDeleteFile;
  766. }
  767. hr = S_OK;
  768. qDeleteFile:
  769. if( lpszFullFileName ) { delete [] lpszFullFileName; lpszFullFileName = NULL; }
  770. if(FAILED(hr)){}
  771. }
  772. __except ( EXCEPTION_EXECUTE_HANDLER, 1 ) {
  773. hr = E_UNEXPECTED;
  774. if( lpszFullFileName ) { delete [] lpszFullFileName; lpszFullFileName = NULL; }
  775. _ASSERTE( false );
  776. }
  777. m_pcs->ReadUnlock();
  778. return hr;
  779. }
  780. STDMETHODIMP
  781. CEmManager::MakeNFO
  782. (
  783. IN BSTR bstrPath,
  784. IN BSTR bstrMachineName,
  785. IN BSTR bstrCategories
  786. )
  787. {
  788. _ASSERTE( bstrCategories != NULL );
  789. HRESULT hr = E_FAIL;
  790. BSTR bstrFilePath = NULL,
  791. bstrMacName = NULL;
  792. BOOL bMsinfoCreated = FALSE;
  793. HINSTANCE hi = NULL;
  794. TCHAR szMsInfo32Path[_MAX_PATH+1] = _T("");
  795. ULONG cchMsInfo32Path = _MAX_PATH;
  796. LPTSTR lpszCmdLine = NULL;
  797. ULONG lCmdLineLen = 0L;
  798. LPCTSTR lpszNfoExt = _T("/nfo ");
  799. m_pcs->ReadLock();
  800. __try
  801. {
  802. if( !bstrCategories ) { hr = E_INVALIDARG; goto qMakeNFO; }
  803. if( bstrPath ) {
  804. bstrFilePath = SysAllocString( bstrPath );
  805. if( !bstrFilePath ) { hr = E_OUTOFMEMORY; goto qMakeNFO; }
  806. }
  807. else {
  808. hr = _Module.GetTempEmFileName( EMOBJ_MSINFO, bstrFilePath );
  809. if( FAILED(hr) ) { goto qMakeNFO; }
  810. }
  811. if( bstrMachineName ) {
  812. bstrMacName = SysAllocString( bstrMachineName );
  813. if( !bstrMacName ) { hr = E_OUTOFMEMORY; goto qMakeNFO; }
  814. }
  815. else {
  816. hr = _Module.GetCompName( bstrMacName );
  817. if( FAILED(hr) ) { goto qMakeNFO; }
  818. }
  819. /*
  820. hr = CoCreateInstance(
  821. CLSID_SystemInfo,
  822. NULL,
  823. CLSCTX_INPROC_SERVER,
  824. IID_ISystemInfo,
  825. (LPVOID *) &pISystemInfo
  826. );
  827. if( FAILED(hr) ) { goto qMakeNFO; }
  828. // Call the make_nfo system Interface
  829. //hrReturn=pISystemInfo->make_nfo(bstrPath,bstrMachineName);
  830. hr = pISystemInfo->MakeNFO(bstrFilePath, bstrMachineName, bstrCategories);
  831. */
  832. STARTUPINFO sp;
  833. PROCESS_INFORMATION pi;
  834. ZeroMemory(&sp, sizeof(sp));
  835. ZeroMemory(&pi, sizeof(pi));
  836. hr = _Module.GetMsInfoPath( szMsInfo32Path, &cchMsInfo32Path );
  837. if( FAILED(hr) ) { goto qMakeNFO; }
  838. //
  839. // msinfo32.exe /nfo <filepath> <- silent file save ( no UI ).
  840. // msinfo32.exe /categories: +xxx /nfo <filepath>
  841. //
  842. lCmdLineLen = _tcslen(szMsInfo32Path)
  843. + SysStringLen( bstrCategories )
  844. + SysStringLen( bstrFilePath )
  845. + _tcslen(lpszNfoExt)
  846. + 4 // This is for quotes..
  847. + 1;
  848. lpszCmdLine = new TCHAR[ lCmdLineLen ];
  849. if( !lpszCmdLine ) {
  850. hr = HRESULT_FROM_WIN32(GetLastError());
  851. goto qMakeNFO;
  852. }
  853. _stprintf( lpszCmdLine,
  854. _T("\"%s\" %s %s \"%s\""),
  855. szMsInfo32Path,
  856. (LPCTSTR)bstrCategories,
  857. lpszNfoExt,
  858. (LPCTSTR)bstrFilePath
  859. );
  860. bMsinfoCreated = CreateProcess(// This has to be obtained from the registry...
  861. NULL,
  862. lpszCmdLine,
  863. NULL,
  864. NULL,
  865. FALSE,
  866. CREATE_NEW_PROCESS_GROUP,
  867. NULL,
  868. NULL,
  869. &sp,
  870. &pi
  871. );
  872. if( !bMsinfoCreated ) {
  873. hr = HRESULT_FROM_WIN32(GetLastError());
  874. goto qMakeNFO;
  875. }
  876. hr = S_OK;
  877. qMakeNFO:
  878. if( lpszCmdLine ) { delete [] lpszCmdLine; lpszCmdLine = NULL; }
  879. if( bstrFilePath ) { SysFreeString( bstrFilePath ); }
  880. if( bstrMacName ) { SysFreeString( bstrMacName ); }
  881. }
  882. __except ( EXCEPTION_EXECUTE_HANDLER, 1 ) {
  883. hr = E_UNEXPECTED;
  884. if( lpszCmdLine ) { delete [] lpszCmdLine; lpszCmdLine = NULL; }
  885. if( bstrFilePath ) { SysFreeString( bstrFilePath ); }
  886. if( bstrMacName ) { SysFreeString( bstrMacName ); }
  887. _ASSERTE( false );
  888. }
  889. m_pcs->ReadUnlock();
  890. return hr;
  891. }