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.

825 lines
20 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 <winerror.h>
  8. BSTR
  9. CopyBSTR
  10. (
  11. LPBYTE pb,
  12. ULONG cb
  13. );
  14. /*
  15. BOOL OleDateFromTm(WORD wYear, WORD wMonth, WORD wDay,
  16. WORD wHour, WORD wMinute, WORD wSecond, DATE& dtDest)
  17. {
  18. // Validate year and month (ignore day of week and milliseconds)
  19. if (wYear > 9999 || wMonth < 1 || wMonth > 12)
  20. return FALSE;
  21. // Check for leap year and set the number of days in the month
  22. BOOL bLeapYear = ((wYear & 3) == 0) &&
  23. ((wYear % 100) != 0 || (wYear % 400) == 0);
  24. int nDaysInMonth =
  25. _afxMonthDays[wMonth] - _afxMonthDays[wMonth-1] +
  26. ((bLeapYear && wDay == 29 && wMonth == 2) ? 1 : 0);
  27. // Finish validating the date
  28. if (wDay < 1 || wDay > nDaysInMonth ||
  29. wHour > 23 || wMinute > 59 ||
  30. wSecond > 59)
  31. {
  32. return FALSE;
  33. }
  34. // Cache the date in days and time in fractional days
  35. long nDate;
  36. double dblTime;
  37. //It is a valid date; make Jan 1, 1AD be 1
  38. nDate = wYear*365L + wYear/4 - wYear/100 + wYear/400 +
  39. _afxMonthDays[wMonth-1] + wDay;
  40. // If leap year and it's before March, subtract 1:
  41. if (wMonth <= 2 && bLeapYear)
  42. --nDate;
  43. // Offset so that 12/30/1899 is 0
  44. nDate -= 693959L;
  45. dblTime = (((long)wHour * 3600L) + // hrs in seconds
  46. ((long)wMinute * 60L) + // mins in seconds
  47. ((long)wSecond)) / 86400.;
  48. dtDest = (double) nDate + ((nDate >= 0) ? dblTime : -dblTime);
  49. return TRUE;
  50. }
  51. const COleDateTime& COleDateTime::operator=(const FILETIME& filetimeSrc)
  52. {
  53. // Assume UTC FILETIME, so convert to LOCALTIME
  54. FILETIME filetimeLocal;
  55. if (!FileTimeToLocalFileTime( &filetimeSrc, &filetimeLocal))
  56. {
  57. #ifdef _DEBUG
  58. DWORD dwError = GetLastError();
  59. TRACE1("\nFileTimeToLocalFileTime failed. Error = %lu.\n\t", dwError);
  60. #endif // _DEBUG
  61. m_status = invalid;
  62. }
  63. else
  64. {
  65. // Take advantage of SYSTEMTIME -> FILETIME conversion
  66. SYSTEMTIME systime;
  67. m_status = FileTimeToSystemTime(&filetimeLocal, &systime) ?
  68. valid : invalid;
  69. // At this point systime should always be valid, but...
  70. if (GetStatus() == valid)
  71. {
  72. m_status = _AfxOleDateFromTm(systime.wYear, systime.wMonth,
  73. systime.wDay, systime.wHour, systime.wMinute,
  74. systime.wSecond, m_dt) ? valid : invalid;
  75. }
  76. }
  77. return *this;
  78. }
  79. */
  80. HRESULT CEmManager::EnumLogFiles
  81. (
  82. VARIANT *lpVariant,
  83. LPCTSTR lpSearchString
  84. )
  85. {
  86. ATLTRACE(_T("CEmManager::EnumLogFiles\n"));
  87. HRESULT hr = E_FAIL;
  88. TCHAR szDirectory[_MAX_PATH] = _T("");
  89. TCHAR szExt[_MAX_EXT] = _T("");
  90. LPWIN32_FIND_DATA lpFindData = NULL;
  91. LONG cFiles = 0;
  92. __try {
  93. if(lpSearchString == NULL) {
  94. _Module.GetEmDirectory (
  95. EMOBJ_LOGFILE,
  96. (LPTSTR)szDirectory,
  97. sizeof szDirectory / sizeof (TCHAR),
  98. (LPTSTR)szExt,
  99. sizeof szExt / sizeof (TCHAR)
  100. );
  101. }
  102. else {
  103. _tcscpy(szDirectory, lpSearchString);
  104. _tcscpy(szExt, _T(""));
  105. }
  106. hr = EnumFiles (
  107. szDirectory,
  108. szExt,
  109. &lpFindData,
  110. &cFiles
  111. );
  112. if ( SUCCEEDED(hr) ) {
  113. hr = PackageFilesToVariant (
  114. EMOBJ_LOGFILE,
  115. lpFindData,
  116. cFiles,
  117. lpVariant
  118. );
  119. }
  120. if( lpFindData ) { free( lpFindData ); lpFindData = NULL; }
  121. }
  122. __except ( EXCEPTION_EXECUTE_HANDLER, 1 ) {
  123. hr = E_UNEXPECTED;
  124. _ASSERTE( false );
  125. }
  126. return (hr);
  127. }
  128. HRESULT
  129. CEmManager::EnumCmdSets
  130. (
  131. OUT VARIANT *lpVariant,
  132. IN LPCTSTR lpSearchString
  133. )
  134. {
  135. ATLTRACE(_T("CEmManager::EnumCmdSets\n"));
  136. HRESULT hr = E_FAIL;
  137. TCHAR szDirectory[_MAX_PATH];
  138. TCHAR szExt[_MAX_EXT];
  139. LPWIN32_FIND_DATA lpFindData = NULL;
  140. LONG cFiles = 0;
  141. __try {
  142. if( lpSearchString == NULL ) {
  143. _Module.GetEmDirectory (
  144. EMOBJ_CMDSET,
  145. (LPTSTR)szDirectory,
  146. sizeof szDirectory / sizeof ( TCHAR ),
  147. (LPTSTR)szExt,
  148. sizeof szExt / sizeof ( TCHAR )
  149. );
  150. }
  151. else {
  152. _tcscpy( szDirectory, lpSearchString );
  153. _tcscpy( szExt, _T(""));
  154. }
  155. hr = EnumFiles (
  156. szDirectory,
  157. szExt,
  158. &lpFindData,
  159. &cFiles
  160. );
  161. if ( SUCCEEDED(hr) ) {
  162. hr = PackageFilesToVariant (
  163. EMOBJ_CMDSET,
  164. lpFindData,
  165. cFiles,
  166. lpVariant
  167. );
  168. }
  169. if( lpFindData ) { free( lpFindData ); lpFindData = NULL; }
  170. }
  171. __except ( EXCEPTION_EXECUTE_HANDLER, 1 ) {
  172. hr = E_UNEXPECTED;
  173. _ASSERTE( false );
  174. }
  175. return (hr);
  176. }
  177. HRESULT
  178. CEmManager::EnumDumpFiles
  179. (
  180. OUT VARIANT *lpVariant,
  181. IN LPCTSTR lpSearchString
  182. )
  183. {
  184. ATLTRACE(_T("CEmManager::EnumDumpFiles\n"));
  185. HRESULT hr = E_FAIL;
  186. TCHAR szDirectory[_MAX_PATH];
  187. TCHAR szExt[_MAX_EXT];
  188. LPWIN32_FIND_DATA lpFindData = NULL;
  189. LONG cFiles = 0;
  190. __try {
  191. if(lpSearchString == NULL) {
  192. _Module.GetEmDirectory (
  193. EMOBJ_MINIDUMP,
  194. (LPTSTR)szDirectory,
  195. sizeof szDirectory / sizeof ( TCHAR ),
  196. (LPTSTR)szExt,
  197. sizeof szExt / sizeof ( TCHAR )
  198. );
  199. }
  200. else {
  201. _tcscpy( szDirectory, lpSearchString );
  202. _tcscpy( szExt, _T(""));
  203. }
  204. hr = EnumFiles (
  205. szDirectory,
  206. szExt,
  207. &lpFindData,
  208. &cFiles
  209. );
  210. if ( SUCCEEDED(hr) ) {
  211. hr = PackageFilesToVariant (
  212. EMOBJ_MINIDUMP,
  213. lpFindData,
  214. cFiles,
  215. lpVariant
  216. );
  217. }
  218. if( lpFindData ) { free( lpFindData ); lpFindData = NULL; }
  219. }
  220. __except ( EXCEPTION_EXECUTE_HANDLER, 1 ) {
  221. hr = E_UNEXPECTED;
  222. _ASSERTE( false );
  223. }
  224. return (hr);
  225. }
  226. HRESULT CEmManager::EnumFiles
  227. (
  228. LPTSTR lpszDirectory,
  229. LPTSTR lpszExt,
  230. LPWIN32_FIND_DATA *lppFindData,
  231. LONG *lpFiles
  232. )
  233. {
  234. ATLTRACE(_T("CEmManager::EnumFiles\n"));
  235. HRESULT hr = E_FAIL;
  236. HANDLE hFind = INVALID_HANDLE_VALUE;
  237. LPWIN32_FIND_DATA lpFindFileData = NULL;
  238. LONG cMaxFiles = 0;
  239. LONG cGrowBy = 100;
  240. LONG cFileBuf = 0;
  241. BOOL fContinue = TRUE;
  242. TCHAR szFileName[_MAX_PATH];
  243. DWORD dwErr;
  244. *lppFindData = NULL;
  245. *lpFiles = 0;
  246. cFileBuf = cGrowBy;
  247. cMaxFiles = 0;
  248. __try {
  249. _tcscpy ( szFileName, lpszDirectory );
  250. if ( _tcslen ( lpszExt ) > 0 ) {
  251. _tcscat ( szFileName, _T ( "\\*" ) );
  252. _tcscat ( szFileName, lpszExt );
  253. }
  254. // start with a initial buffer
  255. lpFindFileData = ( LPWIN32_FIND_DATA) malloc ( sizeof ( WIN32_FIND_DATA) * cFileBuf );
  256. if ( lpFindFileData == NULL )
  257. goto qEnumFiles;
  258. // read from the filesystem
  259. hFind = FindFirstFile ( szFileName, &lpFindFileData[cMaxFiles] );
  260. while ( hFind != INVALID_HANDLE_VALUE && fContinue ) {
  261. cMaxFiles++;
  262. // grow buffer if necessary
  263. if ( cMaxFiles == cFileBuf ) {
  264. cFileBuf += cGrowBy;
  265. LPWIN32_FIND_DATA lpNewFileData = (LPWIN32_FIND_DATA) realloc (
  266. lpFindFileData,
  267. sizeof ( WIN32_FIND_DATA) * cFileBuf
  268. );
  269. if ( lpNewFileData == NULL ) {
  270. goto qEnumFiles;
  271. }
  272. delete lpFindFileData;
  273. lpFindFileData = lpNewFileData;
  274. }
  275. fContinue = FindNextFile ( hFind, &lpFindFileData[cMaxFiles] );
  276. }
  277. if ( hFind == INVALID_HANDLE_VALUE || fContinue == FALSE ) {
  278. dwErr = GetLastError();
  279. }
  280. if ( dwErr == ERROR_NO_MORE_FILES || dwErr == ERROR_FILE_NOT_FOUND )
  281. hr = S_OK;
  282. else
  283. hr = HRESULT_FROM_WIN32 ( dwErr );
  284. qEnumFiles:
  285. if ( SUCCEEDED ( hr ) ) {
  286. *lppFindData = lpFindFileData;
  287. *lpFiles = cMaxFiles;
  288. }
  289. else {
  290. if ( lpFindFileData )
  291. free ( lpFindFileData );
  292. }
  293. if ( hFind != INVALID_HANDLE_VALUE )
  294. FindClose ( hFind );
  295. }
  296. __except ( EXCEPTION_EXECUTE_HANDLER, 1 ) {
  297. if ( lpFindFileData )
  298. free ( lpFindFileData );
  299. if ( hFind != INVALID_HANDLE_VALUE )
  300. FindClose ( hFind );
  301. hr = E_UNEXPECTED;
  302. _ASSERTE( false );
  303. }
  304. return (hr);
  305. }
  306. HRESULT CEmManager::PackageFilesToVariant
  307. (
  308. EmObjectType eObjectType,
  309. LPWIN32_FIND_DATA lpFindFileData,
  310. LONG cFiles,
  311. LPVARIANT lpVariant
  312. )
  313. {
  314. ATLTRACE(_T("CEmManager::PackageFilesToVariant\n"));
  315. HRESULT hr = E_FAIL;
  316. EmObject emObject;
  317. BSTR bstrObject = NULL;
  318. LONG iFile = 0;
  319. __try {
  320. ::VariantClear ( lpVariant );
  321. hr = Variant_CreateOneDim ( lpVariant, cFiles, VT_BSTR );
  322. if ( FAILED(hr) )
  323. goto qPackage;
  324. for ( iFile=0 ; iFile<cFiles ; iFile++ ) {
  325. ZeroMemory ( &emObject, sizeof EmObject );
  326. // type
  327. emObject.type = eObjectType;
  328. // ID
  329. emObject.nId = 0;
  330. // name
  331. _tcscpy ( emObject.szName, lpFindFileData[iFile].cFileName );
  332. emObject.nStatus = 0; //STAT_FILECREATED;
  333. // Start time
  334. emObject.dateStart = CServiceModule::GetDateFromFileTm(lpFindFileData[iFile].ftCreationTime);
  335. // End time
  336. emObject.dateEnd = 0;
  337. emObject.dwBucket1 = lpFindFileData[iFile].nFileSizeLow;
  338. // Now that EmObject is filled up, preprocess as appropriate
  339. switch ( eObjectType ) {
  340. case EMOBJ_MSINFO:
  341. FillMsInfoFileInfo( NULL, &lpFindFileData[iFile], &emObject );
  342. break;
  343. case EMOBJ_MINIDUMP:
  344. case EMOBJ_USERDUMP:
  345. FillDumpFileInfo( NULL, &lpFindFileData[iFile], &emObject );
  346. break;
  347. case EMOBJ_LOGFILE:
  348. FillLogFileInfo( NULL, &lpFindFileData[iFile], &emObject );
  349. break;
  350. case EMOBJ_CMDSET:
  351. ScanCmdfile ( NULL, &lpFindFileData[iFile], &emObject );
  352. break;
  353. }
  354. bstrObject = CopyBSTR ( (LPBYTE) &emObject, sizeof (EmObject) );
  355. if ( bstrObject == NULL ) {
  356. hr = E_OUTOFMEMORY;
  357. goto qPackage;
  358. }
  359. hr = ::SafeArrayPutElement ( lpVariant->parray, &iFile, bstrObject );
  360. if ( FAILED (hr) )
  361. goto qPackage;
  362. SysFreeString ( bstrObject );
  363. }
  364. qPackage:
  365. if ( FAILED(hr)) {
  366. ::VariantClear ( lpVariant );
  367. }
  368. }
  369. __except ( EXCEPTION_EXECUTE_HANDLER, 1 ) {
  370. ::VariantClear ( lpVariant );
  371. hr = E_UNEXPECTED;
  372. _ASSERTE( false );
  373. }
  374. return (hr);
  375. }
  376. HRESULT CEmManager::ScanCmdfile
  377. (
  378. LPCTSTR lpszCmdFileDir,
  379. LPWIN32_FIND_DATA lpFindData,
  380. EmObject *pEmObject
  381. )
  382. {
  383. USES_CONVERSION;
  384. ATLTRACE(_T("CEmManager::ScanCmdfile\n"));
  385. HRESULT hr = S_OK;
  386. const DWORD cchBuf = 512;
  387. DWORD dwBytesRead;
  388. char szBuf[cchBuf+1];
  389. HANDLE hFile = INVALID_HANDLE_VALUE;
  390. const DWORD cTemplates = 4;
  391. LPSTR szTemplate [cTemplates];
  392. DWORD dwErr;
  393. DWORD dwIndex;
  394. TCHAR szCmdDir[_MAX_PATH] = _T("");
  395. TCHAR szCurrentDir[_MAX_PATH] = _T("");
  396. DWORD dwBufSize = _MAX_PATH;
  397. BOOL bMatchFound = FALSE;
  398. char *pNewLine = NULL;
  399. __try {
  400. if( !lpszCmdFileDir ) {
  401. _Module.GetEmDirectory( EMOBJ_CMDSET, szCmdDir, sizeof( szCmdDir ) / sizeof( TCHAR ), NULL, NULL);
  402. lpszCmdFileDir = szCmdDir;
  403. }
  404. // fill template
  405. szTemplate[0] = ( "!emdbg.tag" );
  406. szTemplate[1] = ( "! emdbg.tag" );
  407. szTemplate[2] = ( "*" );
  408. szTemplate[3] = ( " *" );
  409. ZeroMemory ( szBuf, sizeof szBuf );
  410. if(GetCurrentDirectory(dwBufSize, szCurrentDir) == 0) {
  411. hr = HRESULT_FROM_WIN32(GetLastError());
  412. goto qScan;
  413. }
  414. if(SetCurrentDirectory(lpszCmdFileDir) == 0) {
  415. hr = HRESULT_FROM_WIN32(GetLastError());
  416. goto qScan;
  417. }
  418. hFile = ::CreateFile (
  419. lpFindData->cFileName,
  420. GENERIC_READ,
  421. FILE_SHARE_READ,
  422. NULL,
  423. OPEN_EXISTING,
  424. 0,
  425. NULL
  426. );
  427. if ( hFile == INVALID_HANDLE_VALUE ) {
  428. dwErr = GetLastError();
  429. hr = HRESULT_FROM_WIN32 ( dwErr );
  430. goto qScan;
  431. }
  432. if ( !::ReadFile ( hFile, szBuf, cchBuf, &dwBytesRead, NULL ) ) {
  433. dwErr = GetLastError();
  434. hr = HRESULT_FROM_WIN32 ( dwErr );
  435. goto qScan;
  436. }
  437. pNewLine = strchr(szBuf, '\r\n');
  438. if( pNewLine ) *pNewLine = '\0';
  439. // see if a valid .ecx file
  440. for ( dwIndex=0 ; dwIndex<cTemplates ; dwIndex++ ) {
  441. if ( 0 ==
  442. strncmp(
  443. szBuf,
  444. szTemplate[dwIndex],
  445. strlen ( szTemplate[dwIndex] )
  446. )
  447. ) {
  448. bMatchFound = TRUE;
  449. break;
  450. }
  451. }
  452. // check if we got a match
  453. if ( bMatchFound == FALSE ) {
  454. pEmObject->hr = E_FAIL;
  455. }
  456. else {
  457. int cCh = 0;
  458. {
  459. EmObject obj;
  460. cCh = sizeof ( obj.szBucket1 ) / sizeof ( TCHAR );
  461. }
  462. // eat spaces
  463. LPSTR pszSrc = szBuf;
  464. pszSrc += strlen ( szTemplate[dwIndex] );
  465. while ( pszSrc != NULL && *pszSrc == ' ' )
  466. pszSrc++;
  467. LPTSTR pszSrcW = A2T ( pszSrc );
  468. ZeroMemory ( pEmObject->szBucket1, cCh );
  469. _tcsncpy (
  470. pEmObject->szBucket1,
  471. pszSrcW,
  472. cCh - sizeof ( TCHAR )
  473. );
  474. }
  475. qScan:
  476. if ( hFile != INVALID_HANDLE_VALUE )
  477. ::CloseHandle ( hFile );
  478. if ( _tcscmp( szCurrentDir, _T("") ) != 0 ) {
  479. if(SetCurrentDirectory(szCurrentDir) == 0) {
  480. hr = HRESULT_FROM_WIN32(GetLastError());
  481. }
  482. }
  483. }
  484. __except ( EXCEPTION_EXECUTE_HANDLER, 1 ) {
  485. if ( hFile != INVALID_HANDLE_VALUE )
  486. ::CloseHandle ( hFile );
  487. if ( _tcscmp( szCurrentDir, _T("") ) != 0 ) {
  488. SetCurrentDirectory(szCurrentDir);
  489. }
  490. hr = E_UNEXPECTED;
  491. _ASSERTE( false );
  492. }
  493. return hr;
  494. }
  495. HRESULT CEmManager::FillLogFileInfo
  496. (
  497. LPCTSTR lpszLogFileDir,
  498. LPWIN32_FIND_DATA lpFindData,
  499. EmObject *pEmObject
  500. )
  501. {
  502. HRESULT hr = E_FAIL;
  503. LPTSTR lpszLogDir = NULL;
  504. __try
  505. {
  506. if( !lpszLogFileDir ){
  507. lpszLogDir = new TCHAR[_MAX_PATH+1];
  508. if( !lpszLogDir ) return E_OUTOFMEMORY;
  509. _Module.GetEmDirectory( EMOBJ_LOGFILE, lpszLogDir, _MAX_PATH, NULL, NULL );
  510. lpszLogFileDir = lpszLogDir;
  511. }
  512. _tcscpy(pEmObject->szSecName, lpszLogFileDir);
  513. //qFileLogFileInfo:
  514. if( lpszLogDir ) { delete [] lpszLogDir; lpszLogDir = NULL; }
  515. }
  516. __except ( EXCEPTION_EXECUTE_HANDLER, 1 ) {
  517. hr = E_UNEXPECTED;
  518. if( lpszLogDir ) { delete [] lpszLogDir; lpszLogDir = NULL; }
  519. _ASSERTE( false );
  520. }
  521. return hr;
  522. }
  523. HRESULT CEmManager::FillMsInfoFileInfo
  524. (
  525. LPCTSTR lpszMsInfoFileDir,
  526. LPWIN32_FIND_DATA lpFindData,
  527. EmObject *pEmObject
  528. )
  529. {
  530. HRESULT hr = E_FAIL;
  531. LPTSTR lpszMsInfoDir = NULL;
  532. __try
  533. {
  534. if( !lpszMsInfoFileDir ){
  535. lpszMsInfoDir = new TCHAR[_MAX_PATH+1];
  536. if( !lpszMsInfoDir ) return E_OUTOFMEMORY;
  537. _Module.GetEmDirectory( EMOBJ_MSINFO, lpszMsInfoDir, _MAX_PATH, NULL, NULL );
  538. lpszMsInfoFileDir = lpszMsInfoDir;
  539. }
  540. _tcscpy(pEmObject->szSecName, lpszMsInfoFileDir);
  541. //qFileLogFileInfo:
  542. if( lpszMsInfoDir ) { delete [] lpszMsInfoDir; lpszMsInfoDir = NULL; }
  543. }
  544. __except ( EXCEPTION_EXECUTE_HANDLER, 1 ) {
  545. hr = E_UNEXPECTED;
  546. if( lpszMsInfoDir ) { delete [] lpszMsInfoDir; lpszMsInfoDir = NULL; }
  547. _ASSERTE( false );
  548. }
  549. return hr;
  550. }
  551. HRESULT CEmManager::FillDumpFileInfo
  552. (
  553. LPCTSTR lpszDumpFileDir,
  554. LPWIN32_FIND_DATA lpFindData,
  555. EmObject *pEmObject
  556. )
  557. {
  558. HRESULT hr = E_FAIL;
  559. LPTSTR lpszDumpDir = NULL;
  560. __try
  561. {
  562. if( !lpszDumpFileDir ){
  563. lpszDumpDir = new TCHAR[_MAX_PATH+1];
  564. if( !lpszDumpDir ) return E_OUTOFMEMORY;
  565. _Module.GetEmDirectory( EMOBJ_MINIDUMP, lpszDumpDir, _MAX_PATH, NULL, NULL );
  566. lpszDumpFileDir = lpszDumpDir;
  567. }
  568. _tcscpy(pEmObject->szSecName, lpszDumpFileDir);
  569. //qFileLogFileInfo:
  570. if( lpszDumpDir ) { delete [] lpszDumpDir; lpszDumpDir = NULL; }
  571. }
  572. __except ( EXCEPTION_EXECUTE_HANDLER, 1 ) {
  573. hr = E_UNEXPECTED;
  574. if( lpszDumpDir ) { delete [] lpszDumpDir; lpszDumpDir = NULL; }
  575. _ASSERTE( false );
  576. }
  577. return hr;
  578. }
  579. //
  580. // a-mando
  581. //
  582. HRESULT
  583. CEmManager::EnumMsInfoFiles
  584. (
  585. OUT VARIANT *lpVariant,
  586. IN LPCTSTR lpSearchString
  587. )
  588. {
  589. ATLTRACE(_T("CEmManager::EnumMsInfoFiles\n"));
  590. HRESULT hr = E_FAIL;
  591. TCHAR szDirectory[_MAX_PATH];
  592. TCHAR szExt[_MAX_EXT];
  593. LPWIN32_FIND_DATA lpFindData = NULL;
  594. LONG cFiles = 0;
  595. __try {
  596. if(lpSearchString == NULL) {
  597. _Module.GetEmDirectory (
  598. EMOBJ_MSINFO,
  599. (LPTSTR)szDirectory,
  600. sizeof szDirectory / sizeof ( TCHAR ),
  601. (LPTSTR)szExt,
  602. sizeof szExt / sizeof ( TCHAR )
  603. );
  604. }
  605. else {
  606. _tcscpy( szDirectory, lpSearchString );
  607. _tcscpy( szExt, _T(""));
  608. }
  609. hr = EnumFiles (
  610. szDirectory,
  611. szExt,
  612. &lpFindData,
  613. &cFiles
  614. );
  615. if ( SUCCEEDED(hr) ) {
  616. hr = PackageFilesToVariant (
  617. EMOBJ_MSINFO,
  618. lpFindData,
  619. cFiles,
  620. lpVariant
  621. );
  622. }
  623. if( lpFindData ) { free( lpFindData ); lpFindData = NULL; }
  624. }
  625. __except ( EXCEPTION_EXECUTE_HANDLER, 1 ) {
  626. hr = E_UNEXPECTED;
  627. _ASSERTE( false );
  628. }
  629. return (hr);
  630. }
  631. // a-mando