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.

1396 lines
50 KiB

  1. /*++
  2. Copyright (c) 1991-1999 Microsoft Corporation
  3. Module Name:
  4. dumpload.c
  5. Abstract:
  6. functions to dump and load the contents of the performance related registry
  7. entries
  8. Author:
  9. Bob Watson (bobw) 13 Jun 99
  10. Revision History:
  11. --*/
  12. #ifndef UNICODE
  13. #define UNICODE 1
  14. #endif
  15. #ifndef _UNICODE
  16. #define _UNICODE 1
  17. #endif
  18. //
  19. // "C" Include files
  20. //
  21. #include <nt.h>
  22. #include <ntrtl.h>
  23. #include <nturtl.h>
  24. #include <stdio.h>
  25. #include <stdlib.h>
  26. #include <string.h>
  27. //
  28. // Windows Include files
  29. //
  30. #include <windows.h>
  31. #include <winperf.h>
  32. #include <loadperf.h>
  33. #include "wmistr.h"
  34. #include "evntrace.h"
  35. //
  36. // application include files
  37. //
  38. #include "winperfp.h"
  39. #include "common.h"
  40. #include "ldprfmsg.h"
  41. static const WCHAR cszServiceKeyName[] = {L"SYSTEM\\CurrentControlSet\\Services"};
  42. static const WCHAR cszPerflibKeyName[] = {L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Perflib"};
  43. static const WCHAR cszLastCounter[] = {L"Last Counter"};
  44. static const WCHAR cszFirstHelp[] = {L"First Help"};
  45. static const WCHAR cszLastHelp[] = {L"Last Help"};
  46. static const WCHAR cszBaseIndex[] = {L"Base Index"};
  47. static const WCHAR cszPerformance[] = {L"\\Performance"};
  48. static const WCHAR cszDisablePerformanceCounters[] = {L"Disable Performance Counters"};
  49. // headings in save file
  50. static const WCHAR cszFmtSectionHeader[] = {L"\r\n\r\n[%s]"};
  51. static const WCHAR cszFmtServiceSectionHeader[] = {L"\r\n\r\n[PERF_%s]"};
  52. static const WCHAR cszFmtServiceSectionName[] = {L"PERF_%s"};
  53. static const WCHAR cszFmtStringSectionHeader[] = {L"\r\n\r\n[PerfStrings_%s]"};
  54. static const WCHAR cszFmtExtCtrString[] = {L"\r\n%d=%s"};
  55. static const WCHAR cszFmtDecimalParam[] = {L"\r\n%s=%d"};
  56. static const WCHAR cszFmtNoParam[] = {L"\r\n%s="};
  57. static const WCHAR cszExtensiblePerfStrings[] = {L"Strings"};
  58. static const WCHAR cszPerfCounterServices[] = {L"PerfCounterServices"};
  59. static const WCHAR cszNoPerfCounterServices[] = {L"NoPerfCounterServices"};
  60. static const WCHAR cszPerflib[] = {L"Perflib"};
  61. // external forward definitions
  62. LPWSTR
  63. *BuildNameTable(
  64. HKEY hKeyRegistry, // handle to registry db with counter names
  65. LPWSTR lpszLangId, // unicode value of Language subkey
  66. PDWORD pdwLastItem // size of array in elements
  67. );
  68. DWORD
  69. UpdatePerfNameFilesX (
  70. IN LPCWSTR szNewCtrFilePath, // data file with new base counter strings
  71. IN LPCWSTR szNewHlpFilePath, // data file with new base counter strings
  72. IN LPWSTR szLanguageID, // Lang ID to update
  73. IN ULONG_PTR dwFlags // flags
  74. );
  75. DWORD
  76. DumpNameTable (
  77. IN HANDLE hOutputFile,
  78. IN LPCWSTR szLangId,
  79. IN LPCWSTR *pszNameTable,
  80. IN DWORD dwStartIndex,
  81. IN DWORD dwLastIndex
  82. )
  83. {
  84. DWORD dwStatus = ERROR_SUCCESS;
  85. DWORD ndx = 0;
  86. LPWSTR szOutputBuffer = NULL;
  87. DWORD dwBufSize = 4096;
  88. DWORD dwSize = 0;
  89. DWORD dwSizeWritten = 0;
  90. TRACE((WINPERF_DBG_TRACE_INFO),
  91. (& LoadPerfGuid,
  92. __LINE__,
  93. LOADPERF_DUMPNAMETABLE,
  94. ARG_DEF(ARG_TYPE_WSTR, 1),
  95. ERROR_SUCCESS,
  96. TRACE_WSTR(szLangId),
  97. TRACE_DWORD(dwStartIndex),
  98. TRACE_DWORD(dwLastIndex),
  99. NULL));
  100. szOutputBuffer = MemoryAllocate(sizeof(WCHAR) * dwBufSize);
  101. if (szOutputBuffer == NULL) {
  102. dwStatus = GetLastError();
  103. goto Cleanup;
  104. }
  105. ZeroMemory(szOutputBuffer, dwBufSize * sizeof(WCHAR));
  106. dwSize = swprintf(szOutputBuffer, cszFmtStringSectionHeader, szLangId);
  107. dwSize *= sizeof(WCHAR);
  108. WriteFile(hOutputFile, szOutputBuffer, dwSize, & dwSizeWritten, NULL);
  109. for (ndx = dwStartIndex; ndx <= dwLastIndex; ndx++) {
  110. if (pszNameTable[ndx] != NULL) {
  111. if (dwBufSize <= (DWORD) (lstrlenW(pszNameTable[ndx]) + 11)) {
  112. MemoryFree((LPVOID) szOutputBuffer);
  113. dwBufSize = (DWORD) (lstrlenW(pszNameTable[ndx]) + 11);
  114. szOutputBuffer = MemoryAllocate(dwBufSize * sizeof(WCHAR));
  115. if (szOutputBuffer == NULL) {
  116. dwStatus = GetLastError();
  117. goto Cleanup;
  118. }
  119. }
  120. ZeroMemory(szOutputBuffer, dwBufSize * sizeof(WCHAR));
  121. dwSize = swprintf(szOutputBuffer, cszFmtExtCtrString, ndx, pszNameTable[ndx]);
  122. dwSize *= sizeof(WCHAR);
  123. WriteFile(hOutputFile, szOutputBuffer, dwSize, & dwSizeWritten, NULL);
  124. }
  125. }
  126. Cleanup:
  127. if (szOutputBuffer != NULL) MemoryFree((LPVOID) szOutputBuffer);
  128. return dwStatus;
  129. }
  130. DWORD
  131. DumpPerfServiceEntries (
  132. IN HANDLE hOutputFile,
  133. IN LPCWSTR szServiceName
  134. )
  135. {
  136. LONG lStatus = ERROR_SUCCESS;
  137. WCHAR szPerfSubKeyName[MAX_PATH+20];
  138. HKEY hKeyPerformance;
  139. HKEY hKeyServices = NULL;
  140. DWORD dwItemSize, dwType, dwValue;
  141. DWORD dwRegAccessMask;
  142. DWORD dwRetStatus = ERROR_SUCCESS;
  143. DWORD dwSize, dwSizeWritten;
  144. WCHAR szOutputBuffer[4096];
  145. // try read-only then
  146. dwRegAccessMask = KEY_READ;
  147. __try {
  148. lStatus = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
  149. cszServiceKeyName,
  150. 0L,
  151. dwRegAccessMask,
  152. & hKeyServices);
  153. }
  154. __except (EXCEPTION_EXECUTE_HANDLER) {
  155. lStatus = GetExceptionCode();
  156. }
  157. if (lStatus == ERROR_SUCCESS) {
  158. //try to open the perfkey under this key.
  159. lstrcpy (szPerfSubKeyName, szServiceName);
  160. lstrcat (szPerfSubKeyName, cszPerformance);
  161. __try {
  162. lStatus = RegOpenKeyExW(
  163. hKeyServices,
  164. szPerfSubKeyName,
  165. 0L,
  166. dwRegAccessMask,
  167. & hKeyPerformance);
  168. }
  169. __except (EXCEPTION_EXECUTE_HANDLER) {
  170. lStatus = GetExceptionCode();
  171. }
  172. if (lStatus == ERROR_SUCCESS) {
  173. // key found so service has perf data
  174. ZeroMemory(szOutputBuffer, 4096 * sizeof(WCHAR));
  175. dwSize = swprintf (szOutputBuffer, cszFmtServiceSectionHeader, szServiceName);
  176. dwSize *= sizeof (WCHAR);
  177. WriteFile (hOutputFile, szOutputBuffer, dwSize, &dwSizeWritten, NULL);
  178. // now check to see if the strings have been loaded
  179. dwType = dwValue = 0;
  180. dwItemSize = sizeof (dwValue);
  181. __try {
  182. lStatus = RegQueryValueExW(
  183. hKeyPerformance,
  184. cszFirstCounter,
  185. NULL,
  186. & dwType,
  187. (LPBYTE) & dwValue,
  188. & dwItemSize);
  189. }
  190. __except (EXCEPTION_EXECUTE_HANDLER) {
  191. lStatus = GetExceptionCode();
  192. }
  193. TRACE((WINPERF_DBG_TRACE_INFO),
  194. (& LoadPerfGuid,
  195. __LINE__,
  196. LOADPERF_DUMPPERFSERVICEENTRIES,
  197. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  198. lStatus,
  199. TRACE_WSTR(szServiceName),
  200. TRACE_WSTR(cszFirstCounter),
  201. TRACE_DWORD(dwValue),
  202. NULL));
  203. if ((lStatus == ERROR_SUCCESS) &&
  204. ((dwType == REG_DWORD) || dwType == REG_BINARY)) {
  205. ZeroMemory(szOutputBuffer, 4096 * sizeof(WCHAR));
  206. dwSize = swprintf (szOutputBuffer, cszFmtDecimalParam, cszFirstCounter, dwValue);
  207. dwSize *= sizeof (WCHAR);
  208. WriteFile (hOutputFile, szOutputBuffer, dwSize, &dwSizeWritten, NULL);
  209. }
  210. dwType = dwValue = 0;
  211. dwItemSize = sizeof (dwValue);
  212. __try {
  213. lStatus = RegQueryValueExW(
  214. hKeyPerformance,
  215. cszFirstHelp,
  216. NULL,
  217. & dwType,
  218. (LPBYTE) & dwValue,
  219. & dwItemSize);
  220. }
  221. __except (EXCEPTION_EXECUTE_HANDLER) {
  222. lStatus = GetExceptionCode();
  223. }
  224. TRACE((WINPERF_DBG_TRACE_INFO),
  225. (& LoadPerfGuid,
  226. __LINE__,
  227. LOADPERF_DUMPPERFSERVICEENTRIES,
  228. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  229. lStatus,
  230. TRACE_WSTR(szServiceName),
  231. TRACE_WSTR(cszFirstHelp),
  232. TRACE_DWORD(dwValue),
  233. NULL));
  234. if ((lStatus == ERROR_SUCCESS) &&
  235. ((dwType == REG_DWORD) || dwType == REG_BINARY)) {
  236. ZeroMemory(szOutputBuffer, 4096 * sizeof(WCHAR));
  237. dwSize = swprintf (szOutputBuffer, cszFmtDecimalParam, cszFirstHelp, dwValue);
  238. dwSize *= sizeof (WCHAR);
  239. WriteFile (hOutputFile, szOutputBuffer, dwSize, &dwSizeWritten, NULL);
  240. }
  241. dwType = dwValue = 0;
  242. dwItemSize = sizeof (dwValue);
  243. __try {
  244. lStatus = RegQueryValueExW(
  245. hKeyPerformance,
  246. cszLastCounter,
  247. NULL,
  248. & dwType,
  249. (LPBYTE) & dwValue,
  250. & dwItemSize);
  251. }
  252. __except (EXCEPTION_EXECUTE_HANDLER) {
  253. lStatus = GetExceptionCode();
  254. }
  255. TRACE((WINPERF_DBG_TRACE_INFO),
  256. (& LoadPerfGuid,
  257. __LINE__,
  258. LOADPERF_DUMPPERFSERVICEENTRIES,
  259. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  260. lStatus,
  261. TRACE_WSTR(szServiceName),
  262. TRACE_WSTR(cszLastCounter),
  263. TRACE_DWORD(dwValue),
  264. NULL));
  265. if ((lStatus == ERROR_SUCCESS) &&
  266. ((dwType == REG_DWORD) || dwType == REG_BINARY)) {
  267. ZeroMemory(szOutputBuffer, 4096 * sizeof(WCHAR));
  268. dwSize = swprintf (szOutputBuffer, cszFmtDecimalParam, cszLastCounter, dwValue);
  269. dwSize *= sizeof (WCHAR);
  270. WriteFile (hOutputFile, szOutputBuffer, dwSize, &dwSizeWritten, NULL);
  271. }
  272. dwType = dwValue = 0;
  273. dwItemSize = sizeof (dwValue);
  274. __try {
  275. lStatus = RegQueryValueExW(
  276. hKeyPerformance,
  277. cszLastHelp,
  278. NULL,
  279. & dwType,
  280. (LPBYTE) & dwValue,
  281. & dwItemSize);
  282. }
  283. __except (EXCEPTION_EXECUTE_HANDLER) {
  284. lStatus = GetExceptionCode();
  285. }
  286. TRACE((WINPERF_DBG_TRACE_INFO),
  287. (& LoadPerfGuid,
  288. __LINE__,
  289. LOADPERF_DUMPPERFSERVICEENTRIES,
  290. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  291. lStatus,
  292. TRACE_WSTR(szServiceName),
  293. TRACE_WSTR(cszLastHelp),
  294. TRACE_DWORD(dwValue),
  295. NULL));
  296. if ((lStatus == ERROR_SUCCESS) &&
  297. ((dwType == REG_DWORD) || dwType == REG_BINARY)) {
  298. ZeroMemory(szOutputBuffer, 4096 * sizeof(WCHAR));
  299. dwSize = swprintf (szOutputBuffer, cszFmtDecimalParam, cszLastHelp, dwValue);
  300. dwSize *= sizeof (WCHAR);
  301. WriteFile (hOutputFile, szOutputBuffer, dwSize, &dwSizeWritten, NULL);
  302. }
  303. dwType = dwValue = 0;
  304. dwItemSize = sizeof (dwValue);
  305. __try {
  306. lStatus = RegQueryValueExW(
  307. hKeyPerformance,
  308. cszDisablePerformanceCounters,
  309. NULL,
  310. & dwType,
  311. (LPBYTE) & dwValue,
  312. & dwItemSize);
  313. }
  314. __except (EXCEPTION_EXECUTE_HANDLER) {
  315. lStatus = GetExceptionCode();
  316. }
  317. TRACE((WINPERF_DBG_TRACE_INFO),
  318. (& LoadPerfGuid,
  319. __LINE__,
  320. LOADPERF_DUMPPERFSERVICEENTRIES,
  321. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  322. lStatus,
  323. TRACE_WSTR(szServiceName),
  324. TRACE_WSTR(cszDisablePerformanceCounters),
  325. TRACE_DWORD(dwValue),
  326. NULL));
  327. if ((lStatus == ERROR_SUCCESS) &&
  328. ((dwType == REG_DWORD) || dwType == REG_BINARY)) {
  329. ZeroMemory(szOutputBuffer, 4096 * sizeof(WCHAR));
  330. dwSize = swprintf (szOutputBuffer, cszFmtDecimalParam, cszDisablePerformanceCounters, dwValue);
  331. dwSize *= sizeof (WCHAR);
  332. WriteFile (hOutputFile, szOutputBuffer, dwSize, &dwSizeWritten, NULL);
  333. }
  334. RegCloseKey (hKeyPerformance);
  335. } else {
  336. dwRetStatus = lStatus;
  337. TRACE((WINPERF_DBG_TRACE_ERROR),
  338. (& LoadPerfGuid,
  339. __LINE__,
  340. LOADPERF_DUMPPERFSERVICEENTRIES,
  341. ARG_DEF(ARG_TYPE_WSTR, 1),
  342. lStatus,
  343. TRACE_WSTR(szServiceName),
  344. NULL));
  345. }
  346. RegCloseKey (hKeyServices);
  347. }
  348. else {
  349. dwRetStatus = lStatus;
  350. TRACE((WINPERF_DBG_TRACE_ERROR),
  351. (& LoadPerfGuid,
  352. __LINE__,
  353. LOADPERF_DUMPPERFSERVICEENTRIES,
  354. ARG_DEF(ARG_TYPE_WSTR, 1),
  355. lStatus,
  356. TRACE_WSTR(cszServiceKeyName),
  357. NULL));
  358. }
  359. return dwRetStatus;
  360. }
  361. DWORD
  362. DumpPerflibEntries (
  363. IN HANDLE hOutputFile,
  364. IN LPDWORD pdwFirstExtCtrIndex
  365. )
  366. {
  367. HKEY hKeyPerflib = NULL;
  368. DWORD dwStatus;
  369. DWORD dwItemSize, dwType, dwValue;
  370. DWORD dwSize, dwSizeWritten;
  371. WCHAR szOutputBuffer[4096];
  372. __try {
  373. dwStatus = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
  374. cszPerflibKeyName,
  375. 0L,
  376. KEY_READ,
  377. & hKeyPerflib);
  378. }
  379. __except (EXCEPTION_EXECUTE_HANDLER) {
  380. dwStatus = GetExceptionCode();
  381. }
  382. if (dwStatus == ERROR_SUCCESS) {
  383. ZeroMemory(szOutputBuffer, 4096 * sizeof(WCHAR));
  384. dwSize = swprintf (szOutputBuffer, cszFmtSectionHeader, cszPerflib);
  385. dwSize *= sizeof (WCHAR);
  386. WriteFile (hOutputFile, szOutputBuffer, dwSize, &dwSizeWritten, NULL);
  387. }
  388. else {
  389. TRACE((WINPERF_DBG_TRACE_ERROR),
  390. (& LoadPerfGuid,
  391. __LINE__,
  392. LOADPERF_DUMPPERFLIBENTRIES,
  393. ARG_DEF(ARG_TYPE_WSTR, 1),
  394. dwStatus,
  395. TRACE_WSTR(cszPerflibKeyName),
  396. NULL));
  397. }
  398. if (dwStatus == ERROR_SUCCESS) {
  399. dwType = dwValue = 0;
  400. dwItemSize = sizeof (dwValue);
  401. __try {
  402. dwStatus = RegQueryValueEx(
  403. hKeyPerflib,
  404. cszBaseIndex,
  405. NULL,
  406. & dwType,
  407. (LPBYTE) & dwValue,
  408. & dwItemSize);
  409. }
  410. __except (EXCEPTION_EXECUTE_HANDLER) {
  411. dwStatus = GetExceptionCode();
  412. }
  413. TRACE((WINPERF_DBG_TRACE_INFO),
  414. (& LoadPerfGuid,
  415. __LINE__,
  416. LOADPERF_DUMPPERFLIBENTRIES,
  417. ARG_DEF(ARG_TYPE_WSTR, 1),
  418. dwStatus,
  419. TRACE_WSTR(cszBaseIndex),
  420. TRACE_DWORD(dwValue),
  421. NULL));
  422. if ((dwStatus == ERROR_SUCCESS) && (dwType == REG_DWORD)) {
  423. ZeroMemory(szOutputBuffer, 4096 * sizeof(WCHAR));
  424. dwSize = swprintf (szOutputBuffer, cszFmtDecimalParam, cszBaseIndex, dwValue);
  425. dwSize *= sizeof (WCHAR);
  426. WriteFile (hOutputFile, szOutputBuffer, dwSize, &dwSizeWritten, NULL);
  427. *pdwFirstExtCtrIndex = dwValue + 1;
  428. }
  429. }
  430. if (dwStatus == ERROR_SUCCESS) {
  431. dwType = dwValue = 0;
  432. dwItemSize = sizeof (dwValue);
  433. __try {
  434. dwStatus = RegQueryValueEx(
  435. hKeyPerflib,
  436. cszLastCounter,
  437. NULL,
  438. & dwType,
  439. (LPBYTE) & dwValue,
  440. & dwItemSize);
  441. }
  442. __except (EXCEPTION_EXECUTE_HANDLER) {
  443. dwStatus = GetExceptionCode();
  444. }
  445. TRACE((WINPERF_DBG_TRACE_INFO),
  446. (& LoadPerfGuid,
  447. __LINE__,
  448. LOADPERF_DUMPPERFLIBENTRIES,
  449. ARG_DEF(ARG_TYPE_WSTR, 1),
  450. dwStatus,
  451. TRACE_WSTR(cszLastCounter),
  452. TRACE_DWORD(dwValue),
  453. NULL));
  454. if ((dwStatus == ERROR_SUCCESS) && (dwType == REG_DWORD)) {
  455. ZeroMemory(szOutputBuffer, 4096 * sizeof(WCHAR));
  456. dwSize = swprintf (szOutputBuffer, cszFmtDecimalParam, cszLastCounter, dwValue);
  457. dwSize *= sizeof (WCHAR);
  458. WriteFile (hOutputFile, szOutputBuffer, dwSize, &dwSizeWritten, NULL);
  459. }
  460. }
  461. if (dwStatus == ERROR_SUCCESS) {
  462. dwType = dwValue = 0;
  463. dwItemSize = sizeof (dwValue);
  464. __try {
  465. dwStatus = RegQueryValueEx(
  466. hKeyPerflib,
  467. cszLastHelp,
  468. NULL,
  469. & dwType,
  470. (LPBYTE) & dwValue,
  471. & dwItemSize);
  472. }
  473. __except (EXCEPTION_EXECUTE_HANDLER) {
  474. dwStatus = GetExceptionCode();
  475. }
  476. TRACE((WINPERF_DBG_TRACE_INFO),
  477. (& LoadPerfGuid,
  478. __LINE__,
  479. LOADPERF_DUMPPERFLIBENTRIES,
  480. ARG_DEF(ARG_TYPE_WSTR, 1),
  481. dwStatus,
  482. TRACE_WSTR(cszLastHelp),
  483. TRACE_DWORD(dwValue),
  484. NULL));
  485. if ((dwStatus == ERROR_SUCCESS) && (dwType == REG_DWORD)) {
  486. ZeroMemory(szOutputBuffer, 4096 * sizeof(WCHAR));
  487. dwSize = swprintf (szOutputBuffer, cszFmtDecimalParam, cszLastHelp, dwValue);
  488. dwSize *= sizeof (WCHAR);
  489. WriteFile (hOutputFile, szOutputBuffer, dwSize, &dwSizeWritten, NULL);
  490. }
  491. }
  492. if (hKeyPerflib != NULL) RegCloseKey (hKeyPerflib);
  493. return dwStatus;
  494. }
  495. DWORD
  496. BuildServiceLists (
  497. IN LPWSTR mszPerfServiceList,
  498. IN LPDWORD pcchPerfServiceListSize,
  499. IN LPWSTR mszNoPerfServiceList,
  500. IN LPDWORD pcchNoPerfServiceListSize
  501. )
  502. {
  503. LONG lStatus = ERROR_SUCCESS;
  504. LONG lEnumStatus = ERROR_SUCCESS;
  505. DWORD dwServiceIndex = 0;
  506. WCHAR szServiceSubKeyName[MAX_PATH];
  507. WCHAR szPerfSubKeyName[MAX_PATH+20];
  508. DWORD dwNameSize = MAX_PATH;
  509. HKEY hKeyPerformance;
  510. HKEY hKeyServices = NULL;
  511. DWORD dwItemSize, dwType, dwValue;
  512. DWORD dwRegAccessMask;
  513. DWORD bServiceHasPerfCounters;
  514. DWORD dwRetStatus = ERROR_SUCCESS;
  515. LPWSTR szNextNoPerfChar, szNextPerfChar;
  516. DWORD dwNoPerfSizeRem, dwPerfSizeRem;
  517. DWORD dwPerfSizeUsed = 0, dwNoPerfSizeUsed = 0;
  518. // try read-only then
  519. dwRegAccessMask = KEY_READ;
  520. __try {
  521. lStatus = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
  522. cszServiceKeyName,
  523. 0L,
  524. dwRegAccessMask,
  525. & hKeyServices);
  526. }
  527. __except (EXCEPTION_EXECUTE_HANDLER) {
  528. lStatus = GetExceptionCode();
  529. }
  530. if (lStatus == ERROR_SUCCESS) {
  531. szNextNoPerfChar = mszNoPerfServiceList;
  532. szNextPerfChar = mszPerfServiceList;
  533. dwNoPerfSizeRem = *pcchPerfServiceListSize;
  534. dwPerfSizeRem = *pcchNoPerfServiceListSize;
  535. dwPerfSizeUsed = 0;
  536. dwNoPerfSizeUsed = 0;
  537. while ((lEnumStatus = RegEnumKeyExW (
  538. hKeyServices,
  539. dwServiceIndex,
  540. szServiceSubKeyName,
  541. &dwNameSize,
  542. NULL,
  543. NULL,
  544. NULL,
  545. NULL)) == ERROR_SUCCESS) {
  546. //try to open the perfkey under this key.
  547. lstrcpy (szPerfSubKeyName, szServiceSubKeyName);
  548. lstrcat (szPerfSubKeyName, cszPerformance);
  549. __try {
  550. lStatus = RegOpenKeyExW(
  551. hKeyServices,
  552. szPerfSubKeyName,
  553. 0L,
  554. dwRegAccessMask,
  555. & hKeyPerformance);
  556. }
  557. __except (EXCEPTION_EXECUTE_HANDLER) {
  558. lStatus = GetExceptionCode();
  559. }
  560. if (lStatus == ERROR_SUCCESS) {
  561. // key found so service has perf data
  562. // now check to see if the strings have been loaded
  563. dwType = dwValue = 0;
  564. dwItemSize = sizeof (dwValue);
  565. __try {
  566. lStatus = RegQueryValueExW(
  567. hKeyPerformance,
  568. cszFirstCounter,
  569. NULL,
  570. & dwType,
  571. (LPBYTE) & dwValue,
  572. & dwItemSize);
  573. }
  574. __except (EXCEPTION_EXECUTE_HANDLER) {
  575. lStatus = GetExceptionCode();
  576. }
  577. if ((lStatus == ERROR_SUCCESS) &&
  578. ((dwType == REG_DWORD) || dwType == REG_BINARY)) {
  579. bServiceHasPerfCounters = TRUE;
  580. } else {
  581. bServiceHasPerfCounters = FALSE;
  582. }
  583. RegCloseKey (hKeyPerformance);
  584. } else {
  585. // key not found so service doesn't have perfdata
  586. bServiceHasPerfCounters = FALSE;
  587. }
  588. TRACE((WINPERF_DBG_TRACE_INFO),
  589. (& LoadPerfGuid,
  590. __LINE__,
  591. LOADPERF_BUILDSERVICELISTS,
  592. ARG_DEF(ARG_TYPE_WSTR, 1),
  593. lStatus,
  594. TRACE_WSTR(szServiceSubKeyName),
  595. TRACE_DWORD(bServiceHasPerfCounters),
  596. NULL));
  597. if (bServiceHasPerfCounters != FALSE) {
  598. // add to the perf service list
  599. if ((dwNameSize + 1)< dwPerfSizeRem) {
  600. // add to list
  601. lstrcpyW (szNextPerfChar, szServiceSubKeyName);
  602. szNextPerfChar += dwNameSize;
  603. *szNextPerfChar = 0;
  604. szNextPerfChar++;
  605. dwPerfSizeRem -= dwNameSize + 1;
  606. } else {
  607. dwRetStatus = ERROR_MORE_DATA;
  608. }
  609. dwPerfSizeUsed += dwNameSize + 1;
  610. } else {
  611. // add to the no perf list
  612. if ((dwNameSize + 1) < dwNoPerfSizeRem) {
  613. // add to list
  614. lstrcpyW (szNextNoPerfChar, szServiceSubKeyName);
  615. szNextNoPerfChar += dwNameSize;
  616. *szNextNoPerfChar = 0;
  617. szNextNoPerfChar++;
  618. dwNoPerfSizeRem -= dwNameSize + 1;
  619. } else {
  620. dwRetStatus = ERROR_MORE_DATA;
  621. }
  622. dwNoPerfSizeUsed += dwNameSize + 1;
  623. }
  624. // reset for next loop
  625. dwServiceIndex++;
  626. dwNameSize = MAX_PATH;
  627. }
  628. // zero term the MSZ
  629. if (1 < dwPerfSizeRem) {
  630. *szNextPerfChar = 0;
  631. szNextPerfChar++;
  632. dwPerfSizeRem -= 1;
  633. } else {
  634. dwRetStatus = ERROR_MORE_DATA;
  635. }
  636. dwPerfSizeUsed += 1;
  637. // zero term the no perf list
  638. if (1 < dwNoPerfSizeRem) {
  639. // add to list
  640. *szNextNoPerfChar = 0;
  641. szNextNoPerfChar++;
  642. dwNoPerfSizeRem -= 1;
  643. } else {
  644. dwRetStatus = ERROR_MORE_DATA;
  645. }
  646. dwNoPerfSizeUsed += 1;
  647. }
  648. else {
  649. TRACE((WINPERF_DBG_TRACE_ERROR),
  650. (& LoadPerfGuid,
  651. __LINE__,
  652. LOADPERF_BUILDSERVICELISTS,
  653. ARG_DEF(ARG_TYPE_WSTR, 1),
  654. lStatus,
  655. TRACE_WSTR(cszServiceKeyName),
  656. NULL));
  657. }
  658. if (hKeyServices != NULL) RegCloseKey (hKeyServices);
  659. *pcchPerfServiceListSize = dwPerfSizeUsed;
  660. *pcchNoPerfServiceListSize = dwNoPerfSizeUsed;
  661. return dwRetStatus;
  662. }
  663. DWORD
  664. BackupPerfRegistryToFileW (
  665. IN LPCWSTR szFileName,
  666. IN LPCWSTR szCommentString
  667. )
  668. {
  669. HANDLE hOutFile;
  670. DWORD dwStatus = ERROR_SUCCESS;
  671. LPWSTR szNewFileName = NULL;
  672. DWORD dwNewFileNameLen;
  673. DWORD dwOrigFileNameLen;
  674. DWORD dwFileNameSN;
  675. LPWSTR mszPerfServiceList = NULL;
  676. DWORD dwPerfServiceListSize = 0;
  677. LPWSTR mszNoPerfServiceList = NULL;
  678. DWORD dwNoPerfServiceListSize = 0;
  679. LPWSTR *lpCounterText = NULL;
  680. DWORD dwLastElement = 0;
  681. DWORD dwFirstExtCtrIndex = 0;
  682. LPWSTR szThisServiceName;
  683. DBG_UNREFERENCED_PARAMETER (szCommentString);
  684. WinPerfStartTrace(NULL);
  685. // open output file
  686. hOutFile = CreateFileW (
  687. szFileName,
  688. GENERIC_WRITE,
  689. 0, // no sharing
  690. NULL, // default security
  691. CREATE_NEW,
  692. FILE_ATTRIBUTE_NORMAL,
  693. NULL);
  694. // if the file open failed
  695. if (hOutFile == INVALID_HANDLE_VALUE) {
  696. // see if it's because the file already exists
  697. dwStatus = GetLastError();
  698. if (dwStatus == ERROR_FILE_EXISTS) {
  699. // then try appending a serial number to the name
  700. dwOrigFileNameLen = lstrlenW (szFileName);
  701. dwNewFileNameLen = dwOrigFileNameLen + 4;
  702. szNewFileName = MemoryAllocate(
  703. (dwNewFileNameLen +1) * sizeof(WCHAR));
  704. if (szNewFileName != NULL) {
  705. lstrcpyW (szNewFileName, szFileName);
  706. for (dwFileNameSN = 1; dwFileNameSN < 1000; dwFileNameSN++) {
  707. swprintf (&szNewFileName[dwOrigFileNameLen],
  708. (LPCWSTR)L"_%3.3d", dwFileNameSN);
  709. hOutFile = CreateFileW (
  710. szNewFileName,
  711. GENERIC_WRITE,
  712. 0, // no sharing
  713. NULL, // default security
  714. CREATE_NEW,
  715. FILE_ATTRIBUTE_NORMAL,
  716. NULL);
  717. // if the file open failed
  718. if (hOutFile == INVALID_HANDLE_VALUE) {
  719. dwStatus = GetLastError();
  720. if (dwStatus != ERROR_FILE_EXISTS) {
  721. // some other error occurred so bail out
  722. break;
  723. } else {
  724. continue; // with the next try
  725. }
  726. } else {
  727. // found one not in use so continue on
  728. dwStatus = ERROR_SUCCESS;
  729. break;
  730. }
  731. }
  732. } else {
  733. dwStatus = ERROR_OUTOFMEMORY;
  734. }
  735. }
  736. } else {
  737. // file opened so continue
  738. dwStatus = ERROR_SUCCESS;
  739. }
  740. if (dwStatus == ERROR_SUCCESS) {
  741. // dump perflib key entires
  742. dwStatus = DumpPerflibEntries (hOutFile, &dwFirstExtCtrIndex);
  743. }
  744. if (dwStatus == ERROR_SUCCESS) {
  745. do {
  746. if (mszPerfServiceList != NULL) {
  747. MemoryFree(mszPerfServiceList);
  748. mszPerfServiceList = NULL;
  749. }
  750. if (mszNoPerfServiceList != NULL) {
  751. MemoryFree(mszNoPerfServiceList);
  752. mszNoPerfServiceList = NULL;
  753. }
  754. // build service lists
  755. dwPerfServiceListSize += 32768;
  756. dwNoPerfServiceListSize += 65536;
  757. mszPerfServiceList = MemoryAllocate(
  758. (dwPerfServiceListSize) * sizeof(WCHAR));
  759. mszNoPerfServiceList = MemoryAllocate(
  760. (dwNoPerfServiceListSize) * sizeof(WCHAR));
  761. if ((mszNoPerfServiceList == NULL) || (mszPerfServiceList == NULL)) {
  762. dwStatus = ERROR_OUTOFMEMORY;
  763. break;
  764. }
  765. if (dwStatus == ERROR_SUCCESS) {
  766. dwStatus = BuildServiceLists (
  767. mszPerfServiceList,
  768. &dwPerfServiceListSize,
  769. mszNoPerfServiceList,
  770. &dwNoPerfServiceListSize);
  771. if (dwStatus == ERROR_SUCCESS) break; // and continue on
  772. }
  773. } while (dwPerfServiceListSize < 4194304);
  774. }
  775. // dump service entries for those services with perf counters
  776. if (dwStatus == ERROR_SUCCESS) {
  777. for (szThisServiceName = mszPerfServiceList;
  778. *szThisServiceName != 0;
  779. szThisServiceName += lstrlenW(szThisServiceName)+1) {
  780. dwStatus = DumpPerfServiceEntries (
  781. hOutFile,
  782. szThisServiceName);
  783. if (dwStatus != ERROR_SUCCESS) break;
  784. }
  785. }
  786. // dump perf string entries
  787. if (dwStatus == ERROR_SUCCESS) {
  788. WCHAR szLangId[8];
  789. DWORD dwIndex = 0;
  790. DWORD dwBufferSize;
  791. HKEY hPerflibRoot = NULL;
  792. __try {
  793. dwStatus = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
  794. NamesKey,
  795. RESERVED,
  796. KEY_READ,
  797. & hPerflibRoot);
  798. }
  799. __except (EXCEPTION_EXECUTE_HANDLER) {
  800. dwStatus = GetExceptionCode();
  801. }
  802. while (dwStatus == ERROR_SUCCESS) {
  803. dwBufferSize = 8;
  804. ZeroMemory(szLangId, 8 * sizeof(WCHAR));
  805. dwStatus = RegEnumKeyExW(hPerflibRoot,
  806. dwIndex,
  807. szLangId,
  808. & dwBufferSize,
  809. NULL,
  810. NULL,
  811. NULL,
  812. NULL);
  813. if (dwStatus == ERROR_SUCCESS) {
  814. lpCounterText = BuildNameTable(HKEY_LOCAL_MACHINE,
  815. (LPWSTR) szLangId,
  816. & dwLastElement);
  817. if (lpCounterText != NULL) {
  818. __try {
  819. dwStatus = DumpNameTable(hOutFile,
  820. szLangId,
  821. lpCounterText,
  822. 0,
  823. dwLastElement);
  824. }
  825. __except (EXCEPTION_EXECUTE_HANDLER) {
  826. dwStatus = GetExceptionCode();
  827. TRACE((WINPERF_DBG_TRACE_ERROR),
  828. (& LoadPerfGuid,
  829. __LINE__,
  830. LOADPERF_BACKUPPERFREGISTRYTOFILEW,
  831. ARG_DEF(ARG_TYPE_WSTR, 1),
  832. dwStatus,
  833. TRACE_WSTR(szLangId),
  834. TRACE_DWORD(dwLastElement),
  835. NULL));
  836. }
  837. MemoryFree(lpCounterText);
  838. lpCounterText = NULL;
  839. }
  840. else {
  841. dwStatus = GetLastError();
  842. }
  843. }
  844. dwIndex ++;
  845. }
  846. if (dwStatus == ERROR_NO_MORE_ITEMS) dwStatus = ERROR_SUCCESS;
  847. if (hPerflibRoot != NULL) RegCloseKey(hPerflibRoot);
  848. }
  849. // free buffers
  850. if (lpCounterText != NULL) {
  851. MemoryFree(lpCounterText);
  852. lpCounterText = NULL;
  853. }
  854. if (mszNoPerfServiceList != NULL) {
  855. MemoryFree(mszNoPerfServiceList);
  856. mszNoPerfServiceList = NULL;
  857. }
  858. if (mszPerfServiceList != NULL) {
  859. MemoryFree(mszPerfServiceList);
  860. mszPerfServiceList = NULL;
  861. }
  862. if (szNewFileName != NULL) {
  863. MemoryFree(szNewFileName);
  864. szNewFileName = NULL;
  865. }
  866. // close file handles
  867. if (hOutFile != INVALID_HANDLE_VALUE) {
  868. CloseHandle (hOutFile);
  869. }
  870. return dwStatus;
  871. }
  872. DWORD
  873. RestorePerfRegistryFromFileW (
  874. IN LPCWSTR szFileName,
  875. IN LPCWSTR szLangId
  876. )
  877. {
  878. LONG lStatus = ERROR_SUCCESS;
  879. LONG lEnumStatus = ERROR_SUCCESS;
  880. DWORD dwServiceIndex = 0;
  881. WCHAR szServiceSubKeyName[MAX_PATH];
  882. WCHAR szPerfSubKeyName[MAX_PATH+20];
  883. DWORD dwNameSize = MAX_PATH;
  884. HKEY hKeyPerformance;
  885. HKEY hKeyServices = NULL;
  886. HKEY hKeyPerflib = NULL;
  887. DWORD dwItemSize;
  888. DWORD dwRegAccessMask;
  889. DWORD dwRetStatus = ERROR_SUCCESS;
  890. UINT nValue;
  891. DWORD dwnValue;
  892. BOOL bServiceRegistryOk = TRUE;
  893. WCHAR wPerfSection[MAX_PATH * 2];
  894. WCHAR szLocalLangId[8];
  895. WinPerfStartTrace(NULL);
  896. __try {
  897. lStatus = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
  898. cszServiceKeyName,
  899. 0L,
  900. KEY_READ,
  901. & hKeyServices);
  902. }
  903. __except (EXCEPTION_EXECUTE_HANDLER) {
  904. lStatus = GetExceptionCode();
  905. }
  906. if (lStatus == ERROR_SUCCESS) {
  907. // enum service list
  908. while ((lEnumStatus = RegEnumKeyExW (
  909. hKeyServices,
  910. dwServiceIndex,
  911. szServiceSubKeyName,
  912. &dwNameSize,
  913. NULL,
  914. NULL,
  915. NULL,
  916. NULL)) == ERROR_SUCCESS) {
  917. //try to open the perfkey under this key.
  918. lstrcpy (szPerfSubKeyName, szServiceSubKeyName);
  919. lstrcat (szPerfSubKeyName, cszPerformance);
  920. bServiceRegistryOk = TRUE;
  921. dwRegAccessMask = KEY_READ | KEY_WRITE;
  922. // look for a performance subkey
  923. __try {
  924. lStatus = RegOpenKeyExW(
  925. hKeyServices,
  926. szPerfSubKeyName,
  927. 0L,
  928. dwRegAccessMask,
  929. & hKeyPerformance);
  930. }
  931. __except (EXCEPTION_EXECUTE_HANDLER) {
  932. lStatus = GetExceptionCode();
  933. }
  934. if (lStatus == ERROR_SUCCESS) {
  935. // key found so service has perf data
  936. // if performance subkey then
  937. dwItemSize = swprintf (wPerfSection,
  938. cszFmtServiceSectionName, szServiceSubKeyName);
  939. // look into the file for a perf entry for this service
  940. nValue = GetPrivateProfileIntW (
  941. wPerfSection,
  942. cszFirstCounter,
  943. -1,
  944. szFileName);
  945. if (nValue != (UINT) -1) {
  946. // if found in file then update registry with values from file
  947. __try {
  948. lStatus = RegSetValueExW(hKeyPerformance,
  949. cszFirstCounter,
  950. 0L,
  951. REG_DWORD,
  952. (const BYTE *) & nValue,
  953. sizeof(nValue));
  954. }
  955. __except (EXCEPTION_EXECUTE_HANDLER) {
  956. lStatus = GetExceptionCode();
  957. }
  958. dwnValue = nValue;
  959. TRACE((WINPERF_DBG_TRACE_INFO),
  960. (& LoadPerfGuid,
  961. __LINE__,
  962. LOADPERF_RESTOREPERFREGISTRYFROMFILEW,
  963. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  964. lStatus,
  965. TRACE_WSTR(szServiceSubKeyName),
  966. TRACE_WSTR(cszFirstCounter),
  967. TRACE_DWORD(dwnValue),
  968. NULL));
  969. // now read the other values
  970. } else {
  971. // there's one or more missing entries so
  972. // remove the whole entry
  973. bServiceRegistryOk = FALSE;
  974. }
  975. // look into the file for a perf entry for this service
  976. nValue = GetPrivateProfileIntW (
  977. wPerfSection,
  978. cszFirstHelp,
  979. -1,
  980. szFileName);
  981. if (nValue != (UINT)-1) {
  982. // if found in file then update registry with values from file
  983. __try {
  984. lStatus = RegSetValueExW(hKeyPerformance,
  985. cszFirstHelp,
  986. 0L,
  987. REG_DWORD,
  988. (const BYTE *)&nValue,
  989. sizeof(nValue));
  990. }
  991. __except (EXCEPTION_EXECUTE_HANDLER) {
  992. lStatus = GetExceptionCode();
  993. }
  994. dwnValue = nValue;
  995. TRACE((WINPERF_DBG_TRACE_INFO),
  996. (& LoadPerfGuid,
  997. __LINE__,
  998. LOADPERF_RESTOREPERFREGISTRYFROMFILEW,
  999. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  1000. lStatus,
  1001. TRACE_WSTR(szServiceSubKeyName),
  1002. TRACE_WSTR(cszFirstHelp),
  1003. TRACE_DWORD(dwnValue),
  1004. NULL));
  1005. // now read the other values
  1006. } else {
  1007. // there's one or more missing entries so
  1008. // remove the whole entry
  1009. bServiceRegistryOk = FALSE;
  1010. }
  1011. // look into the file for a perf entry for this service
  1012. nValue = GetPrivateProfileIntW (
  1013. wPerfSection,
  1014. cszLastCounter,
  1015. -1,
  1016. szFileName);
  1017. if (nValue != (UINT)-1) {
  1018. // if found in file then update registry with values from file
  1019. __try {
  1020. lStatus = RegSetValueExW(hKeyPerformance,
  1021. cszLastCounter,
  1022. 0L,
  1023. REG_DWORD,
  1024. (const BYTE *)&nValue,
  1025. sizeof(nValue));
  1026. }
  1027. __except (EXCEPTION_EXECUTE_HANDLER) {
  1028. lStatus = GetExceptionCode();
  1029. }
  1030. dwnValue = nValue;
  1031. TRACE((WINPERF_DBG_TRACE_INFO),
  1032. (& LoadPerfGuid,
  1033. __LINE__,
  1034. LOADPERF_RESTOREPERFREGISTRYFROMFILEW,
  1035. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  1036. lStatus,
  1037. TRACE_WSTR(szServiceSubKeyName),
  1038. TRACE_WSTR(cszLastCounter),
  1039. TRACE_DWORD(dwnValue),
  1040. NULL));
  1041. // now read the other values
  1042. } else {
  1043. // there's one or more missing entries so
  1044. // remove the whole entry
  1045. bServiceRegistryOk = FALSE;
  1046. }
  1047. // look into the file for a perf entry for this service
  1048. nValue = GetPrivateProfileIntW (
  1049. wPerfSection,
  1050. cszLastHelp,
  1051. -1,
  1052. szFileName);
  1053. if (nValue != (UINT)-1) {
  1054. // if found in file then update registry with values from file
  1055. __try {
  1056. lStatus = RegSetValueExW(hKeyPerformance,
  1057. cszLastHelp,
  1058. 0L,
  1059. REG_DWORD,
  1060. (const BYTE *) & nValue,
  1061. sizeof(nValue));
  1062. }
  1063. __except (EXCEPTION_EXECUTE_HANDLER) {
  1064. lStatus = GetExceptionCode();
  1065. }
  1066. dwnValue = nValue;
  1067. TRACE((WINPERF_DBG_TRACE_INFO),
  1068. (& LoadPerfGuid,
  1069. __LINE__,
  1070. LOADPERF_RESTOREPERFREGISTRYFROMFILEW,
  1071. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  1072. lStatus,
  1073. TRACE_WSTR(szServiceSubKeyName),
  1074. TRACE_WSTR(cszLastHelp),
  1075. TRACE_DWORD(dwnValue),
  1076. NULL));
  1077. // now read the other values
  1078. } else {
  1079. // there's one or more missing entries so
  1080. // remove the whole entry
  1081. bServiceRegistryOk = FALSE;
  1082. }
  1083. if (!bServiceRegistryOk) {
  1084. // an error occurred so delete the first/last counter/help values
  1085. RegDeleteValue (hKeyPerformance, cszFirstCounter);
  1086. RegDeleteValue (hKeyPerformance, cszFirstHelp);
  1087. RegDeleteValue (hKeyPerformance, cszLastCounter);
  1088. RegDeleteValue (hKeyPerformance, cszLastHelp);
  1089. } // else continiue
  1090. RegCloseKey (hKeyPerformance);
  1091. } // else this service has no perf data so skip
  1092. else {
  1093. TRACE((WINPERF_DBG_TRACE_ERROR),
  1094. (& LoadPerfGuid,
  1095. __LINE__,
  1096. LOADPERF_RESTOREPERFREGISTRYFROMFILEW,
  1097. ARG_DEF(ARG_TYPE_WSTR, 1),
  1098. lStatus,
  1099. TRACE_WSTR(szServiceSubKeyName),
  1100. NULL));
  1101. }
  1102. // reset for next loop
  1103. dwServiceIndex++;
  1104. dwNameSize = MAX_PATH;
  1105. } // end enum service list
  1106. }
  1107. else {
  1108. TRACE((WINPERF_DBG_TRACE_ERROR),
  1109. (& LoadPerfGuid,
  1110. __LINE__,
  1111. LOADPERF_RESTOREPERFREGISTRYFROMFILEW,
  1112. ARG_DEF(ARG_TYPE_WSTR, 1),
  1113. lStatus,
  1114. TRACE_WSTR(cszServiceKeyName),
  1115. NULL));
  1116. }
  1117. if (hKeyServices != NULL) RegCloseKey (hKeyServices);
  1118. if (dwRetStatus == ERROR_SUCCESS) {
  1119. __try {
  1120. lStatus = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
  1121. cszPerflibKeyName,
  1122. RESERVED,
  1123. KEY_ALL_ACCESS,
  1124. & hKeyPerflib);
  1125. }
  1126. __except (EXCEPTION_EXECUTE_HANDLER) {
  1127. lStatus = GetExceptionCode();
  1128. }
  1129. if (lStatus != ERROR_SUCCESS) {
  1130. TRACE((WINPERF_DBG_TRACE_ERROR),
  1131. (& LoadPerfGuid,
  1132. __LINE__,
  1133. LOADPERF_RESTOREPERFREGISTRYFROMFILEW,
  1134. ARG_DEF(ARG_TYPE_WSTR, 1),
  1135. lStatus,
  1136. TRACE_WSTR(cszPerflibKeyName),
  1137. NULL));
  1138. dwRetStatus = lStatus;
  1139. }
  1140. if (szLangId != NULL) {
  1141. // merge registry string values:
  1142. lstrcpyW(szLocalLangId, szLangId);
  1143. dwRetStatus = UpdatePerfNameFilesX(szFileName,
  1144. NULL,
  1145. szLocalLangId,
  1146. LODCTR_UPNF_RESTORE);
  1147. }
  1148. else if (lStatus == ERROR_SUCCESS) {
  1149. DWORD dwIndex = 0;
  1150. DWORD dwBufferSize;
  1151. while (dwRetStatus == ERROR_SUCCESS) {
  1152. dwBufferSize = 8;
  1153. ZeroMemory(szLocalLangId, 8 * sizeof(WCHAR));
  1154. dwRetStatus = RegEnumKeyExW(hKeyPerflib,
  1155. dwIndex,
  1156. szLocalLangId,
  1157. & dwBufferSize,
  1158. NULL,
  1159. NULL,
  1160. NULL,
  1161. NULL);
  1162. if (dwRetStatus == ERROR_SUCCESS) {
  1163. dwRetStatus = UpdatePerfNameFilesX(szFileName,
  1164. NULL,
  1165. szLocalLangId,
  1166. LODCTR_UPNF_RESTORE);
  1167. }
  1168. dwIndex ++;
  1169. }
  1170. if (dwRetStatus == ERROR_NO_MORE_ITEMS) {
  1171. dwRetStatus = ERROR_SUCCESS;
  1172. }
  1173. }
  1174. if (dwRetStatus == ERROR_SUCCESS) {
  1175. // update the keys in the registry
  1176. if (lStatus == ERROR_SUCCESS) {
  1177. nValue = GetPrivateProfileIntW (
  1178. cszPerflib,
  1179. cszLastCounter,
  1180. -1,
  1181. szFileName);
  1182. if (nValue != (UINT)-1) {
  1183. // if found in file then update registry with values from file
  1184. __try {
  1185. lStatus = RegSetValueExW(hKeyPerflib,
  1186. cszLastCounter,
  1187. 0L,
  1188. REG_DWORD,
  1189. (const BYTE *) & nValue,
  1190. sizeof(nValue));
  1191. }
  1192. __except (EXCEPTION_EXECUTE_HANDLER) {
  1193. lStatus = GetExceptionCode();
  1194. }
  1195. dwnValue = nValue;
  1196. TRACE((WINPERF_DBG_TRACE_INFO),
  1197. (& LoadPerfGuid,
  1198. __LINE__,
  1199. LOADPERF_RESTOREPERFREGISTRYFROMFILEW,
  1200. ARG_DEF(ARG_TYPE_WSTR, 1),
  1201. lStatus,
  1202. TRACE_WSTR(cszLastCounter),
  1203. TRACE_DWORD(dwnValue),
  1204. NULL));
  1205. }
  1206. }
  1207. if (lStatus == ERROR_SUCCESS) {
  1208. // look into the file for a perf entry for this service
  1209. nValue = GetPrivateProfileIntW (
  1210. cszPerflib,
  1211. cszLastHelp,
  1212. -1,
  1213. szFileName);
  1214. if (nValue != (UINT)-1) {
  1215. // if found in file then update registry with values from file
  1216. __try {
  1217. lStatus = RegSetValueExW(hKeyPerflib,
  1218. cszLastHelp,
  1219. 0L,
  1220. REG_DWORD,
  1221. (const BYTE *) & nValue,
  1222. sizeof(nValue));
  1223. }
  1224. __except (EXCEPTION_EXECUTE_HANDLER) {
  1225. lStatus = GetExceptionCode();
  1226. }
  1227. dwnValue = nValue;
  1228. TRACE((WINPERF_DBG_TRACE_INFO),
  1229. (& LoadPerfGuid,
  1230. __LINE__,
  1231. LOADPERF_RESTOREPERFREGISTRYFROMFILEW,
  1232. ARG_DEF(ARG_TYPE_WSTR, 1),
  1233. lStatus,
  1234. TRACE_WSTR(cszLastHelp),
  1235. TRACE_DWORD(dwnValue),
  1236. NULL));
  1237. }
  1238. }
  1239. if (lStatus == ERROR_SUCCESS) {
  1240. // look into the file for a perf entry for this service
  1241. nValue = GetPrivateProfileIntW (
  1242. cszPerflib,
  1243. cszBaseIndex,
  1244. -1,
  1245. szFileName);
  1246. if (nValue != (UINT)-1) {
  1247. // if found in file then update registry with values from file
  1248. __try {
  1249. lStatus = RegSetValueExW(hKeyPerflib,
  1250. cszBaseIndex,
  1251. 0L,
  1252. REG_DWORD,
  1253. (const BYTE *) & nValue,
  1254. sizeof(nValue));
  1255. }
  1256. __except (EXCEPTION_EXECUTE_HANDLER) {
  1257. lStatus = GetExceptionCode();
  1258. }
  1259. dwnValue = nValue;
  1260. TRACE((WINPERF_DBG_TRACE_INFO),
  1261. (& LoadPerfGuid,
  1262. __LINE__,
  1263. LOADPERF_RESTOREPERFREGISTRYFROMFILEW,
  1264. ARG_DEF(ARG_TYPE_WSTR, 1),
  1265. lStatus,
  1266. TRACE_WSTR(cszBaseIndex),
  1267. TRACE_DWORD(dwnValue),
  1268. NULL));
  1269. }
  1270. }
  1271. if (hKeyPerflib != NULL) RegCloseKey (hKeyPerflib);
  1272. }
  1273. dwRetStatus = lStatus;
  1274. }
  1275. return dwRetStatus;
  1276. }