Leaked source code of windows server 2003
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.

845 lines
31 KiB

  1. /*****************************************************************************\
  2. Author: Corey Morgan (coreym)
  3. Copyright (c) Microsoft Corporation. All rights reserved.
  4. \*****************************************************************************/
  5. #include <windows.h>
  6. #include <tchar.h>
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <wtypes.h>
  10. #include <pdh.h>
  11. #include <pdhmsg.h>
  12. #include <pdhp.h>
  13. #include "rpdh.h"
  14. #include "resource.h"
  15. #include "varg.c"
  16. DWORD GetLogFormat( LPTSTR str, LPDWORD pdwFormat );
  17. PDH_STATUS GetCountersFromFile( BOOL bExpand, HLOG hLog, HQUERY hQuery );
  18. PDH_STATUS QueryLog( HLOG hLog, HQUERY hQuery, FILE* f );
  19. PDH_STATUS AddCounters( BOOL bExpand, HLOG hLog, HQUERY hQuery );
  20. _inline BOOL IsTextFormat( DWORD dwFormat );
  21. DWORD ValidateBuild();
  22. #define CHECK_STATUS( hr ) if( ERROR_SUCCESS != hr ){ goto cleanup; }
  23. #define RELOG_ERROR_BADFILES 0xF0000001
  24. #define RELOG_ERROR_BADFORMAT 0xF0000002
  25. #define RELOG_ERROR_TIMERANGE 0xF0000003
  26. #define RELOG_ERROR_BADAPPEND 0xF0000004
  27. #define RELOG_ERROR_BADOS 0xF0000005
  28. #define WINDOWS_2000 (2195)
  29. #define REQUIRED_SERVICE_PACK (3)
  30. VARG_DECLARE_COMMANDS
  31. VARG_DEBUG( VARG_FLAG_OPTIONAL|VARG_FLAG_HIDDEN )
  32. VARG_HELP ( VARG_FLAG_OPTIONAL )
  33. VARG_BOOL ( IDS_PARAM_APPEND, VARG_FLAG_OPTIONAL, FALSE )
  34. VARG_MSZ ( IDS_PARAM_COUNTERS, VARG_FLAG_OPTIONAL, _T("") )
  35. VARG_STR ( IDS_PARAM_COUNTERFILE, VARG_FLAG_OPTIONAL|VARG_FLAG_ARG_FILENAME, _T("") )
  36. VARG_STR ( IDS_PARAM_FORMAT, VARG_FLAG_OPTIONAL|VARG_FLAG_LITERAL, _T("BIN") )
  37. VARG_STR ( IDS_PARAM_INPUT, VARG_FLAG_REQUIRED|VARG_FLAG_NOFLAG|VARG_FLAG_ARG_FILENAME, _T("") )
  38. VARG_INT ( IDS_PARAM_INTERVAL, VARG_FLAG_OPTIONAL|VARG_FLAG_ARG_DEFAULT, 0 )
  39. VARG_STR ( IDS_PARAM_OUTPUT, VARG_FLAG_OPTIONAL|VARG_FLAG_DEFAULTABLE|VARG_FLAG_RCDEFAULT, IDS_DEFAULT_OUTPUT )
  40. VARG_DATE ( IDS_PARAM_BEGIN, VARG_FLAG_OPTIONAL|VARG_FLAG_ARG_DATE )
  41. VARG_DATE ( IDS_PARAM_END, VARG_FLAG_OPTIONAL|VARG_FLAG_ARG_DATE )
  42. VARG_INI ( IDS_PARAM_SETTINGS, VARG_FLAG_OPTIONAL, NULL )
  43. VARG_BOOL ( IDS_PARAM_QUERY, VARG_FLAG_OPTIONAL, FALSE )
  44. VARG_BOOL ( IDS_PARAM_YES, VARG_FLAG_OPTIONAL, FALSE )
  45. VARG_BOOL ( IDS_PARAM_FORCERUN, VARG_FLAG_OPTIONAL|VARG_FLAG_HIDDEN, FALSE )
  46. VARG_DECLARE_NAMES
  47. eDebug,
  48. eHelp,
  49. eAppend,
  50. eCounters,
  51. eCounterFile,
  52. eFormat,
  53. eInput,
  54. eInterval,
  55. eOutput,
  56. eBegin,
  57. eEnd,
  58. eSettings,
  59. eQuery,
  60. eYes,
  61. eForceRun
  62. VARG_DECLARE_FORMAT
  63. VARG_EXHELP( eFormat, IDS_EXAMPLE_FORMAT )
  64. VARG_EXHELP( eQuery, IDS_EXAMPLE_QUERY )
  65. VARG_EXHELP( eCounterFile, IDS_EXAMPLE_COUNTERFILE )
  66. VARG_EXHELP( eCounters, IDS_EXAMPLE_COUNTERS )
  67. VARG_DECLARE_END
  68. int __cdecl _tmain( int argc, LPTSTR* argv )
  69. {
  70. DWORD dwStatus = ERROR_SUCCESS;
  71. PDH_STATUS pdhStatus = ERROR_SUCCESS;
  72. PDH_RELOG_INFO RelogInfo;
  73. DWORD dwOutputFormat;
  74. DWORD dwInputFormat;
  75. PDH_TIME_INFO InputTimeRange;
  76. LPTSTR strFile = NULL;
  77. TCHAR strOutputFile[MAXSTR] = _T("\0");
  78. DWORD dwNumEntries = 1;
  79. DWORD dwBufferSize = sizeof(PDH_TIME_INFO);
  80. int nBinary = 0;
  81. int nFiles = 0;
  82. ParseCmd( argc, argv );
  83. HLOG hLogIn = NULL;
  84. HQUERY hQuery = NULL;
  85. ZeroMemory( &RelogInfo, sizeof(PDH_RELOG_INFO) );
  86. if( ! Commands[eForceRun].bValue ){
  87. dwStatus = ValidateBuild();
  88. CHECK_STATUS( dwStatus );
  89. }
  90. if( Commands[eInput].strValue == NULL ){
  91. dwStatus = ERROR_OUTOFMEMORY;
  92. goto cleanup;
  93. }
  94. dwStatus = GetLogFormat( Commands[eFormat].strValue, &dwOutputFormat );
  95. CHECK_STATUS(dwStatus);
  96. strFile = Commands[eInput].strValue;
  97. PrintMessage( g_normal, IDS_MESSAGE_INPUT );
  98. PrintMessage( g_normal, IDS_MESSAGE_FILES );
  99. pdhStatus = R_PdhGetLogFileType( strFile, &dwInputFormat );
  100. if( pdhStatus != ERROR_SUCCESS ){
  101. dwInputFormat = 0;
  102. }
  103. switch( dwInputFormat ){
  104. case PDH_LOG_TYPE_RETIRED_BIN_:
  105. PrintMessage( g_normal, IDS_MESSAGE_LOG_OLD_BIN, strFile );
  106. break;
  107. case PDH_LOG_TYPE_CSV:
  108. PrintMessage( g_normal, IDS_MESSAGE_LOG_CSV, strFile );
  109. break;
  110. case PDH_LOG_TYPE_TSV:
  111. PrintMessage( g_normal, IDS_MESSAGE_LOG_TSV, strFile );
  112. break;
  113. case PDH_LOG_TYPE_BINARY:
  114. nBinary++;
  115. PrintMessage( g_normal, IDS_MESSAGE_LOG_BINARY, strFile );
  116. break;
  117. case PDH_LOG_TYPE_PERFMON:
  118. PrintMessage( g_normal, IDS_MESSAGE_LOG_PERFMON, strFile );
  119. break;
  120. default:
  121. PrintMessage( g_normal, IDS_MESSAGE_LOG_UNKNOWN, strFile );
  122. }
  123. varg_printf( g_normal, _T("\n") );
  124. if( nFiles > 1 && nFiles > nBinary ){
  125. dwStatus = RELOG_ERROR_BADFILES;
  126. goto cleanup;
  127. }
  128. pdhStatus = PdhOpenLogW(
  129. Commands[eInput].strValue,
  130. PDH_LOG_READ_ACCESS | PDH_LOG_OPEN_EXISTING,
  131. &dwInputFormat,
  132. NULL,
  133. 0,
  134. NULL,
  135. & hLogIn
  136. );
  137. CHECK_STATUS( pdhStatus );
  138. pdhStatus = PdhGetDataSourceTimeRange (
  139. Commands[eInput].strValue,
  140. &dwNumEntries,
  141. &InputTimeRange,
  142. &dwBufferSize
  143. );
  144. CHECK_STATUS( pdhStatus );
  145. SYSTEMTIME st;
  146. FileTimeToSystemTime( (FILETIME *)&InputTimeRange.StartTime, &st );
  147. PrintMessage( g_normal, IDS_MESSAGE_BEGIN );
  148. PrintDate( &st );
  149. FileTimeToSystemTime( (FILETIME *)&InputTimeRange.EndTime, &st );
  150. PrintMessage( g_normal, IDS_MESSAGE_END );
  151. PrintDate( &st );
  152. PrintMessage( g_normal, IDS_MESSAGE_SAMPLES, InputTimeRange.SampleCount );
  153. if( Commands[eAppend].bValue ){
  154. StringCchCopy( strOutputFile, MAXSTR, Commands[eOutput].strValue );
  155. pdhStatus = R_PdhAppendLog( Commands[eOutput].strValue, Commands[eInput].strValue );
  156. CHECK_STATUS( pdhStatus );
  157. }else{
  158. pdhStatus = PdhOpenQuery( Commands[eInput].strValue, NULL, &hQuery );
  159. CHECK_STATUS( pdhStatus );
  160. if( Commands[eQuery].bDefined ){
  161. FILE* f = NULL;
  162. if( Commands[eOutput].bDefined ){
  163. dwStatus = CheckFile( Commands[eOutput].strValue,
  164. Commands[eYes].bValue ?
  165. VARG_CF_OVERWRITE :
  166. (VARG_CF_PROMPT|VARG_CF_OVERWRITE)
  167. );
  168. CHECK_STATUS( dwStatus );
  169. f = _tfopen( Commands[eOutput].strValue, _T("w") );
  170. if( NULL == f ){
  171. dwStatus = GetLastError();
  172. }
  173. }
  174. pdhStatus = QueryLog( hLogIn, hQuery, f );
  175. if( NULL != f ){
  176. fclose(f);
  177. }
  178. }else if( (!Commands[eCounters].bDefined && !Commands[eCounterFile].bDefined) ){
  179. pdhStatus = QueryLog( hLogIn, hQuery, NULL );
  180. CHECK_STATUS( pdhStatus );
  181. }
  182. if( Commands[eCounters].bDefined ){
  183. pdhStatus = AddCounters( dwInputFormat, hLogIn, hQuery );
  184. CHECK_STATUS( pdhStatus );
  185. }
  186. if( Commands[eCounterFile].bDefined ){
  187. pdhStatus = GetCountersFromFile(
  188. (IsTextFormat( dwInputFormat ) || IsTextFormat(dwOutputFormat)),
  189. hLogIn,
  190. hQuery
  191. );
  192. CHECK_STATUS( pdhStatus );
  193. }
  194. if( Commands[eBegin].bDefined ){
  195. FILETIME ft;
  196. SystemTimeToFileTime( &Commands[eBegin].stValue, &ft );
  197. RelogInfo.TimeInfo.StartTime = *(LONGLONG *)&ft;
  198. if( RelogInfo.TimeInfo.StartTime >= InputTimeRange.EndTime ){
  199. dwStatus = RELOG_ERROR_TIMERANGE;
  200. }
  201. CHECK_STATUS(dwStatus);
  202. }
  203. if( Commands[eEnd].bDefined ){
  204. FILETIME ft;
  205. SystemTimeToFileTime( &Commands[eEnd].stValue, &ft );
  206. RelogInfo.TimeInfo.EndTime = *(LONGLONG *)&ft;
  207. if( RelogInfo.TimeInfo.EndTime <= InputTimeRange.StartTime ){
  208. dwStatus = RELOG_ERROR_TIMERANGE;
  209. }
  210. CHECK_STATUS(dwStatus);
  211. }
  212. if( Commands[eOutput].bDefined && !Commands[eQuery].bDefined ){
  213. TCHAR drive[_MAX_DRIVE];
  214. TCHAR path[_MAX_DIR];
  215. TCHAR file[_MAX_FNAME];
  216. TCHAR ext[_MAX_EXT];
  217. RelogInfo.dwFileFormat = dwOutputFormat;
  218. _tsplitpath( Commands[eOutput].strValue, drive, path, file, ext );
  219. if( 0 == _tcslen( ext ) ){
  220. switch( RelogInfo.dwFileFormat ){
  221. case PDH_LOG_TYPE_TSV: StringCchCopy( ext, _MAX_EXT, _T("tsv") ); break;
  222. case PDH_LOG_TYPE_CSV: StringCchCopy( ext, _MAX_EXT, _T("csv") ); break;
  223. case PDH_LOG_TYPE_SQL: break;
  224. case PDH_LOG_TYPE_BINARY:
  225. case PDH_LOG_TYPE_RETIRED_BIN_:
  226. StringCchCopy( ext, _MAX_EXT, _T("blg") ); break;
  227. }
  228. }
  229. _tmakepath( strOutputFile, drive, path, file, ext );
  230. RelogInfo.dwFlags = PDH_LOG_WRITE_ACCESS | PDH_LOG_CREATE_ALWAYS;
  231. RelogInfo.strLog = strOutputFile;
  232. RelogInfo.TimeInfo.SampleCount = Commands[eInterval].nValue;
  233. dwStatus = CheckFile( strOutputFile, Commands[eYes].bValue ? VARG_CF_OVERWRITE : (VARG_CF_PROMPT|VARG_CF_OVERWRITE) );
  234. CHECK_STATUS(dwStatus);
  235. pdhStatus = R_PdhRelog( Commands[eInput].strValue, hQuery, &RelogInfo );
  236. CHECK_STATUS( pdhStatus );
  237. }
  238. }
  239. if( Commands[eOutput].bDefined && !Commands[eQuery].bDefined && pdhStatus == ERROR_SUCCESS ){
  240. pdhStatus = PdhGetDataSourceTimeRange (
  241. strOutputFile,
  242. &dwNumEntries,
  243. &InputTimeRange,
  244. &dwBufferSize
  245. );
  246. CHECK_STATUS( pdhStatus );
  247. PrintMessage( g_normal, IDS_MESSAGE_OUTPUT );
  248. PrintMessage( g_normal, IDS_MESSAGE_FILE, strOutputFile );
  249. SYSTEMTIME st;
  250. FileTimeToSystemTime( (FILETIME *)&InputTimeRange.StartTime, &st );
  251. PrintMessage( g_normal, IDS_MESSAGE_BEGIN );
  252. PrintDate( &st );
  253. FileTimeToSystemTime( (FILETIME *)&InputTimeRange.EndTime, &st );
  254. PrintMessage( g_normal, IDS_MESSAGE_END );
  255. PrintDate( &st );
  256. PrintMessage( g_normal, IDS_MESSAGE_SAMPLES, InputTimeRange.SampleCount );
  257. }
  258. cleanup:
  259. if( hLogIn != NULL ){
  260. PdhCloseLog( hLogIn, PDH_FLAGS_CLOSE_QUERY );
  261. }
  262. switch( dwStatus ){
  263. case RELOG_ERROR_BADOS:
  264. varg_printf( g_normal, _T("\n") );
  265. PrintMessage( g_debug, IDS_MESSAGE_BADOS );
  266. break;
  267. case RELOG_ERROR_TIMERANGE:
  268. PrintMessage( g_debug, IDS_MESSAGE_BADRANGE );
  269. break;
  270. case RELOG_ERROR_BADFORMAT:
  271. PrintMessage( g_debug, IDS_MESSAGE_BADFORMAT, Commands[eFormat].strValue );
  272. break;
  273. case RELOG_ERROR_BADAPPEND:
  274. PrintMessage( g_debug, IDS_MESSAGE_BADFORMAT, Commands[eFormat].strValue );
  275. break;
  276. case RELOG_ERROR_BADFILES:
  277. PrintMessage( g_debug, IDS_MESSAGE_BADFILES );
  278. break;
  279. case ERROR_SUCCESS:
  280. if( ERROR_SUCCESS == pdhStatus ){
  281. PrintMessage( g_normal, IDS_MESSAGE_SUCCESS );
  282. }else{
  283. switch( pdhStatus ){
  284. case PDH_TIME_MISMATCH:
  285. PrintMessage( g_debug, IDS_MESSAGE_APPENDTIME );
  286. break;
  287. case PDH_HEADER_MISMATCH:
  288. PrintMessage( g_debug, IDS_MESSAGE_BADHEADERS );
  289. break;
  290. case PDH_TYPE_MISMATCH:
  291. PrintMessage( g_debug, IDS_MESSAGE_TYPEMISMATCH );
  292. break;
  293. default:
  294. PrintErrorEx( pdhStatus, _T("PDH.DLL") );
  295. }
  296. dwStatus = pdhStatus;
  297. }
  298. break;
  299. default:
  300. PrintError( dwStatus );
  301. }
  302. FreeCmd();
  303. return dwStatus;
  304. }
  305. _inline BOOL IsTextFormat( DWORD dwFormat )
  306. {
  307. switch( dwFormat ){
  308. case PDH_LOG_TYPE_CSV:
  309. case PDH_LOG_TYPE_TSV:
  310. case PDH_LOG_TYPE_SQL:
  311. return TRUE;
  312. default:
  313. return FALSE;
  314. }
  315. }
  316. DWORD
  317. GetLogFormat( LPTSTR str, LPDWORD pdwFormat )
  318. {
  319. DWORD dwFormat = PDH_LOG_TYPE_UNDEFINED;
  320. if( str != NULL ){
  321. if( !_tcsicmp( str, _T("TSV")) ){
  322. dwFormat = PDH_LOG_TYPE_TSV;
  323. }else if( !_tcsicmp( str, _T("CSV")) ){
  324. dwFormat = PDH_LOG_TYPE_CSV;
  325. }else if( !_tcsicmp( str, _T("BIN")) ){
  326. dwFormat = PDH_LOG_TYPE_RETIRED_BIN_;
  327. }else if( !_tcsicmp( str, _T("BLG")) ){
  328. dwFormat = PDH_LOG_TYPE_RETIRED_BIN_;
  329. }
  330. }
  331. if( dwFormat == PDH_LOG_TYPE_UNDEFINED ){
  332. return RELOG_ERROR_BADFORMAT;
  333. }
  334. *pdwFormat = dwFormat;
  335. return ERROR_SUCCESS;
  336. }
  337. PDH_STATUS
  338. RelogGetMachines( HLOG hLog, LPTSTR* mszMachines )
  339. {
  340. PDH_STATUS pdhStatus;
  341. DWORD dwSize = 0;
  342. pdhStatus = PdhEnumMachines( Commands[eInput].strValue, NULL, &dwSize );
  343. if( ERROR_SUCCESS == pdhStatus ||
  344. PDH_MORE_DATA == pdhStatus ||
  345. PDH_INSUFFICIENT_BUFFER == pdhStatus ){
  346. *mszMachines = (LPTSTR)VARG_ALLOC( sizeof(TCHAR)*dwSize );
  347. if( *mszMachines != NULL ){
  348. pdhStatus = PdhEnumMachines( Commands[eInput].strValue, *mszMachines, &dwSize );
  349. }else{
  350. pdhStatus = PDH_MEMORY_ALLOCATION_FAILURE;
  351. }
  352. }
  353. return pdhStatus;
  354. }
  355. PDH_STATUS
  356. RelogAddCounter( BOOL bExpand, HLOG hLog, HQUERY hQuery, LPTSTR strCounter, LPTSTR mszMachines )
  357. {
  358. PDH_STATUS pdhStatus = ERROR_SUCCESS;
  359. HCOUNTER pCounter;
  360. if( hQuery == NULL || strCounter == NULL ){
  361. return ERROR_SUCCESS;
  362. }
  363. if( _tcslen( strCounter ) > 3 ){
  364. if( strCounter[1] == _T('\\') ){
  365. pdhStatus = PdhAddCounter(
  366. hQuery,
  367. strCounter,
  368. 0,
  369. &pCounter
  370. );
  371. }else{
  372. TCHAR buffer[MAXSTR];
  373. LPTSTR strMachine = mszMachines;
  374. if( strMachine != NULL ){
  375. while( *strMachine != _T('\0') ){
  376. StringCchPrintf( buffer, MAXSTR, _T("%s%s%s"),
  377. strMachine,
  378. (*strCounter == _T('\\')) ? _T("") : _T("\\"),
  379. strCounter );
  380. if( bExpand ){
  381. LPTSTR pBuffer = NULL;
  382. DWORD dwBufferSize = 0;
  383. do{
  384. pdhStatus = PdhExpandWildCardPath(
  385. Commands[eInput].strValue,
  386. buffer,
  387. pBuffer,
  388. &dwBufferSize,
  389. 0
  390. );
  391. if( PDH_MORE_DATA == pdhStatus ){
  392. VARG_FREE( pBuffer );
  393. pBuffer = (LPTSTR)VARG_ALLOC( ++dwBufferSize * sizeof(TCHAR) );
  394. if( pBuffer == NULL ){
  395. break;
  396. }
  397. }
  398. }while(PDH_MORE_DATA == pdhStatus);
  399. if( ERROR_SUCCESS == pdhStatus && pBuffer != NULL ){
  400. LPTSTR szCounter = pBuffer;
  401. while( *szCounter != _T('\0') ){
  402. pdhStatus = PdhAddCounter(
  403. hQuery,
  404. szCounter,
  405. 0,
  406. &pCounter
  407. );
  408. szCounter += (_tcslen( szCounter) +1 );
  409. }
  410. }
  411. VARG_FREE( pBuffer );
  412. }else{
  413. pdhStatus = PdhAddCounter(
  414. hQuery,
  415. buffer,
  416. 0,
  417. &pCounter
  418. );
  419. }
  420. strMachine += (_tcslen( strMachine ) + 1);
  421. }
  422. }
  423. }
  424. }
  425. return ERROR_SUCCESS;
  426. }
  427. PDH_STATUS
  428. AddCounters( BOOL bExpand, HLOG hLog, HQUERY hQuery )
  429. {
  430. PDH_STATUS pdhStatus;
  431. LPTSTR strPath = Commands[eCounters].strValue;
  432. LPTSTR mszMachines = NULL;
  433. RelogGetMachines( hLog, &mszMachines );
  434. if( strPath != NULL ){
  435. while( *strPath != _T('\0') ){
  436. pdhStatus = RelogAddCounter( bExpand, hLog, hQuery, strPath, mszMachines );
  437. strPath += _tcslen( strPath )+1;
  438. }
  439. }
  440. VARG_FREE( mszMachines );
  441. return ERROR_SUCCESS;
  442. }
  443. PDH_STATUS
  444. GetCountersFromFile( BOOL bExpand, HLOG hLog, HQUERY hQuery )
  445. {
  446. TCHAR buffer[MAXSTR];
  447. PDH_STATUS pdhStatus;
  448. LPTSTR strCounter = NULL;
  449. LPTSTR mszMachines = NULL;
  450. FILE* f = _tfopen( Commands[eCounterFile].strValue, _T("r") );
  451. if( !f ){
  452. DWORD dwStatus = GetLastError();
  453. return PDH_LOG_FILE_OPEN_ERROR;
  454. }
  455. RelogGetMachines( hLog, &mszMachines );
  456. while( NULL != _fgetts( buffer, MAXSTR, f ) ){
  457. if( buffer[0] == _T(';') || // comments
  458. buffer[0] == _T('#') ){
  459. continue;
  460. }
  461. Chomp(buffer);
  462. strCounter = _tcstok( buffer, _T("\"\n") );
  463. if( strCounter != NULL ){
  464. pdhStatus = RelogAddCounter( bExpand, hLog, hQuery, buffer, mszMachines );
  465. }
  466. }
  467. fclose( f );
  468. VARG_FREE( mszMachines );
  469. return ERROR_SUCCESS;
  470. }
  471. _inline BOOL IsSameInstance( LPTSTR strLastInstance, LPTSTR strInstance )
  472. {
  473. if( strLastInstance == NULL || strInstance == NULL ){
  474. return FALSE;
  475. }
  476. return ( _tcscmp( strLastInstance, strInstance ) == 0 );
  477. }
  478. PDH_STATUS
  479. QueryLog( HLOG hLog, HQUERY hQuery, FILE* f )
  480. {
  481. PDH_STATUS pdhStatus;
  482. LPTSTR mszMachines = NULL;
  483. LPTSTR strMachine = NULL;
  484. LPTSTR strFullCounterPath = NULL;
  485. DWORD dwFullCounterPathSize = 0;
  486. DWORD dwMachines = 0;
  487. HCOUNTER pCounter;
  488. pdhStatus = PdhEnumMachines( Commands[eInput].strValue, mszMachines, &dwMachines );
  489. if( ERROR_SUCCESS == pdhStatus ||
  490. PDH_MORE_DATA == pdhStatus ||
  491. PDH_INSUFFICIENT_BUFFER == pdhStatus ){
  492. mszMachines = (LPTSTR)VARG_ALLOC( dwMachines * sizeof(TCHAR) );
  493. if( mszMachines == NULL ){
  494. pdhStatus = PDH_MEMORY_ALLOCATION_FAILURE;
  495. goto cleanup;
  496. }
  497. pdhStatus = PdhEnumMachines( Commands[eInput].strValue, mszMachines, &dwMachines );
  498. if( ERROR_SUCCESS == pdhStatus ){
  499. strMachine = mszMachines;
  500. while( NULL != strMachine && strMachine[0] != _T('\0') ){
  501. LPTSTR mszObjects = NULL;
  502. LPTSTR strObject = NULL;
  503. DWORD dwObjects = 0;
  504. pdhStatus = PdhEnumObjects(
  505. Commands[eInput].strValue,
  506. strMachine,
  507. mszObjects,
  508. &dwObjects,
  509. PERF_DETAIL_WIZARD,
  510. FALSE
  511. );
  512. if( ERROR_SUCCESS == pdhStatus ||
  513. PDH_MORE_DATA == pdhStatus ||
  514. PDH_INSUFFICIENT_BUFFER == pdhStatus ){
  515. mszObjects = (LPTSTR)VARG_ALLOC( dwObjects * sizeof(TCHAR));
  516. if( mszObjects == NULL ){
  517. VARG_FREE( mszMachines );
  518. pdhStatus = PDH_MEMORY_ALLOCATION_FAILURE;
  519. goto cleanup;
  520. }
  521. pdhStatus = PdhEnumObjects(
  522. Commands[eInput].strValue,
  523. strMachine,
  524. mszObjects,
  525. &dwObjects,
  526. PERF_DETAIL_WIZARD,
  527. FALSE
  528. );
  529. strObject = mszObjects;
  530. while( NULL != strObject && strObject[0] != _T('\0') ){
  531. LPTSTR mszCounters = NULL;
  532. LPTSTR strCounter = NULL;
  533. LPTSTR mszInstances = NULL;
  534. LPTSTR strInstance = NULL;
  535. DWORD dwCounters = 0;
  536. DWORD dwInstances = 0;
  537. pdhStatus = PdhEnumObjectItems(
  538. Commands[eInput].strValue,
  539. strMachine,
  540. strObject,
  541. mszCounters,
  542. &dwCounters,
  543. mszInstances,
  544. &dwInstances,
  545. PERF_DETAIL_WIZARD,
  546. 0
  547. );
  548. if( ERROR_SUCCESS == pdhStatus ||
  549. PDH_MORE_DATA == pdhStatus ||
  550. PDH_INSUFFICIENT_BUFFER == pdhStatus ){
  551. if( dwCounters > 0 ){
  552. mszCounters = (LPTSTR)VARG_ALLOC( dwCounters * sizeof(TCHAR) );
  553. }
  554. if( dwInstances > 0 ){
  555. mszInstances = (LPTSTR)VARG_ALLOC( dwInstances * sizeof(TCHAR) );
  556. }
  557. if( (mszCounters == NULL && dwCounters > 0 ) ||
  558. (mszInstances == NULL && dwInstances > 0) ){
  559. VARG_FREE( mszMachines );
  560. VARG_FREE( mszObjects );
  561. VARG_FREE( mszCounters );
  562. VARG_FREE( mszInstances );
  563. pdhStatus = PDH_MEMORY_ALLOCATION_FAILURE;
  564. goto cleanup;
  565. }
  566. pdhStatus = PdhEnumObjectItems(
  567. Commands[eInput].strValue,
  568. strMachine,
  569. strObject,
  570. mszCounters,
  571. &dwCounters,
  572. mszInstances,
  573. &dwInstances,
  574. PERF_DETAIL_WIZARD,
  575. 0
  576. );
  577. if( ERROR_SUCCESS == pdhStatus ){
  578. strCounter = mszCounters;
  579. while( NULL != strCounter && strCounter[0] != _T('\0') ){
  580. PDH_COUNTER_PATH_ELEMENTS_W pdhElements;
  581. ZeroMemory( &pdhElements, sizeof( PDH_COUNTER_PATH_ELEMENTS ) );
  582. pdhElements.szMachineName = strMachine;
  583. pdhElements.szObjectName = strObject;
  584. pdhElements.szCounterName = strCounter;
  585. strInstance = mszInstances;
  586. if( NULL != strInstance && strInstance[0] != _T('\0') ){
  587. LPTSTR strLastInstance = NULL;
  588. ULONG nInstance = 0;
  589. while( strInstance[0] != _T('\0') ){
  590. DWORD dwSize = dwFullCounterPathSize;
  591. pdhElements.szInstanceName = strInstance;
  592. if( ! IsSameInstance( strLastInstance, strInstance ) ){
  593. pdhElements.dwInstanceIndex = -1;
  594. nInstance = 0;
  595. }else{
  596. pdhElements.dwInstanceIndex = ++nInstance;
  597. }
  598. pdhStatus = PdhMakeCounterPath( &pdhElements, strFullCounterPath, &dwSize, 0 );
  599. if( PDH_INSUFFICIENT_BUFFER == pdhStatus || PDH_MORE_DATA == pdhStatus || ERROR_SUCCESS == pdhStatus ){
  600. VARG_FREE( strFullCounterPath );
  601. strFullCounterPath = (LPTSTR)VARG_ALLOC( dwSize * sizeof(TCHAR) );
  602. if( NULL != strFullCounterPath ){
  603. dwFullCounterPathSize = dwSize;
  604. pdhStatus = PdhMakeCounterPath( &pdhElements, strFullCounterPath, &dwSize, 0 );
  605. }
  606. }
  607. strLastInstance = strInstance;
  608. strInstance += _tcslen( strInstance ) + 1;
  609. if( Commands[eQuery].bValue ){
  610. if( NULL != f ){
  611. _ftprintf( f, _T("%s\n"), strFullCounterPath );
  612. }else{
  613. varg_printf( g_normal, _T("%1!s!\n"), strFullCounterPath );
  614. }
  615. }
  616. if( Commands[eCounters].bDefined == FALSE && Commands[eOutput].bDefined ){
  617. pdhStatus = PdhAddCounter(
  618. hQuery,
  619. strFullCounterPath,
  620. 0,
  621. &pCounter
  622. );
  623. }
  624. }
  625. }else{
  626. DWORD dwSize = dwFullCounterPathSize;
  627. pdhStatus = PdhMakeCounterPath( &pdhElements, strFullCounterPath, &dwSize, 0 );
  628. if( PDH_INSUFFICIENT_BUFFER == pdhStatus || PDH_MORE_DATA == pdhStatus || ERROR_SUCCESS == pdhStatus){
  629. VARG_FREE( strFullCounterPath );
  630. strFullCounterPath = (LPTSTR)VARG_ALLOC( dwSize * sizeof(TCHAR) );
  631. if( NULL != strFullCounterPath ){
  632. dwFullCounterPathSize = dwSize;
  633. pdhStatus = PdhMakeCounterPath( &pdhElements, strFullCounterPath, &dwSize, 0 );
  634. }
  635. }
  636. if( Commands[eQuery].bValue ){
  637. if( NULL != f ){
  638. _ftprintf( f, _T("%s\n"), strFullCounterPath );
  639. }else{
  640. varg_printf( g_normal, _T("%1!s!\n"), strFullCounterPath );
  641. }
  642. }
  643. if( Commands[eCounters].bDefined == FALSE && Commands[eOutput].bDefined ){
  644. pdhStatus = PdhAddCounter(
  645. hQuery,
  646. strFullCounterPath,
  647. 0,
  648. &pCounter
  649. );
  650. }
  651. }
  652. strCounter += _tcslen( strCounter ) + 1;
  653. }
  654. }
  655. VARG_FREE( mszCounters );
  656. VARG_FREE( mszInstances );
  657. }
  658. strObject += _tcslen( strObject ) + 1;
  659. }
  660. VARG_FREE( mszObjects );
  661. }
  662. strMachine += _tcslen( strMachine ) + 1;
  663. }
  664. }
  665. VARG_FREE( mszMachines );
  666. }
  667. cleanup:
  668. VARG_FREE( strFullCounterPath );
  669. if( NULL == f ){
  670. if( ERROR_SUCCESS == pdhStatus && Commands[eQuery].bValue){
  671. varg_printf( g_normal, _T("\n") );
  672. }
  673. }
  674. return pdhStatus;
  675. }
  676. DWORD ValidateBuild()
  677. {
  678. OSVERSIONINFO VersionInfo;
  679. BOOL bResult;
  680. VersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  681. bResult = GetVersionEx( &VersionInfo );
  682. return ERROR_SUCCESS;
  683. if( ! bResult ){
  684. ZeroMemory( &VersionInfo, sizeof( OSVERSIONINFO ) );
  685. }
  686. if( VersionInfo.dwBuildNumber == WINDOWS_2000 ){
  687. TCHAR buffer[128];
  688. LPTSTR szServicePack;
  689. _tcsncpy( buffer, VersionInfo.szCSDVersion, 128 );
  690. szServicePack = _tcstok( buffer, _T(" \n") );
  691. szServicePack = _tcstok( NULL, _T(" \n") );
  692. szServicePack = _tcstok( NULL, _T(" \n") );
  693. if( szServicePack != NULL ){
  694. int nPack;
  695. nPack = _ttoi( szServicePack );
  696. if( nPack >= REQUIRED_SERVICE_PACK ){
  697. return ERROR_SUCCESS;
  698. }
  699. }
  700. }
  701. return RELOG_ERROR_BADOS;
  702. }