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.

1312 lines
38 KiB

  1. // exctrdlg.cpp : implementation file
  2. //
  3. #ifndef UNICODE
  4. #define UNICODE 1
  5. #endif
  6. #ifndef _UNICODE
  7. #define _UNICODE 1
  8. #endif
  9. #include "stdafx.h"
  10. #include "exctrlst.h"
  11. #include "exctrdlg.h"
  12. #include "tchar.h"
  13. // string constants
  14. // displayed strings
  15. static const TCHAR cszNotFound[] = {TEXT("Not Found")};
  16. static const TCHAR cszNA[] = {TEXT("N/A")};
  17. // strings that are not displayed
  18. static const WCHAR cszDisablePerformanceCounters[] = {L"Disable Performance Counters"};
  19. static const WCHAR cszDefaultLangId[] = {L"009"};
  20. static const TCHAR cszDoubleBackslash[] = {TEXT("\\\\")};
  21. static const TCHAR cszSpace[] = {TEXT(" ")};
  22. static const TCHAR cszSplat[] = {TEXT("*")};
  23. static const TCHAR cszServIdFmt[] = {TEXT("%d %s")};
  24. static const TCHAR cszOpen[] = {TEXT("Open")};
  25. static const TCHAR cszCollect[] = {TEXT("Collect")};
  26. static const TCHAR cszClose[] = {TEXT("Close")};
  27. static const TCHAR cszIdFmt[] = {TEXT("0x%8.8x (%d) %s")};
  28. static const TCHAR cszSortIdFmt[] = {TEXT("0x%8.8x\t%s")};
  29. static const TCHAR cszTab[] = {TEXT("\t")};
  30. static const TCHAR cszFirstCounter[] = {TEXT("First Counter")};
  31. static const TCHAR cszLastCounter[] = {TEXT("Last Counter")};
  32. static const TCHAR cszFirstHelp[] = {TEXT("First Help")};
  33. static const TCHAR cszLastHelp[] = {TEXT("Last Help")};
  34. static const TCHAR cszLibrary[] = {TEXT("Library")};
  35. static const TCHAR cszPerformance[] = {TEXT("\\Performance")};
  36. static const TCHAR cszServiceKeyName[] = {TEXT("SYSTEM\\CurrentControlSet\\Services")};
  37. static const TCHAR cszNamesKey[] = {TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Perflib")};
  38. static const TCHAR cszSlash[] = {TEXT("\\")};
  39. static const WCHAR cszVersionName[] = {L"Version"};
  40. static const WCHAR cszCounterName[] = {L"Counter "};
  41. static const WCHAR cszHelpName[] = {L"Explain "};
  42. static const WCHAR cszCounters[] = {L"Counters"};
  43. static const TCHAR cszHelp[] = {TEXT("Help")};
  44. #ifdef _DEBUG
  45. #undef THIS_FILE
  46. static char BASED_CODE THIS_FILE[] = __FILE__;
  47. #endif
  48. BOOL CExctrlstDlg::IndexHasString (
  49. DWORD dwIndex
  50. )
  51. {
  52. if ((dwIndex <= dwLastElement) && (pNameTable != NULL)) {
  53. if (pNameTable[dwIndex] != NULL) {
  54. return TRUE;
  55. } else {
  56. return FALSE;
  57. }
  58. } else {
  59. return FALSE;
  60. }
  61. }
  62. static
  63. LPWSTR
  64. *BuildNameTable(
  65. LPCWSTR szMachineName,
  66. LPCWSTR lpszLangIdArg, // unicode value of Language subkey
  67. PDWORD pdwLastItem, // size of array in elements
  68. PDWORD pdwIdArray // array for index ID's
  69. )
  70. /*++
  71. BuildNameTable
  72. Arguments:
  73. hKeyRegistry
  74. Handle to an open registry (this can be local or remote.) and
  75. is the value returned by RegConnectRegistry or a default key.
  76. lpszLangId
  77. The unicode id of the language to look up. (default is 409)
  78. Return Value:
  79. pointer to an allocated table. (the caller must MemoryFree it when finished!)
  80. the table is an array of pointers to zero terminated strings. NULL is
  81. returned if an error occured.
  82. --*/
  83. {
  84. HKEY hKeyRegistry; // handle to registry db with counter names
  85. LPWSTR *lpReturnValue;
  86. LPCWSTR lpszLangId;
  87. LPWSTR *lpCounterId;
  88. LPWSTR lpCounterNames;
  89. LPWSTR lpHelpText;
  90. LPWSTR lpThisName;
  91. LONG lWin32Status;
  92. DWORD dwLastError;
  93. DWORD dwValueType;
  94. DWORD dwArraySize;
  95. DWORD dwBufferSize;
  96. DWORD dwCounterSize;
  97. DWORD dwHelpSize;
  98. DWORD dwThisCounter;
  99. DWORD dwSystemVersion;
  100. DWORD dwLastId;
  101. DWORD dwLastHelpId;
  102. DWORD dwLastCounterIdUsed;
  103. DWORD dwLastHelpIdUsed;
  104. HKEY hKeyValue;
  105. HKEY hKeyNames;
  106. LPWSTR lpValueNameString;
  107. WCHAR CounterNameBuffer [50];
  108. WCHAR HelpNameBuffer [50];
  109. if (szMachineName != NULL) {
  110. lWin32Status = RegConnectRegistryW (szMachineName,
  111. HKEY_LOCAL_MACHINE,
  112. &hKeyRegistry);
  113. } else {
  114. lWin32Status = ERROR_SUCCESS;
  115. hKeyRegistry = HKEY_LOCAL_MACHINE;
  116. }
  117. lpValueNameString = NULL; //initialize to NULL
  118. lpReturnValue = NULL;
  119. hKeyValue = NULL;
  120. hKeyNames = NULL;
  121. // check for null arguments and insert defaults if necessary
  122. if (!lpszLangIdArg) {
  123. lpszLangId = cszDefaultLangId;
  124. } else {
  125. lpszLangId = lpszLangIdArg;
  126. }
  127. // open registry to get number of items for computing array size
  128. lWin32Status = RegOpenKeyEx (
  129. hKeyRegistry,
  130. cszNamesKey,
  131. RESERVED,
  132. KEY_READ,
  133. &hKeyValue);
  134. if (lWin32Status != ERROR_SUCCESS) {
  135. goto BNT_BAILOUT;
  136. }
  137. // get number of items
  138. dwBufferSize = sizeof (dwLastHelpId);
  139. lWin32Status = RegQueryValueEx (
  140. hKeyValue,
  141. cszLastHelp,
  142. RESERVED,
  143. &dwValueType,
  144. (LPBYTE)&dwLastHelpId,
  145. &dwBufferSize);
  146. if ((lWin32Status != ERROR_SUCCESS) || (dwValueType != REG_DWORD)) {
  147. goto BNT_BAILOUT;
  148. }
  149. pdwIdArray[2] = dwLastHelpId;
  150. // get number of items
  151. dwBufferSize = sizeof (dwLastId);
  152. lWin32Status = RegQueryValueEx (
  153. hKeyValue,
  154. cszLastCounter,
  155. RESERVED,
  156. &dwValueType,
  157. (LPBYTE)&dwLastId,
  158. &dwBufferSize);
  159. if ((lWin32Status != ERROR_SUCCESS) || (dwValueType != REG_DWORD)) {
  160. goto BNT_BAILOUT;
  161. }
  162. pdwIdArray[0] = dwLastId;
  163. if (dwLastId < dwLastHelpId)
  164. dwLastId = dwLastHelpId;
  165. dwArraySize = dwLastId * sizeof(LPWSTR);
  166. // get Perflib system version
  167. dwBufferSize = sizeof (dwSystemVersion);
  168. lWin32Status = RegQueryValueEx (
  169. hKeyValue,
  170. cszVersionName,
  171. RESERVED,
  172. &dwValueType,
  173. (LPBYTE)&dwSystemVersion,
  174. &dwBufferSize);
  175. if ((lWin32Status != ERROR_SUCCESS) || (dwValueType != REG_DWORD)) {
  176. dwSystemVersion = OLD_VERSION;
  177. // reset the error status
  178. lWin32Status = ERROR_SUCCESS;
  179. }
  180. if (dwSystemVersion == OLD_VERSION) {
  181. // get names from registry
  182. lpValueNameString = (LPWSTR)HeapAlloc (GetProcessHeap(), 0,
  183. lstrlen(cszNamesKey) * sizeof (WCHAR) +
  184. lstrlen(cszSlash) * sizeof (WCHAR) +
  185. lstrlen(lpszLangId) * sizeof (WCHAR) +
  186. sizeof (UNICODE_NULL));
  187. if (!lpValueNameString) goto BNT_BAILOUT;
  188. lstrcpy (lpValueNameString, cszNamesKey);
  189. lstrcat (lpValueNameString, cszSlash);
  190. lstrcat (lpValueNameString, lpszLangId);
  191. lWin32Status = RegOpenKeyEx (
  192. hKeyRegistry,
  193. lpValueNameString,
  194. RESERVED,
  195. KEY_READ,
  196. &hKeyNames);
  197. } else {
  198. if (szMachineName[0] == 0) {
  199. hKeyNames = HKEY_PERFORMANCE_DATA;
  200. } else {
  201. lWin32Status = RegConnectRegistry (szMachineName,
  202. HKEY_PERFORMANCE_DATA,
  203. &hKeyNames);
  204. }
  205. lstrcpy (CounterNameBuffer, cszCounterName);
  206. lstrcat (CounterNameBuffer, lpszLangId);
  207. lstrcpy (HelpNameBuffer, cszHelpName);
  208. lstrcat (HelpNameBuffer, lpszLangId);
  209. }
  210. // get size of counter names and add that to the arrays
  211. if (lWin32Status != ERROR_SUCCESS) {
  212. goto BNT_BAILOUT;
  213. }
  214. dwBufferSize = 0;
  215. lWin32Status = RegQueryValueEx (
  216. hKeyNames,
  217. dwSystemVersion == (DWORD)OLD_VERSION ? cszCounters : CounterNameBuffer,
  218. RESERVED,
  219. &dwValueType,
  220. NULL,
  221. &dwBufferSize);
  222. if (lWin32Status != ERROR_SUCCESS) {
  223. goto BNT_BAILOUT;
  224. }
  225. dwCounterSize = dwBufferSize;
  226. // get size of counter names and add that to the arrays
  227. if (lWin32Status != ERROR_SUCCESS) goto BNT_BAILOUT;
  228. dwBufferSize = 0;
  229. lWin32Status = RegQueryValueEx (
  230. hKeyNames,
  231. dwSystemVersion == (DWORD)OLD_VERSION ? cszHelp : HelpNameBuffer,
  232. RESERVED,
  233. &dwValueType,
  234. NULL,
  235. &dwBufferSize);
  236. if (lWin32Status != ERROR_SUCCESS) {
  237. goto BNT_BAILOUT;
  238. }
  239. dwHelpSize = dwBufferSize;
  240. lpReturnValue = (LPWSTR *)HeapAlloc (GetProcessHeap(), 0,dwArraySize + dwCounterSize + dwHelpSize);
  241. if (!lpReturnValue) {
  242. goto BNT_BAILOUT;
  243. }
  244. // initialize pointers into buffer
  245. lpCounterId = lpReturnValue;
  246. lpCounterNames = (LPWSTR)((LPBYTE)lpCounterId + dwArraySize);
  247. lpHelpText = (LPWSTR)((LPBYTE)lpCounterNames + dwCounterSize);
  248. // read counters into memory
  249. dwBufferSize = dwCounterSize;
  250. lWin32Status = RegQueryValueExW (
  251. hKeyNames,
  252. dwSystemVersion == OLD_VERSION ? cszCounters : CounterNameBuffer,
  253. RESERVED,
  254. &dwValueType,
  255. (LPBYTE)lpCounterNames,
  256. &dwBufferSize);
  257. if (!lpReturnValue) {
  258. goto BNT_BAILOUT;
  259. }
  260. dwBufferSize = dwHelpSize;
  261. lWin32Status = RegQueryValueExW (
  262. hKeyNames,
  263. dwSystemVersion == OLD_VERSION ? cszHelp : HelpNameBuffer,
  264. RESERVED,
  265. &dwValueType,
  266. (LPBYTE)lpHelpText,
  267. &dwBufferSize);
  268. if (!lpReturnValue) {
  269. goto BNT_BAILOUT;
  270. }
  271. dwLastCounterIdUsed = 0;
  272. dwLastHelpIdUsed = 0;
  273. // load counter array items
  274. for (lpThisName = lpCounterNames;
  275. *lpThisName;
  276. lpThisName += (lstrlen(lpThisName)+1) ) {
  277. // first string should be an integer (in decimal unicode digits)
  278. dwThisCounter = wcstoul (lpThisName, NULL, 10);
  279. if (dwThisCounter == 0) {
  280. goto BNT_BAILOUT; // bad entry
  281. }
  282. // point to corresponding counter name
  283. lpThisName += (lstrlen(lpThisName)+1);
  284. // and load array element;
  285. lpCounterId[dwThisCounter] = lpThisName;
  286. if (dwThisCounter > dwLastCounterIdUsed) dwLastCounterIdUsed = dwThisCounter;
  287. }
  288. pdwIdArray[1] = dwLastCounterIdUsed;
  289. for (lpThisName = lpHelpText;
  290. *lpThisName;
  291. lpThisName += (lstrlen(lpThisName)+1) ) {
  292. // first string should be an integer (in decimal unicode digits)
  293. dwThisCounter = wcstoul (lpThisName, NULL, 10);
  294. if (dwThisCounter == 0) {
  295. goto BNT_BAILOUT; // bad entry
  296. }
  297. // point to corresponding counter name
  298. lpThisName += (lstrlen(lpThisName)+1);
  299. // and load array element;
  300. lpCounterId[dwThisCounter] = lpThisName;
  301. if (dwThisCounter > dwLastHelpIdUsed) dwLastHelpIdUsed= dwThisCounter;
  302. }
  303. pdwIdArray[3] = dwLastHelpIdUsed;
  304. dwLastId = dwLastHelpIdUsed;
  305. if (dwLastId < dwLastCounterIdUsed) dwLastId = dwLastCounterIdUsed;
  306. if (pdwLastItem) *pdwLastItem = dwLastId;
  307. HeapFree (GetProcessHeap(), 0, (LPVOID)lpValueNameString);
  308. RegCloseKey (hKeyValue);
  309. // if (dwSystemVersion == OLD_VERSION)
  310. RegCloseKey (hKeyNames);
  311. return lpReturnValue;
  312. BNT_BAILOUT:
  313. if (lWin32Status != ERROR_SUCCESS) {
  314. dwLastError = GetLastError();
  315. }
  316. if (lpValueNameString) {
  317. HeapFree (GetProcessHeap(), 0, (LPVOID)lpValueNameString);
  318. }
  319. if (lpReturnValue) {
  320. HeapFree (GetProcessHeap(), 0, (LPVOID)lpReturnValue);
  321. }
  322. if (hKeyValue) RegCloseKey (hKeyValue);
  323. // if (dwSystemVersion == OLD_VERSION &&
  324. // hKeyNames)
  325. RegCloseKey (hKeyNames);
  326. return NULL;
  327. }
  328. static
  329. BOOL
  330. IsMsObject(CString *pLibraryName)
  331. {
  332. CString LocalLibraryName;
  333. LocalLibraryName = *pLibraryName;
  334. LocalLibraryName.MakeLower();
  335. // for now this just compares known DLL names. valid as of
  336. // NT v4.0
  337. if (LocalLibraryName.Find((LPCWSTR)L"perfctrs.dll") >= 0) return TRUE;
  338. if (LocalLibraryName.Find((LPCWSTR)L"ftpctrs.dll") >= 0) return TRUE;
  339. if (LocalLibraryName.Find((LPCWSTR)L"rasctrs.dll") >= 0) return TRUE;
  340. if (LocalLibraryName.Find((LPCWSTR)L"winsctrs.dll") >= 0) return TRUE;
  341. if (LocalLibraryName.Find((LPCWSTR)L"sfmctrs.dll") >= 0) return TRUE;
  342. if (LocalLibraryName.Find((LPCWSTR)L"atkctrs.dll") >= 0) return TRUE;
  343. if (LocalLibraryName.Find((LPCWSTR)L"bhmon.dll") >= 0) return TRUE;
  344. if (LocalLibraryName.Find((LPCWSTR)L"tapictrs.dll") >= 0) return TRUE;
  345. // NT v5.0
  346. if (LocalLibraryName.Find((LPCWSTR)L"perfdisk.dll") >= 0) return TRUE;
  347. if (LocalLibraryName.Find((LPCWSTR)L"perfos.dll") >= 0) return TRUE;
  348. if (LocalLibraryName.Find((LPCWSTR)L"perfproc.dll") >= 0) return TRUE;
  349. if (LocalLibraryName.Find((LPCWSTR)L"perfnet.dll") >= 0) return TRUE;
  350. if (LocalLibraryName.Find((LPCWSTR)L"winspool.drv") >= 0) return TRUE;
  351. if (LocalLibraryName.Find((LPCWSTR)L"tapiperf.dll") >= 0) return TRUE;
  352. return FALSE;
  353. }
  354. /////////////////////////////////////////////////////////////////////////////
  355. // CExctrlstDlg dialog
  356. CExctrlstDlg::CExctrlstDlg(CWnd* pParent /*=NULL*/)
  357. : CDialog(CExctrlstDlg::IDD, pParent)
  358. {
  359. //{{AFX_DATA_INIT(CExctrlstDlg)
  360. // NOTE: the ClassWizard will add member initialization here
  361. //}}AFX_DATA_INIT
  362. // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
  363. m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
  364. hKeyMachine = HKEY_LOCAL_MACHINE;
  365. hKeyServices = NULL;
  366. dwSortOrder = SORT_ORDER_SERVICE;
  367. bReadWriteAccess = TRUE;
  368. dwRegAccessMask = KEY_READ | KEY_WRITE;
  369. pNameTable = NULL;
  370. dwLastElement = 0;
  371. dwListBoxHorizExtent = 0;
  372. dwTabStopCount = 1;
  373. dwTabStopArray[0] = 85;
  374. memset (&dwIdArray[0], 0, sizeof(dwIdArray));
  375. }
  376. CExctrlstDlg::~CExctrlstDlg()
  377. {
  378. if (pNameTable != NULL) {
  379. HeapFree (GetProcessHeap(), 0, pNameTable);
  380. pNameTable = NULL;
  381. dwLastElement = 0;
  382. }
  383. }
  384. void CExctrlstDlg::DoDataExchange(CDataExchange* pDX)
  385. {
  386. CDialog::DoDataExchange(pDX);
  387. //{{AFX_DATA_MAP(CExctrlstDlg)
  388. // NOTE: the ClassWizard will add DDX and DDV calls here
  389. //}}AFX_DATA_MAP
  390. }
  391. BEGIN_MESSAGE_MAP(CExctrlstDlg, CDialog)
  392. //{{AFX_MSG_MAP(CExctrlstDlg)
  393. ON_WM_PAINT()
  394. ON_WM_QUERYDRAGICON()
  395. ON_LBN_SELCHANGE(IDC_EXT_LIST, OnSelchangeExtList)
  396. ON_WM_DESTROY()
  397. ON_BN_CLICKED(IDC_REFRESH, OnRefresh)
  398. ON_BN_CLICKED(IDC_ABOUT, OnAbout)
  399. ON_EN_KILLFOCUS(IDC_MACHINE_NAME, OnKillfocusMachineName)
  400. ON_BN_CLICKED(IDC_SORT_LIBRARY, OnSortButton)
  401. ON_BN_CLICKED(IDC_SORT_SERVICE, OnSortButton)
  402. ON_BN_CLICKED(IDC_SORT_ID, OnSortButton)
  403. ON_BN_CLICKED(IDC_ENABLED_BTN, OnEnablePerf)
  404. ON_WM_SYSCOMMAND()
  405. //}}AFX_MSG_MAP
  406. END_MESSAGE_MAP()
  407. DWORD CExctrlstDlg::EnablePerfCounters (HKEY hKeyItem, DWORD dwNewValue)
  408. {
  409. DWORD dwStatus;
  410. DWORD dwType;
  411. DWORD dwValue;
  412. DWORD dwSize;
  413. DWORD dwReturn;
  414. switch (dwNewValue) {
  415. case ENABLE_PERF_CTR_QUERY:
  416. dwType = 0;
  417. dwSize = sizeof (dwValue);
  418. dwValue = 0;
  419. dwStatus = RegQueryValueExW (
  420. hKeyItem,
  421. cszDisablePerformanceCounters,
  422. NULL,
  423. &dwType,
  424. (LPBYTE)&dwValue,
  425. &dwSize);
  426. if ((dwStatus == ERROR_SUCCESS) && (dwType == REG_DWORD)) {
  427. switch (dwValue) {
  428. case 0: dwReturn = ENABLE_PERF_CTR_ENABLE; break;
  429. case 1: dwReturn = ENABLE_PERF_CTR_DISABLE; break;
  430. default: dwReturn = 0; break;
  431. }
  432. } else {
  433. // if the value is not present, or not = 1, then the perfctrs
  434. // are enabled
  435. dwReturn = ENABLE_PERF_CTR_ENABLE;
  436. }
  437. break;
  438. case ENABLE_PERF_CTR_ENABLE:
  439. dwType = REG_DWORD;
  440. dwSize = sizeof (dwValue);
  441. dwValue = 0;
  442. dwStatus = RegSetValueExW (
  443. hKeyItem,
  444. cszDisablePerformanceCounters,
  445. 0L,
  446. dwType,
  447. (LPBYTE)&dwValue,
  448. dwSize);
  449. if (dwStatus == ERROR_SUCCESS) {
  450. dwReturn = ENABLE_PERF_CTR_ENABLE;
  451. } else {
  452. dwReturn = 0;
  453. }
  454. break;
  455. case ENABLE_PERF_CTR_DISABLE:
  456. dwType = REG_DWORD;
  457. dwSize = sizeof (dwValue);
  458. dwValue = 1;
  459. dwStatus = RegSetValueExW (
  460. hKeyItem,
  461. cszDisablePerformanceCounters,
  462. 0L,
  463. dwType,
  464. (LPBYTE)&dwValue,
  465. dwSize);
  466. if (dwStatus == ERROR_SUCCESS) {
  467. dwReturn = ENABLE_PERF_CTR_DISABLE;
  468. } else {
  469. dwReturn = 0;
  470. }
  471. break;
  472. default:
  473. dwReturn = 0;
  474. }
  475. return dwReturn;
  476. }
  477. void CExctrlstDlg::ScanForExtensibleCounters ()
  478. {
  479. LONG lStatus = ERROR_SUCCESS;
  480. LONG lEnumStatus = ERROR_SUCCESS;
  481. DWORD dwServiceIndex;
  482. TCHAR szServiceSubKeyName[MAX_PATH];
  483. TCHAR szPerfSubKeyName[MAX_PATH+20];
  484. TCHAR szItemText[MAX_PATH];
  485. TCHAR szListText[MAX_PATH*2];
  486. DWORD dwNameSize;
  487. HKEY hKeyPerformance;
  488. UINT_PTR nListBoxEntry;
  489. DWORD dwItemSize, dwType, dwValue;
  490. HCURSOR hOldCursor;
  491. DWORD dwThisExtent;
  492. HDC hDcListBox;
  493. CWnd *pCWndListBox;
  494. hOldCursor = ::SetCursor (LoadCursor(NULL, IDC_WAIT));
  495. ResetListBox();
  496. if (hKeyServices == NULL) {
  497. // try read/write access
  498. lStatus = RegOpenKeyEx (hKeyMachine,
  499. cszServiceKeyName,
  500. 0L,
  501. dwRegAccessMask,
  502. &hKeyServices);
  503. if (lStatus != ERROR_SUCCESS) {
  504. // try read-only then
  505. dwRegAccessMask = KEY_READ;
  506. bReadWriteAccess = FALSE;
  507. lStatus = RegOpenKeyEx (hKeyMachine,
  508. cszServiceKeyName,
  509. 0L,
  510. dwRegAccessMask,
  511. &hKeyServices);
  512. if (lStatus != ERROR_SUCCESS) {
  513. // display Read Only message
  514. AfxMessageBox (IDS_READ_ONLY);
  515. } else {
  516. // fall through with error code
  517. // display no access message
  518. AfxMessageBox (IDS_NO_ACCESS);
  519. }
  520. }
  521. } else {
  522. lStatus = ERROR_SUCCESS;
  523. }
  524. if (lStatus == ERROR_SUCCESS) {
  525. pCWndListBox = GetDlgItem (IDC_EXT_LIST);
  526. hDcListBox = ::GetDC (pCWndListBox->m_hWnd);
  527. if (hDcListBox == NULL) {
  528. return;
  529. }
  530. dwServiceIndex = 0;
  531. dwNameSize = MAX_PATH;
  532. while ((lEnumStatus = RegEnumKeyEx (
  533. hKeyServices,
  534. dwServiceIndex,
  535. szServiceSubKeyName,
  536. &dwNameSize,
  537. NULL,
  538. NULL,
  539. NULL,
  540. NULL)) == ERROR_SUCCESS) {
  541. //try to open the perfkey under this key.
  542. lstrcpy (szPerfSubKeyName, szServiceSubKeyName);
  543. lstrcat (szPerfSubKeyName, cszPerformance);
  544. lStatus = RegOpenKeyEx (
  545. hKeyServices,
  546. szPerfSubKeyName,
  547. 0L,
  548. dwRegAccessMask,
  549. &hKeyPerformance);
  550. if (lStatus == ERROR_SUCCESS) {
  551. // look up the library name
  552. dwItemSize = MAX_PATH * sizeof(TCHAR);
  553. dwType = 0;
  554. lStatus = RegQueryValueEx (
  555. hKeyPerformance,
  556. cszLibrary,
  557. NULL,
  558. &dwType,
  559. (LPBYTE)&szItemText[0],
  560. &dwItemSize);
  561. if ((lStatus != ERROR_SUCCESS) ||
  562. ((dwType != REG_SZ) && dwType != REG_EXPAND_SZ)) {
  563. lstrcpy (szItemText, cszNotFound);
  564. }
  565. dwItemSize = sizeof(DWORD);
  566. dwType = 0;
  567. dwValue = 0;
  568. lStatus = RegQueryValueEx (
  569. hKeyPerformance,
  570. cszFirstCounter,
  571. NULL,
  572. &dwType,
  573. (LPBYTE)&dwValue,
  574. &dwItemSize);
  575. if ((lStatus != ERROR_SUCCESS) || (dwType != REG_DWORD)) {
  576. dwValue = 0;
  577. }
  578. // make the string for the list box here depending
  579. // on the selected sort order.
  580. if (dwSortOrder == SORT_ORDER_LIBRARY) {
  581. lstrcpy(szListText, szItemText);
  582. lstrcat(szListText, cszTab);
  583. lstrcat(szListText, szServiceSubKeyName);
  584. } else if (dwSortOrder == SORT_ORDER_ID) {
  585. _stprintf (szListText, cszSortIdFmt,
  586. dwValue, szServiceSubKeyName);
  587. } else { // default is sort by service
  588. lstrcpy(szListText, szServiceSubKeyName);
  589. lstrcat(szListText, cszTab);
  590. lstrcat(szListText, szItemText);
  591. }
  592. // add this name to the list box
  593. nListBoxEntry = SendDlgItemMessage(IDC_EXT_LIST,
  594. LB_ADDSTRING, 0, (LPARAM)&szListText);
  595. if (nListBoxEntry != LB_ERR) {
  596. dwThisExtent = GetTabbedTextExtent (
  597. hDcListBox,
  598. szListText,
  599. lstrlen(szListText),
  600. (int)dwTabStopCount,
  601. (int *)&dwTabStopArray[0]);
  602. if (dwThisExtent > dwListBoxHorizExtent) {
  603. dwListBoxHorizExtent = dwThisExtent;
  604. SendDlgItemMessage(IDC_EXT_LIST,
  605. LB_SETHORIZONTALEXTENT,
  606. (WPARAM)LOWORD(dwListBoxHorizExtent), (LPARAM)0);
  607. }
  608. // save key to this entry in the registry
  609. SendDlgItemMessage (IDC_EXT_LIST,
  610. LB_SETITEMDATA, (WPARAM)nListBoxEntry,
  611. (LPARAM)hKeyPerformance);
  612. } else {
  613. // close the key since there's no point in
  614. // keeping it open
  615. RegCloseKey (hKeyPerformance);
  616. }
  617. }
  618. // reset for next loop
  619. dwServiceIndex++;
  620. dwNameSize = MAX_PATH;
  621. }
  622. ::ReleaseDC (pCWndListBox->m_hWnd, hDcListBox);
  623. }
  624. nListBoxEntry = SendDlgItemMessage (IDC_EXT_LIST, LB_GETCOUNT);
  625. if (nListBoxEntry > 0) {
  626. SendDlgItemMessage (IDC_EXT_LIST, LB_SETCURSEL, 0, 0);
  627. }
  628. ::SetCursor (hOldCursor);
  629. }
  630. void CExctrlstDlg::UpdateSystemInfo () {
  631. TCHAR szItemText[MAX_PATH];
  632. _stprintf (szItemText, cszIdFmt,
  633. dwIdArray[0], dwIdArray[0], cszSpace);
  634. SetDlgItemText (IDC_LAST_COUNTER_VALUE, szItemText);
  635. _stprintf (szItemText, cszIdFmt,
  636. dwIdArray[1], dwIdArray[1],
  637. dwIdArray[1] != dwIdArray[0] ? cszSplat : cszSpace);
  638. SetDlgItemText (IDC_LAST_TEXT_COUNTER_VALUE, szItemText);
  639. _stprintf (szItemText, cszIdFmt,
  640. dwIdArray[2], dwIdArray[2], cszSpace);
  641. SetDlgItemText (IDC_LAST_HELP_VALUE, szItemText);
  642. _stprintf (szItemText, cszIdFmt,
  643. dwIdArray[3], dwIdArray[3],
  644. dwIdArray[3] != dwIdArray[2] ? cszSplat : cszSpace);
  645. SetDlgItemText (IDC_LAST_TEXT_HELP_VALUE, szItemText);
  646. }
  647. void CExctrlstDlg::UpdateDllInfo () {
  648. HKEY hKeyItem;
  649. TCHAR szItemText[MAX_PATH];
  650. UINT_PTR nSelectedItem;
  651. LONG lStatus;
  652. DWORD dwType;
  653. DWORD dwValue;
  654. DWORD dwItemSize;
  655. BOOL bNoIndexValues = FALSE;
  656. DWORD dwEnabled;
  657. CString OpenProcName;
  658. CString LibraryName;
  659. HCURSOR hOldCursor;
  660. hOldCursor = ::SetCursor (LoadCursor(NULL, IDC_WAIT));
  661. OpenProcName.Empty();
  662. LibraryName.Empty();
  663. // update the performance counter information
  664. nSelectedItem = SendDlgItemMessage (IDC_EXT_LIST, LB_GETCURSEL);
  665. if (nSelectedItem != LB_ERR) {
  666. // get registry key for the selected item
  667. hKeyItem = (HKEY)SendDlgItemMessage (IDC_EXT_LIST, LB_GETITEMDATA,
  668. (WPARAM)nSelectedItem, 0);
  669. dwItemSize = MAX_PATH * sizeof(TCHAR);
  670. dwType = 0;
  671. lStatus = RegQueryValueEx (
  672. hKeyItem,
  673. cszLibrary,
  674. NULL,
  675. &dwType,
  676. (LPBYTE)&szItemText[0],
  677. &dwItemSize);
  678. if ((lStatus != ERROR_SUCCESS) ||
  679. ((dwType != REG_SZ) && dwType != REG_EXPAND_SZ)) {
  680. lstrcpy (szItemText, cszNotFound);
  681. } else {
  682. LibraryName = szItemText;
  683. }
  684. SetDlgItemText (IDC_DLL_NAME, szItemText);
  685. dwItemSize = MAX_PATH * sizeof(TCHAR);
  686. dwType = 0;
  687. lStatus = RegQueryValueEx (
  688. hKeyItem,
  689. cszOpen,
  690. NULL,
  691. &dwType,
  692. (LPBYTE)&szItemText[0],
  693. &dwItemSize);
  694. if ((lStatus != ERROR_SUCCESS) ||
  695. ((dwType != REG_SZ) && dwType != REG_EXPAND_SZ)) {
  696. lstrcpy (szItemText, cszNotFound);
  697. } else {
  698. OpenProcName = szItemText;
  699. }
  700. SetDlgItemText (IDC_OPEN_PROC, szItemText);
  701. dwItemSize = MAX_PATH * sizeof(TCHAR);
  702. dwType = 0;
  703. lStatus = RegQueryValueEx (
  704. hKeyItem,
  705. cszCollect,
  706. NULL,
  707. &dwType,
  708. (LPBYTE)&szItemText[0],
  709. &dwItemSize);
  710. if ((lStatus != ERROR_SUCCESS) ||
  711. ((dwType != REG_SZ) && dwType != REG_EXPAND_SZ)) {
  712. lstrcpy (szItemText, cszNotFound);
  713. }
  714. SetDlgItemText (IDC_COLLECT_PROC, szItemText);
  715. dwItemSize = MAX_PATH * sizeof(TCHAR);
  716. dwType = 0;
  717. lStatus = RegQueryValueEx (
  718. hKeyItem,
  719. cszClose,
  720. NULL,
  721. &dwType,
  722. (LPBYTE)&szItemText[0],
  723. &dwItemSize);
  724. if ((lStatus != ERROR_SUCCESS) ||
  725. ((dwType != REG_SZ) && dwType != REG_EXPAND_SZ)) {
  726. lstrcpy (szItemText, cszNotFound);
  727. }
  728. SetDlgItemText (IDC_CLOSE_PROC, szItemText);
  729. dwItemSize = sizeof(DWORD);
  730. dwType = 0;
  731. dwValue = 0;
  732. lStatus = RegQueryValueEx (
  733. hKeyItem,
  734. cszFirstCounter,
  735. NULL,
  736. &dwType,
  737. (LPBYTE)&dwValue,
  738. &dwItemSize);
  739. if ((lStatus != ERROR_SUCCESS) || (dwType != REG_DWORD)) {
  740. lstrcpy (szItemText, cszNotFound);
  741. bNoIndexValues = TRUE;
  742. } else {
  743. _stprintf (szItemText, cszServIdFmt, dwValue, IndexHasString (dwValue) ? cszSpace : cszSplat);
  744. }
  745. SetDlgItemText (IDC_FIRST_CTR_ID, szItemText);
  746. dwItemSize = sizeof(DWORD);
  747. dwType = 0;
  748. dwValue = 0;
  749. lStatus = RegQueryValueEx (
  750. hKeyItem,
  751. cszLastCounter,
  752. NULL,
  753. &dwType,
  754. (LPBYTE)&dwValue,
  755. &dwItemSize);
  756. if ((lStatus != ERROR_SUCCESS) || (dwType != REG_DWORD)) {
  757. lstrcpy (szItemText, cszNotFound);
  758. } else {
  759. _stprintf (szItemText, cszServIdFmt, dwValue, IndexHasString (dwValue) ? cszSpace : cszSplat);
  760. }
  761. SetDlgItemText (IDC_LAST_CTR_ID, szItemText);
  762. dwItemSize = sizeof(DWORD);
  763. dwType = 0;
  764. dwValue = 0;
  765. lStatus = RegQueryValueEx (
  766. hKeyItem,
  767. cszFirstHelp,
  768. NULL,
  769. &dwType,
  770. (LPBYTE)&dwValue,
  771. &dwItemSize);
  772. if ((lStatus != ERROR_SUCCESS) || (dwType != REG_DWORD)) {
  773. lstrcpy (szItemText, cszNotFound);
  774. bNoIndexValues = TRUE;
  775. } else {
  776. _stprintf (szItemText, cszServIdFmt, dwValue, IndexHasString (dwValue) ? cszSpace : cszSplat);
  777. }
  778. SetDlgItemText (IDC_FIRST_HELP_ID, szItemText);
  779. dwItemSize = sizeof(DWORD);
  780. dwType = 0;
  781. dwValue = 0;
  782. lStatus = RegQueryValueEx (
  783. hKeyItem,
  784. cszLastHelp,
  785. NULL,
  786. &dwType,
  787. (LPBYTE)&dwValue,
  788. &dwItemSize);
  789. if ((lStatus != ERROR_SUCCESS) || (dwType != REG_DWORD)) {
  790. lstrcpy (szItemText, cszNotFound);
  791. } else {
  792. _stprintf (szItemText, cszServIdFmt, dwValue, IndexHasString (dwValue) ? cszSpace : cszSplat);
  793. }
  794. SetDlgItemText (IDC_LAST_HELP_ID, szItemText);
  795. if (bNoIndexValues) {
  796. // test to see if this is a "standard" i.e. Microsoft provided
  797. // extensible counter or simply one that hasn't been completely
  798. // installed
  799. if (IsMsObject(&LibraryName)) {
  800. SetDlgItemText (IDC_FIRST_HELP_ID, cszNA);
  801. SetDlgItemText (IDC_LAST_HELP_ID, cszNA);
  802. SetDlgItemText (IDC_FIRST_CTR_ID, cszNA);
  803. SetDlgItemText (IDC_LAST_CTR_ID, cszNA);
  804. }
  805. }
  806. GetDlgItem(IDC_ENABLED_BTN)->ShowWindow (bReadWriteAccess ? SW_SHOW : SW_HIDE);
  807. GetDlgItem(IDC_ENABLED_BTN)->EnableWindow (bReadWriteAccess);
  808. dwEnabled = EnablePerfCounters (hKeyItem, ENABLE_PERF_CTR_QUERY);
  809. if (bReadWriteAccess) {
  810. // then set the check box
  811. CheckDlgButton (IDC_ENABLED_BTN, dwEnabled == ENABLE_PERF_CTR_ENABLE ? 1 : 0);
  812. GetDlgItem(IDC_DISABLED_TEXT)->ShowWindow (SW_HIDE);
  813. } else {
  814. // update the text message
  815. GetDlgItem(IDC_DISABLED_TEXT)->ShowWindow (
  816. (!(dwEnabled == ENABLE_PERF_CTR_ENABLE)) ?
  817. SW_SHOW : SW_HIDE);
  818. GetDlgItem(IDC_DISABLED_TEXT)->EnableWindow (TRUE);
  819. }
  820. }
  821. ::SetCursor (hOldCursor);
  822. }
  823. void CExctrlstDlg::ResetListBox ()
  824. {
  825. INT_PTR nItemCount;
  826. INT nThisItem;
  827. HKEY hKeyItem;
  828. nItemCount = SendDlgItemMessage (IDC_EXT_LIST, LB_GETCOUNT);
  829. nThisItem = 0;
  830. while (nThisItem > nItemCount) {
  831. hKeyItem = (HKEY) SendDlgItemMessage (IDC_EXT_LIST,
  832. LB_GETITEMDATA, (WPARAM)nThisItem);
  833. RegCloseKey (hKeyItem);
  834. nThisItem++;
  835. }
  836. SendDlgItemMessage (IDC_EXT_LIST, LB_RESETCONTENT);
  837. dwListBoxHorizExtent = 0;
  838. SendDlgItemMessage(IDC_EXT_LIST,
  839. LB_SETHORIZONTALEXTENT,
  840. (WPARAM)LOWORD(dwListBoxHorizExtent), (LPARAM)0);
  841. }
  842. void CExctrlstDlg::SetSortButtons()
  843. {
  844. DWORD dwBtn;
  845. switch (dwSortOrder) {
  846. case SORT_ORDER_LIBRARY: dwBtn = IDC_SORT_LIBRARY; break;
  847. case SORT_ORDER_SERVICE: dwBtn = IDC_SORT_SERVICE; break;
  848. case SORT_ORDER_ID: dwBtn = IDC_SORT_ID; break;
  849. default: dwBtn = IDC_SORT_SERVICE; break;
  850. }
  851. CheckRadioButton (
  852. IDC_SORT_LIBRARY,
  853. IDC_SORT_ID,
  854. dwBtn);
  855. }
  856. /////////////////////////////////////////////////////////////////////////////
  857. // CExctrlstDlg message handlers
  858. BOOL CExctrlstDlg::OnInitDialog()
  859. {
  860. HCURSOR hOldCursor;
  861. DWORD dwLength;
  862. hOldCursor = ::SetCursor (::LoadCursor (NULL, IDC_WAIT));
  863. CDialog::OnInitDialog();
  864. CenterWindow();
  865. lstrcpy (szThisComputerName, cszDoubleBackslash);
  866. dwLength = MAX_COMPUTERNAME_LENGTH+1;
  867. GetComputerName (&szThisComputerName[2], &dwLength);
  868. lstrcpy (szComputerName, szThisComputerName);
  869. SetDlgItemText (IDC_MACHINE_NAME, szComputerName);
  870. hKeyMachine = HKEY_LOCAL_MACHINE;
  871. pNameTable = BuildNameTable (
  872. szComputerName,
  873. cszDefaultLangId,
  874. &dwLastElement, // size of array in elements
  875. &dwIdArray[0]);
  876. SendDlgItemMessage (IDC_MACHINE_NAME, EM_LIMITTEXT,
  877. (WPARAM)MAX_COMPUTERNAME_LENGTH+2, 0); // include 2 leading backslash
  878. SendDlgItemMessage (IDC_EXT_LIST, LB_SETTABSTOPS,
  879. (WPARAM)dwTabStopCount, (LPARAM)&dwTabStopArray[0]);
  880. SetSortButtons();
  881. ScanForExtensibleCounters(); //.checks for access to the registry
  882. UpdateSystemInfo();
  883. // set the check box to the appropriate state
  884. UpdateDllInfo ();
  885. ::SetCursor(hOldCursor);
  886. return TRUE; // return TRUE unless you set the focus to a control
  887. }
  888. // If you add a minimize button to your dialog, you will need the code below
  889. // to draw the icon. For MFC applications using the document/view model,
  890. // this is automatically done for you by the framework.
  891. void CExctrlstDlg::OnPaint()
  892. {
  893. if (IsIconic())
  894. {
  895. CPaintDC dc(this); // device context for painting
  896. SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
  897. // Center icon in client rectangle
  898. int cxIcon = GetSystemMetrics(SM_CXICON);
  899. int cyIcon = GetSystemMetrics(SM_CYICON);
  900. CRect rect;
  901. GetClientRect(&rect);
  902. int x = (rect.Width() - cxIcon + 1) / 2;
  903. int y = (rect.Height() - cyIcon + 1) / 2;
  904. // Draw the icon
  905. dc.DrawIcon(x, y, m_hIcon);
  906. }
  907. else
  908. {
  909. CDialog::OnPaint();
  910. }
  911. }
  912. // The system calls this to obtain the cursor to display while the user drags
  913. // the minimized window.
  914. HCURSOR CExctrlstDlg::OnQueryDragIcon()
  915. {
  916. return (HCURSOR) m_hIcon;
  917. }
  918. void CExctrlstDlg::OnSelchangeExtList()
  919. {
  920. UpdateDllInfo ();
  921. }
  922. void CExctrlstDlg::OnDestroy()
  923. {
  924. ResetListBox();
  925. CDialog::OnDestroy();
  926. }
  927. void CExctrlstDlg::OnAbout()
  928. {
  929. CAbout dlg;
  930. dlg.DoModal();
  931. }
  932. void CExctrlstDlg::OnRefresh()
  933. {
  934. HCURSOR hOldCursor;
  935. hOldCursor = ::SetCursor (::LoadCursor (NULL, IDC_WAIT));
  936. ScanForExtensibleCounters();
  937. if (pNameTable != NULL) {
  938. HeapFree (GetProcessHeap(), 0, pNameTable);
  939. pNameTable = NULL;
  940. dwLastElement = 0;
  941. }
  942. pNameTable = BuildNameTable (
  943. szComputerName,
  944. cszDefaultLangId,
  945. &dwLastElement, // size of array in elements
  946. &dwIdArray[0]);
  947. UpdateSystemInfo();
  948. UpdateDllInfo ();
  949. ::SetCursor(hOldCursor);
  950. }
  951. void CExctrlstDlg::OnKillfocusMachineName()
  952. {
  953. TCHAR szNewMachineName[MAX_PATH];
  954. HKEY hKeyNewMachine;
  955. LONG lStatus;
  956. HCURSOR hOldCursor;
  957. hOldCursor = ::SetCursor (::LoadCursor (NULL, IDC_WAIT));
  958. GetDlgItemText (IDC_MACHINE_NAME, szNewMachineName, MAX_PATH);
  959. if (lstrcmpi(szComputerName, szNewMachineName) != 0) {
  960. // a new computer has been entered so try to connect to it
  961. lStatus = RegConnectRegistry (szNewMachineName,
  962. HKEY_LOCAL_MACHINE, &hKeyNewMachine);
  963. if (lStatus == ERROR_SUCCESS) {
  964. RegCloseKey (hKeyServices); // close the old key
  965. hKeyServices = NULL; // clear it
  966. bReadWriteAccess = TRUE; // reset the access variables
  967. dwRegAccessMask = KEY_READ | KEY_WRITE;
  968. RegCloseKey (hKeyMachine); // close the old machine
  969. hKeyMachine = hKeyNewMachine; // update to the new machine
  970. lstrcpy (szComputerName, szNewMachineName); // update the name
  971. OnRefresh(); // get new counters
  972. } else {
  973. SetDlgItemText (IDC_MACHINE_NAME, szComputerName);
  974. }
  975. } else {
  976. // the machine name has not changed
  977. }
  978. ::SetCursor (hOldCursor);
  979. }
  980. void CExctrlstDlg::OnSortButton()
  981. {
  982. if (IsDlgButtonChecked(IDC_SORT_LIBRARY)) {
  983. dwSortOrder = SORT_ORDER_LIBRARY;
  984. } else if (IsDlgButtonChecked(IDC_SORT_SERVICE)) {
  985. dwSortOrder = SORT_ORDER_SERVICE;
  986. } else if (IsDlgButtonChecked(IDC_SORT_ID)) {
  987. dwSortOrder = SORT_ORDER_ID;
  988. }
  989. ScanForExtensibleCounters();
  990. UpdateDllInfo ();
  991. }
  992. void CExctrlstDlg::OnEnablePerf()
  993. {
  994. HKEY hKeyItem;
  995. UINT_PTR nSelectedItem;
  996. DWORD dwNewValue;
  997. nSelectedItem = SendDlgItemMessage (IDC_EXT_LIST, LB_GETCURSEL);
  998. if (nSelectedItem != LB_ERR) {
  999. // get registry key for the selected item
  1000. hKeyItem = (HKEY)SendDlgItemMessage (IDC_EXT_LIST, LB_GETITEMDATA,
  1001. (WPARAM)nSelectedItem, 0);
  1002. // get selected perf item and the corre
  1003. dwNewValue = IsDlgButtonChecked(IDC_ENABLED_BTN) ?
  1004. ENABLE_PERF_CTR_ENABLE :
  1005. ENABLE_PERF_CTR_DISABLE;
  1006. if (EnablePerfCounters (hKeyItem, dwNewValue) == 0) {
  1007. MessageBeep(0xFFFFFFFF);
  1008. // then it failed so reset to the curent value
  1009. dwNewValue = EnablePerfCounters (hKeyItem, ENABLE_PERF_CTR_QUERY);
  1010. CheckDlgButton (IDC_ENABLED_BTN, dwNewValue == ENABLE_PERF_CTR_ENABLE ? 1 : 0);
  1011. }
  1012. }
  1013. }
  1014. void CExctrlstDlg::OnSysCommand(UINT nID, LPARAM lParam)
  1015. {
  1016. switch (nID) {
  1017. case SC_CLOSE:
  1018. EndDialog(IDOK);
  1019. break;
  1020. default:
  1021. CDialog::OnSysCommand (nID, lParam);
  1022. break;
  1023. }
  1024. }
  1025. /////////////////////////////////////////////////////////////////////////////
  1026. // CAbout dialog
  1027. CAbout::CAbout(CWnd* pParent /*=NULL*/)
  1028. : CDialog(CAbout::IDD, pParent)
  1029. {
  1030. //{{AFX_DATA_INIT(CAbout)
  1031. // NOTE: the ClassWizard will add member initialization here
  1032. //}}AFX_DATA_INIT
  1033. }
  1034. void CAbout::DoDataExchange(CDataExchange* pDX)
  1035. {
  1036. CDialog::DoDataExchange(pDX);
  1037. //{{AFX_DATA_MAP(CAbout)
  1038. // NOTE: the ClassWizard will add DDX and DDV calls here
  1039. //}}AFX_DATA_MAP
  1040. }
  1041. BOOL CAbout::OnInitDialog()
  1042. {
  1043. CDialog::OnInitDialog();
  1044. TCHAR buffer[512];
  1045. TCHAR strProgram[1024];
  1046. TCHAR strMicrosoft[1024];
  1047. DWORD dw;
  1048. BYTE* pVersionInfo;
  1049. LPTSTR pVersion = NULL;
  1050. LPTSTR pProduct = NULL;
  1051. LPTSTR pCopyRight = NULL;
  1052. dw = GetModuleFileName(NULL, strProgram, 1024);
  1053. if( dw>0 ){
  1054. dw = GetFileVersionInfoSize( strProgram, &dw );
  1055. if( dw > 0 ){
  1056. pVersionInfo = (BYTE*)malloc(dw);
  1057. if( NULL != pVersionInfo ){
  1058. if(GetFileVersionInfo( strProgram, 0, dw, pVersionInfo )){
  1059. LPDWORD lptr = NULL;
  1060. VerQueryValue( pVersionInfo, _T("\\VarFileInfo\\Translation"), (void**)&lptr, (UINT*)&dw );
  1061. if( lptr != NULL ){
  1062. _stprintf( buffer, _T("\\StringFileInfo\\%04x%04x\\%s"), LOWORD(*lptr), HIWORD(*lptr), _T("ProductVersion") );
  1063. VerQueryValue( pVersionInfo, buffer, (void**)&pVersion, (UINT*)&dw );
  1064. _stprintf( buffer, _T("\\StringFileInfo\\%04x%04x\\%s"), LOWORD(*lptr), HIWORD(*lptr), _T("OriginalFilename") );
  1065. VerQueryValue( pVersionInfo, buffer, (void**)&pProduct, (UINT*)&dw );
  1066. _stprintf( buffer, _T("\\StringFileInfo\\%04x%04x\\%s"), LOWORD(*lptr), HIWORD(*lptr), _T("LegalCopyright") );
  1067. VerQueryValue( pVersionInfo, buffer, (void**)&pCopyRight, (UINT*)&dw );
  1068. }
  1069. if( pProduct != NULL && pVersion != NULL && pCopyRight != NULL ){
  1070. GetDlgItem(IDC_COPYRIGHT)->SetWindowText( pCopyRight );
  1071. GetDlgItem(IDC_VERSION)->SetWindowText( pVersion );
  1072. }
  1073. }
  1074. free( pVersionInfo );
  1075. }
  1076. }
  1077. }
  1078. return TRUE;
  1079. }
  1080. BEGIN_MESSAGE_MAP(CAbout, CDialog)
  1081. //{{AFX_MSG_MAP(CAbout)
  1082. // NOTE: the ClassWizard will add message map macros here
  1083. //}}AFX_MSG_MAP
  1084. END_MESSAGE_MAP()
  1085. /////////////////////////////////////////////////////////////////////////////
  1086. // CAbout message handlers