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.

1795 lines
73 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. //
  13. // Windows Include files
  14. //
  15. #include <windows.h>
  16. #include "strsafe.h"
  17. #include "stdlib.h"
  18. #include <winperf.h>
  19. #include <loadperf.h>
  20. #include "wmistr.h"
  21. #include "evntrace.h"
  22. //
  23. // application include files
  24. //
  25. #include "winperfp.h"
  26. #include "common.h"
  27. #include "ldprfmsg.h"
  28. #define DUMPLOAD_SERVICE_SIZE 32768
  29. #define DUMPLOAD_NOSERVICE_SIZE 65536
  30. #define DUMPLOAD_MAX_SERVICE_SIZE 4194304
  31. // headings in save file
  32. LPCWSTR cszFmtSectionHeader = L"\r\n\r\n[%s]";
  33. LPCWSTR cszFmtServiceSectionHeader = L"\r\n\r\n[PERF_%s]";
  34. LPCWSTR cszFmtServiceSectionName = L"PERF_%s";
  35. LPCWSTR cszFmtStringSectionHeader = L"\r\n\r\n[PerfStrings_%s]";
  36. LPCWSTR cszFmtExtCtrString = L"\r\n%d=%s";
  37. LPCWSTR cszFmtDecimalParam = L"\r\n%s=%d";
  38. LPCWSTR cszFmtNoParam = L"\r\n%s=";
  39. LPCWSTR cszExtensiblePerfStrings = L"Strings";
  40. LPCWSTR cszPerfCounterServices = L"PerfCounterServices";
  41. LPCWSTR cszNoPerfCounterServices = L"NoPerfCounterServices";
  42. LPCWSTR cszPerflib = L"Perflib";
  43. DWORD
  44. DumpNameTable(
  45. HANDLE hOutputFile,
  46. LPCWSTR szLangId,
  47. LPCWSTR * pszNameTable,
  48. DWORD dwStartIndex,
  49. DWORD dwLastIndex
  50. )
  51. {
  52. DWORD dwStatus = ERROR_SUCCESS;
  53. DWORD ndx = 0;
  54. LPWSTR szOutputBuffer = NULL;
  55. DWORD dwBufSize = SMALL_BUFFER_SIZE;
  56. DWORD dwSize = 0;
  57. DWORD dwSizeWritten = 0;
  58. HRESULT hr;
  59. TRACE((WINPERF_DBG_TRACE_INFO),
  60. (& LoadPerfGuid,
  61. __LINE__,
  62. LOADPERF_DUMPNAMETABLE,
  63. ARG_DEF(ARG_TYPE_WSTR, 1),
  64. ERROR_SUCCESS,
  65. TRACE_WSTR(szLangId),
  66. TRACE_DWORD(dwStartIndex),
  67. TRACE_DWORD(dwLastIndex),
  68. NULL));
  69. szOutputBuffer = MemoryAllocate(sizeof(WCHAR) * dwBufSize);
  70. if (szOutputBuffer == NULL) {
  71. dwStatus = GetLastError();
  72. goto Cleanup;
  73. }
  74. hr = StringCchPrintfW(szOutputBuffer, dwBufSize, cszFmtStringSectionHeader, szLangId);
  75. dwSize = lstrlenW(szOutputBuffer) * sizeof(WCHAR);
  76. WriteFile(hOutputFile, szOutputBuffer, dwSize, & dwSizeWritten, NULL);
  77. for (ndx = dwStartIndex; ndx <= dwLastIndex; ndx++) {
  78. if (pszNameTable[ndx] != NULL) {
  79. if (dwBufSize <= (DWORD) (lstrlenW(pszNameTable[ndx]) + 11)) {
  80. MemoryFree((LPVOID) szOutputBuffer);
  81. dwBufSize = (DWORD) (lstrlenW(pszNameTable[ndx]) + 11);
  82. szOutputBuffer = MemoryAllocate(dwBufSize * sizeof(WCHAR));
  83. if (szOutputBuffer == NULL) {
  84. dwStatus = GetLastError();
  85. goto Cleanup;
  86. }
  87. }
  88. ZeroMemory(szOutputBuffer, dwBufSize * sizeof(WCHAR));
  89. hr = StringCchPrintfW(szOutputBuffer, dwBufSize, cszFmtExtCtrString, ndx, pszNameTable[ndx]);
  90. dwSize = lstrlenW(szOutputBuffer) * sizeof(WCHAR);
  91. WriteFile(hOutputFile, szOutputBuffer, dwSize, & dwSizeWritten, NULL);
  92. }
  93. }
  94. Cleanup:
  95. MemoryFree(szOutputBuffer);
  96. return dwStatus;
  97. }
  98. DWORD
  99. DumpPerfServiceEntries(
  100. HANDLE hOutputFile,
  101. LPCWSTR szServiceName,
  102. LPDWORD pdwFirstCounter,
  103. LPDWORD pdwFirstHelp,
  104. LPDWORD pdwLastCounter,
  105. LPDWORD pdwLastHelp,
  106. LPDWORD pdwDisablePerfCounters,
  107. LPWSTR szPerfIniFile,
  108. DWORD dwPerfIniFile,
  109. LPWSTR mszObjectList,
  110. DWORD dwObjectList,
  111. BOOL bRemove
  112. )
  113. {
  114. DWORD dwPerfSubKeyName = 0;
  115. LPWSTR szPerfSubKeyName = NULL;
  116. HKEY hKeyPerformance = NULL;
  117. DWORD dwItemSize, dwType, dwValue;
  118. DWORD dwRegAccessMask;
  119. DWORD dwRetStatus = ERROR_SUCCESS;
  120. DWORD dwSize, dwSizeWritten;
  121. LPWSTR szOutputBuffer = NULL;
  122. HRESULT hr;
  123. szOutputBuffer = MemoryAllocate(sizeof(WCHAR) * SMALL_BUFFER_SIZE);
  124. if (szOutputBuffer == NULL) {
  125. dwRetStatus = GetLastError();
  126. goto Cleanup;
  127. }
  128. // try read-only then
  129. if (bRemove) {
  130. dwRegAccessMask = KEY_READ | KEY_WRITE;
  131. }
  132. else {
  133. dwRegAccessMask = KEY_READ;
  134. }
  135. dwPerfSubKeyName = lstrlenW(DriverPathRoot) + lstrlenW(Slash)
  136. + lstrlenW(szServiceName) + lstrlenW(Slash)
  137. + lstrlenW(Performance) + 1;
  138. szPerfSubKeyName = MemoryAllocate(dwPerfSubKeyName * sizeof(WCHAR));
  139. if (szPerfSubKeyName != NULL) {
  140. hr = StringCchPrintfW(szPerfSubKeyName, dwPerfSubKeyName, L"%s%s%s%s%s",
  141. DriverPathRoot, Slash, szServiceName, Slash, Performance);
  142. __try {
  143. dwRetStatus = RegOpenKeyExW(HKEY_LOCAL_MACHINE, szPerfSubKeyName, 0L, dwRegAccessMask, & hKeyPerformance);
  144. }
  145. __except (EXCEPTION_EXECUTE_HANDLER) {
  146. dwRetStatus = GetExceptionCode();
  147. }
  148. }
  149. else {
  150. dwRetStatus = ERROR_OUTOFMEMORY;
  151. }
  152. if (dwRetStatus == ERROR_SUCCESS) {
  153. // key found so service has perf data
  154. if (hOutputFile != NULL) {
  155. ZeroMemory(szOutputBuffer, SMALL_BUFFER_SIZE * sizeof(WCHAR));
  156. hr = StringCchPrintfW(szOutputBuffer, SMALL_BUFFER_SIZE, cszFmtServiceSectionHeader, szServiceName);
  157. dwSize = lstrlenW(szOutputBuffer) * sizeof(WCHAR);
  158. WriteFile(hOutputFile, szOutputBuffer, dwSize, & dwSizeWritten, NULL);
  159. }
  160. // now check to see if the strings have been loaded
  161. dwType = dwValue = 0;
  162. dwItemSize = sizeof(dwValue);
  163. __try {
  164. dwRetStatus = RegQueryValueExW(hKeyPerformance,
  165. FirstCounter,
  166. NULL,
  167. & dwType,
  168. (LPBYTE) & dwValue,
  169. & dwItemSize);
  170. }
  171. __except (EXCEPTION_EXECUTE_HANDLER) {
  172. dwRetStatus = GetExceptionCode();
  173. }
  174. TRACE((WINPERF_DBG_TRACE_INFO),
  175. (& LoadPerfGuid,
  176. __LINE__,
  177. LOADPERF_DUMPPERFSERVICEENTRIES,
  178. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  179. dwRetStatus,
  180. TRACE_WSTR(szServiceName),
  181. TRACE_WSTR(FirstCounter),
  182. TRACE_DWORD(dwValue),
  183. NULL));
  184. if (dwRetStatus == ERROR_SUCCESS && (dwType == REG_DWORD || dwType == REG_BINARY)) {
  185. if (pdwFirstCounter != NULL) {
  186. * pdwFirstCounter = dwValue;
  187. }
  188. if (hOutputFile != NULL) {
  189. ZeroMemory(szOutputBuffer, SMALL_BUFFER_SIZE * sizeof(WCHAR));
  190. hr = StringCchPrintfW(szOutputBuffer, SMALL_BUFFER_SIZE, cszFmtDecimalParam, FirstCounter, dwValue);
  191. dwSize = lstrlenW(szOutputBuffer) * sizeof(WCHAR);
  192. WriteFile(hOutputFile, szOutputBuffer, dwSize, & dwSizeWritten, NULL);
  193. }
  194. }
  195. dwType = dwValue = 0;
  196. dwItemSize = sizeof(dwValue);
  197. __try {
  198. dwRetStatus = RegQueryValueExW(hKeyPerformance,
  199. FirstHelp,
  200. NULL,
  201. & dwType,
  202. (LPBYTE) & dwValue,
  203. & dwItemSize);
  204. }
  205. __except (EXCEPTION_EXECUTE_HANDLER) {
  206. dwRetStatus = GetExceptionCode();
  207. }
  208. TRACE((WINPERF_DBG_TRACE_INFO),
  209. (& LoadPerfGuid,
  210. __LINE__,
  211. LOADPERF_DUMPPERFSERVICEENTRIES,
  212. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  213. dwRetStatus,
  214. TRACE_WSTR(szServiceName),
  215. TRACE_WSTR(FirstHelp),
  216. TRACE_DWORD(dwValue),
  217. NULL));
  218. if (dwRetStatus == ERROR_SUCCESS && (dwType == REG_DWORD || dwType == REG_BINARY)) {
  219. if (pdwFirstHelp != NULL) {
  220. * pdwFirstHelp = dwValue;
  221. }
  222. if (hOutputFile != NULL) {
  223. ZeroMemory(szOutputBuffer, SMALL_BUFFER_SIZE * sizeof(WCHAR));
  224. hr = StringCchPrintfW(szOutputBuffer, SMALL_BUFFER_SIZE, cszFmtDecimalParam, FirstHelp, dwValue);
  225. dwSize = lstrlenW(szOutputBuffer) * sizeof(WCHAR);
  226. WriteFile(hOutputFile, szOutputBuffer, dwSize, & dwSizeWritten, NULL);
  227. }
  228. }
  229. dwType = dwValue = 0;
  230. dwItemSize = sizeof(dwValue);
  231. __try {
  232. dwRetStatus = RegQueryValueExW(hKeyPerformance,
  233. LastCounter,
  234. NULL,
  235. & dwType,
  236. (LPBYTE) & dwValue,
  237. & dwItemSize);
  238. }
  239. __except (EXCEPTION_EXECUTE_HANDLER) {
  240. dwRetStatus = GetExceptionCode();
  241. }
  242. TRACE((WINPERF_DBG_TRACE_INFO),
  243. (& LoadPerfGuid,
  244. __LINE__,
  245. LOADPERF_DUMPPERFSERVICEENTRIES,
  246. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  247. dwRetStatus,
  248. TRACE_WSTR(szServiceName),
  249. TRACE_WSTR(LastCounter),
  250. TRACE_DWORD(dwValue),
  251. NULL));
  252. if (dwRetStatus == ERROR_SUCCESS && (dwType == REG_DWORD || dwType == REG_BINARY)) {
  253. if (pdwLastCounter != NULL) {
  254. * pdwLastCounter = dwValue;
  255. }
  256. if (hOutputFile != NULL) {
  257. ZeroMemory(szOutputBuffer, SMALL_BUFFER_SIZE * sizeof(WCHAR));
  258. hr = StringCchPrintfW(szOutputBuffer, SMALL_BUFFER_SIZE, cszFmtDecimalParam, LastCounter, dwValue);
  259. dwSize = lstrlenW(szOutputBuffer) * sizeof(WCHAR);
  260. WriteFile(hOutputFile, szOutputBuffer, dwSize, & dwSizeWritten, NULL);
  261. }
  262. }
  263. dwType = dwValue = 0;
  264. dwItemSize = sizeof(dwValue);
  265. __try {
  266. dwRetStatus = RegQueryValueExW(hKeyPerformance,
  267. LastHelp,
  268. NULL,
  269. & dwType,
  270. (LPBYTE) & dwValue,
  271. & dwItemSize);
  272. }
  273. __except (EXCEPTION_EXECUTE_HANDLER) {
  274. dwRetStatus = GetExceptionCode();
  275. }
  276. TRACE((WINPERF_DBG_TRACE_INFO),
  277. (& LoadPerfGuid,
  278. __LINE__,
  279. LOADPERF_DUMPPERFSERVICEENTRIES,
  280. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  281. dwRetStatus,
  282. TRACE_WSTR(szServiceName),
  283. TRACE_WSTR(LastHelp),
  284. TRACE_DWORD(dwValue),
  285. NULL));
  286. if (dwRetStatus == ERROR_SUCCESS && (dwType == REG_DWORD || dwType == REG_BINARY)) {
  287. if (pdwLastHelp != NULL) {
  288. * pdwLastHelp = dwValue;
  289. }
  290. if (hOutputFile != NULL) {
  291. ZeroMemory(szOutputBuffer, SMALL_BUFFER_SIZE * sizeof(WCHAR));
  292. hr = StringCchPrintfW(szOutputBuffer, SMALL_BUFFER_SIZE, cszFmtDecimalParam, LastHelp, dwValue);
  293. dwSize = lstrlenW(szOutputBuffer) * sizeof(WCHAR);
  294. WriteFile(hOutputFile, szOutputBuffer, dwSize, & dwSizeWritten, NULL);
  295. }
  296. }
  297. dwType = dwValue = 0;
  298. dwItemSize = sizeof(dwValue);
  299. __try {
  300. dwRetStatus = RegQueryValueExW(hKeyPerformance,
  301. DisablePerformanceCounters,
  302. NULL,
  303. & dwType,
  304. (LPBYTE) & dwValue,
  305. & dwItemSize);
  306. }
  307. __except (EXCEPTION_EXECUTE_HANDLER) {
  308. dwRetStatus = GetExceptionCode();
  309. }
  310. TRACE((WINPERF_DBG_TRACE_INFO),
  311. (& LoadPerfGuid,
  312. __LINE__,
  313. LOADPERF_DUMPPERFSERVICEENTRIES,
  314. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  315. dwRetStatus,
  316. TRACE_WSTR(szServiceName),
  317. TRACE_WSTR(DisablePerformanceCounters),
  318. TRACE_DWORD(dwValue),
  319. NULL));
  320. if (dwRetStatus == ERROR_SUCCESS && (dwType == REG_DWORD || dwType == REG_BINARY)) {
  321. if (pdwDisablePerfCounters != NULL) {
  322. * pdwDisablePerfCounters = dwValue;
  323. }
  324. if (hOutputFile != NULL) {
  325. ZeroMemory(szOutputBuffer, SMALL_BUFFER_SIZE * sizeof(WCHAR));
  326. hr = StringCchPrintfW(szOutputBuffer, SMALL_BUFFER_SIZE, cszFmtDecimalParam, DisablePerformanceCounters, dwValue);
  327. dwSize = lstrlenW(szOutputBuffer) * sizeof (WCHAR);
  328. WriteFile(hOutputFile, szOutputBuffer, dwSize, & dwSizeWritten, NULL);
  329. }
  330. }
  331. else {
  332. dwRetStatus = ERROR_SUCCESS;
  333. }
  334. if (szPerfIniFile != NULL) {
  335. dwType = 0;
  336. dwItemSize = sizeof(WCHAR) * dwPerfIniFile;
  337. __try {
  338. dwRetStatus = RegQueryValueExW(hKeyPerformance,
  339. szPerfIniPath,
  340. NULL,
  341. & dwType,
  342. (LPBYTE) szPerfIniFile,
  343. & dwItemSize);
  344. }
  345. __except (EXCEPTION_EXECUTE_HANDLER) {
  346. dwRetStatus = GetExceptionCode();
  347. }
  348. TRACE((WINPERF_DBG_TRACE_INFO),
  349. (& LoadPerfGuid,
  350. __LINE__,
  351. LOADPERF_DUMPPERFSERVICEENTRIES,
  352. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  353. dwRetStatus,
  354. TRACE_WSTR(szServiceName),
  355. TRACE_WSTR(DisablePerformanceCounters),
  356. TRACE_DWORD(dwValue),
  357. NULL));
  358. }
  359. if (mszObjectList != NULL) {
  360. dwType = 0;
  361. dwItemSize = sizeof(WCHAR) * dwObjectList;
  362. __try {
  363. dwRetStatus = RegQueryValueExW(hKeyPerformance,
  364. szObjectList,
  365. NULL,
  366. & dwType,
  367. (LPBYTE) mszObjectList,
  368. & dwItemSize);
  369. }
  370. __except (EXCEPTION_EXECUTE_HANDLER) {
  371. dwRetStatus = GetExceptionCode();
  372. }
  373. TRACE((WINPERF_DBG_TRACE_INFO),
  374. (& LoadPerfGuid,
  375. __LINE__,
  376. LOADPERF_DUMPPERFSERVICEENTRIES,
  377. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  378. dwRetStatus,
  379. TRACE_WSTR(szServiceName),
  380. TRACE_WSTR(DisablePerformanceCounters),
  381. TRACE_DWORD(dwValue),
  382. NULL));
  383. if (dwRetStatus == ERROR_SUCCESS && dwType != REG_MULTI_SZ) {
  384. LPWSTR szChar = mszObjectList;
  385. while ((szChar != NULL) && (* szChar != cNull)) {
  386. if (* szChar == cSpace) * szChar = cNull;
  387. szChar ++;
  388. }
  389. }
  390. else {
  391. dwRetStatus = ERROR_SUCCESS;
  392. }
  393. }
  394. if (bRemove) {
  395. RegDeleteValueW(hKeyPerformance, FirstCounter);
  396. RegDeleteValueW(hKeyPerformance, LastCounter);
  397. RegDeleteValueW(hKeyPerformance, FirstHelp);
  398. RegDeleteValueW(hKeyPerformance, LastHelp);
  399. RegDeleteValueW(hKeyPerformance, szObjectList);
  400. }
  401. RegCloseKey (hKeyPerformance);
  402. }
  403. else {
  404. TRACE((WINPERF_DBG_TRACE_ERROR),
  405. (& LoadPerfGuid,
  406. __LINE__,
  407. LOADPERF_DUMPPERFSERVICEENTRIES,
  408. ARG_DEF(ARG_TYPE_WSTR, 1),
  409. dwRetStatus,
  410. TRACE_WSTR(szServiceName),
  411. NULL));
  412. }
  413. Cleanup:
  414. MemoryFree(szPerfSubKeyName);
  415. return dwRetStatus;
  416. }
  417. DWORD
  418. DumpPerflibEntries(
  419. HANDLE hOutputFile,
  420. LPDWORD pdwBaseIndex,
  421. LPDWORD pdwLastCounter,
  422. LPDWORD pdwLastHelp,
  423. LPDWORD pdwFirstExtCtrIndex
  424. )
  425. {
  426. HKEY hKeyPerflib = NULL;
  427. DWORD dwStatus = ERROR_SUCCESS;
  428. DWORD dwItemSize, dwType, dwValue;
  429. DWORD dwSize, dwSizeWritten;
  430. LPWSTR szOutputBuffer = NULL;
  431. HRESULT hr;
  432. szOutputBuffer = MemoryAllocate(sizeof(WCHAR) * SMALL_BUFFER_SIZE);
  433. if (szOutputBuffer == NULL) {
  434. dwStatus = ERROR_OUTOFMEMORY;
  435. }
  436. if (dwStatus == ERROR_SUCCESS) {
  437. __try {
  438. dwStatus = RegOpenKeyExW(HKEY_LOCAL_MACHINE, NamesKey, 0L, KEY_READ, & hKeyPerflib);
  439. }
  440. __except (EXCEPTION_EXECUTE_HANDLER) {
  441. dwStatus = GetExceptionCode();
  442. }
  443. }
  444. if (dwStatus == ERROR_SUCCESS) {
  445. if (hOutputFile != NULL) {
  446. ZeroMemory(szOutputBuffer, SMALL_BUFFER_SIZE * sizeof(WCHAR));
  447. hr = StringCchPrintfW(szOutputBuffer, SMALL_BUFFER_SIZE, cszFmtSectionHeader, cszPerflib);
  448. dwSize = lstrlenW(szOutputBuffer) * sizeof(WCHAR);
  449. WriteFile (hOutputFile, szOutputBuffer, dwSize, & dwSizeWritten, NULL);
  450. }
  451. }
  452. else {
  453. TRACE((WINPERF_DBG_TRACE_ERROR),
  454. (& LoadPerfGuid,
  455. __LINE__,
  456. LOADPERF_DUMPPERFLIBENTRIES,
  457. ARG_DEF(ARG_TYPE_WSTR, 1),
  458. dwStatus,
  459. TRACE_WSTR(NamesKey),
  460. NULL));
  461. }
  462. if (dwStatus == ERROR_SUCCESS) {
  463. dwType = dwValue = 0;
  464. dwItemSize = sizeof(dwValue);
  465. __try {
  466. dwStatus = RegQueryValueExW(hKeyPerflib, BaseIndex, NULL, & dwType, (LPBYTE) & dwValue, & dwItemSize);
  467. }
  468. __except (EXCEPTION_EXECUTE_HANDLER) {
  469. dwStatus = GetExceptionCode();
  470. }
  471. TRACE((WINPERF_DBG_TRACE_INFO),
  472. (& LoadPerfGuid,
  473. __LINE__,
  474. LOADPERF_DUMPPERFLIBENTRIES,
  475. ARG_DEF(ARG_TYPE_WSTR, 1),
  476. dwStatus,
  477. TRACE_WSTR(BaseIndex),
  478. TRACE_DWORD(dwValue),
  479. NULL));
  480. if ((dwStatus == ERROR_SUCCESS) && (dwType == REG_DWORD)) {
  481. if (pdwBaseIndex != NULL) {
  482. * pdwBaseIndex = dwValue;
  483. }
  484. if (hOutputFile != NULL) {
  485. ZeroMemory(szOutputBuffer, SMALL_BUFFER_SIZE * sizeof(WCHAR));
  486. hr = StringCchPrintfW(szOutputBuffer, SMALL_BUFFER_SIZE, cszFmtDecimalParam, BaseIndex, dwValue);
  487. dwSize = lstrlenW(szOutputBuffer) * sizeof(WCHAR);
  488. WriteFile(hOutputFile, szOutputBuffer, dwSize, & dwSizeWritten, NULL);
  489. }
  490. if (pdwFirstExtCtrIndex != NULL) {
  491. * pdwFirstExtCtrIndex = dwValue + 1;
  492. }
  493. }
  494. }
  495. if (dwStatus == ERROR_SUCCESS) {
  496. dwType = dwValue = 0;
  497. dwItemSize = sizeof(dwValue);
  498. __try {
  499. dwStatus = RegQueryValueExW(hKeyPerflib, LastCounter, NULL, & dwType, (LPBYTE) & dwValue, & dwItemSize);
  500. }
  501. __except (EXCEPTION_EXECUTE_HANDLER) {
  502. dwStatus = GetExceptionCode();
  503. }
  504. TRACE((WINPERF_DBG_TRACE_INFO),
  505. (& LoadPerfGuid,
  506. __LINE__,
  507. LOADPERF_DUMPPERFLIBENTRIES,
  508. ARG_DEF(ARG_TYPE_WSTR, 1),
  509. dwStatus,
  510. TRACE_WSTR(LastCounter),
  511. TRACE_DWORD(dwValue),
  512. NULL));
  513. if ((dwStatus == ERROR_SUCCESS) && (dwType == REG_DWORD)) {
  514. if (pdwLastCounter != NULL) {
  515. * pdwLastCounter = dwValue;
  516. }
  517. if (hOutputFile != NULL) {
  518. ZeroMemory(szOutputBuffer, SMALL_BUFFER_SIZE * sizeof(WCHAR));
  519. hr = StringCchPrintfW(szOutputBuffer, SMALL_BUFFER_SIZE, cszFmtDecimalParam, LastCounter, dwValue);
  520. dwSize = lstrlenW(szOutputBuffer) * sizeof(WCHAR);
  521. WriteFile(hOutputFile, szOutputBuffer, dwSize, & dwSizeWritten, NULL);
  522. }
  523. }
  524. }
  525. if (dwStatus == ERROR_SUCCESS) {
  526. dwType = dwValue = 0;
  527. dwItemSize = sizeof(dwValue);
  528. __try {
  529. dwStatus = RegQueryValueExW(hKeyPerflib, LastHelp, NULL, & dwType, (LPBYTE) & dwValue, & dwItemSize);
  530. }
  531. __except (EXCEPTION_EXECUTE_HANDLER) {
  532. dwStatus = GetExceptionCode();
  533. }
  534. TRACE((WINPERF_DBG_TRACE_INFO),
  535. (& LoadPerfGuid,
  536. __LINE__,
  537. LOADPERF_DUMPPERFLIBENTRIES,
  538. ARG_DEF(ARG_TYPE_WSTR, 1),
  539. dwStatus,
  540. TRACE_WSTR(LastHelp),
  541. TRACE_DWORD(dwValue),
  542. NULL));
  543. if ((dwStatus == ERROR_SUCCESS) && (dwType == REG_DWORD)) {
  544. if (pdwLastHelp != NULL) {
  545. * pdwLastHelp = dwValue;
  546. }
  547. if (hOutputFile != NULL) {
  548. ZeroMemory(szOutputBuffer, SMALL_BUFFER_SIZE * sizeof(WCHAR));
  549. hr = StringCchPrintfW(szOutputBuffer, SMALL_BUFFER_SIZE, cszFmtDecimalParam, LastHelp, dwValue);
  550. dwSize = lstrlenW(szOutputBuffer) * sizeof(WCHAR);
  551. WriteFile(hOutputFile, szOutputBuffer, dwSize, & dwSizeWritten, NULL);
  552. }
  553. }
  554. }
  555. if (hKeyPerflib != NULL) RegCloseKey(hKeyPerflib);
  556. MemoryFree(szOutputBuffer);
  557. return dwStatus;
  558. }
  559. DWORD
  560. BuildServiceLists(
  561. LPWSTR mszPerfServiceList,
  562. LPDWORD pcchPerfServiceListSize,
  563. LPWSTR mszNoPerfServiceList,
  564. LPDWORD pcchNoPerfServiceListSize
  565. )
  566. {
  567. LONG lEnumStatus = ERROR_SUCCESS;
  568. DWORD dwServiceIndex = 0;
  569. LPWSTR szServiceSubKeyName = NULL;
  570. LPWSTR szPerfSubKeyName = NULL;
  571. DWORD dwNameSize = MAX_PATH;
  572. HKEY hKeyPerformance;
  573. HKEY hKeyServices = NULL;
  574. DWORD dwItemSize, dwType, dwValue;
  575. DWORD dwRegAccessMask;
  576. DWORD bServiceHasPerfCounters;
  577. DWORD dwRetStatus = ERROR_SUCCESS;
  578. LPWSTR szNextNoPerfChar, szNextPerfChar;
  579. DWORD dwNoPerfSizeRem, dwPerfSizeRem;
  580. DWORD dwPerfSizeUsed = 0, dwNoPerfSizeUsed = 0;
  581. HRESULT hr;
  582. // try read-only then
  583. dwRegAccessMask = KEY_READ;
  584. szServiceSubKeyName = MemoryAllocate(MAX_PATH * sizeof(WCHAR));
  585. szPerfSubKeyName = MemoryAllocate((MAX_PATH + 32) * sizeof(WCHAR));
  586. if (szServiceSubKeyName == NULL || szPerfSubKeyName == NULL) {
  587. dwRetStatus = ERROR_OUTOFMEMORY;
  588. goto Cleanup;
  589. }
  590. __try {
  591. dwRetStatus = RegOpenKeyExW(HKEY_LOCAL_MACHINE, DriverPathRoot, 0L, dwRegAccessMask, & hKeyServices);
  592. }
  593. __except (EXCEPTION_EXECUTE_HANDLER) {
  594. dwRetStatus = GetExceptionCode();
  595. }
  596. if (dwRetStatus == ERROR_SUCCESS) {
  597. szNextNoPerfChar = mszNoPerfServiceList;
  598. szNextPerfChar = mszPerfServiceList;
  599. dwNoPerfSizeRem = * pcchPerfServiceListSize;
  600. dwPerfSizeRem = * pcchNoPerfServiceListSize;
  601. dwPerfSizeUsed = 0;
  602. dwNoPerfSizeUsed = 0;
  603. dwNameSize = MAX_PATH;
  604. ZeroMemory(szServiceSubKeyName, MAX_PATH * sizeof(WCHAR));
  605. ZeroMemory(szPerfSubKeyName, (MAX_PATH + 32) * sizeof(WCHAR));
  606. while ((lEnumStatus = RegEnumKeyExW(hKeyServices,
  607. dwServiceIndex,
  608. szServiceSubKeyName,
  609. & dwNameSize,
  610. NULL,
  611. NULL,
  612. NULL,
  613. NULL)) == ERROR_SUCCESS) {
  614. //try to open the perfkey under this key.
  615. hr = StringCchPrintfW(szPerfSubKeyName, MAX_PATH + 32, L"%s%s%s", szServiceSubKeyName, Slash, Performance);
  616. __try {
  617. dwRetStatus = RegOpenKeyExW(hKeyServices, szPerfSubKeyName, 0L, dwRegAccessMask, & hKeyPerformance);
  618. }
  619. __except (EXCEPTION_EXECUTE_HANDLER) {
  620. dwRetStatus = GetExceptionCode();
  621. }
  622. if (dwRetStatus == ERROR_SUCCESS) {
  623. // key found so service has perf data
  624. // now check to see if the strings have been loaded
  625. dwType = dwValue = 0;
  626. dwItemSize = sizeof(dwValue);
  627. __try {
  628. dwRetStatus = RegQueryValueExW(hKeyPerformance,
  629. FirstCounter,
  630. NULL,
  631. & dwType,
  632. (LPBYTE) & dwValue,
  633. & dwItemSize);
  634. }
  635. __except (EXCEPTION_EXECUTE_HANDLER) {
  636. dwRetStatus = GetExceptionCode();
  637. }
  638. if (dwRetStatus == ERROR_SUCCESS && (dwType == REG_DWORD || dwType == REG_BINARY)) {
  639. bServiceHasPerfCounters = TRUE;
  640. }
  641. else {
  642. bServiceHasPerfCounters = FALSE;
  643. }
  644. RegCloseKey (hKeyPerformance);
  645. }
  646. else {
  647. // key not found so service doesn't have perfdata
  648. bServiceHasPerfCounters = FALSE;
  649. dwRetStatus = ERROR_SUCCESS;
  650. }
  651. TRACE((WINPERF_DBG_TRACE_INFO),
  652. (& LoadPerfGuid,
  653. __LINE__,
  654. LOADPERF_BUILDSERVICELISTS,
  655. ARG_DEF(ARG_TYPE_WSTR, 1),
  656. dwRetStatus,
  657. TRACE_WSTR(szServiceSubKeyName),
  658. TRACE_DWORD(bServiceHasPerfCounters),
  659. NULL));
  660. if (bServiceHasPerfCounters != FALSE) {
  661. // add to the perf service list
  662. if ((dwNameSize + 1) < dwPerfSizeRem) {
  663. // add to list
  664. hr = StringCchCopyW(szNextPerfChar, dwPerfSizeRem, szServiceSubKeyName);
  665. szNextPerfChar += dwNameSize;
  666. * szNextPerfChar = L'\0';
  667. szNextPerfChar ++;
  668. dwPerfSizeRem -= dwNameSize + 1;
  669. }
  670. else {
  671. dwPerfSizeRem = 0;
  672. dwRetStatus = ERROR_MORE_DATA;
  673. }
  674. dwPerfSizeUsed += dwNameSize + 1;
  675. }
  676. else {
  677. // add to the no perf list
  678. if ((dwNameSize + 1) < dwNoPerfSizeRem) {
  679. // add to list
  680. hr = StringCchCopyW(szNextNoPerfChar, dwNoPerfSizeRem, szServiceSubKeyName);
  681. szNextNoPerfChar += dwNameSize;
  682. * szNextNoPerfChar = L'\0';
  683. szNextNoPerfChar ++;
  684. dwNoPerfSizeRem -= dwNameSize + 1;
  685. }
  686. else {
  687. dwNoPerfSizeRem = 0;
  688. dwRetStatus = ERROR_MORE_DATA;
  689. }
  690. dwNoPerfSizeUsed += dwNameSize + 1;
  691. }
  692. // reset for next loop
  693. dwServiceIndex ++;
  694. dwNameSize = MAX_PATH;
  695. ZeroMemory(szServiceSubKeyName, MAX_PATH * sizeof(WCHAR));
  696. ZeroMemory(szPerfSubKeyName, (MAX_PATH + 32) * sizeof(WCHAR));
  697. }
  698. // zero term the MSZ
  699. if (1 < dwPerfSizeRem) {
  700. * szNextPerfChar = L'\0';
  701. szNextPerfChar ++;
  702. dwPerfSizeRem -= 1;
  703. }
  704. else {
  705. dwRetStatus = ERROR_MORE_DATA;
  706. }
  707. dwPerfSizeUsed += 1;
  708. // zero term the no perf list
  709. if (1 < dwNoPerfSizeRem) {
  710. // add to list
  711. * szNextNoPerfChar = L'\0';
  712. szNextNoPerfChar ++;
  713. dwNoPerfSizeRem -= 1;
  714. }
  715. else {
  716. dwRetStatus = ERROR_MORE_DATA;
  717. }
  718. dwNoPerfSizeUsed += 1;
  719. }
  720. else {
  721. TRACE((WINPERF_DBG_TRACE_ERROR),
  722. (& LoadPerfGuid,
  723. __LINE__,
  724. LOADPERF_BUILDSERVICELISTS,
  725. ARG_DEF(ARG_TYPE_WSTR, 1),
  726. dwRetStatus,
  727. TRACE_WSTR(DriverPathRoot),
  728. NULL));
  729. }
  730. Cleanup:
  731. if (hKeyServices != NULL) RegCloseKey(hKeyServices);
  732. MemoryFree(szServiceSubKeyName);
  733. MemoryFree(szPerfSubKeyName);
  734. if (dwRetStatus == ERROR_SUCCESS || dwRetStatus == ERROR_MORE_DATA) {
  735. * pcchPerfServiceListSize = dwPerfSizeUsed;
  736. * pcchNoPerfServiceListSize = dwNoPerfSizeUsed;
  737. }
  738. return dwRetStatus;
  739. }
  740. DWORD
  741. BackupPerfRegistryToFileW(
  742. IN LPCWSTR szFileName,
  743. IN LPCWSTR szCommentString
  744. )
  745. {
  746. HANDLE hOutFile = NULL;
  747. DWORD dwStatus = ERROR_SUCCESS;
  748. LPWSTR szNewFileName = NULL;
  749. DWORD dwNewFileNameLen;
  750. DWORD dwOrigFileNameLen;
  751. DWORD dwFileNameSN;
  752. LPWSTR mszPerfServiceList = NULL;
  753. DWORD dwPerfServiceListSize = 0;
  754. LPWSTR mszNoPerfServiceList = NULL;
  755. DWORD dwNoPerfServiceListSize = 0;
  756. LPWSTR * lpCounterText = NULL;
  757. DWORD dwLastElement = 0;
  758. DWORD dwFirstExtCtrIndex = 0;
  759. LPWSTR szThisServiceName;
  760. HRESULT hr;
  761. DBG_UNREFERENCED_PARAMETER(szCommentString);
  762. WinPerfStartTrace(NULL);
  763. if (szFileName == NULL) {
  764. dwStatus = ERROR_INVALID_PARAMETER;
  765. }
  766. else {
  767. __try {
  768. dwNewFileNameLen = lstrlenW(szFileName);
  769. if (dwNewFileNameLen == 0) dwStatus = ERROR_INVALID_PARAMETER;
  770. }
  771. __except (EXCEPTION_EXECUTE_HANDLER) {
  772. dwStatus = ERROR_INVALID_PARAMETER;
  773. }
  774. }
  775. if (dwStatus == ERROR_SUCCESS) {
  776. // open output file
  777. hOutFile = CreateFileW(szFileName,
  778. GENERIC_WRITE,
  779. 0, // no sharing
  780. NULL, // default security
  781. CREATE_NEW,
  782. FILE_ATTRIBUTE_NORMAL,
  783. NULL);
  784. // if the file open failed
  785. if (hOutFile == INVALID_HANDLE_VALUE) {
  786. // see if it's because the file already exists
  787. dwStatus = GetLastError();
  788. if (dwStatus == ERROR_FILE_EXISTS) {
  789. // then try appending a serial number to the name
  790. dwOrigFileNameLen = lstrlenW(szFileName) + 1;
  791. dwNewFileNameLen = dwOrigFileNameLen + 4;
  792. szNewFileName = MemoryAllocate(dwNewFileNameLen * sizeof(WCHAR));
  793. if (szNewFileName != NULL) {
  794. hr = StringCchCopyW(szNewFileName, dwOrigFileNameLen, szFileName);
  795. for (dwFileNameSN = 1; dwFileNameSN < 1000; dwFileNameSN++) {
  796. hr = StringCchPrintfW(& szNewFileName[dwOrigFileNameLen - 1],
  797. dwNewFileNameLen,
  798. L"_%3.3d",
  799. dwFileNameSN);
  800. hOutFile = CreateFileW(szNewFileName,
  801. GENERIC_WRITE,
  802. 0, // no sharing
  803. NULL, // default security
  804. CREATE_NEW,
  805. FILE_ATTRIBUTE_NORMAL,
  806. NULL);
  807. // if the file open failed
  808. if (hOutFile == INVALID_HANDLE_VALUE) {
  809. dwStatus = GetLastError();
  810. if (dwStatus != ERROR_FILE_EXISTS) {
  811. // some other error occurred so bail out
  812. break;
  813. }
  814. else {
  815. continue; // with the next try
  816. }
  817. }
  818. else {
  819. // found one not in use so continue on
  820. dwStatus = ERROR_SUCCESS;
  821. break;
  822. }
  823. }
  824. }
  825. else {
  826. dwStatus = ERROR_OUTOFMEMORY;
  827. }
  828. }
  829. }
  830. else {
  831. // file opened so continue
  832. dwStatus = ERROR_SUCCESS;
  833. }
  834. }
  835. if (dwStatus == ERROR_SUCCESS) {
  836. // dump perflib key entires
  837. dwStatus = DumpPerflibEntries(hOutFile, NULL, NULL, NULL, & dwFirstExtCtrIndex);
  838. }
  839. if (dwStatus == ERROR_SUCCESS) {
  840. do {
  841. MemoryFree(mszPerfServiceList);
  842. mszPerfServiceList = NULL;
  843. MemoryFree(mszNoPerfServiceList);
  844. mszNoPerfServiceList = NULL;
  845. // build service lists
  846. dwPerfServiceListSize += DUMPLOAD_SERVICE_SIZE;
  847. dwNoPerfServiceListSize += DUMPLOAD_NOSERVICE_SIZE;
  848. mszPerfServiceList = MemoryAllocate(dwPerfServiceListSize * sizeof(WCHAR));
  849. mszNoPerfServiceList = MemoryAllocate(dwNoPerfServiceListSize * sizeof(WCHAR));
  850. if (mszNoPerfServiceList == NULL || mszPerfServiceList == NULL) {
  851. dwStatus = ERROR_OUTOFMEMORY;
  852. break;
  853. }
  854. if (dwStatus != ERROR_OUTOFMEMORY) {
  855. dwStatus = BuildServiceLists(mszPerfServiceList,
  856. & dwPerfServiceListSize,
  857. mszNoPerfServiceList,
  858. & dwNoPerfServiceListSize);
  859. }
  860. } while (dwStatus == ERROR_MORE_DATA && dwPerfServiceListSize < DUMPLOAD_MAX_SERVICE_SIZE);
  861. }
  862. // dump service entries for those services with perf counters
  863. if (dwStatus == ERROR_SUCCESS) {
  864. for (szThisServiceName = mszPerfServiceList;
  865. * szThisServiceName != 0;
  866. szThisServiceName += lstrlenW(szThisServiceName) + 1) {
  867. dwStatus = DumpPerfServiceEntries(hOutFile,
  868. szThisServiceName,
  869. NULL,
  870. NULL,
  871. NULL,
  872. NULL,
  873. NULL,
  874. NULL,
  875. 0,
  876. NULL,
  877. 0,
  878. FALSE);
  879. if (dwStatus != ERROR_SUCCESS) break;
  880. }
  881. }
  882. // dump perf string entries
  883. if (dwStatus == ERROR_SUCCESS) {
  884. WCHAR szLangId[8];
  885. DWORD dwIndex = 0;
  886. DWORD dwCopyIndex = 0;
  887. DWORD dwTmpStatus = ERROR_SUCCESS;
  888. DWORD dwBufferSize;
  889. HKEY hPerflibRoot = NULL;
  890. __try {
  891. dwStatus = RegOpenKeyExW(HKEY_LOCAL_MACHINE, NamesKey, RESERVED, KEY_READ, & hPerflibRoot);
  892. }
  893. __except (EXCEPTION_EXECUTE_HANDLER) {
  894. dwStatus = GetExceptionCode();
  895. }
  896. while (dwStatus == ERROR_SUCCESS) {
  897. dwBufferSize = 8;
  898. ZeroMemory(szLangId, 8 * sizeof(WCHAR));
  899. dwStatus = RegEnumKeyExW(hPerflibRoot,
  900. dwIndex,
  901. szLangId,
  902. & dwBufferSize,
  903. NULL,
  904. NULL,
  905. NULL,
  906. NULL);
  907. if (dwStatus == ERROR_SUCCESS) {
  908. lpCounterText = BuildNameTable(HKEY_LOCAL_MACHINE, (LPWSTR) szLangId, & dwLastElement);
  909. if (lpCounterText != NULL) {
  910. __try {
  911. dwStatus = DumpNameTable(hOutFile, szLangId, lpCounterText, 0, dwLastElement);
  912. }
  913. __except (EXCEPTION_EXECUTE_HANDLER) {
  914. dwStatus = GetExceptionCode();
  915. TRACE((WINPERF_DBG_TRACE_ERROR),
  916. (& LoadPerfGuid,
  917. __LINE__,
  918. LOADPERF_BACKUPPERFREGISTRYTOFILEW,
  919. ARG_DEF(ARG_TYPE_WSTR, 1),
  920. dwStatus,
  921. TRACE_WSTR(szLangId),
  922. TRACE_DWORD(dwLastElement),
  923. NULL));
  924. }
  925. MemoryFree(lpCounterText);
  926. lpCounterText = NULL;
  927. }
  928. else {
  929. dwStatus = GetLastError();
  930. }
  931. if (dwStatus == ERROR_SUCCESS) {
  932. dwCopyIndex ++;
  933. }
  934. else {
  935. dwTmpStatus = dwStatus;
  936. dwStatus = ERROR_SUCCESS;
  937. }
  938. }
  939. dwIndex ++;
  940. }
  941. if (dwStatus == ERROR_NO_MORE_ITEMS) dwStatus = ERROR_SUCCESS;
  942. if (dwStatus == ERROR_SUCCESS && dwCopyIndex == 0) {
  943. dwStatus = dwTmpStatus;
  944. }
  945. if (hPerflibRoot != NULL) RegCloseKey(hPerflibRoot);
  946. }
  947. // free buffers
  948. MemoryFree(lpCounterText);
  949. MemoryFree(mszNoPerfServiceList);
  950. MemoryFree(mszPerfServiceList);
  951. MemoryFree(szNewFileName);
  952. // close file handles
  953. if (hOutFile != NULL && hOutFile != INVALID_HANDLE_VALUE) {
  954. CloseHandle (hOutFile);
  955. }
  956. return dwStatus;
  957. }
  958. DWORD
  959. LoadPerfRepairPerfRegistry()
  960. {
  961. DWORD dwStatus = ERROR_SUCCESS;
  962. DWORD dwBaseIndex = 0;
  963. DWORD dwLastCounter = 0;
  964. DWORD dwLastHelp = 0;
  965. HKEY hKeyPerflib = NULL;
  966. DWORD dwValue = 0;
  967. DWORD dwIndex = 0;
  968. DWORD dw1Size = 0;
  969. DWORD dwSize = 0;
  970. LPWSTR szInfPath = NULL;
  971. LPWSTR szLangID = NULL;
  972. LPWSTR szCtrFile = NULL;
  973. LPWSTR szHlpFile = NULL;
  974. HANDLE hCtrFile = NULL;
  975. HANDLE hHlpFile = NULL;
  976. WIN32_FIND_DATAW FindCtrFile;
  977. WIN32_FIND_DATAW FindHlpFile;
  978. PLANG_ENTRY LangList = NULL;
  979. PLANG_ENTRY pThisLang = NULL;
  980. LPWSTR mszService = NULL;
  981. DWORD dwService = 0;
  982. LPWSTR mszObjectList = NULL;
  983. DWORD dwObjectList = 0;
  984. LPWSTR mszNonService = NULL;
  985. DWORD dwNonService = 0;
  986. LPWSTR szThisService = NULL;
  987. PSERVICE_ENTRY ServiceList = NULL;
  988. PSERVICE_ENTRY pThisService = NULL;
  989. HRESULT hr;
  990. if (LoadPerfGrabMutex() == FALSE) {
  991. return GetLastError();
  992. }
  993. dwStatus = DumpPerflibEntries(NULL, & dwBaseIndex, & dwLastCounter, & dwLastHelp, NULL);
  994. if (dwStatus != ERROR_SUCCESS) goto Cleanup;
  995. __try {
  996. dwStatus = RegOpenKeyExW(HKEY_LOCAL_MACHINE, NamesKey, RESERVED, KEY_WRITE | KEY_READ, & hKeyPerflib);
  997. }
  998. __except (EXCEPTION_EXECUTE_HANDLER) {
  999. dwStatus = GetExceptionCode();
  1000. }
  1001. if (dwStatus != ERROR_SUCCESS) {
  1002. TRACE((WINPERF_DBG_TRACE_ERROR),
  1003. (& LoadPerfGuid,
  1004. __LINE__,
  1005. LOADPERF_REPAIRPERFREGISTRY,
  1006. ARG_DEF(ARG_TYPE_WSTR, 1),
  1007. dwStatus,
  1008. TRACE_WSTR(NamesKey),
  1009. NULL));
  1010. goto Cleanup;
  1011. }
  1012. if ((szInfPath = LoadPerfGetInfPath()) == NULL) {
  1013. dwStatus = GetLastError();
  1014. goto Cleanup;
  1015. }
  1016. // String format <szInfPath><lang-id>\PERFD<langid>.DAT
  1017. // The buffer size will be lstrlenW(szInfPath) + 18
  1018. //
  1019. dw1Size = lstrlenW(szInfPath) + 20;
  1020. if (dw1Size < MAX_PATH) dw1Size = MAX_PATH;
  1021. dwSize = dw1Size + dw1Size + 8;
  1022. szCtrFile = MemoryAllocate(dwSize * sizeof(WCHAR));
  1023. if (szCtrFile == NULL) {
  1024. dwStatus = ERROR_OUTOFMEMORY;
  1025. goto Cleanup;
  1026. }
  1027. szHlpFile = (LPWSTR) (szCtrFile + dw1Size);
  1028. szLangID = (LPWSTR) (szHlpFile + dw1Size);
  1029. dwIndex = 0;
  1030. dwSize = 8;
  1031. dwStatus = RegEnumKeyExW(hKeyPerflib, dwIndex, szLangID, & dwSize, NULL, NULL, NULL, NULL);
  1032. while (dwStatus == ERROR_SUCCESS) {
  1033. LPWSTR szThisLang = LoadPerfGetLanguage(szLangID, FALSE);
  1034. DWORD dwLast;
  1035. pThisLang = (PLANG_ENTRY) MemoryAllocate(sizeof(LANG_ENTRY) + sizeof(WCHAR) * (lstrlenW(szThisLang) + 1));
  1036. if (pThisLang == NULL) {
  1037. dwStatus = ERROR_OUTOFMEMORY;
  1038. goto Cleanup;
  1039. }
  1040. pThisLang->szLang = (LPWSTR) (((LPBYTE) pThisLang) + sizeof(LANG_ENTRY));
  1041. hr = StringCchCopyW(pThisLang->szLang, (lstrlenW(szThisLang) + 1), szThisLang);
  1042. pThisLang->dwLang = LoadPerfGetLCIDFromString(pThisLang->szLang);
  1043. pThisLang->dwLastCounter = dwLastCounter;
  1044. pThisLang->dwLastHelp = dwLastHelp;
  1045. pThisLang->lpText = BuildNameTable(HKEY_LOCAL_MACHINE, szLangID, & dwLast);
  1046. pThisLang->pNext = LangList;
  1047. LangList = pThisLang;
  1048. dwIndex ++;
  1049. dwSize = 8;
  1050. ZeroMemory(szLangID, 8 * sizeof(WCHAR));
  1051. dwStatus = RegEnumKeyExW(hKeyPerflib, dwIndex, szLangID, & dwSize, NULL, NULL, NULL, NULL);
  1052. }
  1053. if (dwStatus == ERROR_NO_MORE_ITEMS) dwStatus = ERROR_SUCCESS;
  1054. if (dwStatus != ERROR_SUCCESS) goto Cleanup;
  1055. dwValue = dwBaseIndex - 1;
  1056. __try {
  1057. dwStatus = RegSetValueExW(hKeyPerflib, LastCounter, RESERVED, REG_DWORD, (LPBYTE) & dwValue, sizeof(DWORD));
  1058. }
  1059. __except (EXCEPTION_EXECUTE_HANDLER) {
  1060. dwStatus = GetExceptionCode();
  1061. }
  1062. if (dwStatus != ERROR_SUCCESS) {
  1063. TRACE((WINPERF_DBG_TRACE_ERROR),
  1064. (& LoadPerfGuid,
  1065. __LINE__,
  1066. LOADPERF_REPAIRPERFREGISTRY,
  1067. ARG_DEF(ARG_TYPE_WSTR, 1),
  1068. dwStatus,
  1069. TRACE_WSTR(LastCounter),
  1070. TRACE_DWORD(dwValue),
  1071. NULL));
  1072. goto Cleanup;
  1073. }
  1074. dwValue = dwBaseIndex;
  1075. __try {
  1076. dwStatus = RegSetValueExW(hKeyPerflib, LastHelp, RESERVED, REG_DWORD, (LPBYTE) & dwValue, sizeof(DWORD));
  1077. }
  1078. __except (EXCEPTION_EXECUTE_HANDLER) {
  1079. dwStatus = GetExceptionCode();
  1080. }
  1081. if (dwStatus != ERROR_SUCCESS) {
  1082. TRACE((WINPERF_DBG_TRACE_ERROR),
  1083. (& LoadPerfGuid,
  1084. __LINE__,
  1085. LOADPERF_REPAIRPERFREGISTRY,
  1086. ARG_DEF(ARG_TYPE_WSTR, 1),
  1087. dwStatus,
  1088. TRACE_WSTR(LastHelp),
  1089. TRACE_DWORD(dwValue),
  1090. NULL));
  1091. goto Cleanup;
  1092. }
  1093. dwIndex = 0;
  1094. dwSize = 8;
  1095. dwStatus = RegEnumKeyExW(hKeyPerflib, dwIndex, szLangID, & dwSize, NULL, NULL, NULL, NULL);
  1096. while (dwStatus == ERROR_SUCCESS) {
  1097. LPWSTR szThisLang = LoadPerfGetLanguage(szLangID, FALSE);
  1098. DWORD dwLast;
  1099. ZeroMemory(szCtrFile, dw1Size * sizeof(WCHAR));
  1100. hr = StringCchPrintfW(szCtrFile, dw1Size, L"%s%s%s*d%s%s", szInfPath, szThisLang, Slash, szThisLang, szDatExt);
  1101. ZeroMemory(szHlpFile, dw1Size * sizeof(WCHAR));
  1102. hr = StringCchPrintfW(szHlpFile, dw1Size, L"%s%s%s*i%s%s", szInfPath, szThisLang, Slash, szThisLang, szDatExt);
  1103. hCtrFile = FindFirstFileW(szCtrFile, & FindCtrFile);
  1104. hHlpFile = FindFirstFileW(szHlpFile, & FindHlpFile);
  1105. if (hCtrFile == INVALID_HANDLE_VALUE || hHlpFile == INVALID_HANDLE_VALUE) {
  1106. szThisLang = (LPWSTR) DefaultLangId;
  1107. ZeroMemory(szCtrFile, dw1Size * sizeof(WCHAR));
  1108. hr = StringCchPrintfW(szCtrFile, dw1Size, L"%s%s%s*d%s%s", szInfPath, szThisLang, Slash, szThisLang, szDatExt);
  1109. ZeroMemory(szHlpFile, dw1Size * sizeof(WCHAR));
  1110. hr = StringCchPrintfW(szHlpFile, dw1Size, L"%s%s%s*i%s%s", szInfPath, szThisLang, Slash, szThisLang, szDatExt);
  1111. hCtrFile = FindFirstFileW(szCtrFile, & FindCtrFile);
  1112. hHlpFile = FindFirstFileW(szHlpFile, & FindHlpFile);
  1113. }
  1114. if (hCtrFile != INVALID_HANDLE_VALUE && hHlpFile != INVALID_HANDLE_VALUE) {
  1115. ZeroMemory(szCtrFile, dw1Size * sizeof(WCHAR));
  1116. hr = StringCchPrintfW(szCtrFile, dw1Size, L"%s%s%s%s", szInfPath, szThisLang, Slash, FindCtrFile.cFileName);
  1117. ZeroMemory(szHlpFile, dw1Size * sizeof(WCHAR));
  1118. hr = StringCchPrintfW(szHlpFile, dw1Size, L"%s%s%s%s", szInfPath, szThisLang, Slash, FindHlpFile.cFileName);
  1119. FindClose(hCtrFile);
  1120. FindClose(hHlpFile);
  1121. dwStatus = UpdatePerfNameFilesX(szCtrFile, szHlpFile, szLangID, LODCTR_UPNF_REPAIR);
  1122. }
  1123. else {
  1124. dwStatus = GetLastError();
  1125. }
  1126. if (dwStatus == ERROR_SUCCESS) {
  1127. dwIndex ++;
  1128. dwSize = 8;
  1129. ZeroMemory(szLangID, 8 * sizeof(WCHAR));
  1130. dwStatus = RegEnumKeyExW(hKeyPerflib, dwIndex, szLangID, & dwSize, NULL, NULL, NULL, NULL);
  1131. }
  1132. }
  1133. if (dwStatus == ERROR_NO_MORE_ITEMS) dwStatus = ERROR_SUCCESS;
  1134. if (dwStatus != ERROR_SUCCESS) goto Cleanup;
  1135. do {
  1136. MemoryFree(mszService);
  1137. mszService = NULL;
  1138. MemoryFree(mszNonService);
  1139. mszNonService = NULL;
  1140. dwService += DUMPLOAD_SERVICE_SIZE;
  1141. dwNonService += DUMPLOAD_NOSERVICE_SIZE;
  1142. mszService = MemoryAllocate(dwService * sizeof(WCHAR));
  1143. mszNonService = MemoryAllocate(dwNonService * sizeof(WCHAR));
  1144. if (mszService == NULL || mszNonService == NULL) {
  1145. dwStatus = ERROR_OUTOFMEMORY;
  1146. break;
  1147. }
  1148. if (dwStatus == ERROR_SUCCESS) {
  1149. dwStatus = BuildServiceLists(mszService, & dwService, mszNonService, & dwNonService);
  1150. }
  1151. }
  1152. while (dwStatus == ERROR_MORE_DATA && dwService < DUMPLOAD_MAX_SERVICE_SIZE);
  1153. if (dwStatus != ERROR_SUCCESS) goto Cleanup;
  1154. dwObjectList = LOADPERF_BUFF_SIZE;
  1155. mszObjectList = MemoryAllocate(dwObjectList * sizeof(WCHAR));
  1156. if (mszObjectList == NULL) {
  1157. dwStatus = ERROR_OUTOFMEMORY;
  1158. goto Cleanup;
  1159. }
  1160. for (szThisService = mszService;
  1161. szThisService != NULL && szThisService[0] != cNull && dwStatus == ERROR_SUCCESS;
  1162. szThisService += (lstrlenW(szThisService) + 1)) {
  1163. pThisService = (PSERVICE_ENTRY) MemoryAllocate(sizeof(SERVICE_ENTRY)
  1164. + sizeof(WCHAR) * (MAX_PATH + lstrlenW(szThisService) + 1));
  1165. if (pThisService == NULL) {
  1166. dwStatus = ERROR_OUTOFMEMORY;
  1167. goto Cleanup;
  1168. }
  1169. pThisService->pNext = ServiceList;
  1170. ServiceList = pThisService;
  1171. pThisService->szIniFile = (LPWSTR) (((LPBYTE) pThisService) + sizeof(SERVICE_ENTRY));
  1172. pThisService->szService = (LPWSTR) (((LPBYTE) pThisService->szIniFile) + sizeof(WCHAR) * MAX_PATH);
  1173. hr = StringCchCopyW(pThisService->szService, lstrlenW(szThisService) + 1, szThisService);
  1174. ZeroMemory(mszObjectList, dwObjectList * sizeof(WCHAR));
  1175. dwStatus = DumpPerfServiceEntries(NULL,
  1176. pThisService->szService,
  1177. & pThisService->dwFirstCounter,
  1178. & pThisService->dwFirstHelp,
  1179. & pThisService->dwLastCounter,
  1180. & pThisService->dwLastHelp,
  1181. & pThisService->dwDisable,
  1182. pThisService->szIniFile,
  1183. MAX_PATH,
  1184. mszObjectList,
  1185. dwObjectList,
  1186. TRUE);
  1187. if (dwStatus == ERROR_SUCCESS) {
  1188. LPWSTR szObjectId = mszObjectList;
  1189. pThisService->dwNumObjects = 0;
  1190. while ((szObjectId != NULL) && (* szObjectId != cNull)) {
  1191. if (pThisService->dwNumObjects
  1192. >= MAX_PERF_OBJECTS_IN_QUERY_FUNCTION) {
  1193. break;
  1194. }
  1195. pThisService->dwObjects[pThisService->dwNumObjects] =
  1196. wcstoul(szObjectId, NULL, 10) - pThisService->dwFirstCounter;
  1197. pThisService->dwNumObjects ++;
  1198. szObjectId += (lstrlenW(szObjectId) + 1);
  1199. }
  1200. }
  1201. }
  1202. for (pThisService = ServiceList; pThisService != NULL; pThisService = pThisService->pNext) {
  1203. if (pThisService->szIniFile[0] != cNull) {
  1204. dwStatus = LoadPerfInstallPerfDll(LODCTR_UPNF_REPAIR,
  1205. NULL,
  1206. pThisService->szService,
  1207. pThisService->szIniFile,
  1208. NULL,
  1209. NULL,
  1210. LOADPERF_FLAGS_LOAD_REGISTRY_ONLY);
  1211. }
  1212. else {
  1213. dwStatus = LoadPerfInstallPerfDll(LODCTR_UPNF_REPAIR | LODCTR_UPNF_NOINI,
  1214. NULL,
  1215. pThisService->szService,
  1216. NULL,
  1217. LangList,
  1218. pThisService,
  1219. LOADPERF_FLAGS_LOAD_REGISTRY_ONLY);
  1220. }
  1221. if (dwStatus != ERROR_SUCCESS) {
  1222. ReportLoadPerfEvent(
  1223. EVENTLOG_WARNING_TYPE,
  1224. (DWORD) LDPRFMSG_REPAIR_SERVICE_FAIL,
  1225. 2, dwStatus, __LINE__, 0, 0,
  1226. 1, (LPWSTR) pThisService->szService, NULL, NULL);
  1227. }
  1228. }
  1229. Cleanup:
  1230. if (hKeyPerflib != NULL) RegCloseKey(hKeyPerflib);
  1231. MemoryFree(szCtrFile);
  1232. MemoryFree(mszObjectList);
  1233. MemoryFree(mszService);
  1234. MemoryFree(mszNonService);
  1235. pThisLang = LangList;
  1236. while (pThisLang != NULL) {
  1237. PLANG_ENTRY pTmpLang = pThisLang;
  1238. pThisLang = pThisLang->pNext;
  1239. MemoryFree(pTmpLang->lpText);
  1240. MemoryFree(pTmpLang);
  1241. }
  1242. pThisService = ServiceList;
  1243. while (pThisService != NULL) {
  1244. PSERVICE_ENTRY pTmpService = pThisService;
  1245. pThisService = pThisService->pNext;
  1246. MemoryFree(pTmpService);
  1247. }
  1248. ReleaseMutex(hLoadPerfMutex);
  1249. return dwStatus;
  1250. }
  1251. DWORD
  1252. RestorePerfRegistryFromFileW(
  1253. IN LPCWSTR szFileName,
  1254. IN LPCWSTR szLangId
  1255. )
  1256. {
  1257. LONG lEnumStatus = ERROR_SUCCESS;
  1258. DWORD dwServiceIndex = 0;
  1259. LPWSTR szServiceSubKeyName = NULL;
  1260. LPWSTR szPerfSubKeyName = NULL;
  1261. LPWSTR wPerfSection = NULL;
  1262. DWORD dwNameSize = MAX_PATH;
  1263. HKEY hKeyPerformance;
  1264. HKEY hKeyServices = NULL;
  1265. HKEY hKeyPerflib = NULL;
  1266. DWORD dwRegAccessMask;
  1267. DWORD dwRetStatus = ERROR_SUCCESS;
  1268. UINT nValue;
  1269. DWORD dwnValue;
  1270. BOOL bServiceRegistryOk = TRUE;
  1271. WCHAR szLocalLangId[8];
  1272. HRESULT hr;
  1273. WinPerfStartTrace(NULL);
  1274. if (szFileName == NULL) {
  1275. // this is the case to repair performance registry.
  1276. //
  1277. dwRetStatus = LoadPerfRepairPerfRegistry();
  1278. goto Cleanup;
  1279. }
  1280. else {
  1281. __try {
  1282. DWORD dwName = lstrlenW(szFileName);
  1283. if (dwName == 0) dwRetStatus = ERROR_INVALID_PARAMETER;
  1284. if (szLangId != NULL) {
  1285. dwName = lstrlenW(szLangId);
  1286. if (dwName == 0) dwRetStatus = ERROR_INVALID_PARAMETER;
  1287. }
  1288. }
  1289. __except (EXCEPTION_EXECUTE_HANDLER) {
  1290. dwRetStatus = ERROR_INVALID_PARAMETER;
  1291. }
  1292. }
  1293. if (dwRetStatus != ERROR_SUCCESS) goto Cleanup;
  1294. szServiceSubKeyName = MemoryAllocate(MAX_PATH * sizeof(WCHAR));
  1295. szPerfSubKeyName = MemoryAllocate((MAX_PATH + 32) * sizeof(WCHAR));
  1296. wPerfSection = MemoryAllocate((MAX_PATH + 32) * sizeof(WCHAR));
  1297. if (szServiceSubKeyName == NULL || szPerfSubKeyName == NULL || wPerfSection == NULL) {
  1298. dwRetStatus = ERROR_OUTOFMEMORY;
  1299. goto Cleanup;
  1300. }
  1301. __try {
  1302. dwRetStatus = RegOpenKeyExW(HKEY_LOCAL_MACHINE, DriverPathRoot, 0L, KEY_READ, & hKeyServices);
  1303. }
  1304. __except (EXCEPTION_EXECUTE_HANDLER) {
  1305. dwRetStatus = GetExceptionCode();
  1306. }
  1307. if (dwRetStatus == ERROR_SUCCESS) {
  1308. // enum service list
  1309. dwNameSize = MAX_PATH;
  1310. ZeroMemory(szServiceSubKeyName, MAX_PATH * sizeof(WCHAR));
  1311. ZeroMemory(szPerfSubKeyName, (MAX_PATH + 32) * sizeof(WCHAR));
  1312. while ((lEnumStatus = RegEnumKeyExW(hKeyServices,
  1313. dwServiceIndex,
  1314. szServiceSubKeyName,
  1315. & dwNameSize,
  1316. NULL, NULL, NULL, NULL)) == ERROR_SUCCESS) {
  1317. //try to open the perfkey under this key.
  1318. hr = StringCchPrintfW(szPerfSubKeyName, MAX_PATH + 32, L"%ws%ws%ws", szServiceSubKeyName, Slash, Performance);
  1319. bServiceRegistryOk = TRUE;
  1320. dwRegAccessMask = KEY_READ | KEY_WRITE;
  1321. // look for a performance subkey
  1322. __try {
  1323. dwRetStatus = RegOpenKeyExW(hKeyServices, szPerfSubKeyName, 0L, dwRegAccessMask, & hKeyPerformance);
  1324. }
  1325. __except (EXCEPTION_EXECUTE_HANDLER) {
  1326. dwRetStatus = GetExceptionCode();
  1327. }
  1328. if (dwRetStatus == ERROR_SUCCESS) {
  1329. // key found so service has perf data
  1330. // if performance subkey then
  1331. hr = StringCchPrintfW(wPerfSection, MAX_PATH + 32, cszFmtServiceSectionName, szServiceSubKeyName);
  1332. // look into the file for a perf entry for this service
  1333. nValue = GetPrivateProfileIntW(wPerfSection, FirstCounter, -1, szFileName);
  1334. if (nValue != (UINT) -1) {
  1335. // if found in file then update registry with values from file
  1336. __try {
  1337. dwRetStatus = RegSetValueExW(hKeyPerformance,
  1338. FirstCounter,
  1339. 0L,
  1340. REG_DWORD,
  1341. (const BYTE *) & nValue,
  1342. sizeof(nValue));
  1343. }
  1344. __except (EXCEPTION_EXECUTE_HANDLER) {
  1345. dwRetStatus = GetExceptionCode();
  1346. }
  1347. dwnValue = nValue;
  1348. TRACE((WINPERF_DBG_TRACE_INFO),
  1349. (& LoadPerfGuid,
  1350. __LINE__,
  1351. LOADPERF_RESTOREPERFREGISTRYFROMFILEW,
  1352. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2)
  1353. | ARG_DEF(ARG_TYPE_WSTR, 3),
  1354. dwRetStatus,
  1355. TRACE_WSTR(szFileName),
  1356. TRACE_WSTR(szServiceSubKeyName),
  1357. TRACE_WSTR(FirstCounter),
  1358. TRACE_DWORD(dwnValue),
  1359. NULL));
  1360. // now read the other values
  1361. }
  1362. else {
  1363. // there's one or more missing entries so
  1364. // remove the whole entry
  1365. bServiceRegistryOk = FALSE;
  1366. }
  1367. // look into the file for a perf entry for this service
  1368. nValue = GetPrivateProfileIntW(wPerfSection, FirstHelp, -1, szFileName);
  1369. if (nValue != (UINT) -1) {
  1370. // if found in file then update registry with values from file
  1371. __try {
  1372. dwRetStatus = RegSetValueExW(hKeyPerformance,
  1373. FirstHelp,
  1374. 0L,
  1375. REG_DWORD,
  1376. (const BYTE *) & nValue,
  1377. sizeof(nValue));
  1378. }
  1379. __except (EXCEPTION_EXECUTE_HANDLER) {
  1380. dwRetStatus = GetExceptionCode();
  1381. }
  1382. dwnValue = nValue;
  1383. TRACE((WINPERF_DBG_TRACE_INFO),
  1384. (& LoadPerfGuid,
  1385. __LINE__,
  1386. LOADPERF_RESTOREPERFREGISTRYFROMFILEW,
  1387. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2)
  1388. | ARG_DEF(ARG_TYPE_WSTR, 3),
  1389. dwRetStatus,
  1390. TRACE_WSTR(szFileName),
  1391. TRACE_WSTR(szServiceSubKeyName),
  1392. TRACE_WSTR(FirstHelp),
  1393. TRACE_DWORD(dwnValue),
  1394. NULL));
  1395. // now read the other values
  1396. }
  1397. else {
  1398. // there's one or more missing entries so
  1399. // remove the whole entry
  1400. bServiceRegistryOk = FALSE;
  1401. }
  1402. // look into the file for a perf entry for this service
  1403. nValue = GetPrivateProfileIntW(wPerfSection, LastCounter, -1, szFileName);
  1404. if (nValue != (UINT) -1) {
  1405. // if found in file then update registry with values from file
  1406. __try {
  1407. dwRetStatus = RegSetValueExW(hKeyPerformance,
  1408. LastCounter,
  1409. 0L,
  1410. REG_DWORD,
  1411. (const BYTE *) & nValue,
  1412. sizeof(nValue));
  1413. }
  1414. __except (EXCEPTION_EXECUTE_HANDLER) {
  1415. dwRetStatus = GetExceptionCode();
  1416. }
  1417. dwnValue = nValue;
  1418. TRACE((WINPERF_DBG_TRACE_INFO),
  1419. (& LoadPerfGuid,
  1420. __LINE__,
  1421. LOADPERF_RESTOREPERFREGISTRYFROMFILEW,
  1422. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2)
  1423. | ARG_DEF(ARG_TYPE_WSTR, 3),
  1424. dwRetStatus,
  1425. TRACE_WSTR(szFileName),
  1426. TRACE_WSTR(szServiceSubKeyName),
  1427. TRACE_WSTR(LastCounter),
  1428. TRACE_DWORD(dwnValue),
  1429. NULL));
  1430. // now read the other values
  1431. }
  1432. else {
  1433. // there's one or more missing entries so
  1434. // remove the whole entry
  1435. bServiceRegistryOk = FALSE;
  1436. }
  1437. // look into the file for a perf entry for this service
  1438. nValue = GetPrivateProfileIntW(wPerfSection, LastHelp, -1, szFileName);
  1439. if (nValue != (UINT) -1) {
  1440. // if found in file then update registry with values from file
  1441. __try {
  1442. dwRetStatus = RegSetValueExW(hKeyPerformance,
  1443. LastHelp,
  1444. 0L,
  1445. REG_DWORD,
  1446. (const BYTE *) & nValue,
  1447. sizeof(nValue));
  1448. }
  1449. __except (EXCEPTION_EXECUTE_HANDLER) {
  1450. dwRetStatus = GetExceptionCode();
  1451. }
  1452. dwnValue = nValue;
  1453. TRACE((WINPERF_DBG_TRACE_INFO),
  1454. (& LoadPerfGuid,
  1455. __LINE__,
  1456. LOADPERF_RESTOREPERFREGISTRYFROMFILEW,
  1457. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2)
  1458. | ARG_DEF(ARG_TYPE_WSTR, 3),
  1459. dwRetStatus,
  1460. TRACE_WSTR(szFileName),
  1461. TRACE_WSTR(szServiceSubKeyName),
  1462. TRACE_WSTR(LastHelp),
  1463. TRACE_DWORD(dwnValue),
  1464. NULL));
  1465. // now read the other values
  1466. }
  1467. else {
  1468. // there's one or more missing entries so
  1469. // remove the whole entry
  1470. bServiceRegistryOk = FALSE;
  1471. }
  1472. if (! bServiceRegistryOk) {
  1473. TRACE((WINPERF_DBG_TRACE_INFO),
  1474. (& LoadPerfGuid,
  1475. __LINE__,
  1476. LOADPERF_RESTOREPERFREGISTRYFROMFILEW,
  1477. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  1478. ERROR_SUCCESS,
  1479. TRACE_WSTR(szFileName),
  1480. TRACE_WSTR(szServiceSubKeyName),
  1481. NULL));
  1482. // an error occurred so delete the first/last counter/help values
  1483. RegDeleteValueW(hKeyPerformance, FirstCounter);
  1484. RegDeleteValueW(hKeyPerformance, FirstHelp);
  1485. RegDeleteValueW(hKeyPerformance, LastCounter);
  1486. RegDeleteValueW(hKeyPerformance, LastHelp);
  1487. } // else continiue
  1488. RegCloseKey (hKeyPerformance);
  1489. } // else this service has no perf data so skip
  1490. else {
  1491. TRACE((WINPERF_DBG_TRACE_ERROR),
  1492. (& LoadPerfGuid,
  1493. __LINE__,
  1494. LOADPERF_RESTOREPERFREGISTRYFROMFILEW,
  1495. ARG_DEF(ARG_TYPE_WSTR, 1),
  1496. dwRetStatus,
  1497. TRACE_WSTR(szServiceSubKeyName),
  1498. NULL));
  1499. if (dwRetStatus != ERROR_FILE_NOT_FOUND && dwRetStatus != ERROR_NO_MORE_ITEMS) break;
  1500. }
  1501. // reset for next loop
  1502. dwServiceIndex ++;
  1503. dwNameSize = MAX_PATH;
  1504. ZeroMemory(szServiceSubKeyName, MAX_PATH * sizeof(WCHAR));
  1505. ZeroMemory(szPerfSubKeyName, (MAX_PATH + 32) * sizeof(WCHAR));
  1506. } // end enum service list
  1507. if (dwRetStatus == ERROR_NO_MORE_ITEMS || dwRetStatus == ERROR_FILE_NOT_FOUND) dwRetStatus = ERROR_SUCCESS;
  1508. }
  1509. else {
  1510. TRACE((WINPERF_DBG_TRACE_ERROR),
  1511. (& LoadPerfGuid,
  1512. __LINE__,
  1513. LOADPERF_RESTOREPERFREGISTRYFROMFILEW,
  1514. ARG_DEF(ARG_TYPE_WSTR, 1),
  1515. dwRetStatus,
  1516. TRACE_WSTR(DriverPathRoot),
  1517. NULL));
  1518. }
  1519. if (hKeyServices != NULL) RegCloseKey(hKeyServices);
  1520. if (dwRetStatus == ERROR_SUCCESS) {
  1521. __try {
  1522. dwRetStatus = RegOpenKeyExW(HKEY_LOCAL_MACHINE, NamesKey, RESERVED, KEY_ALL_ACCESS, & hKeyPerflib);
  1523. }
  1524. __except (EXCEPTION_EXECUTE_HANDLER) {
  1525. dwRetStatus = GetExceptionCode();
  1526. }
  1527. if (dwRetStatus != ERROR_SUCCESS) {
  1528. TRACE((WINPERF_DBG_TRACE_ERROR),
  1529. (& LoadPerfGuid,
  1530. __LINE__,
  1531. LOADPERF_RESTOREPERFREGISTRYFROMFILEW,
  1532. ARG_DEF(ARG_TYPE_WSTR, 1),
  1533. dwRetStatus,
  1534. TRACE_WSTR(NamesKey),
  1535. NULL));
  1536. }
  1537. if (szLangId != NULL) {
  1538. // merge registry string values:
  1539. hr = StringCchCopyW(szLocalLangId, 8, szLangId);
  1540. dwRetStatus = UpdatePerfNameFilesX(szFileName, NULL, szLocalLangId, LODCTR_UPNF_RESTORE);
  1541. TRACE((WINPERF_DBG_TRACE_INFO),
  1542. (& LoadPerfGuid,
  1543. __LINE__,
  1544. LOADPERF_RESTOREPERFREGISTRYFROMFILEW,
  1545. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  1546. dwRetStatus,
  1547. TRACE_WSTR(szFileName),
  1548. TRACE_WSTR(szLocalLangId),
  1549. NULL));
  1550. }
  1551. else if (dwRetStatus == ERROR_SUCCESS) {
  1552. DWORD dwIndex = 0;
  1553. DWORD dwBufferSize;
  1554. while (dwRetStatus == ERROR_SUCCESS) {
  1555. dwBufferSize = 8;
  1556. ZeroMemory(szLocalLangId, 8 * sizeof(WCHAR));
  1557. dwRetStatus = RegEnumKeyExW(hKeyPerflib,
  1558. dwIndex,
  1559. szLocalLangId,
  1560. & dwBufferSize,
  1561. NULL,
  1562. NULL,
  1563. NULL,
  1564. NULL);
  1565. TRACE((WINPERF_DBG_TRACE_INFO),
  1566. (& LoadPerfGuid,
  1567. __LINE__,
  1568. LOADPERF_RESTOREPERFREGISTRYFROMFILEW,
  1569. ARG_DEF(ARG_TYPE_WSTR, 1),
  1570. dwRetStatus,
  1571. TRACE_WSTR(szLocalLangId),
  1572. TRACE_DWORD(dwIndex),
  1573. TRACE_DWORD(dwBufferSize),
  1574. NULL));
  1575. if (dwRetStatus == ERROR_SUCCESS) {
  1576. dwRetStatus = UpdatePerfNameFilesX(szFileName, NULL, szLocalLangId, LODCTR_UPNF_RESTORE);
  1577. TRACE((WINPERF_DBG_TRACE_INFO),
  1578. (& LoadPerfGuid,
  1579. __LINE__,
  1580. LOADPERF_RESTOREPERFREGISTRYFROMFILEW,
  1581. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  1582. dwRetStatus,
  1583. TRACE_WSTR(szFileName),
  1584. TRACE_WSTR(szLocalLangId),
  1585. NULL));
  1586. }
  1587. dwIndex ++;
  1588. }
  1589. if (dwRetStatus == ERROR_NO_MORE_ITEMS) {
  1590. dwRetStatus = ERROR_SUCCESS;
  1591. }
  1592. }
  1593. if (dwRetStatus == ERROR_SUCCESS) {
  1594. // update the keys in the registry
  1595. if (dwRetStatus == ERROR_SUCCESS) {
  1596. nValue = GetPrivateProfileIntW(cszPerflib, LastCounter, -1, szFileName);
  1597. if (nValue != (UINT) -1) {
  1598. // if found in file then update registry with values from file
  1599. __try {
  1600. dwRetStatus = RegSetValueExW(hKeyPerflib,
  1601. LastCounter,
  1602. 0L,
  1603. REG_DWORD,
  1604. (const BYTE *) & nValue,
  1605. sizeof(nValue));
  1606. }
  1607. __except (EXCEPTION_EXECUTE_HANDLER) {
  1608. dwRetStatus = GetExceptionCode();
  1609. }
  1610. dwnValue = nValue;
  1611. TRACE((WINPERF_DBG_TRACE_INFO),
  1612. (& LoadPerfGuid,
  1613. __LINE__,
  1614. LOADPERF_RESTOREPERFREGISTRYFROMFILEW,
  1615. ARG_DEF(ARG_TYPE_WSTR, 1),
  1616. dwRetStatus,
  1617. TRACE_WSTR(LastCounter),
  1618. TRACE_DWORD(dwnValue),
  1619. NULL));
  1620. }
  1621. }
  1622. if (dwRetStatus == ERROR_SUCCESS) {
  1623. // look into the file for a perf entry for this service
  1624. nValue = GetPrivateProfileIntW(cszPerflib, LastHelp, -1, szFileName);
  1625. if (nValue != (UINT) -1) {
  1626. // if found in file then update registry with values from file
  1627. __try {
  1628. dwRetStatus = RegSetValueExW(hKeyPerflib,
  1629. LastHelp,
  1630. 0L,
  1631. REG_DWORD,
  1632. (const BYTE *) & nValue,
  1633. sizeof(nValue));
  1634. }
  1635. __except (EXCEPTION_EXECUTE_HANDLER) {
  1636. dwRetStatus = GetExceptionCode();
  1637. }
  1638. dwnValue = nValue;
  1639. TRACE((WINPERF_DBG_TRACE_INFO),
  1640. (& LoadPerfGuid,
  1641. __LINE__,
  1642. LOADPERF_RESTOREPERFREGISTRYFROMFILEW,
  1643. ARG_DEF(ARG_TYPE_WSTR, 1),
  1644. dwRetStatus,
  1645. TRACE_WSTR(LastHelp),
  1646. TRACE_DWORD(dwnValue),
  1647. NULL));
  1648. }
  1649. }
  1650. if (dwRetStatus == ERROR_SUCCESS) {
  1651. // look into the file for a perf entry for this service
  1652. nValue = GetPrivateProfileIntW(cszPerflib, BaseIndex, -1, szFileName);
  1653. if (nValue != (UINT) -1) {
  1654. // if found in file then update registry with values from file
  1655. __try {
  1656. dwRetStatus = RegSetValueExW(hKeyPerflib,
  1657. BaseIndex,
  1658. 0L,
  1659. REG_DWORD,
  1660. (const BYTE *) & nValue,
  1661. sizeof(nValue));
  1662. }
  1663. __except (EXCEPTION_EXECUTE_HANDLER) {
  1664. dwRetStatus = GetExceptionCode();
  1665. }
  1666. dwnValue = nValue;
  1667. TRACE((WINPERF_DBG_TRACE_INFO),
  1668. (& LoadPerfGuid,
  1669. __LINE__,
  1670. LOADPERF_RESTOREPERFREGISTRYFROMFILEW,
  1671. ARG_DEF(ARG_TYPE_WSTR, 1),
  1672. dwRetStatus,
  1673. TRACE_WSTR(BaseIndex),
  1674. TRACE_DWORD(dwnValue),
  1675. NULL));
  1676. }
  1677. }
  1678. }
  1679. if (hKeyPerflib != NULL && hKeyPerflib != INVALID_HANDLE_VALUE) RegCloseKey(hKeyPerflib);
  1680. dwRetStatus = dwRetStatus;
  1681. }
  1682. Cleanup:
  1683. MemoryFree(szServiceSubKeyName);
  1684. MemoryFree(szPerfSubKeyName);
  1685. MemoryFree(wPerfSection);
  1686. return dwRetStatus;
  1687. }