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.

6289 lines
205 KiB

  1. /*++
  2. Copyright (c) 1991-1999 Microsoft Corporation
  3. Module Name:
  4. lodctr.c
  5. Abstract:
  6. Program to read the contents of the file specified in the command line
  7. and update the registry accordingly
  8. Author:
  9. Bob Watson (a-robw) 10 Feb 93
  10. Revision History:
  11. a-robw 25-Feb-93 revised calls to make it compile as a UNICODE or
  12. an ANSI app.
  13. Bob Watson (bobw) 10 Mar 99 added event log messages
  14. --*/
  15. #ifndef UNICODE
  16. #define UNICODE 1
  17. #endif
  18. #ifndef _UNICODE
  19. #define _UNICODE 1
  20. #endif
  21. #ifdef _LODCTR_DBG_OUTPUT
  22. #undef _LODCTR_DBG_OUTPUT
  23. #endif
  24. //#define _LODCTR_DBG_OUTPUT
  25. //
  26. // "C" Include files
  27. //
  28. #include <nt.h>
  29. #include <ntrtl.h>
  30. #include <nturtl.h>
  31. #include <stdio.h>
  32. #include <stdlib.h>
  33. #include <conio.h>
  34. #include <string.h>
  35. #include <assert.h>
  36. //
  37. // Windows Include files
  38. //
  39. #include <windows.h>
  40. #define __LOADPERF__
  41. #include <loadperf.h>
  42. #include <winperf.h>
  43. #include <tchar.h>
  44. #include "wmistr.h"
  45. #include "evntrace.h"
  46. //
  47. // application include files
  48. //
  49. #include "winperfp.h"
  50. #include "common.h"
  51. #include "lodctr.h"
  52. #include "wbemutil.h"
  53. #include "mofcomp.h"
  54. #include "ldprfmsg.h"
  55. typedef struct _DllValidationData {
  56. FILETIME CreationDate;
  57. LONGLONG FileSize;
  58. } DllValidationData, *pDllValidationData;
  59. #define OLD_VERSION 0x010000
  60. #define MAX_PROFILE_BUFFER 65536
  61. static DWORD dwSystemVersion;
  62. static DWORD dwFileSize;
  63. static TCHAR ComputerName[FILE_NAME_BUFFER_SIZE];
  64. static TCHAR szServiceName[MAX_PATH];
  65. static TCHAR szServiceDisplayName[MAX_PATH];
  66. static HKEY hPerfData;
  67. static BOOL bQuietMode = TRUE; // quiet means no _tprintf's
  68. // string constants
  69. static const TCHAR szDataFileRoot[] = {TEXT("%systemroot%\\system32\\Perf")};
  70. static const TCHAR szDatExt[] = {TEXT(".DAT")};
  71. static const TCHAR szBakExt[] = {TEXT(".BAK")};
  72. static const TCHAR szInfo[] = {TEXT("info")};
  73. static const TCHAR szDriverName[] = {TEXT("drivername")};
  74. static const TCHAR szMofFileName[] = {TEXT("MofFile")};
  75. static const TCHAR szNotFound[] = {TEXT("NotFound")};
  76. static const TCHAR szLanguages[] = {TEXT("languages")};
  77. static const TCHAR sz009[] = {TEXT("009")};
  78. static const TCHAR szSymbolFile[] = {TEXT("symbolfile")};
  79. static const TCHAR szName[] = {TEXT("_NAME")};
  80. static const TCHAR szHelp[] = {TEXT("_HELP")};
  81. static const TCHAR sz_DFormat[] = {TEXT(" %d")};
  82. static const TCHAR szDFormat[] = {TEXT("%d")};
  83. static const TCHAR szText[] = {TEXT("text")};
  84. static const TCHAR szObjects[] = {TEXT("objects")};
  85. static const TCHAR szSpace[] = {TEXT(" ")};
  86. static const TCHAR MapFileName[] = {TEXT("Perflib Busy")};
  87. static const TCHAR szPerflib[] = {TEXT("Perflib")};
  88. static const TCHAR cszLibrary[] = {TEXT("Library")};
  89. static const CHAR caszOpen[] = {"Open"};
  90. static const CHAR caszCollect[] = {"Collect"};
  91. static const CHAR caszClose[] = {"Close"};
  92. static const TCHAR szBaseIndex[] = {TEXT("Base Index")};
  93. static const TCHAR szTrusted[] = {TEXT("Trusted")};
  94. static const TCHAR szDisablePerformanceCounters[] = {TEXT("Disable Performance Counters")};
  95. #define OLD_VERSION 0x010000
  96. LPCWSTR VersionName = (LPCWSTR)L"Version";
  97. LPCWSTR CounterName = (LPCWSTR)L"Counter ";
  98. LPCWSTR HelpName = (LPCWSTR)L"Explain ";
  99. int __cdecl
  100. My_vfwprintf(
  101. FILE *str,
  102. const wchar_t *format,
  103. va_list argptr
  104. );
  105. __inline
  106. void __cdecl
  107. OUTPUT_MESSAGE (
  108. const TCHAR* format,
  109. ...
  110. )
  111. {
  112. va_list args;
  113. va_start( args, format );
  114. if (!bQuietMode) {
  115. My_vfwprintf(stdout, format, args);
  116. }
  117. va_end(args);
  118. }
  119. __inline
  120. static
  121. PPERF_OBJECT_TYPE
  122. NextObject (
  123. PPERF_OBJECT_TYPE pObject
  124. )
  125. { // NextObject
  126. return ((PPERF_OBJECT_TYPE) ((PBYTE) pObject + pObject->TotalByteLength));
  127. } // NextObject
  128. __inline
  129. static
  130. PERF_COUNTER_DEFINITION *
  131. FirstCounter(
  132. PERF_OBJECT_TYPE *pObjectDef
  133. )
  134. {
  135. return (PERF_COUNTER_DEFINITION *)
  136. ((PCHAR) pObjectDef + pObjectDef->HeaderLength);
  137. }
  138. __inline
  139. static
  140. PERF_COUNTER_DEFINITION *
  141. NextCounter(
  142. PERF_COUNTER_DEFINITION *pCounterDef
  143. )
  144. {
  145. return (PERF_COUNTER_DEFINITION *)
  146. ((PCHAR) pCounterDef + pCounterDef->ByteLength);
  147. }
  148. DWORD
  149. MakeTempFileName (
  150. LPCWSTR wszRoot,
  151. LPWSTR wszTempFilename
  152. )
  153. {
  154. FILETIME ft;
  155. DWORD dwReturn;
  156. WCHAR wszLocalFilename[MAX_PATH];
  157. GetSystemTimeAsFileTime (&ft);
  158. dwReturn = (DWORD) swprintf(wszLocalFilename,
  159. (LPCWSTR)L"%%windir%%\\system32\\wbem\\%s_%8.8x%8.8x.mof",
  160. (wszRoot != NULL ? wszRoot : (LPCWSTR)L"LodCtr"),
  161. ft.dwHighDateTime, ft.dwLowDateTime);
  162. if (dwReturn > 0) {
  163. // expand env. vars
  164. dwReturn = ExpandEnvironmentStringsW (
  165. wszLocalFilename,
  166. wszTempFilename,
  167. MAX_PATH-1);
  168. }
  169. return dwReturn;
  170. }
  171. DWORD
  172. WriteWideStringToAnsiFile (
  173. HANDLE hFile,
  174. LPCWSTR szWideString,
  175. LPDWORD pdwLength
  176. )
  177. {
  178. BOOL bStatus;
  179. DWORD dwStatus;
  180. LPSTR szAnsiString;
  181. DWORD dwBytesWritten = 0;
  182. szAnsiString = MemoryAllocate(* pdwLength);
  183. if (szAnsiString != NULL) {
  184. wcstombs (szAnsiString, szWideString, *pdwLength);
  185. bStatus = WriteFile (
  186. hFile,
  187. (LPCVOID) szAnsiString,
  188. *pdwLength,
  189. &dwBytesWritten,
  190. NULL);
  191. if (bStatus) {
  192. *pdwLength = dwBytesWritten;
  193. dwStatus = ERROR_SUCCESS;
  194. } else {
  195. dwStatus = GetLastError();
  196. }
  197. MemoryFree (szAnsiString);
  198. } else {
  199. dwStatus = GetLastError();
  200. }
  201. return dwStatus;
  202. }
  203. LPWSTR
  204. *BuildNameTable(
  205. HKEY hKeyRegistry, // handle to registry db with counter names
  206. LPWSTR lpszLangId, // unicode value of Language subkey
  207. PDWORD pdwLastItem // size of array in elements
  208. )
  209. /*++
  210. BuildNameTable
  211. Arguments:
  212. hKeyRegistry
  213. Handle to an open registry (this can be local or remote.) and
  214. is the value returned by RegConnectRegistry or a default key.
  215. lpszLangId
  216. The unicode id of the language to look up. (default is 409)
  217. Return Value:
  218. pointer to an allocated table. (the caller must MemoryFree it when finished!)
  219. the table is an array of pointers to zero terminated strings. NULL is
  220. returned if an error occured.
  221. --*/
  222. {
  223. LPWSTR *lpReturnValue;
  224. LPWSTR *lpCounterId;
  225. LPWSTR lpCounterNames;
  226. LPWSTR lpHelpText;
  227. LPWSTR lpThisName;
  228. LONG lWin32Status;
  229. DWORD dwLastError;
  230. DWORD dwValueType;
  231. DWORD dwArraySize;
  232. DWORD dwBufferSize;
  233. DWORD dwCounterSize;
  234. DWORD dwHelpSize;
  235. DWORD dwThisCounter;
  236. DWORD dwSystemVersion;
  237. DWORD dwLastId;
  238. DWORD dwLastHelpId;
  239. DWORD dwLastCounterId;
  240. DWORD dwLastCounterIdUsed;
  241. DWORD dwLastHelpIdUsed;
  242. HKEY hKeyValue;
  243. HKEY hKeyNames;
  244. LPWSTR lpValueNameString;
  245. WCHAR CounterNameBuffer [50];
  246. WCHAR HelpNameBuffer [50];
  247. lpValueNameString = NULL; //initialize to NULL
  248. lpReturnValue = NULL;
  249. hKeyValue = NULL;
  250. hKeyNames = NULL;
  251. // check for null arguments and insert defaults if necessary
  252. if (!lpszLangId) {
  253. lpszLangId = (LPWSTR)DefaultLangId;
  254. }
  255. // open registry to get number of items for computing array size
  256. __try {
  257. lWin32Status = RegOpenKeyEx (
  258. hKeyRegistry,
  259. NamesKey,
  260. RESERVED,
  261. KEY_READ,
  262. & hKeyValue);
  263. }
  264. __except (EXCEPTION_EXECUTE_HANDLER) {
  265. lWin32Status = GetExceptionCode();
  266. }
  267. if (lWin32Status != ERROR_SUCCESS) {
  268. ReportLoadPerfEvent(
  269. EVENTLOG_ERROR_TYPE, // error type
  270. (DWORD) LDPRFMSG_UNABLE_OPEN_KEY, // event,
  271. 2, lWin32Status, __LINE__, 0, 0,
  272. 1, (LPWSTR) NamesKey, NULL, NULL);
  273. TRACE((WINPERF_DBG_TRACE_ERROR),
  274. (& LoadPerfGuid,
  275. __LINE__,
  276. LOADPERF_LODCTR_BUILDNAMETABLE,
  277. ARG_DEF(ARG_TYPE_WSTR, 1),
  278. lWin32Status,
  279. TRACE_WSTR(NamesKey),
  280. NULL));
  281. goto BNT_BAILOUT;
  282. }
  283. // get number of items
  284. dwBufferSize = sizeof (dwLastHelpId);
  285. __try {
  286. lWin32Status = RegQueryValueEx (
  287. hKeyValue,
  288. LastHelp,
  289. RESERVED,
  290. & dwValueType,
  291. (LPBYTE) & dwLastHelpId,
  292. & dwBufferSize);
  293. }
  294. __except (EXCEPTION_EXECUTE_HANDLER) {
  295. lWin32Status = GetExceptionCode();
  296. }
  297. if ((lWin32Status != ERROR_SUCCESS) || (dwValueType != REG_DWORD)) {
  298. ReportLoadPerfEvent(
  299. EVENTLOG_ERROR_TYPE, // error type
  300. (DWORD) LDPRFMSG_UNABLE_READ_VALUE, // event,
  301. 2, lWin32Status, __LINE__, 0, 0,
  302. 1, (LPWSTR) LastHelp, NULL, NULL);
  303. TRACE((WINPERF_DBG_TRACE_ERROR),
  304. (& LoadPerfGuid,
  305. __LINE__,
  306. LOADPERF_LODCTR_BUILDNAMETABLE,
  307. ARG_DEF(ARG_TYPE_WSTR, 1),
  308. lWin32Status,
  309. TRACE_WSTR(LastHelp),
  310. NULL));
  311. goto BNT_BAILOUT;
  312. }
  313. // get number of items
  314. dwBufferSize = sizeof (dwLastId);
  315. __try {
  316. lWin32Status = RegQueryValueEx (
  317. hKeyValue,
  318. LastCounter,
  319. RESERVED,
  320. & dwValueType,
  321. (LPBYTE) & dwLastCounterId,
  322. & dwBufferSize);
  323. }
  324. __except (EXCEPTION_EXECUTE_HANDLER) {
  325. lWin32Status = GetExceptionCode();
  326. }
  327. if ((lWin32Status != ERROR_SUCCESS) || (dwValueType != REG_DWORD)) {
  328. ReportLoadPerfEvent(
  329. EVENTLOG_ERROR_TYPE, // error type
  330. (DWORD) LDPRFMSG_UNABLE_READ_VALUE, // event,
  331. 2, lWin32Status, __LINE__, 0, 0,
  332. 1, (LPWSTR) LastCounter, NULL, NULL);
  333. TRACE((WINPERF_DBG_TRACE_ERROR),
  334. (& LoadPerfGuid,
  335. __LINE__,
  336. LOADPERF_LODCTR_BUILDNAMETABLE,
  337. ARG_DEF(ARG_TYPE_WSTR, 1),
  338. lWin32Status,
  339. TRACE_WSTR(LastCounter),
  340. NULL));
  341. goto BNT_BAILOUT;
  342. }
  343. dwLastId = (dwLastCounterId < dwLastHelpId)
  344. ? (dwLastHelpId) : (dwLastCounterId);
  345. // compute size of pointer array
  346. dwArraySize = (dwLastId + 1) * sizeof(LPWSTR);
  347. // get Perflib system version
  348. dwBufferSize = sizeof (dwSystemVersion);
  349. __try {
  350. lWin32Status = RegQueryValueEx (
  351. hKeyValue,
  352. VersionName,
  353. RESERVED,
  354. & dwValueType,
  355. (LPBYTE) & dwSystemVersion,
  356. & dwBufferSize);
  357. }
  358. __except (EXCEPTION_EXECUTE_HANDLER) {
  359. lWin32Status = GetExceptionCode();
  360. }
  361. if ((lWin32Status != ERROR_SUCCESS) || (dwValueType != REG_DWORD)) {
  362. dwSystemVersion = OLD_VERSION;
  363. // reset the error status
  364. lWin32Status = ERROR_SUCCESS;
  365. }
  366. TRACE((WINPERF_DBG_TRACE_INFO),
  367. (& LoadPerfGuid,
  368. __LINE__,
  369. LOADPERF_LODCTR_BUILDNAMETABLE,
  370. 0,
  371. lWin32Status,
  372. TRACE_DWORD(dwLastCounterId),
  373. TRACE_DWORD(dwLastHelpId),
  374. NULL));
  375. if (dwSystemVersion == OLD_VERSION) {
  376. // get names from registry
  377. lpValueNameString = MemoryAllocate (
  378. lstrlen(NamesKey) * sizeof (WCHAR) +
  379. lstrlen(Slash) * sizeof (WCHAR) +
  380. lstrlen(lpszLangId) * sizeof (WCHAR) +
  381. sizeof (UNICODE_NULL));
  382. if (!lpValueNameString) goto BNT_BAILOUT;
  383. lstrcpy (lpValueNameString, NamesKey);
  384. lstrcat (lpValueNameString, Slash);
  385. lstrcat (lpValueNameString, lpszLangId);
  386. lWin32Status = RegOpenKeyEx (
  387. hKeyRegistry,
  388. lpValueNameString,
  389. RESERVED,
  390. KEY_READ,
  391. & hKeyNames);
  392. } else {
  393. if (ComputerName[0] == 0) {
  394. hKeyNames = HKEY_PERFORMANCE_DATA;
  395. } else {
  396. __try {
  397. lWin32Status = RegConnectRegistry(ComputerName,
  398. HKEY_PERFORMANCE_DATA,
  399. & hKeyNames);
  400. }
  401. __except (EXCEPTION_EXECUTE_HANDLER) {
  402. lWin32Status = GetExceptionCode();
  403. }
  404. }
  405. lstrcpy (CounterNameBuffer, CounterName);
  406. lstrcat (CounterNameBuffer, lpszLangId);
  407. lstrcpy (HelpNameBuffer, HelpName);
  408. lstrcat (HelpNameBuffer, lpszLangId);
  409. }
  410. // get size of counter names and add that to the arrays
  411. if (lWin32Status != ERROR_SUCCESS) {
  412. ReportLoadPerfEvent(
  413. EVENTLOG_ERROR_TYPE, // error type
  414. (DWORD) LDPRFMSG_UNABLE_ACCESS_STRINGS, // event,
  415. 2, lWin32Status, __LINE__, 0, 0,
  416. 1, (LPWSTR) lpszLangId, NULL, NULL);
  417. goto BNT_BAILOUT;
  418. }
  419. dwBufferSize = 0;
  420. __try {
  421. lWin32Status = RegQueryValueEx (
  422. hKeyNames,
  423. dwSystemVersion == OLD_VERSION ? Counters : CounterNameBuffer,
  424. RESERVED,
  425. & dwValueType,
  426. NULL,
  427. & dwBufferSize);
  428. }
  429. __except (EXCEPTION_EXECUTE_HANDLER) {
  430. lWin32Status = GetExceptionCode();
  431. }
  432. if (lWin32Status != ERROR_SUCCESS) {
  433. ReportLoadPerfEvent(
  434. EVENTLOG_ERROR_TYPE, // error type
  435. (DWORD) LDPRFMSG_UNABLE_READ_COUNTER_STRINGS, // event,
  436. 2, lWin32Status, __LINE__, 0, 0,
  437. 1, (LPWSTR) lpszLangId, NULL, NULL);
  438. TRACE((WINPERF_DBG_TRACE_ERROR),
  439. (& LoadPerfGuid,
  440. __LINE__,
  441. LOADPERF_LODCTR_BUILDNAMETABLE,
  442. ARG_DEF(ARG_TYPE_WSTR, 1),
  443. lWin32Status,
  444. TRACE_WSTR(Counters),
  445. NULL));
  446. goto BNT_BAILOUT;
  447. }
  448. dwCounterSize = dwBufferSize;
  449. // get size of counter names and add that to the arrays
  450. if (lWin32Status != ERROR_SUCCESS) goto BNT_BAILOUT;
  451. dwBufferSize = 0;
  452. __try {
  453. lWin32Status = RegQueryValueEx (
  454. hKeyNames,
  455. dwSystemVersion == OLD_VERSION ? Help : HelpNameBuffer,
  456. RESERVED,
  457. & dwValueType,
  458. NULL,
  459. & dwBufferSize);
  460. }
  461. __except (EXCEPTION_EXECUTE_HANDLER) {
  462. lWin32Status = GetExceptionCode();
  463. }
  464. if (lWin32Status != ERROR_SUCCESS) {
  465. ReportLoadPerfEvent(
  466. EVENTLOG_ERROR_TYPE, // error type
  467. (DWORD) LDPRFMSG_UNABLE_READ_HELP_STRINGS, // event,
  468. 2, lWin32Status, __LINE__, 0, 0,
  469. 1, (LPWSTR) lpszLangId, NULL, NULL);
  470. TRACE((WINPERF_DBG_TRACE_ERROR),
  471. (& LoadPerfGuid,
  472. __LINE__,
  473. LOADPERF_LODCTR_BUILDNAMETABLE,
  474. ARG_DEF(ARG_TYPE_WSTR, 1),
  475. lWin32Status,
  476. TRACE_WSTR(Help),
  477. NULL));
  478. goto BNT_BAILOUT;
  479. }
  480. dwHelpSize = dwBufferSize;
  481. lpReturnValue = MemoryAllocate (dwArraySize + dwCounterSize + dwHelpSize);
  482. if (!lpReturnValue) {
  483. lWin32Status = ERROR_OUTOFMEMORY;
  484. SetLastError(lWin32Status);
  485. ReportLoadPerfEvent(
  486. EVENTLOG_ERROR_TYPE, // error type
  487. (DWORD) LDPRFMSG_MEMORY_ALLOCATION_FAILURE, // event,
  488. 1, __LINE__, 0, 0, 0,
  489. 0, NULL, NULL, NULL);
  490. TRACE((WINPERF_DBG_TRACE_ERROR),
  491. (& LoadPerfGuid,
  492. __LINE__,
  493. LOADPERF_LODCTR_BUILDNAMETABLE,
  494. 0,
  495. ERROR_OUTOFMEMORY,
  496. NULL));
  497. goto BNT_BAILOUT;
  498. }
  499. // initialize pointers into buffer
  500. lpCounterId = lpReturnValue;
  501. lpCounterNames = (LPWSTR)((LPBYTE)lpCounterId + dwArraySize);
  502. lpHelpText = (LPWSTR)((LPBYTE)lpCounterNames + dwCounterSize);
  503. // read counters into memory
  504. dwBufferSize = dwCounterSize;
  505. __try {
  506. lWin32Status = RegQueryValueEx (
  507. hKeyNames,
  508. dwSystemVersion == OLD_VERSION ? Counters : CounterNameBuffer,
  509. RESERVED,
  510. & dwValueType,
  511. (LPVOID) lpCounterNames,
  512. & dwBufferSize);
  513. }
  514. __except (EXCEPTION_EXECUTE_HANDLER) {
  515. lWin32Status = GetExceptionCode();
  516. }
  517. if (lWin32Status != ERROR_SUCCESS) {
  518. ReportLoadPerfEvent(
  519. EVENTLOG_ERROR_TYPE, // error type
  520. (DWORD) LDPRFMSG_UNABLE_READ_COUNTER_STRINGS, // event,
  521. 2, lWin32Status, __LINE__, 0, 0,
  522. 1, (LPWSTR) lpszLangId, NULL, NULL);
  523. TRACE((WINPERF_DBG_TRACE_ERROR),
  524. (& LoadPerfGuid,
  525. __LINE__,
  526. LOADPERF_LODCTR_BUILDNAMETABLE,
  527. ARG_DEF(ARG_TYPE_WSTR, 1),
  528. lWin32Status,
  529. TRACE_WSTR(Counters),
  530. NULL));
  531. goto BNT_BAILOUT;
  532. }
  533. dwBufferSize = dwHelpSize;
  534. __try {
  535. lWin32Status = RegQueryValueEx (
  536. hKeyNames,
  537. dwSystemVersion == OLD_VERSION ? Help : HelpNameBuffer,
  538. RESERVED,
  539. & dwValueType,
  540. (LPVOID) lpHelpText,
  541. & dwBufferSize);
  542. }
  543. __except (EXCEPTION_EXECUTE_HANDLER) {
  544. lWin32Status = GetExceptionCode();
  545. }
  546. if (lWin32Status != ERROR_SUCCESS) {
  547. ReportLoadPerfEvent(
  548. EVENTLOG_ERROR_TYPE, // error type
  549. (DWORD) LDPRFMSG_UNABLE_READ_HELP_STRINGS, // event,
  550. 2, lWin32Status, __LINE__, 0, 0,
  551. 1, (LPWSTR) lpszLangId, NULL, NULL);
  552. TRACE((WINPERF_DBG_TRACE_ERROR),
  553. (& LoadPerfGuid,
  554. __LINE__,
  555. LOADPERF_LODCTR_BUILDNAMETABLE,
  556. ARG_DEF(ARG_TYPE_WSTR, 1),
  557. lWin32Status,
  558. TRACE_WSTR(Help),
  559. NULL));
  560. goto BNT_BAILOUT;
  561. }
  562. dwLastCounterIdUsed = 0;
  563. dwLastHelpIdUsed = 0;
  564. // load counter array items
  565. for (lpThisName = lpCounterNames;
  566. *lpThisName;
  567. lpThisName += (lstrlen(lpThisName)+1) ) {
  568. // first string should be an integer (in decimal unicode digits)
  569. dwThisCounter = wcstoul (lpThisName, NULL, 10);
  570. if ((dwThisCounter == 0) || (dwThisCounter > dwLastId)) {
  571. lWin32Status = ERROR_INVALID_DATA;
  572. SetLastError(lWin32Status);
  573. ReportLoadPerfEvent(
  574. EVENTLOG_ERROR_TYPE, // error type
  575. (DWORD) LDPRFMSG_REGISTRY_COUNTER_STRINGS_CORRUPT, // event,
  576. 4, dwThisCounter, dwLastCounterId, dwLastId, __LINE__,
  577. 1, lpThisName, NULL, NULL);
  578. TRACE((WINPERF_DBG_TRACE_ERROR),
  579. (& LoadPerfGuid,
  580. __LINE__,
  581. LOADPERF_LODCTR_BUILDNAMETABLE,
  582. ARG_DEF(ARG_TYPE_WSTR, 1),
  583. lWin32Status,
  584. TRACE_WSTR(lpThisName),
  585. TRACE_DWORD(dwThisCounter),
  586. TRACE_DWORD(dwLastId),
  587. NULL));
  588. goto BNT_BAILOUT; // bad entry
  589. }
  590. // point to corresponding counter name
  591. lpThisName += (lstrlen(lpThisName)+1);
  592. // and load array element;
  593. lpCounterId[dwThisCounter] = lpThisName;
  594. if (dwThisCounter > dwLastCounterIdUsed) dwLastCounterIdUsed = dwThisCounter;
  595. }
  596. for (lpThisName = lpHelpText;
  597. *lpThisName;
  598. lpThisName += (lstrlen(lpThisName)+1) ) {
  599. // first string should be an integer (in decimal unicode digits)
  600. dwThisCounter = wcstoul (lpThisName, NULL, 10);
  601. if ((dwThisCounter == 0) || (dwThisCounter > dwLastId)) {
  602. lWin32Status = ERROR_INVALID_DATA;
  603. SetLastError(lWin32Status);
  604. ReportLoadPerfEvent(
  605. EVENTLOG_ERROR_TYPE, // error type
  606. (DWORD) LDPRFMSG_REGISTRY_HELP_STRINGS_CORRUPT, // event,
  607. 4, dwThisCounter, dwLastHelpId, dwLastId, __LINE__,
  608. 1, lpThisName, NULL, NULL);
  609. TRACE((WINPERF_DBG_TRACE_ERROR),
  610. (& LoadPerfGuid,
  611. __LINE__,
  612. LOADPERF_LODCTR_BUILDNAMETABLE,
  613. ARG_DEF(ARG_TYPE_WSTR, 1),
  614. lWin32Status,
  615. TRACE_WSTR(lpThisName),
  616. TRACE_DWORD(dwThisCounter),
  617. TRACE_DWORD(dwLastId),
  618. NULL));
  619. goto BNT_BAILOUT; // bad entry
  620. }
  621. // point to corresponding counter name
  622. lpThisName += (lstrlen(lpThisName)+1);
  623. // and load array element;
  624. lpCounterId[dwThisCounter] = lpThisName;
  625. if (dwThisCounter > dwLastHelpIdUsed) dwLastHelpIdUsed= dwThisCounter;
  626. }
  627. TRACE((WINPERF_DBG_TRACE_INFO),
  628. (& LoadPerfGuid,
  629. __LINE__,
  630. LOADPERF_LODCTR_BUILDNAMETABLE,
  631. ARG_DEF(ARG_TYPE_WSTR, 1),
  632. lWin32Status,
  633. TRACE_WSTR(lpszLangId),
  634. TRACE_DWORD(dwLastCounterIdUsed),
  635. TRACE_DWORD(dwLastHelpIdUsed),
  636. TRACE_DWORD(dwLastId),
  637. NULL));
  638. // check the registry for consistency
  639. // the last help string index should be the last ID used
  640. if (dwLastCounterIdUsed > dwLastId) {
  641. lWin32Status = ERROR_INVALID_DATA;
  642. SetLastError(lWin32Status);
  643. ReportLoadPerfEvent(
  644. EVENTLOG_ERROR_TYPE, // error type
  645. (DWORD) LDPRFMSG_REGISTRY_INDEX_CORRUPT, // event,
  646. 3, dwLastId, dwLastCounterIdUsed, __LINE__, 0,
  647. 0, NULL, NULL, NULL);
  648. goto BNT_BAILOUT; // bad registry
  649. }
  650. if (dwLastHelpIdUsed > dwLastId) {
  651. lWin32Status = ERROR_INVALID_DATA;
  652. SetLastError(lWin32Status);
  653. ReportLoadPerfEvent(
  654. EVENTLOG_ERROR_TYPE, // error type
  655. (DWORD) LDPRFMSG_REGISTRY_INDEX_CORRUPT, // event,
  656. 3, dwLastId, dwLastHelpIdUsed, __LINE__, 0,
  657. 0, NULL, NULL, NULL);
  658. goto BNT_BAILOUT; // bad registry
  659. }
  660. if (pdwLastItem) *pdwLastItem = dwLastId;
  661. MemoryFree ((LPVOID)lpValueNameString);
  662. if (hKeyValue) {
  663. RegCloseKey (hKeyValue);
  664. }
  665. if (hKeyNames && hKeyNames != HKEY_PERFORMANCE_DATA) {
  666. RegCloseKey (hKeyNames);
  667. }
  668. return lpReturnValue;
  669. BNT_BAILOUT:
  670. if (lWin32Status != ERROR_SUCCESS) {
  671. dwLastError = GetLastError();
  672. }
  673. if (lpValueNameString) {
  674. MemoryFree ((LPVOID)lpValueNameString);
  675. }
  676. if (lpReturnValue) {
  677. MemoryFree ((LPVOID)lpReturnValue);
  678. }
  679. if (hKeyValue) {
  680. RegCloseKey (hKeyValue);
  681. }
  682. if (hKeyNames && hKeyNames != HKEY_PERFORMANCE_DATA) {
  683. RegCloseKey (hKeyNames);
  684. }
  685. return NULL;
  686. }
  687. BOOL
  688. MakeBackupCopyOfLanguageFiles (
  689. IN LPCTSTR szLangId
  690. )
  691. {
  692. TCHAR szOldFileName[MAX_PATH];
  693. TCHAR szTmpFileName[MAX_PATH];
  694. TCHAR szNewFileName[MAX_PATH];
  695. BOOL bStatus;
  696. DWORD dwStatus;
  697. HANDLE hOutFile;
  698. UNREFERENCED_PARAMETER (szLangId);
  699. ExpandEnvironmentStrings (szDataFileRoot, szOldFileName, MAX_PATH);
  700. _stprintf (szNewFileName, (LPCTSTR)(TEXT("%sStringBackup.INI")), szOldFileName);
  701. _stprintf(szTmpFileName,
  702. (LPCTSTR)(TEXT("%sStringBackup.TMP")),
  703. szOldFileName);
  704. // see if the file already exists
  705. hOutFile = CreateFile(
  706. szTmpFileName,
  707. GENERIC_READ,
  708. 0, // no sharing
  709. NULL, // default security
  710. OPEN_EXISTING,
  711. FILE_ATTRIBUTE_NORMAL,
  712. NULL);
  713. if (hOutFile != INVALID_HANDLE_VALUE) {
  714. CloseHandle(hOutFile);
  715. bStatus = DeleteFile(szTmpFileName);
  716. }
  717. // create backup of file
  718. //
  719. dwStatus = BackupPerfRegistryToFileW (szTmpFileName, NULL);
  720. if (dwStatus == ERROR_SUCCESS) {
  721. bStatus = CopyFile(szTmpFileName, szNewFileName, FALSE);
  722. if (bStatus) {
  723. DeleteFile(szTmpFileName);
  724. }
  725. } else {
  726. // unable to create a backup file
  727. SetLastError (dwStatus);
  728. bStatus = FALSE;
  729. }
  730. TRACE((WINPERF_DBG_TRACE_INFO),
  731. (& LoadPerfGuid,
  732. __LINE__,
  733. LOADPERF_MAKEBACKUPCOPYOFLANGUAGEFILES,
  734. ARG_DEF(ARG_TYPE_WSTR, 1),
  735. GetLastError(),
  736. TRACE_WSTR(szNewFileName),
  737. NULL));
  738. return bStatus;
  739. }
  740. BOOL
  741. GetFileFromCommandLine (
  742. IN LPTSTR lpCommandLine,
  743. OUT LPTSTR *lpFileName,
  744. IN DWORD_PTR *pdwFlags
  745. )
  746. /*++
  747. GetFileFromCommandLine
  748. parses the command line to retrieve the ini filename that should be
  749. the first and only argument.
  750. Arguments
  751. lpCommandLine pointer to command line (returned by GetCommandLine)
  752. lpFileName pointer to buffer that will recieve address of the
  753. validated filename entered on the command line
  754. pdwFlags pointer to dword containing flag bits
  755. Return Value
  756. TRUE if a valid filename was returned
  757. FALSE if the filename is not valid or missing
  758. error is returned in GetLastError
  759. --*/
  760. {
  761. INT iNumArgs;
  762. LPTSTR lpExeName = NULL;
  763. LPTSTR lpCmdLineName = NULL;
  764. LPWSTR lpIniFileName = NULL;
  765. LPWSTR lpMofFlag = NULL;
  766. HANDLE hFileHandle;
  767. TCHAR LocalComputerName[FILE_NAME_BUFFER_SIZE];
  768. DWORD NameBuffer;
  769. DWORD dwCpuArg, dwIniArg;
  770. // check for valid arguments
  771. if (!lpCommandLine) return (ERROR_INVALID_PARAMETER);
  772. if (!lpFileName) return (ERROR_INVALID_PARAMETER);
  773. if (!pdwFlags) return (ERROR_INVALID_PARAMETER);
  774. // allocate memory for parsing operation
  775. lpExeName = MemoryAllocate (FILE_NAME_BUFFER_SIZE * sizeof(TCHAR));
  776. lpCmdLineName = MemoryAllocate (FILE_NAME_BUFFER_SIZE * sizeof(TCHAR));
  777. lpIniFileName = MemoryAllocate (FILE_NAME_BUFFER_SIZE * sizeof(WCHAR));
  778. lpMofFlag = MemoryAllocate (FILE_NAME_BUFFER_SIZE * sizeof(WCHAR));
  779. if (!lpExeName || !lpIniFileName || !lpCmdLineName || !lpMofFlag) {
  780. SetLastError (ERROR_OUTOFMEMORY);
  781. if (lpExeName) MemoryFree (lpExeName);
  782. if (lpIniFileName) MemoryFree (lpIniFileName);
  783. if (lpCmdLineName) MemoryFree (lpCmdLineName);
  784. if (lpMofFlag) MemoryFree (lpMofFlag);
  785. return FALSE;
  786. } else {
  787. // get strings from command line
  788. RtlZeroMemory(ComputerName, sizeof(TCHAR) * FILE_NAME_BUFFER_SIZE);
  789. RtlZeroMemory(LocalComputerName, sizeof(TCHAR) * FILE_NAME_BUFFER_SIZE);
  790. // check for mof Flag
  791. lstrcpyW (lpMofFlag, GetItemFromString (lpCommandLine, 2, cSpace));
  792. *pdwFlags |= LOADPERF_FLAGS_LOAD_REGISTRY_ONLY; // default unless a switch is found
  793. if ((lpMofFlag[0] == cHyphen) || (lpMofFlag[0] == cSlash)) {
  794. if ((lpMofFlag[1] == cM) || (lpMofFlag[1] == cm)) {
  795. *pdwFlags &= ~LOADPERF_FLAGS_LOAD_REGISTRY_ONLY; // clear that bit
  796. } else if ((lpMofFlag[1] == cQuestion)) {
  797. // ask for usage
  798. if (lpExeName) MemoryFree (lpExeName);
  799. if (lpIniFileName) MemoryFree (lpIniFileName);
  800. if (lpMofFlag) MemoryFree (lpMofFlag);
  801. return FALSE;
  802. }
  803. dwCpuArg = 3;
  804. dwIniArg = 4;
  805. } else {
  806. dwCpuArg = 2;
  807. dwIniArg = 3;
  808. }
  809. // Get INI File name
  810. lstrcpy (lpCmdLineName, GetItemFromString (lpCommandLine, dwIniArg, cSpace));
  811. if (lstrlen(lpCmdLineName) == 0) {
  812. // then no computer name was specified so try to get the
  813. // ini file from the 2nd entry
  814. lstrcpy (lpCmdLineName, GetItemFromString (lpCommandLine, dwCpuArg, cSpace));
  815. if (lstrlen(lpCmdLineName) == 0) {
  816. // no ini file found
  817. iNumArgs = 1;
  818. } else {
  819. // fill in a blank computer name
  820. iNumArgs = 2;
  821. ComputerName[0] = 0;
  822. }
  823. } else {
  824. // the computer name must be present so fetch it
  825. lstrcpy (LocalComputerName, GetItemFromString (lpCommandLine, dwCpuArg, cSpace));
  826. iNumArgs = 3;
  827. }
  828. if (iNumArgs != 2 && iNumArgs != 3) {
  829. // wrong number of arguments
  830. SetLastError (ERROR_INVALID_PARAMETER);
  831. if (lpExeName) MemoryFree (lpExeName);
  832. if (lpIniFileName) MemoryFree (lpIniFileName);
  833. if (lpMofFlag) MemoryFree (lpMofFlag);
  834. return FALSE;
  835. } else {
  836. // check if there is a computer name in the input line
  837. if (LocalComputerName[0] == cBackslash &&
  838. LocalComputerName[1] == cBackslash) {
  839. // save it form now
  840. lstrcpy (ComputerName, LocalComputerName);
  841. // reuse local buffer to get the this computer's name
  842. NameBuffer = sizeof (LocalComputerName) / sizeof (TCHAR);
  843. GetComputerName(LocalComputerName, &NameBuffer);
  844. if (!lstrcmpi(LocalComputerName, &ComputerName[2])) {
  845. // same name as local computer name
  846. // so clear computer name buffer
  847. ComputerName[0] = 0;
  848. }
  849. }
  850. if (SearchPath (NULL, lpCmdLineName,
  851. NULL, FILE_NAME_BUFFER_SIZE,
  852. lpIniFileName, NULL) > 0) {
  853. hFileHandle = CreateFile (
  854. lpIniFileName,
  855. GENERIC_READ,
  856. 0,
  857. NULL,
  858. OPEN_EXISTING,
  859. FILE_ATTRIBUTE_NORMAL,
  860. NULL);
  861. MemoryFree (lpCmdLineName);
  862. if (hFileHandle && hFileHandle != INVALID_HANDLE_VALUE) {
  863. // get file size
  864. dwFileSize = GetFileSize (hFileHandle, NULL);
  865. if (dwFileSize == 0xffffffff) {
  866. dwFileSize = 0L;
  867. } else {
  868. dwFileSize *= sizeof (TCHAR);
  869. }
  870. CloseHandle (hFileHandle);
  871. // file exists, so return name and success
  872. if (lpExeName) MemoryFree (lpExeName);
  873. lstrcpyW (*lpFileName, lpIniFileName);
  874. if (lpIniFileName) MemoryFree (lpIniFileName);
  875. return TRUE;
  876. } else {
  877. // filename was on command line, but not valid so return
  878. // false, but send name back for error message
  879. if (lpExeName) MemoryFree (lpExeName);
  880. lstrcpyW (*lpFileName, lpIniFileName);
  881. if (lpIniFileName) MemoryFree (lpIniFileName);
  882. return FALSE;
  883. }
  884. } else {
  885. MemoryFree (lpCmdLineName);
  886. SetLastError (ERROR_OPEN_FAILED);
  887. if (lpExeName) MemoryFree (lpExeName);
  888. if (lpIniFileName) MemoryFree (lpIniFileName);
  889. return FALSE;
  890. }
  891. }
  892. }
  893. }
  894. BOOL
  895. LodctrSetSericeAsTrusted(
  896. IN LPCTSTR lpIniFile,
  897. IN LPCTSTR szMachineName,
  898. IN LPCTSTR szServiceName
  899. )
  900. /*++
  901. GetDriverName
  902. looks up driver name in the .ini file and returns it in lpDevName
  903. Arguments
  904. lpIniFile
  905. Filename of ini file
  906. lpDevName
  907. pointer to pointer to reciev buffer w/dev name in it
  908. Return Value
  909. TRUE if found
  910. FALSE if not found in .ini file
  911. --*/
  912. {
  913. DWORD dwRetSize;
  914. DWORD dwStatus;
  915. BOOL bReturn;
  916. static WCHAR szParam[MAX_PATH];
  917. dwRetSize = GetPrivateProfileString (
  918. szInfo, // info section
  919. szTrusted, // Trusted name value
  920. szNotFound, // default value
  921. szParam,
  922. MAX_PATH,
  923. lpIniFile);
  924. if ((lstrcmpi(szParam, szNotFound)) != 0) {
  925. // Trusted string found so set
  926. dwStatus = SetServiceAsTrustedW (
  927. szMachineName,
  928. szServiceName);
  929. if (dwStatus != ERROR_SUCCESS) {
  930. SetLastError (dwStatus);
  931. bReturn = FALSE;
  932. }
  933. bReturn = TRUE;
  934. } else {
  935. // Service is not trusted to have a good Perf DLL
  936. SetLastError (ERROR_SUCCESS);
  937. bReturn = FALSE;
  938. }
  939. return bReturn;
  940. }
  941. BOOL
  942. GetDriverName (
  943. IN LPTSTR lpIniFile,
  944. OUT LPTSTR *lpDevName
  945. )
  946. /*++
  947. GetDriverName
  948. looks up driver name in the .ini file and returns it in lpDevName
  949. Arguments
  950. lpIniFile
  951. Filename of ini file
  952. lpDevName
  953. pointer to pointer to reciev buffer w/dev name in it
  954. Return Value
  955. TRUE if found
  956. FALSE if not found in .ini file
  957. --*/
  958. {
  959. DWORD dwRetSize;
  960. BOOL bReturn = FALSE;
  961. if (lpDevName) {
  962. dwRetSize = GetPrivateProfileString (
  963. szInfo, // info section
  964. szDriverName, // driver name value
  965. szNotFound, // default value
  966. * lpDevName,
  967. MAX_PATH,
  968. lpIniFile);
  969. if ((lstrcmpi(*lpDevName, szNotFound)) != 0) {
  970. // name found
  971. bReturn = TRUE;
  972. } else {
  973. // name not found, default returned so return NULL string
  974. SetLastError (ERROR_BAD_DRIVER);
  975. *lpDevName = 0;
  976. }
  977. } else {
  978. SetLastError (ERROR_INVALID_PARAMETER);
  979. }
  980. TRACE((WINPERF_DBG_TRACE_INFO),
  981. (& LoadPerfGuid,
  982. __LINE__,
  983. LOADPERF_GETDRIVERNAME,
  984. ARG_DEF(ARG_TYPE_WSTR, 1),
  985. GetLastError(),
  986. TRACE_WSTR(lpIniFile),
  987. NULL));
  988. return bReturn;
  989. }
  990. BOOL
  991. BuildLanguageTables (
  992. IN LPTSTR lpIniFile,
  993. IN OUT PLANGUAGE_LIST_ELEMENT pFirstElem
  994. )
  995. /*++
  996. BuildLanguageTables
  997. Creates a list of structures that will hold the text for
  998. each supported language
  999. Arguments
  1000. lpIniFile
  1001. Filename with data
  1002. pFirstElem
  1003. pointer to first list entry
  1004. ReturnValue
  1005. TRUE if all OK
  1006. FALSE if not
  1007. --*/
  1008. {
  1009. LPTSTR lpEnumeratedLangs = NULL;
  1010. LPTSTR lpThisLang = NULL;
  1011. PLANGUAGE_LIST_ELEMENT pThisElem;
  1012. PLANGUAGE_LIST_ELEMENT pPrevElem;
  1013. DWORD dwSize;
  1014. BOOL bReturn = FALSE;
  1015. if (lpIniFile == NULL || pFirstElem == NULL) {
  1016. SetLastError (ERROR_INVALID_PARAMETER);
  1017. goto Cleanup;
  1018. }
  1019. lpEnumeratedLangs = MemoryAllocate(SMALL_BUFFER_SIZE * sizeof(TCHAR));
  1020. if (!lpEnumeratedLangs) {
  1021. SetLastError (ERROR_OUTOFMEMORY);
  1022. goto Cleanup;
  1023. }
  1024. dwSize = GetPrivateProfileString (
  1025. szLanguages,
  1026. NULL, // return all values in multi-sz string
  1027. sz009, // english as the default
  1028. lpEnumeratedLangs,
  1029. SMALL_BUFFER_SIZE,
  1030. lpIniFile);
  1031. // do first language
  1032. lpThisLang = lpEnumeratedLangs;
  1033. pThisElem = NULL;
  1034. pPrevElem = NULL;
  1035. while (*lpThisLang) {
  1036. //
  1037. // see if this language is supporte on this machine
  1038. //
  1039. if (pThisElem == NULL) {
  1040. pThisElem = pPrevElem = pFirstElem;
  1041. } else {
  1042. pThisElem->pNextLang = MemoryAllocate (sizeof(LANGUAGE_LIST_ELEMENT));
  1043. if (!pThisElem->pNextLang) {
  1044. SetLastError (ERROR_OUTOFMEMORY);
  1045. goto Cleanup;
  1046. }
  1047. pPrevElem = pThisElem;
  1048. pThisElem = pThisElem->pNextLang; // point to new one
  1049. }
  1050. pThisElem->pNextLang = NULL;
  1051. pThisElem->LangId = (LPTSTR) MemoryAllocate ((lstrlen(lpThisLang) + 1) * sizeof(TCHAR));
  1052. if (pThisElem->LangId == NULL) {
  1053. if (pThisElem == pFirstElem) {
  1054. pThisElem = pPrevElem = NULL;
  1055. }
  1056. else {
  1057. MemoryFree(pThisElem);
  1058. pThisElem = pPrevElem;
  1059. pThisElem->pNextLang = NULL;
  1060. }
  1061. SetLastError(ERROR_OUTOFMEMORY);
  1062. goto Cleanup;
  1063. }
  1064. lstrcpy (pThisElem->LangId, lpThisLang);
  1065. pThisElem->pFirstName = NULL;
  1066. pThisElem->pThisName = NULL;
  1067. pThisElem->dwNumElements=0;
  1068. pThisElem->NameBuffer = NULL;
  1069. pThisElem->HelpBuffer = NULL;
  1070. pThisElem->dwNameBuffSize = 0;
  1071. pThisElem->dwHelpBuffSize = 0;
  1072. TRACE((WINPERF_DBG_TRACE_INFO),
  1073. (& LoadPerfGuid,
  1074. __LINE__,
  1075. LOADPERF_BUILDLANGUAGETABLES,
  1076. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  1077. ERROR_SUCCESS,
  1078. TRACE_WSTR(lpIniFile),
  1079. TRACE_WSTR(pThisElem->LangId),
  1080. NULL));
  1081. // go to next string
  1082. lpThisLang += lstrlen(lpThisLang) + 1;
  1083. }
  1084. if (pThisElem == NULL) {
  1085. // then no languages were found
  1086. SetLastError (ERROR_RESOURCE_LANG_NOT_FOUND);
  1087. } else {
  1088. bReturn = TRUE;
  1089. }
  1090. Cleanup:
  1091. if (! bReturn) {
  1092. TRACE((WINPERF_DBG_TRACE_ERROR),
  1093. (& LoadPerfGuid,
  1094. __LINE__,
  1095. LOADPERF_BUILDLANGUAGETABLES,
  1096. ARG_DEF(ARG_TYPE_WSTR, 1),
  1097. GetLastError(),
  1098. TRACE_WSTR(lpThisLang),
  1099. NULL));
  1100. }
  1101. if (lpEnumeratedLangs != NULL) {
  1102. MemoryFree(lpEnumeratedLangs);
  1103. }
  1104. return bReturn;
  1105. }
  1106. BOOL
  1107. LoadIncludeFile (
  1108. IN LPTSTR lpIniFile,
  1109. OUT PSYMBOL_TABLE_ENTRY *pTable
  1110. )
  1111. /*++
  1112. LoadIncludeFile
  1113. Reads the include file that contains symbolic name definitions and
  1114. loads a table with the values defined
  1115. Arguments
  1116. lpIniFile
  1117. Ini file with include file name
  1118. pTable
  1119. address of pointer to table structure created
  1120. Return Value
  1121. TRUE if table read or if no table defined
  1122. FALSE if error encountere reading table
  1123. --*/
  1124. {
  1125. INT iNumArgs;
  1126. DWORD dwSize;
  1127. BOOL bReUse;
  1128. PSYMBOL_TABLE_ENTRY pThisSymbol = NULL;
  1129. LPTSTR lpIncludeFileName = NULL;
  1130. LPTSTR lpIncludeFile = NULL;
  1131. LPTSTR lpIniPath = NULL;
  1132. LPSTR lpLineBuffer = NULL;
  1133. LPSTR lpAnsiSymbol = NULL;
  1134. TCHAR szIniDrive[_MAX_DRIVE];
  1135. TCHAR szIniDir[_MAX_DIR];
  1136. FILE * fIncludeFile = NULL;
  1137. DWORD dwLen;
  1138. BOOL bReturn = TRUE;
  1139. lpIncludeFileName = MemoryAllocate (MAX_PATH * sizeof (TCHAR));
  1140. lpIncludeFile = MemoryAllocate (MAX_PATH * sizeof(TCHAR));
  1141. lpLineBuffer = MemoryAllocate (DISP_BUFF_SIZE);
  1142. lpAnsiSymbol = MemoryAllocate (DISP_BUFF_SIZE);
  1143. lpIniPath = MemoryAllocate (MAX_PATH * sizeof (TCHAR));
  1144. if (!lpIncludeFileName || !lpLineBuffer || !lpAnsiSymbol || !lpIniPath) {
  1145. ReportLoadPerfEvent(
  1146. EVENTLOG_ERROR_TYPE, // error type
  1147. (DWORD) LDPRFMSG_MEMORY_ALLOCATION_FAILURE, // event,
  1148. 1, __LINE__, 0, 0, 0,
  1149. 0, NULL, NULL, NULL);
  1150. SetLastError (ERROR_OUTOFMEMORY);
  1151. bReturn = FALSE;
  1152. goto Cleanup;
  1153. }
  1154. // get name of include file (if present)
  1155. dwSize = GetPrivateProfileString (
  1156. szInfo,
  1157. szSymbolFile,
  1158. szNotFound,
  1159. lpIncludeFileName,
  1160. MAX_PATH,
  1161. lpIniFile);
  1162. TRACE((WINPERF_DBG_TRACE_INFO),
  1163. (& LoadPerfGuid,
  1164. __LINE__,
  1165. LOADPERF_LOADINCLUDEFILE,
  1166. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  1167. ERROR_SUCCESS,
  1168. TRACE_WSTR(lpIniFile),
  1169. TRACE_WSTR(lpIncludeFileName),
  1170. NULL));
  1171. if (lstrcmpi(lpIncludeFileName, szNotFound) == 0) {
  1172. // no symbol file defined
  1173. * pTable = NULL;
  1174. bReturn = TRUE;
  1175. goto Cleanup;
  1176. }
  1177. // if here, then a symbol file was defined and is now stored in
  1178. // lpIncludeFileName
  1179. // get path for the ini file and search that first
  1180. _tsplitpath (lpIniFile, szIniDrive, szIniDir, NULL, NULL);
  1181. lpIniPath = lstrcpy (lpIniPath, szIniDrive);
  1182. lpIniPath = lstrcat (lpIniPath, szIniDir);
  1183. dwLen = SearchPath(lpIniPath, lpIncludeFileName, NULL,
  1184. MAX_PATH, lpIncludeFile, NULL);
  1185. if (dwLen == 0) {
  1186. // include file not found with the ini file so search the std. path
  1187. dwLen = SearchPath(NULL, lpIncludeFileName, NULL,
  1188. MAX_PATH, lpIncludeFile, NULL);
  1189. }
  1190. if (dwLen > 0) {
  1191. // file name expanded and found so open
  1192. fIncludeFile = _tfopen (lpIncludeFile, (LPCTSTR)TEXT("rt"));
  1193. if (fIncludeFile == NULL) {
  1194. OUTPUT_MESSAGE (GetFormatResource(LC_ERR_OPEN_INCLUDE), lpIncludeFileName);
  1195. *pTable = NULL;
  1196. SetLastError (ERROR_OPEN_FAILED);
  1197. bReturn = FALSE;
  1198. TRACE((WINPERF_DBG_TRACE_INFO),
  1199. (& LoadPerfGuid,
  1200. __LINE__,
  1201. LOADPERF_LOADINCLUDEFILE,
  1202. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  1203. ERROR_OPEN_FAILED,
  1204. TRACE_WSTR(lpIniFile),
  1205. TRACE_WSTR(lpIncludeFile),
  1206. NULL));
  1207. goto Cleanup;
  1208. }
  1209. } else {
  1210. // unable to find the include filename
  1211. // error is already in GetLastError
  1212. OUTPUT_MESSAGE (GetFormatResource(LC_ERR_OPEN_INCLUDE), lpIncludeFileName);
  1213. *pTable = NULL;
  1214. SetLastError (ERROR_BAD_PATHNAME);
  1215. bReturn = FALSE;
  1216. TRACE((WINPERF_DBG_TRACE_INFO),
  1217. (& LoadPerfGuid,
  1218. __LINE__,
  1219. LOADPERF_LOADINCLUDEFILE,
  1220. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  1221. ERROR_BAD_PATHNAME,
  1222. TRACE_WSTR(lpIniFile),
  1223. TRACE_WSTR(lpIncludeFileName),
  1224. NULL));
  1225. goto Cleanup;
  1226. }
  1227. //
  1228. // read ANSI Characters from include file
  1229. //
  1230. bReUse = FALSE;
  1231. while (fgets(lpLineBuffer, DISP_BUFF_SIZE, fIncludeFile) != NULL) {
  1232. if (strlen(lpLineBuffer) > 8) {
  1233. if (!bReUse) {
  1234. if (*pTable) {
  1235. // then add to list
  1236. pThisSymbol->pNext = MemoryAllocate (sizeof (SYMBOL_TABLE_ENTRY));
  1237. pThisSymbol = pThisSymbol->pNext;
  1238. } else { // allocate first element
  1239. *pTable = MemoryAllocate (sizeof (SYMBOL_TABLE_ENTRY));
  1240. pThisSymbol = *pTable;
  1241. }
  1242. if (!pThisSymbol) {
  1243. SetLastError (ERROR_OUTOFMEMORY);
  1244. bReturn = FALSE;
  1245. goto Cleanup;
  1246. }
  1247. // allocate room for the symbol name by using the line length
  1248. // - the size of "#define "
  1249. // pThisSymbol->SymbolName = MemoryAllocate ((strlen(lpLineBuffer) - 8) * sizeof (TCHAR));
  1250. pThisSymbol->SymbolName = MemoryAllocate (DISP_BUFF_SIZE * sizeof (TCHAR));
  1251. if (!pThisSymbol->SymbolName) {
  1252. SetLastError (ERROR_OUTOFMEMORY);
  1253. bReturn = FALSE;
  1254. goto Cleanup;
  1255. }
  1256. }
  1257. // all the memory is allocated so load the fields
  1258. pThisSymbol->pNext = NULL;
  1259. iNumArgs = sscanf (lpLineBuffer, "#define %s %d",
  1260. lpAnsiSymbol, &pThisSymbol->Value);
  1261. if (iNumArgs != 2) {
  1262. *(pThisSymbol->SymbolName) = 0;
  1263. pThisSymbol->Value = (DWORD)-1L;
  1264. bReUse = TRUE;
  1265. } else {
  1266. // OemToChar (lpAnsiSymbol, pThisSymbol->SymbolName);
  1267. mbstowcs (pThisSymbol->SymbolName,
  1268. lpAnsiSymbol, lstrlenA(lpAnsiSymbol)+1);
  1269. TRACE((WINPERF_DBG_TRACE_INFO),
  1270. (& LoadPerfGuid,
  1271. __LINE__,
  1272. LOADPERF_LOADINCLUDEFILE,
  1273. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  1274. ERROR_SUCCESS,
  1275. TRACE_WSTR(lpIncludeFileName),
  1276. TRACE_WSTR(pThisSymbol->SymbolName),
  1277. TRACE_DWORD(pThisSymbol->Value),
  1278. NULL));
  1279. bReUse = FALSE;
  1280. }
  1281. }
  1282. }
  1283. Cleanup:
  1284. if (! bReturn) {
  1285. TRACE((WINPERF_DBG_TRACE_ERROR),
  1286. (& LoadPerfGuid,
  1287. __LINE__,
  1288. LOADPERF_LOADINCLUDEFILE,
  1289. ARG_DEF(ARG_TYPE_WSTR, 1),
  1290. GetLastError(),
  1291. TRACE_WSTR(lpIniFile),
  1292. NULL));
  1293. }
  1294. if (lpIncludeFileName) MemoryFree(lpIncludeFileName);
  1295. if (lpIncludeFile) MemoryFree(lpIncludeFile);
  1296. if (lpLineBuffer) MemoryFree(lpLineBuffer);
  1297. if (lpIniPath) MemoryFree(lpIniPath);
  1298. if (fIncludeFile != NULL) fclose(fIncludeFile);
  1299. return bReturn;
  1300. }
  1301. BOOL
  1302. ParseTextId (
  1303. IN LPTSTR lpTextId,
  1304. IN PSYMBOL_TABLE_ENTRY pFirstSymbol,
  1305. OUT PDWORD pdwOffset,
  1306. OUT LPTSTR *lpLangId,
  1307. OUT PDWORD pdwType
  1308. )
  1309. /*++
  1310. ParseTextId
  1311. decodes Text Id key from .INI file
  1312. syntax for this process is:
  1313. {<DecimalNumber>} {"NAME"}
  1314. {<SymbolInTable>}_<LangIdString>_{"HELP"}
  1315. e.g. 0_009_NAME
  1316. OBJECT_1_009_HELP
  1317. Arguments
  1318. lpTextId
  1319. string to decode
  1320. pFirstSymbol
  1321. pointer to first entry in symbol table (NULL if no table)
  1322. pdwOffset
  1323. address of DWORD to recive offest value
  1324. lpLangId
  1325. address of pointer to Language Id string
  1326. (NOTE: this will point into the string lpTextID which will be
  1327. modified by this routine)
  1328. pdwType
  1329. pointer to dword that will recieve the type of string i.e.
  1330. HELP or NAME
  1331. Return Value
  1332. TRUE text Id decoded successfully
  1333. FALSE unable to decode string
  1334. NOTE: the string in lpTextID will be modified by this procedure
  1335. --*/
  1336. {
  1337. LPTSTR lpThisChar;
  1338. PSYMBOL_TABLE_ENTRY pThisSymbol;
  1339. // check for valid return arguments
  1340. if (!(pdwOffset) || !(lpLangId) || !(pdwType)) {
  1341. SetLastError (ERROR_INVALID_PARAMETER);
  1342. return FALSE;
  1343. }
  1344. // search string from right to left in order to identify the
  1345. // components of the string.
  1346. lpThisChar = lpTextId + lstrlen(lpTextId); // point to end of string
  1347. while (*lpThisChar != cUnderscore) {
  1348. lpThisChar--;
  1349. if (lpThisChar <= lpTextId) {
  1350. // underscore not found in string
  1351. SetLastError (ERROR_INVALID_DATA);
  1352. return FALSE;
  1353. }
  1354. }
  1355. // first underscore found
  1356. if ((lstrcmpi(lpThisChar, szName)) == 0) {
  1357. // name found, so set type
  1358. *pdwType = TYPE_NAME;
  1359. } else if ((lstrcmpi(lpThisChar, szHelp)) == 0) {
  1360. // help text found, so set type
  1361. *pdwType = TYPE_HELP;
  1362. } else {
  1363. // bad format
  1364. SetLastError (ERROR_INVALID_DATA);
  1365. return FALSE;
  1366. }
  1367. // set the current underscore to \0 and look for language ID
  1368. *lpThisChar-- = 0;
  1369. while (*lpThisChar != cUnderscore) {
  1370. lpThisChar--;
  1371. if (lpThisChar <= lpTextId) {
  1372. // underscore not found in string
  1373. SetLastError (ERROR_INVALID_DATA);
  1374. return FALSE;
  1375. }
  1376. }
  1377. // set lang ID string pointer to current char ('_') + 1
  1378. *lpLangId = lpThisChar + 1;
  1379. // set this underscore to a NULL and try to decode the remaining text
  1380. *lpThisChar = 0;
  1381. // see if the first part of the string is a decimal digit
  1382. if ((_stscanf (lpTextId, sz_DFormat, pdwOffset)) != 1) {
  1383. // it's not a digit, so try to decode it as a symbol in the
  1384. // loaded symbol table
  1385. for (pThisSymbol=pFirstSymbol;
  1386. pThisSymbol && *(pThisSymbol->SymbolName);
  1387. pThisSymbol = pThisSymbol->pNext) {
  1388. if ((lstrcmpi(lpTextId, pThisSymbol->SymbolName)) == 0) {
  1389. // a matching symbol was found, so insert it's value
  1390. // and return (that's all that needs to be done
  1391. *pdwOffset = pThisSymbol->Value;
  1392. return TRUE;
  1393. }
  1394. }
  1395. // if here, then no matching symbol was found, and it's not
  1396. // a number, so return an error
  1397. SetLastError (ERROR_BAD_TOKEN_TYPE);
  1398. return FALSE;
  1399. } else {
  1400. // symbol was prefixed with a decimal number
  1401. return TRUE;
  1402. }
  1403. }
  1404. PLANGUAGE_LIST_ELEMENT
  1405. FindLanguage (
  1406. IN PLANGUAGE_LIST_ELEMENT pFirstLang,
  1407. IN LPCTSTR pLangId
  1408. )
  1409. /*++
  1410. FindLanguage
  1411. searchs the list of languages and returns a pointer to the language
  1412. list entry that matches the pLangId string argument
  1413. Arguments
  1414. pFirstLang
  1415. pointer to first language list element
  1416. pLangId
  1417. pointer to text string with language ID to look up
  1418. Return Value
  1419. Pointer to matching language list entry
  1420. or NULL if no match
  1421. --*/
  1422. {
  1423. PLANGUAGE_LIST_ELEMENT pThisLang;
  1424. for (pThisLang = pFirstLang;
  1425. pThisLang;
  1426. pThisLang = pThisLang->pNextLang) {
  1427. if ((lstrcmpi(pLangId, pThisLang->LangId)) == 0) {
  1428. // match found so return pointer
  1429. return pThisLang;
  1430. }
  1431. }
  1432. return NULL; // no match found
  1433. }
  1434. BOOL
  1435. GetValue(
  1436. LPTSTR lpLocalSectionBuff,
  1437. LPTSTR lpLocalStringBuff
  1438. )
  1439. {
  1440. LPTSTR lpPosition;
  1441. BOOL bReturn = FALSE;
  1442. lpPosition = _tcschr(lpLocalSectionBuff,cEquals);
  1443. if (lpPosition) {
  1444. lpPosition++;
  1445. // make sure the "=" isn't the last char
  1446. if (*lpPosition != 0) {
  1447. //Found the "equals" sign
  1448. lstrcpy (lpLocalStringBuff,lpPosition);
  1449. } else {
  1450. // empty string, return a pseudo blank string
  1451. lstrcpy(lpLocalStringBuff, L" ");
  1452. }
  1453. bReturn = TRUE;
  1454. } else {
  1455. //ErrorFinfing the "="
  1456. // bad format
  1457. SetLastError (ERROR_INVALID_DATA);
  1458. }
  1459. return bReturn;
  1460. }
  1461. BOOL
  1462. GetValueFromIniKey (LPTSTR lpValueKey,
  1463. LPTSTR lpTextSection,
  1464. DWORD* pdwLastReadOffset,
  1465. DWORD dwTryCount,
  1466. LPTSTR lpLocalStringBuff
  1467. )
  1468. {
  1469. LPTSTR lpLocalSectionBuff;
  1470. DWORD dwIndex;
  1471. DWORD dwLastReadOffset;
  1472. BOOL bRetVal = FALSE;
  1473. if ((lpTextSection) && (lpValueKey)) {
  1474. dwLastReadOffset = *pdwLastReadOffset;
  1475. lpLocalSectionBuff = lpTextSection ;
  1476. lpLocalSectionBuff += dwLastReadOffset;
  1477. while(!(*lpLocalSectionBuff)){
  1478. dwLastReadOffset += (lstrlen(lpTextSection + dwLastReadOffset) + 1);
  1479. lpLocalSectionBuff = lpTextSection + dwLastReadOffset;
  1480. *pdwLastReadOffset = dwLastReadOffset;
  1481. }
  1482. // search next N entries in buffer for entry
  1483. // this should usually work since the file
  1484. // is scanned sequentially so it's tried first
  1485. for (dwIndex = 0;
  1486. dwIndex < dwTryCount ;
  1487. dwIndex++) {
  1488. // see if this is the correct entry
  1489. // and return it if it is
  1490. if (_tcsstr(lpLocalSectionBuff,lpValueKey)) {
  1491. bRetVal = GetValue(lpLocalSectionBuff,
  1492. lpLocalStringBuff);
  1493. //Set the lastReadOffset First
  1494. dwLastReadOffset += (lstrlen(lpTextSection + dwLastReadOffset) + 1);
  1495. *pdwLastReadOffset = dwLastReadOffset;
  1496. break; // out of the for loop
  1497. } else {
  1498. // this isn't the correct one so go to the next
  1499. // entry in the file
  1500. dwLastReadOffset += (lstrlen(lpTextSection + dwLastReadOffset) + 1);
  1501. lpLocalSectionBuff = lpTextSection + dwLastReadOffset;
  1502. *pdwLastReadOffset = dwLastReadOffset;
  1503. }
  1504. }
  1505. if (!bRetVal) {
  1506. //Cannont Find the key using lastReadOffset
  1507. //try again from the beggining of the Array
  1508. dwLastReadOffset = 0;
  1509. lpLocalSectionBuff = lpTextSection;
  1510. *pdwLastReadOffset = dwLastReadOffset;
  1511. while (*lpLocalSectionBuff != 0) {
  1512. if (_tcsstr(lpLocalSectionBuff,lpValueKey)) {
  1513. bRetVal = GetValue(lpLocalSectionBuff,
  1514. lpLocalStringBuff);
  1515. break;
  1516. } else {
  1517. // go to the next entry
  1518. dwLastReadOffset += (lstrlen(lpTextSection + dwLastReadOffset) + 1);
  1519. lpLocalSectionBuff = lpTextSection + dwLastReadOffset;
  1520. *pdwLastReadOffset = dwLastReadOffset;
  1521. }
  1522. }
  1523. }
  1524. } else {
  1525. // one or two null pointers so give up now
  1526. }
  1527. return bRetVal;
  1528. }
  1529. BOOL
  1530. AddEntryToLanguage (
  1531. PLANGUAGE_LIST_ELEMENT pLang,
  1532. LPTSTR lpValueKey,
  1533. LPTSTR lpTextSection,
  1534. DWORD *pdwLastReadOffset,
  1535. DWORD dwTryCount,
  1536. DWORD dwType,
  1537. DWORD dwOffset,
  1538. LPTSTR lpIniFile
  1539. )
  1540. /*++
  1541. AddEntryToLanguage
  1542. Add a text entry to the list of text entries for the specified language
  1543. Arguments
  1544. pLang
  1545. pointer to language structure to update
  1546. lpValueKey
  1547. value key to look up in .ini file
  1548. dwOffset
  1549. numeric offset of name in registry
  1550. lpIniFile
  1551. ini file
  1552. Return Value
  1553. TRUE if added successfully
  1554. FALSE if error
  1555. (see GetLastError for status)
  1556. --*/
  1557. {
  1558. LPTSTR lpLocalStringBuff = NULL;
  1559. DWORD dwBufferSize;
  1560. DWORD dwStatus = ERROR_SUCCESS;
  1561. BOOL bRetVal;
  1562. BOOL bReturn = FALSE;
  1563. UNREFERENCED_PARAMETER (lpIniFile);
  1564. if ( (dwType == TYPE_NAME && dwOffset < FIRST_EXT_COUNTER_INDEX)
  1565. || (dwType == TYPE_HELP && dwOffset < FIRST_EXT_HELP_INDEX)) {
  1566. ReportLoadPerfEvent(
  1567. EVENTLOG_ERROR_TYPE,
  1568. (DWORD) LDPRFMSG_CORRUPT_INDEX,
  1569. 3, dwOffset, dwType, __LINE__, 0,
  1570. 1, lpValueKey, NULL, NULL);
  1571. TRACE((WINPERF_DBG_TRACE_ERROR),
  1572. (& LoadPerfGuid,
  1573. __LINE__,
  1574. LOADPERF_ADDENTRYTOLANGUAGE,
  1575. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  1576. ERROR_BADKEY,
  1577. TRACE_WSTR(lpTextSection),
  1578. TRACE_WSTR(lpValueKey),
  1579. TRACE_DWORD(dwType),
  1580. TRACE_DWORD(dwOffset),
  1581. NULL));
  1582. dwStatus = ERROR_BADKEY;
  1583. goto Cleanup;
  1584. }
  1585. dwBufferSize = SMALL_BUFFER_SIZE * 4 * sizeof(TCHAR);
  1586. if (dwBufferSize < dwFileSize) {
  1587. dwBufferSize = dwFileSize;
  1588. }
  1589. lpLocalStringBuff = MemoryAllocate (dwBufferSize);
  1590. if (!lpLocalStringBuff) {
  1591. dwStatus = ERROR_OUTOFMEMORY;
  1592. goto Cleanup;
  1593. }
  1594. bRetVal = GetValueFromIniKey(lpValueKey,
  1595. lpTextSection,
  1596. pdwLastReadOffset,
  1597. dwTryCount,
  1598. lpLocalStringBuff);
  1599. if (!bRetVal) {
  1600. DWORD dwLastReadOffset = * pdwLastReadOffset;
  1601. TRACE((WINPERF_DBG_TRACE_ERROR),
  1602. (& LoadPerfGuid,
  1603. __LINE__,
  1604. LOADPERF_ADDENTRYTOLANGUAGE,
  1605. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  1606. ERROR_BADKEY,
  1607. TRACE_WSTR(lpTextSection),
  1608. TRACE_WSTR(lpValueKey),
  1609. TRACE_DWORD(dwLastReadOffset),
  1610. NULL));
  1611. dwStatus = ERROR_BADKEY;
  1612. goto Cleanup;
  1613. }
  1614. if ((lstrcmpi(lpLocalStringBuff, szNotFound))== 0) {
  1615. TRACE((WINPERF_DBG_TRACE_ERROR),
  1616. (& LoadPerfGuid,
  1617. __LINE__,
  1618. LOADPERF_ADDENTRYTOLANGUAGE,
  1619. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  1620. ERROR_BADKEY,
  1621. TRACE_WSTR(lpTextSection),
  1622. TRACE_WSTR(lpValueKey),
  1623. NULL));
  1624. dwStatus = ERROR_BADKEY;
  1625. goto Cleanup;
  1626. }
  1627. // key found, so load structure
  1628. if (!pLang->pThisName) {
  1629. // this is the first
  1630. pLang->pThisName =
  1631. MemoryAllocate (sizeof (NAME_ENTRY) +
  1632. (lstrlen(lpLocalStringBuff) + 1) * sizeof (TCHAR));
  1633. if (!pLang->pThisName) {
  1634. dwStatus = ERROR_OUTOFMEMORY;
  1635. goto Cleanup;
  1636. } else {
  1637. pLang->pFirstName = pLang->pThisName;
  1638. }
  1639. } else {
  1640. pLang->pThisName->pNext =
  1641. MemoryAllocate (sizeof (NAME_ENTRY) +
  1642. (lstrlen(lpLocalStringBuff) + 1) * sizeof (TCHAR));
  1643. if (!pLang->pThisName->pNext) {
  1644. dwStatus = ERROR_OUTOFMEMORY;
  1645. goto Cleanup;
  1646. } else {
  1647. pLang->pThisName = pLang->pThisName->pNext;
  1648. }
  1649. }
  1650. // pLang->pThisName now points to an uninitialized structre
  1651. pLang->pThisName->pNext = NULL;
  1652. pLang->pThisName->dwOffset = dwOffset;
  1653. pLang->pThisName->dwType = dwType;
  1654. pLang->pThisName->lpText = (LPTSTR) & (pLang->pThisName[1]);
  1655. lstrcpy (pLang->pThisName->lpText, lpLocalStringBuff);
  1656. bReturn = TRUE;
  1657. Cleanup:
  1658. if (lpLocalStringBuff != NULL) MemoryFree (lpLocalStringBuff);
  1659. SetLastError(dwStatus);
  1660. return (bReturn);
  1661. }
  1662. BOOL
  1663. CreateObjectList (
  1664. IN LPTSTR lpIniFile,
  1665. IN DWORD dwFirstDriverCounter,
  1666. IN PSYMBOL_TABLE_ENTRY pFirstSymbol,
  1667. IN LPTSTR lpszObjectList,
  1668. IN PPERFOBJECT_LOOKUP pObjectGuidTable,
  1669. IN LPDWORD pdwObjectGuidTableEntries
  1670. )
  1671. {
  1672. TCHAR szDigits[32];
  1673. LPTSTR szLangId;
  1674. TCHAR szTempString[256];
  1675. LPWSTR szGuidStringBuffer;
  1676. LPTSTR szThisKey;
  1677. DWORD dwSize;
  1678. DWORD dwObjectCount = 0;
  1679. DWORD dwId;
  1680. DWORD dwType;
  1681. DWORD dwObjectGuidIndex = 0;
  1682. DWORD dwBufferSize = dwFileSize;
  1683. LPTSTR szObjectSectionEntries = NULL;
  1684. BOOL bResult = TRUE;
  1685. if (dwBufferSize < MAX_PROFILE_BUFFER * sizeof(TCHAR)) {
  1686. dwBufferSize = MAX_PROFILE_BUFFER * sizeof(TCHAR);
  1687. }
  1688. szObjectSectionEntries = MemoryAllocate(dwBufferSize);
  1689. if (szObjectSectionEntries == NULL) {
  1690. SetLastError(ERROR_OUTOFMEMORY);
  1691. bResult = FALSE;
  1692. goto Cleanup;
  1693. }
  1694. ZeroMemory(szObjectSectionEntries, dwBufferSize);
  1695. szThisKey = & szObjectSectionEntries[0];
  1696. dwSize = GetPrivateProfileString (
  1697. szObjects,
  1698. NULL,
  1699. szNotFound,
  1700. szObjectSectionEntries,
  1701. dwBufferSize / sizeof(TCHAR),
  1702. lpIniFile);
  1703. * lpszObjectList = 0;
  1704. if (lstrcmp(szObjectSectionEntries, szNotFound) != 0) {
  1705. // then some entries were found so read each one, compute the
  1706. // index value and save in the string buffer passed by the caller
  1707. for (szThisKey = szObjectSectionEntries;
  1708. *szThisKey != 0;
  1709. szThisKey += lstrlen(szThisKey) + 1) {
  1710. // ParstTextId modifies the string so we need to make a work copy
  1711. lstrcpy (szTempString, szThisKey);
  1712. if (ParseTextId(szTempString, pFirstSymbol, &dwId, &szLangId, &dwType)) {
  1713. // then dwID is the id of an object supported by this DLL
  1714. if (dwObjectCount != 0) {
  1715. lstrcat (lpszObjectList, szSpace);
  1716. }
  1717. _ultot ((dwId + dwFirstDriverCounter), szDigits, 10);
  1718. lstrcat (lpszObjectList, szDigits);
  1719. //
  1720. // now see if this object has a GUID string
  1721. //
  1722. szGuidStringBuffer = MemoryAllocate(1024);
  1723. if (szGuidStringBuffer == NULL) {
  1724. // cannot allocate memory for szGuidStringBuffer, ignore
  1725. // and continue the next one.
  1726. //
  1727. dwObjectCount ++;
  1728. continue;
  1729. }
  1730. dwSize = GetPrivateProfileStringW (
  1731. szObjects,
  1732. szThisKey,
  1733. szNotFound,
  1734. szGuidStringBuffer,
  1735. 1024,
  1736. lpIniFile);
  1737. if (dwSize > 0) {
  1738. if (lstrcmpW (szGuidStringBuffer, szNotFound) != 0) {
  1739. // then some string is present, so see if
  1740. // it looks like a GUID
  1741. if ((szGuidStringBuffer[0] == L'{') &&
  1742. (szGuidStringBuffer[9] == L'-') &&
  1743. (szGuidStringBuffer[14] == L'-') &&
  1744. (szGuidStringBuffer[19] == L'-') &&
  1745. (szGuidStringBuffer[24] == L'-') &&
  1746. (szGuidStringBuffer[37] == L'}')) {
  1747. // then it's probably a GUID so store it
  1748. szGuidStringBuffer = MemoryResize (szGuidStringBuffer,
  1749. (dwSize + 1) * sizeof(WCHAR));
  1750. if (szGuidStringBuffer == NULL) {
  1751. // cannot reallocate memory for
  1752. // szGuidStringBuffer, ignore and continue
  1753. // the next one.
  1754. //
  1755. continue;
  1756. }
  1757. if (dwObjectGuidIndex < *pdwObjectGuidTableEntries) {
  1758. pObjectGuidTable[dwObjectGuidIndex].PerfObjectId =
  1759. dwId + dwFirstDriverCounter;
  1760. pObjectGuidTable[dwObjectGuidIndex].GuidString =
  1761. szGuidStringBuffer;
  1762. dwObjectGuidIndex++;
  1763. TRACE((WINPERF_DBG_TRACE_INFO),
  1764. (& LoadPerfGuid,
  1765. __LINE__,
  1766. LOADPERF_CREATEOBJECTLIST,
  1767. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  1768. ERROR_SUCCESS,
  1769. TRACE_WSTR(lpIniFile),
  1770. TRACE_WSTR(szGuidStringBuffer),
  1771. TRACE_DWORD(dwObjectGuidIndex),
  1772. NULL));
  1773. } else {
  1774. // table is full
  1775. }
  1776. } else {
  1777. // not a GUID so ignore
  1778. }
  1779. } else {
  1780. // no string after object reference
  1781. }
  1782. }
  1783. dwObjectCount++;
  1784. } else {
  1785. // invalid key format
  1786. }
  1787. }
  1788. // save size of Guid Table
  1789. *pdwObjectGuidTableEntries = dwObjectGuidIndex;
  1790. } else {
  1791. // log message that object list is not used
  1792. TRACE((WINPERF_DBG_TRACE_WARNING),
  1793. (& LoadPerfGuid,
  1794. __LINE__,
  1795. LOADPERF_CREATEOBJECTLIST,
  1796. ARG_DEF(ARG_TYPE_WSTR, 1),
  1797. ERROR_SUCCESS,
  1798. TRACE_WSTR(lpIniFile),
  1799. TRACE_DWORD(dwFirstDriverCounter),
  1800. NULL));
  1801. }
  1802. Cleanup:
  1803. if (szObjectSectionEntries != NULL) {
  1804. MemoryFree(szObjectSectionEntries);
  1805. }
  1806. return bResult;
  1807. }
  1808. BOOL
  1809. LoadLanguageLists (
  1810. IN LPTSTR lpIniFile,
  1811. IN DWORD dwFirstCounter,
  1812. IN DWORD dwFirstHelp,
  1813. IN PSYMBOL_TABLE_ENTRY pFirstSymbol,
  1814. IN PLANGUAGE_LIST_ELEMENT pFirstLang
  1815. )
  1816. /*++
  1817. LoadLanguageLists
  1818. Reads in the name and explain text definitions from the ini file and
  1819. builds a list of these items for each of the supported languages and
  1820. then combines all the entries into a sorted MULTI_SZ string buffer.
  1821. Arguments
  1822. lpIniFile
  1823. file containing the definitions to add to the registry
  1824. dwFirstCounter
  1825. starting counter name index number
  1826. dwFirstHelp
  1827. starting help text index number
  1828. pFirstLang
  1829. pointer to first element in list of language elements
  1830. Return Value
  1831. TRUE if all is well
  1832. FALSE if not
  1833. error is returned in GetLastError
  1834. --*/
  1835. {
  1836. LPTSTR lpTextIdArray;
  1837. LPTSTR lpLocalKey;
  1838. LPTSTR lpThisKey;
  1839. LPTSTR lpTextSectionArray;
  1840. DWORD dwSize;
  1841. LPTSTR lpLang;
  1842. DWORD dwOffset;
  1843. DWORD dwType;
  1844. PLANGUAGE_LIST_ELEMENT pThisLang, pLangPointer=NULL;
  1845. DWORD dwBufferSize;
  1846. DWORD dwSuccessCount = 0;
  1847. DWORD dwErrorCount = 0;
  1848. DWORD dwLastReadOffset = 0;
  1849. DWORD dwTryCount = 4; //Init this value with 4 (at least 4 times to try maching Key and Value)
  1850. pLangPointer = pFirstLang;
  1851. while (pFirstLang) {
  1852. pFirstLang = pFirstLang->pNextLang;
  1853. //if you have more languages then increase this try limit to 4 + No. of langs
  1854. dwTryCount++;
  1855. }
  1856. pFirstLang = pLangPointer;
  1857. dwBufferSize = SMALL_BUFFER_SIZE * 4 * sizeof(TCHAR);
  1858. if (dwBufferSize < dwFileSize) {
  1859. dwBufferSize = dwFileSize;
  1860. }
  1861. lpTextIdArray = MemoryAllocate (dwBufferSize);
  1862. if (lpTextIdArray == NULL) {
  1863. SetLastError (ERROR_OUTOFMEMORY);
  1864. TRACE((WINPERF_DBG_TRACE_INFO),
  1865. (& LoadPerfGuid,
  1866. __LINE__,
  1867. LOADPERF_LOADLANGUAGELISTS,
  1868. ARG_DEF(ARG_TYPE_WSTR, 1),
  1869. ERROR_OUTOFMEMORY,
  1870. TRACE_WSTR(lpIniFile),
  1871. TRACE_DWORD(dwFirstCounter),
  1872. TRACE_DWORD(dwFirstHelp),
  1873. NULL));
  1874. return FALSE;
  1875. }
  1876. lpLocalKey = MemoryAllocate (MAX_PATH * sizeof(TCHAR));
  1877. if (lpLocalKey == NULL) {
  1878. SetLastError (ERROR_OUTOFMEMORY);
  1879. if (lpTextIdArray) MemoryFree (lpTextIdArray);
  1880. TRACE((WINPERF_DBG_TRACE_INFO),
  1881. (& LoadPerfGuid,
  1882. __LINE__,
  1883. LOADPERF_LOADLANGUAGELISTS,
  1884. ARG_DEF(ARG_TYPE_WSTR, 1),
  1885. ERROR_OUTOFMEMORY,
  1886. TRACE_WSTR(lpIniFile),
  1887. TRACE_DWORD(dwFirstCounter),
  1888. TRACE_DWORD(dwFirstHelp),
  1889. NULL));
  1890. return FALSE;
  1891. }
  1892. lpTextSectionArray = MemoryAllocate (dwBufferSize);
  1893. if (lpTextSectionArray == NULL) {
  1894. SetLastError (ERROR_OUTOFMEMORY);
  1895. if (lpTextIdArray) MemoryFree(lpTextIdArray);
  1896. if (lpLocalKey) MemoryFree(lpLocalKey);
  1897. TRACE((WINPERF_DBG_TRACE_INFO),
  1898. (& LoadPerfGuid,
  1899. __LINE__,
  1900. LOADPERF_LOADLANGUAGELISTS,
  1901. ARG_DEF(ARG_TYPE_WSTR, 1),
  1902. ERROR_OUTOFMEMORY,
  1903. TRACE_WSTR(lpIniFile),
  1904. TRACE_DWORD(dwFirstCounter),
  1905. TRACE_DWORD(dwFirstHelp),
  1906. NULL));
  1907. return FALSE;
  1908. }
  1909. TRACE((WINPERF_DBG_TRACE_INFO),
  1910. (& LoadPerfGuid,
  1911. __LINE__,
  1912. LOADPERF_LOADLANGUAGELISTS,
  1913. ARG_DEF(ARG_TYPE_WSTR, 1),
  1914. ERROR_SUCCESS,
  1915. TRACE_WSTR(lpIniFile),
  1916. TRACE_DWORD(dwFirstCounter),
  1917. TRACE_DWORD(dwFirstHelp),
  1918. NULL));
  1919. // get list of text keys to look up
  1920. dwSize = GetPrivateProfileString (
  1921. szText, // [text] section of .INI file
  1922. NULL, // return all keys
  1923. szNotFound,
  1924. lpTextIdArray, // return buffer
  1925. dwBufferSize / sizeof(TCHAR),
  1926. lpIniFile); // .INI file name
  1927. if ((lstrcmpi(lpTextIdArray, szNotFound)) == 0) {
  1928. // key not found, default returned
  1929. SetLastError (ERROR_NO_SUCH_GROUP);
  1930. if (lpTextIdArray) MemoryFree(lpTextIdArray);
  1931. if (lpLocalKey) MemoryFree(lpLocalKey);
  1932. if (lpTextSectionArray) MemoryFree(lpTextSectionArray);
  1933. TRACE((WINPERF_DBG_TRACE_INFO),
  1934. (& LoadPerfGuid,
  1935. __LINE__,
  1936. LOADPERF_LOADLANGUAGELISTS,
  1937. ARG_DEF(ARG_TYPE_WSTR, 1),
  1938. ERROR_NO_SUCH_GROUP,
  1939. TRACE_WSTR(lpIniFile),
  1940. TRACE_DWORD(dwFirstCounter),
  1941. TRACE_DWORD(dwFirstHelp),
  1942. NULL));
  1943. return FALSE;
  1944. }
  1945. // get the the [text] section from the ini file
  1946. dwSize = GetPrivateProfileSection (
  1947. szText, // [text] section of .INI file
  1948. lpTextSectionArray, // return buffer
  1949. dwBufferSize / sizeof(TCHAR),
  1950. lpIniFile); // .INI file name
  1951. // do each key returned
  1952. for (lpThisKey=lpTextIdArray;
  1953. * lpThisKey;
  1954. lpThisKey += (lstrlen(lpThisKey) + 1)) {
  1955. lstrcpy (lpLocalKey, lpThisKey); // make a copy of the key
  1956. // parse key to see if it's in the correct format
  1957. if (ParseTextId(lpLocalKey, pFirstSymbol, &dwOffset, &lpLang, &dwType)) {
  1958. // so get pointer to language entry structure
  1959. pThisLang = FindLanguage (pFirstLang, lpLang);
  1960. if (pThisLang) {
  1961. if (!AddEntryToLanguage(pThisLang,
  1962. lpThisKey,
  1963. lpTextSectionArray,
  1964. & dwLastReadOffset,
  1965. dwTryCount,
  1966. dwType,
  1967. (dwOffset + ( (dwType == TYPE_NAME)
  1968. ? dwFirstCounter
  1969. : dwFirstHelp)),
  1970. lpIniFile)) {
  1971. OUTPUT_MESSAGE (GetFormatResource (LC_ERRADDTOLANG),
  1972. lpThisKey,
  1973. lpLang,
  1974. GetLastError());
  1975. dwErrorCount ++;
  1976. } else {
  1977. dwSuccessCount ++;
  1978. }
  1979. TRACE((WINPERF_DBG_TRACE_INFO),
  1980. (& LoadPerfGuid,
  1981. __LINE__,
  1982. LOADPERF_LOADLANGUAGELISTS,
  1983. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  1984. ERROR_SUCCESS,
  1985. TRACE_WSTR(lpThisKey),
  1986. TRACE_WSTR(lpLang),
  1987. TRACE_DWORD(dwOffset),
  1988. TRACE_DWORD(dwType),
  1989. NULL));
  1990. } else { // language not in list
  1991. OUTPUT_MESSAGE (GetFormatResource(LC_LANGNOTFOUND), lpLang, lpThisKey);
  1992. TRACE((WINPERF_DBG_TRACE_INFO),
  1993. (& LoadPerfGuid,
  1994. __LINE__,
  1995. LOADPERF_LOADLANGUAGELISTS,
  1996. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  1997. ERROR_SUCCESS,
  1998. TRACE_WSTR(lpThisKey),
  1999. TRACE_WSTR(lpLang),
  2000. NULL));
  2001. }
  2002. } else { // unable to parse ID string
  2003. OUTPUT_MESSAGE(GetFormatResource(LC_BAD_KEY), lpThisKey);
  2004. TRACE((WINPERF_DBG_TRACE_ERROR),
  2005. (& LoadPerfGuid,
  2006. __LINE__,
  2007. LOADPERF_LOADLANGUAGELISTS,
  2008. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  2009. ERROR_BADKEY,
  2010. TRACE_WSTR(lpThisKey),
  2011. TRACE_WSTR(lpLang),
  2012. NULL));
  2013. }
  2014. }
  2015. if (lpTextIdArray) MemoryFree(lpTextIdArray);
  2016. if (lpLocalKey) MemoryFree(lpLocalKey);
  2017. if (lpTextSectionArray) MemoryFree(lpTextSectionArray);
  2018. return (BOOL) (dwErrorCount == 0);
  2019. }
  2020. BOOL
  2021. SortLanguageTables (
  2022. PLANGUAGE_LIST_ELEMENT pFirstLang,
  2023. PDWORD pdwLastName,
  2024. PDWORD pdwLastHelp
  2025. )
  2026. /*++
  2027. SortLangageTables
  2028. walks list of languages loaded, allocates and loads a sorted multi_SZ
  2029. buffer containing new entries to be added to current names/help text
  2030. Arguments
  2031. pFirstLang
  2032. pointer to first element in list of languages
  2033. ReturnValue
  2034. TRUE everything done as expected
  2035. FALSE error occurred, status in GetLastError
  2036. --*/
  2037. {
  2038. PLANGUAGE_LIST_ELEMENT pThisLang;
  2039. BOOL bSorted;
  2040. LPTSTR pNameBufPos, pHelpBufPos;
  2041. PNAME_ENTRY pThisName, pPrevName;
  2042. DWORD dwHelpSize, dwNameSize, dwSize;
  2043. DWORD dwCurrentLastName;
  2044. DWORD dwCurrentLastHelp;
  2045. if (!pdwLastName || !pdwLastHelp) {
  2046. SetLastError (ERROR_BAD_ARGUMENTS);
  2047. TRACE((WINPERF_DBG_TRACE_INFO),
  2048. (& LoadPerfGuid,
  2049. __LINE__,
  2050. LOADPERF_SORTLANGUAGETABLES,
  2051. 0,
  2052. ERROR_BAD_ARGUMENTS,
  2053. NULL));
  2054. return FALSE;
  2055. }
  2056. for (pThisLang = pFirstLang;
  2057. pThisLang;
  2058. pThisLang = pThisLang->pNextLang) {
  2059. // do each language in list
  2060. // sort elements in list by value (offset) so that lowest is first
  2061. if (pThisLang->pFirstName == NULL) {
  2062. // no elements in this list, continue the next one
  2063. continue;
  2064. }
  2065. bSorted = FALSE;
  2066. while (!bSorted ) {
  2067. // point to start of list
  2068. pPrevName = pThisLang->pFirstName;
  2069. if (pPrevName) {
  2070. pThisName = pPrevName->pNext;
  2071. } else {
  2072. break; // no elements in this list
  2073. }
  2074. if (!pThisName) {
  2075. break; // only one element in the list
  2076. }
  2077. bSorted = TRUE; // assume that it's sorted
  2078. // go until end of list
  2079. while (pThisName->pNext) {
  2080. if (pThisName->dwOffset > pThisName->pNext->dwOffset) {
  2081. // switch 'em
  2082. PNAME_ENTRY pA, pB;
  2083. pPrevName->pNext = pThisName->pNext;
  2084. pA = pThisName->pNext;
  2085. pB = pThisName->pNext->pNext;
  2086. pThisName->pNext = pB;
  2087. pA->pNext = pThisName;
  2088. pThisName = pA;
  2089. bSorted = FALSE;
  2090. }
  2091. //move to next entry
  2092. pPrevName = pThisName;
  2093. pThisName = pThisName->pNext;
  2094. }
  2095. // if bSorted = TRUE , then we walked all the way down
  2096. // the list without changing anything so that's the end.
  2097. }
  2098. // with the list sorted, build the MULTI_SZ strings for the
  2099. // help and name text strings
  2100. // compute buffer size
  2101. dwNameSize = dwHelpSize = 0;
  2102. dwCurrentLastName = 0;
  2103. dwCurrentLastHelp = 0;
  2104. for (pThisName = pThisLang->pFirstName;
  2105. pThisName;
  2106. pThisName = pThisName->pNext) {
  2107. // compute buffer requirements for this entry
  2108. dwSize = SIZE_OF_OFFSET_STRING;
  2109. dwSize += lstrlen (pThisName->lpText);
  2110. dwSize += 1; // null
  2111. dwSize *= sizeof (TCHAR); // adjust for character size
  2112. // add to appropriate size register
  2113. if (pThisName->dwType == TYPE_NAME) {
  2114. dwNameSize += dwSize;
  2115. if (pThisName->dwOffset > dwCurrentLastName) {
  2116. dwCurrentLastName = pThisName->dwOffset;
  2117. }
  2118. } else if (pThisName->dwType == TYPE_HELP) {
  2119. dwHelpSize += dwSize;
  2120. if (pThisName->dwOffset > dwCurrentLastHelp) {
  2121. dwCurrentLastHelp = pThisName->dwOffset;
  2122. }
  2123. }
  2124. }
  2125. // allocate buffers for the Multi_SZ strings
  2126. pThisLang->NameBuffer = MemoryAllocate (dwNameSize);
  2127. pThisLang->HelpBuffer = MemoryAllocate (dwHelpSize);
  2128. if (!pThisLang->NameBuffer || !pThisLang->HelpBuffer) {
  2129. SetLastError (ERROR_OUTOFMEMORY);
  2130. TRACE((WINPERF_DBG_TRACE_INFO),
  2131. (& LoadPerfGuid,
  2132. __LINE__,
  2133. LOADPERF_SORTLANGUAGETABLES,
  2134. ARG_DEF(ARG_TYPE_WSTR, 1),
  2135. ERROR_OUTOFMEMORY,
  2136. TRACE_WSTR(pThisLang->LangId),
  2137. TRACE_DWORD(pThisLang->dwNumElements),
  2138. TRACE_DWORD(dwCurrentLastName),
  2139. TRACE_DWORD(dwCurrentLastHelp),
  2140. NULL));
  2141. return FALSE;
  2142. }
  2143. // fill in buffers with sorted strings
  2144. pNameBufPos = (LPTSTR)pThisLang->NameBuffer;
  2145. pHelpBufPos = (LPTSTR)pThisLang->HelpBuffer;
  2146. for (pThisName = pThisLang->pFirstName;
  2147. pThisName;
  2148. pThisName = pThisName->pNext) {
  2149. if (pThisName->dwType == TYPE_NAME) {
  2150. // load number as first 0-term. string
  2151. dwSize = _stprintf (pNameBufPos, szDFormat, pThisName->dwOffset);
  2152. pNameBufPos += dwSize + 1; // save NULL term.
  2153. // load the text to match
  2154. lstrcpy (pNameBufPos, pThisName->lpText);
  2155. pNameBufPos += lstrlen(pNameBufPos) + 1;
  2156. } else if (pThisName->dwType == TYPE_HELP) {
  2157. // load number as first 0-term. string
  2158. dwSize = _stprintf (pHelpBufPos, szDFormat, pThisName->dwOffset);
  2159. pHelpBufPos += dwSize + 1; // save NULL term.
  2160. // load the text to match
  2161. lstrcpy (pHelpBufPos, pThisName->lpText);
  2162. pHelpBufPos += lstrlen(pHelpBufPos) + 1;
  2163. }
  2164. }
  2165. // add additional NULL at end of string to terminate MULTI_SZ
  2166. * pHelpBufPos = 0;
  2167. * pNameBufPos = 0;
  2168. // compute size of MULTI_SZ strings
  2169. pThisLang->dwNameBuffSize = (DWORD)((PBYTE)pNameBufPos -
  2170. (PBYTE)pThisLang->NameBuffer) +
  2171. sizeof(TCHAR);
  2172. pThisLang->dwHelpBuffSize = (DWORD)((PBYTE)pHelpBufPos -
  2173. (PBYTE)pThisLang->HelpBuffer) +
  2174. sizeof(TCHAR);
  2175. if (* pdwLastName < dwCurrentLastName) {
  2176. * pdwLastName = dwCurrentLastName;
  2177. }
  2178. if (* pdwLastHelp < dwCurrentLastHelp) {
  2179. * pdwLastHelp = dwCurrentLastHelp;
  2180. }
  2181. TRACE((WINPERF_DBG_TRACE_INFO),
  2182. (& LoadPerfGuid,
  2183. __LINE__,
  2184. LOADPERF_SORTLANGUAGETABLES,
  2185. ARG_DEF(ARG_TYPE_WSTR, 1),
  2186. ERROR_SUCCESS,
  2187. TRACE_WSTR(pThisLang->LangId),
  2188. TRACE_DWORD(pThisLang->dwNumElements),
  2189. TRACE_DWORD(dwCurrentLastName),
  2190. TRACE_DWORD(dwCurrentLastHelp),
  2191. NULL));
  2192. }
  2193. dwCurrentLastName = * pdwLastName;
  2194. dwCurrentLastHelp = * pdwLastHelp;
  2195. TRACE((WINPERF_DBG_TRACE_INFO),
  2196. (& LoadPerfGuid,
  2197. __LINE__,
  2198. LOADPERF_SORTLANGUAGETABLES,
  2199. 0,
  2200. ERROR_SUCCESS,
  2201. TRACE_DWORD(dwCurrentLastName),
  2202. TRACE_DWORD(dwCurrentLastHelp),
  2203. NULL));
  2204. return TRUE;
  2205. }
  2206. BOOL
  2207. GetInstalledLanguageList (
  2208. HKEY hPerflibRoot,
  2209. LPTSTR *mszLangList
  2210. )
  2211. /*++
  2212. returns a list of language sub keys found under the perflib key
  2213. --*/
  2214. {
  2215. BOOL bReturn = TRUE;
  2216. LONG lStatus;
  2217. DWORD dwIndex = 0;
  2218. LPTSTR szBuffer;
  2219. DWORD dwBufSize;
  2220. LPTSTR szRetBuffer = NULL;
  2221. DWORD dwRetBufSize = 0;
  2222. DWORD dwLastBufSize = 0;
  2223. LPTSTR szNextString;
  2224. dwBufSize = MAX_PATH;
  2225. szBuffer = MemoryAllocate(MAX_PATH * sizeof(TCHAR));
  2226. if (szBuffer == NULL) {
  2227. SetLastError (ERROR_OUTOFMEMORY);
  2228. bReturn = FALSE;
  2229. }
  2230. if (bReturn) {
  2231. while ((lStatus = RegEnumKeyEx (hPerflibRoot,
  2232. dwIndex, szBuffer, &dwBufSize,
  2233. NULL, NULL, NULL, NULL)) == ERROR_SUCCESS) {
  2234. TRACE((WINPERF_DBG_TRACE_INFO),
  2235. (& LoadPerfGuid,
  2236. __LINE__,
  2237. LOADPERF_GETINSTALLEDLANGUAGELIST,
  2238. ARG_DEF(ARG_TYPE_WSTR, 1),
  2239. ERROR_SUCCESS,
  2240. TRACE_WSTR(szBuffer),
  2241. TRACE_DWORD(dwIndex),
  2242. NULL));
  2243. dwRetBufSize += (lstrlen(szBuffer) + 1) * sizeof(TCHAR);
  2244. if (szRetBuffer != NULL) {
  2245. LPTSTR szTmpBuffer = szRetBuffer;
  2246. szRetBuffer = MemoryResize(szRetBuffer, dwRetBufSize);
  2247. if (szRetBuffer == NULL) {
  2248. MemoryFree(szTmpBuffer);
  2249. }
  2250. } else {
  2251. szRetBuffer = MemoryAllocate(dwRetBufSize);
  2252. }
  2253. if (szRetBuffer == NULL) {
  2254. SetLastError (ERROR_OUTOFMEMORY);
  2255. bReturn = FALSE;
  2256. TRACE((WINPERF_DBG_TRACE_INFO),
  2257. (& LoadPerfGuid,
  2258. __LINE__,
  2259. LOADPERF_GETINSTALLEDLANGUAGELIST,
  2260. ARG_DEF(ARG_TYPE_WSTR, 1),
  2261. ERROR_OUTOFMEMORY,
  2262. TRACE_WSTR(szBuffer),
  2263. TRACE_DWORD(dwIndex),
  2264. NULL));
  2265. break;
  2266. }
  2267. szNextString = (LPTSTR) ((LPBYTE) szRetBuffer + dwLastBufSize);
  2268. lstrcpy(szNextString, szBuffer);
  2269. dwLastBufSize = dwRetBufSize;
  2270. dwIndex ++;
  2271. dwBufSize = MAX_PATH;
  2272. RtlZeroMemory(szBuffer, MAX_PATH * sizeof(TCHAR));
  2273. }
  2274. }
  2275. if (bReturn) {
  2276. LPTSTR szTmpBuffer = szRetBuffer;
  2277. // add terminating null char
  2278. dwRetBufSize += sizeof (TCHAR);
  2279. if (szRetBuffer != NULL) {
  2280. szRetBuffer = MemoryResize(szRetBuffer, dwRetBufSize);
  2281. } else {
  2282. szRetBuffer = MemoryAllocate(dwRetBufSize);
  2283. }
  2284. if (szRetBuffer == NULL) {
  2285. if (szTmpBuffer != NULL) MemoryFree(szTmpBuffer);
  2286. SetLastError (ERROR_OUTOFMEMORY);
  2287. bReturn = FALSE;
  2288. }
  2289. else {
  2290. szNextString = (LPTSTR) ((LPBYTE) szRetBuffer + dwLastBufSize);
  2291. * szNextString = _T('\0');
  2292. }
  2293. }
  2294. if (bReturn) {
  2295. * mszLangList = szRetBuffer;
  2296. }
  2297. else {
  2298. * mszLangList = NULL;
  2299. MemoryFree(szRetBuffer);
  2300. }
  2301. return bReturn;
  2302. }
  2303. BOOL
  2304. CheckNameTable(
  2305. LPTSTR lpNameStr,
  2306. LPTSTR lpHelpStr,
  2307. LPDWORD pdwLastCounter,
  2308. LPDWORD pdwLastHelp,
  2309. BOOL bUpdate
  2310. )
  2311. {
  2312. BOOL bResult = TRUE;
  2313. BOOL bChanged = FALSE;
  2314. LPTSTR lpThisId;
  2315. DWORD dwThisId;
  2316. DWORD dwLastCounter = * pdwLastCounter;
  2317. DWORD dwLastHelp = * pdwLastHelp;
  2318. DWORD dwLastId = (dwLastCounter > dwLastHelp)
  2319. ? (dwLastCounter) : (dwLastHelp);
  2320. TRACE((WINPERF_DBG_TRACE_INFO),
  2321. (& LoadPerfGuid,
  2322. __LINE__,
  2323. LOADPERF_CHECKNAMETABLE,
  2324. 0,
  2325. ERROR_SUCCESS,
  2326. TRACE_DWORD(dwLastCounter),
  2327. TRACE_DWORD(dwLastHelp),
  2328. NULL));
  2329. for (lpThisId = lpNameStr;
  2330. * lpThisId;
  2331. lpThisId += (lstrlen(lpThisId) + 1)) {
  2332. dwThisId = _tcstoul(lpThisId, NULL, 10);
  2333. if ((dwThisId == 0) || (dwThisId != 1 && dwThisId % 2 != 0)) {
  2334. ReportLoadPerfEvent(
  2335. EVENTLOG_ERROR_TYPE, // error type
  2336. (DWORD) LDPRFMSG_REGISTRY_COUNTER_STRINGS_CORRUPT,
  2337. 4, dwThisId, dwLastCounter, dwLastId, __LINE__,
  2338. 1, lpThisId, NULL, NULL);
  2339. TRACE((WINPERF_DBG_TRACE_ERROR),
  2340. (& LoadPerfGuid,
  2341. __LINE__,
  2342. LOADPERF_CHECKNAMETABLE,
  2343. ARG_DEF(ARG_TYPE_WSTR, 1),
  2344. ERROR_BADKEY,
  2345. TRACE_WSTR(lpThisId),
  2346. TRACE_DWORD(dwThisId),
  2347. TRACE_DWORD(dwLastCounter),
  2348. TRACE_DWORD(dwLastHelp),
  2349. NULL));
  2350. SetLastError(ERROR_BADKEY);
  2351. bResult = FALSE;
  2352. break;
  2353. }
  2354. else if (dwThisId > dwLastId || dwThisId > dwLastCounter) {
  2355. if (bUpdate) {
  2356. ReportLoadPerfEvent(
  2357. EVENTLOG_ERROR_TYPE, // error type
  2358. (DWORD) LDPRFMSG_REGISTRY_COUNTER_STRINGS_CORRUPT,
  2359. 4, dwThisId, dwLastCounter, dwLastId, __LINE__,
  2360. 1, lpThisId, NULL, NULL);
  2361. TRACE((WINPERF_DBG_TRACE_ERROR),
  2362. (& LoadPerfGuid,
  2363. __LINE__,
  2364. LOADPERF_CHECKNAMETABLE,
  2365. ARG_DEF(ARG_TYPE_WSTR, 1),
  2366. ERROR_BADKEY,
  2367. TRACE_WSTR(lpThisId),
  2368. TRACE_DWORD(dwThisId),
  2369. TRACE_DWORD(dwLastCounter),
  2370. TRACE_DWORD(dwLastHelp),
  2371. NULL));
  2372. SetLastError(ERROR_BADKEY);
  2373. bResult = FALSE;
  2374. break;
  2375. }
  2376. else {
  2377. bChanged = TRUE;
  2378. if (dwThisId > dwLastCounter) dwLastCounter = dwThisId;
  2379. if (dwLastCounter > dwLastId) dwLastId = dwLastCounter;
  2380. }
  2381. }
  2382. lpThisId += (lstrlen(lpThisId) + 1);
  2383. }
  2384. if (! bResult) goto Cleanup;
  2385. for (lpThisId = lpHelpStr;
  2386. * lpThisId;
  2387. lpThisId += (lstrlen(lpThisId) + 1)) {
  2388. dwThisId = _tcstoul(lpThisId, NULL, 10);
  2389. if ((dwThisId == 0) || (dwThisId != 1 && dwThisId % 2 == 0)) {
  2390. ReportLoadPerfEvent(
  2391. EVENTLOG_ERROR_TYPE, // error type
  2392. (DWORD) LDPRFMSG_REGISTRY_HELP_STRINGS_CORRUPT,
  2393. 4, dwThisId, dwLastHelp, dwLastId, __LINE__,
  2394. 1, lpThisId, NULL, NULL);
  2395. TRACE((WINPERF_DBG_TRACE_ERROR),
  2396. (& LoadPerfGuid,
  2397. __LINE__,
  2398. LOADPERF_CHECKNAMETABLE,
  2399. ARG_DEF(ARG_TYPE_WSTR, 1),
  2400. ERROR_BADKEY,
  2401. TRACE_WSTR(lpThisId),
  2402. TRACE_DWORD(dwThisId),
  2403. TRACE_DWORD(dwLastCounter),
  2404. TRACE_DWORD(dwLastHelp),
  2405. NULL));
  2406. SetLastError(ERROR_BADKEY);
  2407. bResult = FALSE;
  2408. break;
  2409. }
  2410. else if (dwThisId > dwLastId || dwThisId > dwLastHelp) {
  2411. if (bUpdate) {
  2412. ReportLoadPerfEvent(
  2413. EVENTLOG_ERROR_TYPE, // error type
  2414. (DWORD) LDPRFMSG_REGISTRY_HELP_STRINGS_CORRUPT,
  2415. 4, dwThisId, dwLastHelp, dwLastId, __LINE__,
  2416. 1, lpThisId, NULL, NULL);
  2417. TRACE((WINPERF_DBG_TRACE_ERROR),
  2418. (& LoadPerfGuid,
  2419. __LINE__,
  2420. LOADPERF_CHECKNAMETABLE,
  2421. ARG_DEF(ARG_TYPE_WSTR, 1),
  2422. ERROR_BADKEY,
  2423. TRACE_WSTR(lpThisId),
  2424. TRACE_DWORD(dwThisId),
  2425. TRACE_DWORD(dwLastCounter),
  2426. TRACE_DWORD(dwLastHelp),
  2427. NULL));
  2428. SetLastError(ERROR_BADKEY);
  2429. bResult = FALSE;
  2430. break;
  2431. }
  2432. else {
  2433. bChanged = TRUE;
  2434. if (dwThisId > dwLastHelp) dwLastHelp = dwThisId;
  2435. if (dwLastHelp > dwLastId) dwLastId = dwLastHelp;
  2436. }
  2437. }
  2438. lpThisId += (lstrlen(lpThisId) + 1);
  2439. }
  2440. Cleanup:
  2441. if (bResult) {
  2442. if (bChanged) {
  2443. ReportLoadPerfEvent(
  2444. EVENTLOG_WARNING_TYPE,
  2445. (DWORD) LDPRFMSG_CORRUPT_PERFLIB_INDEX,
  2446. 4, * pdwLastCounter, * pdwLastHelp, dwLastCounter, dwLastHelp,
  2447. 0, NULL, NULL, NULL);
  2448. * pdwLastCounter = dwLastCounter;
  2449. * pdwLastHelp = dwLastHelp;
  2450. }
  2451. }
  2452. TRACE((WINPERF_DBG_TRACE_INFO),
  2453. (& LoadPerfGuid,
  2454. __LINE__,
  2455. LOADPERF_CHECKNAMETABLE,
  2456. 0,
  2457. GetLastError(),
  2458. TRACE_DWORD(dwLastCounter),
  2459. TRACE_DWORD(dwLastHelp),
  2460. NULL));
  2461. return bResult;
  2462. }
  2463. BOOL
  2464. UpdateEachLanguage (
  2465. HKEY hPerflibRoot,
  2466. LPWSTR mszInstalledLangList,
  2467. LPDWORD pdwLastCounter,
  2468. LPDWORD pdwLastHelp,
  2469. PLANGUAGE_LIST_ELEMENT pFirstLang,
  2470. BOOL bUpdate
  2471. )
  2472. /*++
  2473. UpdateEachLanguage
  2474. Goes through list of languages and adds the sorted MULTI_SZ strings
  2475. to the existing counter and explain text in the registry.
  2476. Also updates the "Last Counter and Last Help" values
  2477. Arguments
  2478. hPerflibRoot handle to Perflib key in the registry
  2479. mszInstalledLangList
  2480. MSZ string of installed language keys
  2481. pFirstLanguage pointer to first language entry
  2482. Return Value
  2483. TRUE all went as planned
  2484. FALSE an error occured, use GetLastError to find out what it was.
  2485. --*/
  2486. {
  2487. PLANGUAGE_LIST_ELEMENT pThisLang;
  2488. LPTSTR pHelpBuffer = NULL;
  2489. LPTSTR pNameBuffer = NULL;
  2490. LPTSTR pNewName = NULL;
  2491. LPTSTR pNewHelp = NULL;
  2492. DWORD dwLastCounter = * pdwLastCounter;
  2493. DWORD dwLastHelp = * pdwLastHelp;
  2494. DWORD dwBufferSize;
  2495. DWORD dwValueType;
  2496. DWORD dwCounterSize;
  2497. DWORD dwHelpSize;
  2498. HKEY hKeyThisLang;
  2499. LONG lStatus;
  2500. TCHAR CounterNameBuffer [20];
  2501. TCHAR HelpNameBuffer [20];
  2502. TCHAR AddCounterNameBuffer [20];
  2503. TCHAR AddHelpNameBuffer [20];
  2504. LPTSTR szThisLang;
  2505. BOOL bResult = TRUE;
  2506. if (bUpdate && dwSystemVersion != OLD_VERSION) {
  2507. // this isn't possible on 3.1
  2508. MakeBackupCopyOfLanguageFiles(NULL);
  2509. }
  2510. for (szThisLang = mszInstalledLangList;
  2511. *szThisLang != 0;
  2512. szThisLang += (lstrlen(szThisLang) + 1)) {
  2513. TRACE((WINPERF_DBG_TRACE_INFO),
  2514. (& LoadPerfGuid,
  2515. __LINE__,
  2516. LOADPERF_UPDATEEACHLANGUAGE,
  2517. ARG_DEF(ARG_TYPE_WSTR, 1),
  2518. ERROR_SUCCESS,
  2519. TRACE_WSTR(szThisLang),
  2520. NULL));
  2521. if (dwSystemVersion == OLD_VERSION) {
  2522. // Open key for this language
  2523. lStatus = RegOpenKeyEx(
  2524. hPerflibRoot,
  2525. szThisLang,
  2526. RESERVED,
  2527. KEY_READ | KEY_WRITE,
  2528. & hKeyThisLang);
  2529. } else {
  2530. lstrcpy(CounterNameBuffer, CounterNameStr);
  2531. lstrcat(CounterNameBuffer, szThisLang);
  2532. lstrcpy(HelpNameBuffer, HelpNameStr);
  2533. lstrcat(HelpNameBuffer, szThisLang);
  2534. lstrcpy(AddCounterNameBuffer, AddCounterNameStr);
  2535. lstrcat(AddCounterNameBuffer, szThisLang);
  2536. lstrcpy(AddHelpNameBuffer, AddHelpNameStr);
  2537. lstrcat(AddHelpNameBuffer, szThisLang);
  2538. // make sure this language is loaded
  2539. __try {
  2540. lStatus = RegOpenKeyEx(
  2541. hPerflibRoot,
  2542. szThisLang,
  2543. RESERVED,
  2544. KEY_READ,
  2545. & hKeyThisLang);
  2546. }
  2547. __except (EXCEPTION_EXECUTE_HANDLER) {
  2548. lStatus = GetExceptionCode();
  2549. TRACE((WINPERF_DBG_TRACE_ERROR),
  2550. (& LoadPerfGuid,
  2551. __LINE__,
  2552. LOADPERF_UPDATEEACHLANGUAGE,
  2553. ARG_DEF(ARG_TYPE_WSTR, 1),
  2554. lStatus,
  2555. TRACE_WSTR(szThisLang),
  2556. NULL));
  2557. }
  2558. // we just need the open status, not the key handle so
  2559. // close this handle and set the one we need.
  2560. if (lStatus == ERROR_SUCCESS) {
  2561. RegCloseKey (hKeyThisLang);
  2562. }
  2563. hKeyThisLang = hPerfData;
  2564. }
  2565. if (bUpdate) {
  2566. // look up the new strings to add
  2567. pThisLang = FindLanguage(pFirstLang, szThisLang);
  2568. if (pThisLang == NULL) {
  2569. // try default language if available
  2570. pThisLang = FindLanguage(pFirstLang, DefaultLangTag);
  2571. }
  2572. if (pThisLang == NULL) {
  2573. // try english language if available
  2574. pThisLang = FindLanguage(pFirstLang, DefaultLangId);
  2575. }
  2576. if (pThisLang == NULL) {
  2577. // unable to add this language so continue
  2578. lStatus = ERROR_NO_MATCH;
  2579. TRACE((WINPERF_DBG_TRACE_ERROR),
  2580. (& LoadPerfGuid,
  2581. __LINE__,
  2582. LOADPERF_UPDATEEACHLANGUAGE,
  2583. 0,
  2584. lStatus,
  2585. TRACE_DWORD(dwLastCounter),
  2586. TRACE_DWORD(dwLastHelp),
  2587. NULL));
  2588. }
  2589. else {
  2590. if ( pThisLang->NameBuffer == NULL
  2591. || pThisLang->HelpBuffer == NULL) {
  2592. ReportLoadPerfEvent(
  2593. EVENTLOG_WARNING_TYPE, // error type
  2594. (DWORD) LDPRFMSG_CORRUPT_INCLUDE_FILE, // event,
  2595. 1, __LINE__, 0, 0, 0,
  2596. 1, pThisLang->LangId, NULL, NULL);
  2597. TRACE((WINPERF_DBG_TRACE_WARNING),
  2598. (& LoadPerfGuid,
  2599. __LINE__,
  2600. LOADPERF_UPDATEEACHLANGUAGE,
  2601. ARG_DEF(ARG_TYPE_WSTR, 1),
  2602. LDPRFMSG_CORRUPT_INCLUDE_FILE,
  2603. TRACE_WSTR(pThisLang->LangId),
  2604. NULL));
  2605. lStatus = LDPRFMSG_CORRUPT_INCLUDE_FILE;
  2606. }
  2607. TRACE((WINPERF_DBG_TRACE_INFO),
  2608. (& LoadPerfGuid,
  2609. __LINE__,
  2610. LOADPERF_UPDATEEACHLANGUAGE,
  2611. ARG_DEF(ARG_TYPE_WSTR, 1),
  2612. lStatus,
  2613. TRACE_WSTR(pThisLang->LangId),
  2614. TRACE_DWORD(dwLastCounter),
  2615. TRACE_DWORD(dwLastHelp),
  2616. NULL));
  2617. }
  2618. }
  2619. if (lStatus == ERROR_SUCCESS) {
  2620. // get size of counter names
  2621. dwBufferSize = 0;
  2622. __try {
  2623. lStatus = RegQueryValueEx (
  2624. hKeyThisLang,
  2625. (dwSystemVersion == OLD_VERSION) ? Counters : CounterNameBuffer,
  2626. RESERVED,
  2627. & dwValueType,
  2628. NULL,
  2629. & dwBufferSize);
  2630. }
  2631. __except (EXCEPTION_EXECUTE_HANDLER) {
  2632. lStatus = GetExceptionCode();
  2633. }
  2634. if (lStatus != ERROR_SUCCESS) {
  2635. if (dwSystemVersion != OLD_VERSION) {
  2636. // this means the language is not installed in the system.
  2637. continue;
  2638. }
  2639. ReportLoadPerfEvent(
  2640. EVENTLOG_ERROR_TYPE, // error type
  2641. (DWORD) LDPRFMSG_UNABLE_READ_COUNTER_STRINGS, // event,
  2642. 2, lStatus, __LINE__, 0, 0,
  2643. 1, szThisLang, NULL, NULL);
  2644. TRACE((WINPERF_DBG_TRACE_ERROR),
  2645. (& LoadPerfGuid,
  2646. __LINE__,
  2647. LOADPERF_UPDATEEACHLANGUAGE,
  2648. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  2649. lStatus,
  2650. TRACE_WSTR(szThisLang),
  2651. TRACE_WSTR(Counters),
  2652. NULL));
  2653. bResult = FALSE;
  2654. goto Cleanup;
  2655. }
  2656. dwCounterSize = dwBufferSize;
  2657. // get size of help text
  2658. dwBufferSize = 0;
  2659. __try {
  2660. lStatus = RegQueryValueEx (
  2661. hKeyThisLang,
  2662. (dwSystemVersion == OLD_VERSION) ? Help : HelpNameBuffer,
  2663. RESERVED,
  2664. & dwValueType,
  2665. NULL,
  2666. & dwBufferSize);
  2667. }
  2668. __except (EXCEPTION_EXECUTE_HANDLER) {
  2669. lStatus = GetExceptionCode();
  2670. }
  2671. if (lStatus != ERROR_SUCCESS) {
  2672. if (dwSystemVersion != OLD_VERSION) {
  2673. // this means the language is not installed in the system.
  2674. continue;
  2675. }
  2676. ReportLoadPerfEvent(
  2677. EVENTLOG_ERROR_TYPE, // error type
  2678. (DWORD) LDPRFMSG_UNABLE_READ_HELP_STRINGS, // event,
  2679. 2, lStatus, __LINE__, 0, 0,
  2680. 1, szThisLang, NULL, NULL);
  2681. TRACE((WINPERF_DBG_TRACE_ERROR),
  2682. (& LoadPerfGuid,
  2683. __LINE__,
  2684. LOADPERF_UPDATEEACHLANGUAGE,
  2685. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  2686. lStatus,
  2687. TRACE_WSTR(szThisLang),
  2688. TRACE_WSTR(Help),
  2689. NULL));
  2690. bResult = FALSE;
  2691. goto Cleanup;
  2692. }
  2693. dwHelpSize = dwBufferSize;
  2694. // allocate new buffers
  2695. if (bUpdate) {
  2696. dwCounterSize += pThisLang->dwNameBuffSize;
  2697. dwHelpSize += pThisLang->dwHelpBuffSize;
  2698. }
  2699. pNameBuffer = MemoryAllocate(dwCounterSize);
  2700. pHelpBuffer = MemoryAllocate(dwHelpSize);
  2701. if (!pNameBuffer || !pHelpBuffer) {
  2702. lStatus = ERROR_OUTOFMEMORY;
  2703. TRACE((WINPERF_DBG_TRACE_ERROR),
  2704. (& LoadPerfGuid,
  2705. __LINE__,
  2706. LOADPERF_UPDATEEACHLANGUAGE,
  2707. 0,
  2708. ERROR_OUTOFMEMORY,
  2709. NULL));
  2710. bResult = FALSE;
  2711. goto Cleanup;
  2712. }
  2713. ZeroMemory(pNameBuffer, dwCounterSize);
  2714. ZeroMemory(pHelpBuffer, dwHelpSize);
  2715. // load current buffers into memory
  2716. // read counter names into buffer. Counter names will be stored as
  2717. // a MULTI_SZ string in the format of "###" "Name"
  2718. dwBufferSize = dwCounterSize;
  2719. __try {
  2720. lStatus = RegQueryValueEx (
  2721. hKeyThisLang,
  2722. (dwSystemVersion == OLD_VERSION) ? Counters : CounterNameBuffer,
  2723. RESERVED,
  2724. & dwValueType,
  2725. (LPVOID)pNameBuffer,
  2726. & dwBufferSize);
  2727. }
  2728. __except (EXCEPTION_EXECUTE_HANDLER) {
  2729. lStatus = GetExceptionCode();
  2730. }
  2731. if (lStatus != ERROR_SUCCESS) {
  2732. ReportLoadPerfEvent(
  2733. EVENTLOG_ERROR_TYPE, // error type
  2734. (DWORD) LDPRFMSG_UNABLE_READ_COUNTER_STRINGS, // event,
  2735. 2, lStatus, __LINE__, 0, 0,
  2736. 1, szThisLang, NULL, NULL);
  2737. TRACE((WINPERF_DBG_TRACE_ERROR),
  2738. (& LoadPerfGuid,
  2739. __LINE__,
  2740. LOADPERF_UPDATEEACHLANGUAGE,
  2741. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  2742. lStatus,
  2743. TRACE_WSTR(szThisLang),
  2744. TRACE_WSTR(Counters),
  2745. NULL));
  2746. bResult = FALSE;
  2747. goto Cleanup;
  2748. }
  2749. if (bUpdate) {
  2750. // set pointer to location in buffer where new string should be
  2751. // appended: end of buffer - 1 (second null at end of MULTI_SZ
  2752. pNewName = (LPTSTR)
  2753. ((PBYTE)pNameBuffer + dwBufferSize - sizeof(TCHAR));
  2754. // adjust buffer length to take into account 2nd null from 1st
  2755. // buffer that has been overwritten
  2756. dwCounterSize -= sizeof(TCHAR);
  2757. }
  2758. // read explain text into buffer. Counter names will be stored as
  2759. // a MULTI_SZ string in the format of "###" "Text..."
  2760. dwBufferSize = dwHelpSize;
  2761. __try {
  2762. lStatus = RegQueryValueEx (
  2763. hKeyThisLang,
  2764. (dwSystemVersion == OLD_VERSION) ? Help : HelpNameBuffer,
  2765. RESERVED,
  2766. & dwValueType,
  2767. (LPVOID)pHelpBuffer,
  2768. & dwBufferSize);
  2769. }
  2770. __except (EXCEPTION_EXECUTE_HANDLER) {
  2771. lStatus = GetExceptionCode();
  2772. }
  2773. if (lStatus != ERROR_SUCCESS) {
  2774. ReportLoadPerfEvent(
  2775. EVENTLOG_ERROR_TYPE, // error type
  2776. (DWORD) LDPRFMSG_UNABLE_READ_HELP_STRINGS, // event,
  2777. 2, lStatus, __LINE__, 0, 0,
  2778. 1, szThisLang, NULL, NULL);
  2779. TRACE((WINPERF_DBG_TRACE_ERROR),
  2780. (& LoadPerfGuid,
  2781. __LINE__,
  2782. LOADPERF_UPDATEEACHLANGUAGE,
  2783. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  2784. lStatus,
  2785. TRACE_WSTR(szThisLang),
  2786. TRACE_WSTR(Help),
  2787. NULL));
  2788. bResult = FALSE;
  2789. goto Cleanup;
  2790. }
  2791. if (bUpdate) {
  2792. // set pointer to location in buffer where new string should be
  2793. // appended: end of buffer - 1 (second null at end of MULTI_SZ
  2794. pNewHelp = (LPTSTR)
  2795. ((PBYTE)pHelpBuffer + dwBufferSize - sizeof(TCHAR));
  2796. // adjust buffer length to take into account 2nd null from 1st
  2797. // buffer that has been overwritten
  2798. dwHelpSize -= sizeof(TCHAR);
  2799. }
  2800. if (bUpdate) {
  2801. // append new strings to end of current strings
  2802. memcpy(pNewHelp, pThisLang->HelpBuffer, pThisLang->dwHelpBuffSize);
  2803. memcpy(pNewName, pThisLang->NameBuffer, pThisLang->dwNameBuffSize);
  2804. }
  2805. if (! CheckNameTable(pNameBuffer, pHelpBuffer,
  2806. & dwLastCounter, & dwLastHelp, bUpdate)) {
  2807. bResult = FALSE;
  2808. goto Cleanup;
  2809. }
  2810. if (bUpdate) {
  2811. if (dwSystemVersion == OLD_VERSION) {
  2812. // load new strings back to the registry
  2813. lStatus = RegSetValueEx (
  2814. hKeyThisLang,
  2815. Counters,
  2816. RESERVED,
  2817. REG_MULTI_SZ,
  2818. (LPBYTE) pNameBuffer,
  2819. dwCounterSize);
  2820. if (lStatus != ERROR_SUCCESS) {
  2821. ReportLoadPerfEvent(
  2822. EVENTLOG_ERROR_TYPE, // error type
  2823. (DWORD) LDPRFMSG_UNABLE_UPDATE_COUNTER_STRINGS, // event,
  2824. 2, lStatus, __LINE__, 0, 0,
  2825. 1, pThisLang->LangId, NULL, NULL);
  2826. TRACE((WINPERF_DBG_TRACE_ERROR),
  2827. (& LoadPerfGuid,
  2828. __LINE__,
  2829. LOADPERF_UPDATEEACHLANGUAGE,
  2830. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  2831. lStatus,
  2832. TRACE_WSTR(pThisLang->LangId),
  2833. TRACE_WSTR(Counters),
  2834. NULL));
  2835. bResult = FALSE;
  2836. goto Cleanup;
  2837. }
  2838. lStatus = RegSetValueEx (
  2839. hKeyThisLang,
  2840. Help,
  2841. RESERVED,
  2842. REG_MULTI_SZ,
  2843. (LPBYTE) pHelpBuffer,
  2844. dwHelpSize);
  2845. if (lStatus != ERROR_SUCCESS) {
  2846. ReportLoadPerfEvent(
  2847. EVENTLOG_ERROR_TYPE, // error type
  2848. (DWORD) LDPRFMSG_UNABLE_UPDATE_HELP_STRINGS, // event,
  2849. 2, lStatus, __LINE__, 0, 0,
  2850. 1, pThisLang->LangId, NULL, NULL);
  2851. TRACE((WINPERF_DBG_TRACE_ERROR),
  2852. (& LoadPerfGuid,
  2853. __LINE__,
  2854. LOADPERF_UPDATEEACHLANGUAGE,
  2855. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  2856. lStatus,
  2857. TRACE_WSTR(pThisLang->LangId),
  2858. TRACE_WSTR(Help),
  2859. NULL));
  2860. bResult = FALSE;
  2861. goto Cleanup;
  2862. }
  2863. } else {
  2864. // write to the file thru PerfLib
  2865. dwBufferSize = dwCounterSize;
  2866. __try {
  2867. lStatus = RegQueryValueEx (
  2868. hKeyThisLang,
  2869. AddCounterNameBuffer,
  2870. RESERVED,
  2871. & dwValueType,
  2872. (LPVOID) pNameBuffer,
  2873. & dwBufferSize);
  2874. }
  2875. __except (EXCEPTION_EXECUTE_HANDLER) {
  2876. lStatus = GetExceptionCode();
  2877. }
  2878. if (lStatus != ERROR_SUCCESS) {
  2879. ReportLoadPerfEvent(
  2880. EVENTLOG_ERROR_TYPE, // error type
  2881. (DWORD) LDPRFMSG_UNABLE_UPDATE_COUNTER_STRINGS, // event,
  2882. 2, lStatus, __LINE__, 0, 0,
  2883. 1, pThisLang->LangId, NULL, NULL);
  2884. TRACE((WINPERF_DBG_TRACE_ERROR),
  2885. (& LoadPerfGuid,
  2886. __LINE__,
  2887. LOADPERF_UPDATEEACHLANGUAGE,
  2888. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  2889. lStatus,
  2890. TRACE_WSTR(pThisLang->LangId),
  2891. TRACE_WSTR(AddCounterNameBuffer),
  2892. NULL));
  2893. bResult = FALSE;
  2894. goto Cleanup;
  2895. }
  2896. dwBufferSize = dwHelpSize;
  2897. __try {
  2898. lStatus = RegQueryValueEx (
  2899. hKeyThisLang,
  2900. AddHelpNameBuffer,
  2901. RESERVED,
  2902. & dwValueType,
  2903. (LPVOID) pHelpBuffer,
  2904. & dwBufferSize);
  2905. }
  2906. __except (EXCEPTION_EXECUTE_HANDLER) {
  2907. lStatus = GetExceptionCode();
  2908. }
  2909. if (lStatus != ERROR_SUCCESS) {
  2910. ReportLoadPerfEvent(
  2911. EVENTLOG_ERROR_TYPE, // error type
  2912. (DWORD) LDPRFMSG_UNABLE_UPDATE_HELP_STRINGS, // event,
  2913. 2, lStatus, __LINE__, 0, 0,
  2914. 1, pThisLang->LangId, NULL, NULL);
  2915. TRACE((WINPERF_DBG_TRACE_ERROR),
  2916. (& LoadPerfGuid,
  2917. __LINE__,
  2918. LOADPERF_UPDATEEACHLANGUAGE,
  2919. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  2920. lStatus,
  2921. TRACE_WSTR(pThisLang->LangId),
  2922. TRACE_WSTR(AddHelpNameBuffer),
  2923. NULL));
  2924. bResult = FALSE;
  2925. goto Cleanup;
  2926. }
  2927. }
  2928. }
  2929. MemoryFree(pNameBuffer);
  2930. MemoryFree(pHelpBuffer);
  2931. pNameBuffer = NULL;
  2932. pHelpBuffer = NULL;
  2933. if (dwSystemVersion == OLD_VERSION) {
  2934. RegCloseKey (hKeyThisLang);
  2935. }
  2936. } else {
  2937. OUTPUT_MESSAGE (GetFormatResource (LC_UNABLEOPENLANG), szThisLang);
  2938. }
  2939. }
  2940. Cleanup:
  2941. if (! bResult) {
  2942. SetLastError(lStatus);
  2943. }
  2944. else if (! bUpdate) {
  2945. * pdwLastCounter = dwLastCounter;
  2946. * pdwLastHelp = dwLastHelp;
  2947. }
  2948. if (pNameBuffer != NULL) MemoryFree(pNameBuffer);
  2949. if (pHelpBuffer != NULL) MemoryFree(pHelpBuffer);
  2950. return bResult;
  2951. }
  2952. BOOL
  2953. UpdateRegistry (
  2954. LPTSTR lpIniFile,
  2955. LPTSTR lpDriverName,
  2956. PLANGUAGE_LIST_ELEMENT pFirstLang,
  2957. PSYMBOL_TABLE_ENTRY pFirstSymbol,
  2958. PPERFOBJECT_LOOKUP plObjectGuidTable,
  2959. LPDWORD pdwObjectGuidTableSize,
  2960. LPDWORD pdwIndexValues
  2961. )
  2962. /*++
  2963. UpdateRegistry
  2964. - checks, and if not busy, sets the "busy" key in the registry
  2965. - Reads in the text and help definitions from the .ini file
  2966. - Reads in the current contents of the HELP and COUNTER names
  2967. - Builds a sorted MULTI_SZ struct containing the new definitions
  2968. - Appends the new MULTI_SZ to the current as read from the registry
  2969. - loads the new MULTI_SZ string into the registry
  2970. - updates the keys in the driver's entry and Perflib's entry in the
  2971. registry (e.g. first, last, etc)
  2972. - deletes the DisablePerformanceCounters value if it's present in
  2973. order to re-enable the perf counter DLL
  2974. - clears the "busy" key
  2975. Arguments
  2976. lpIniFile
  2977. pathname to .ini file conatining definitions
  2978. hKeyMachine
  2979. handle to HKEY_LOCAL_MACHINE in registry on system to
  2980. update counters for.
  2981. lpDriverName
  2982. Name of device driver to load counters for
  2983. pFirstLang
  2984. pointer to first element in language structure list
  2985. pFirstSymbol
  2986. pointer to first element in symbol definition list
  2987. Return Value
  2988. TRUE if registry updated successfully
  2989. FALSE if registry not updated
  2990. (This routine will print an error message to stdout if an error
  2991. is encountered).
  2992. --*/
  2993. {
  2994. HKEY hDriverPerf = NULL;
  2995. HKEY hPerflib = NULL;
  2996. LPTSTR lpDriverKeyPath;
  2997. HKEY hKeyMachine = NULL;
  2998. DWORD dwType;
  2999. DWORD dwSize;
  3000. DWORD dwFirstDriverCounter;
  3001. DWORD dwFirstDriverHelp;
  3002. DWORD dwLastDriverCounter;
  3003. DWORD dwLastPerflibCounter;
  3004. DWORD dwLastPerflibHelp;
  3005. DWORD dwPerflibBaseIndex;
  3006. DWORD dwLastCounter;
  3007. DWORD dwLastHelp;
  3008. BOOL bStatus;
  3009. LONG lStatus;
  3010. LPTSTR lpszObjectList = NULL;
  3011. DWORD dwObjectList = dwFileSize;
  3012. LPTSTR mszLangList = NULL;
  3013. DWORD dwWaitStatus;
  3014. HANDLE hLocalMutex = NULL;
  3015. if (LoadPerfGrabMutex() == FALSE) {
  3016. return FALSE;
  3017. }
  3018. bStatus = FALSE;
  3019. SetLastError (ERROR_SUCCESS);
  3020. // allocate temporary buffers
  3021. lpDriverKeyPath = MemoryAllocate (MAX_PATH * sizeof(TCHAR));
  3022. if (dwObjectList < MAX_PROFILE_BUFFER * sizeof(TCHAR)) {
  3023. dwObjectList = MAX_PROFILE_BUFFER * sizeof(TCHAR);
  3024. }
  3025. lpszObjectList = MemoryAllocate(dwObjectList);
  3026. if (lpDriverKeyPath == NULL || lpszObjectList == NULL) {
  3027. SetLastError (ERROR_OUTOFMEMORY);
  3028. goto UpdateRegExit;
  3029. }
  3030. ZeroMemory(lpDriverKeyPath, MAX_PATH * sizeof(TCHAR));
  3031. ZeroMemory(lpszObjectList, dwObjectList);
  3032. // build driver key path string
  3033. lstrcpy (lpDriverKeyPath, DriverPathRoot);
  3034. lstrcat (lpDriverKeyPath, Slash);
  3035. lstrcat (lpDriverKeyPath, lpDriverName);
  3036. lstrcat (lpDriverKeyPath, Slash);
  3037. lstrcat (lpDriverKeyPath, Performance);
  3038. // check if we need to connect to remote machine
  3039. if (ComputerName[0]) {
  3040. lStatus = !ERROR_SUCCESS;
  3041. try {
  3042. lStatus = RegConnectRegistry(
  3043. (LPTSTR) ComputerName,
  3044. HKEY_LOCAL_MACHINE,
  3045. & hKeyMachine);
  3046. } finally {
  3047. if (lStatus != ERROR_SUCCESS) {
  3048. SetLastError (lStatus);
  3049. hKeyMachine = NULL;
  3050. OUTPUT_MESSAGE (GetFormatResource(LC_CONNECT_PROBLEM),
  3051. ComputerName, lStatus);
  3052. bStatus = FALSE;
  3053. }
  3054. }
  3055. if (lStatus != ERROR_SUCCESS)
  3056. goto UpdateRegExit;
  3057. } else {
  3058. hKeyMachine = HKEY_LOCAL_MACHINE;
  3059. }
  3060. // open keys to registry
  3061. // open key to driver's performance key
  3062. __try {
  3063. lStatus = RegOpenKeyEx(
  3064. hKeyMachine,
  3065. lpDriverKeyPath,
  3066. RESERVED,
  3067. KEY_WRITE | KEY_READ,
  3068. & hDriverPerf);
  3069. }
  3070. __except (EXCEPTION_EXECUTE_HANDLER) {
  3071. lStatus = GetExceptionCode();
  3072. }
  3073. if (lStatus != ERROR_SUCCESS) {
  3074. ReportLoadPerfEvent(
  3075. EVENTLOG_ERROR_TYPE, // error type
  3076. (DWORD) LDPRFMSG_UNABLE_OPEN_KEY, // event,
  3077. 2, lStatus, __LINE__, 0, 0,
  3078. 1, (LPWSTR) lpDriverKeyPath, NULL, NULL);
  3079. OUTPUT_MESSAGE (GetFormatResource(LC_ERR_OPEN_DRIVERPERF1), lpDriverKeyPath);
  3080. OUTPUT_MESSAGE (GetFormatResource(LC_ERR_OPEN_DRIVERPERF2), lStatus);
  3081. SetLastError (lStatus);
  3082. TRACE((WINPERF_DBG_TRACE_ERROR),
  3083. (& LoadPerfGuid,
  3084. __LINE__,
  3085. LOADPERF_UPDATEREGISTRY,
  3086. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  3087. lStatus,
  3088. TRACE_WSTR(lpIniFile),
  3089. TRACE_WSTR(lpDriverName),
  3090. NULL));
  3091. goto UpdateRegExit;
  3092. }
  3093. // open key to perflib's "root" key
  3094. __try {
  3095. lStatus = RegOpenKeyEx(
  3096. hKeyMachine,
  3097. NamesKey,
  3098. RESERVED,
  3099. KEY_WRITE | KEY_READ,
  3100. & hPerflib);
  3101. }
  3102. __except (EXCEPTION_EXECUTE_HANDLER) {
  3103. lStatus = GetExceptionCode();
  3104. }
  3105. if (lStatus != ERROR_SUCCESS) {
  3106. ReportLoadPerfEvent(
  3107. EVENTLOG_ERROR_TYPE, // error type
  3108. (DWORD) LDPRFMSG_UNABLE_OPEN_KEY, // event,
  3109. 2, lStatus, __LINE__, 0, 0,
  3110. 1, (LPWSTR) NamesKey, NULL, NULL);
  3111. OUTPUT_MESSAGE (GetFormatResource(LC_ERR_OPEN_PERFLIB), lStatus);
  3112. SetLastError (lStatus);
  3113. TRACE((WINPERF_DBG_TRACE_ERROR),
  3114. (& LoadPerfGuid,
  3115. __LINE__,
  3116. LOADPERF_UPDATEREGISTRY,
  3117. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  3118. lStatus,
  3119. TRACE_WSTR(lpDriverName),
  3120. TRACE_WSTR(NamesKey),
  3121. NULL));
  3122. goto UpdateRegExit;
  3123. }
  3124. // get "LastCounter" values from PERFLIB
  3125. dwType = 0;
  3126. dwLastPerflibCounter = 0;
  3127. dwSize = sizeof (dwLastPerflibCounter);
  3128. __try {
  3129. lStatus = RegQueryValueEx (
  3130. hPerflib,
  3131. LastCounter,
  3132. RESERVED,
  3133. & dwType,
  3134. (LPBYTE) & dwLastPerflibCounter,
  3135. & dwSize);
  3136. }
  3137. __except (EXCEPTION_EXECUTE_HANDLER) {
  3138. lStatus = GetExceptionCode();
  3139. }
  3140. if (lStatus != ERROR_SUCCESS) {
  3141. // this request should always succeed, if not then worse things
  3142. // will happen later on, so quit now and avoid the trouble.
  3143. ReportLoadPerfEvent(
  3144. EVENTLOG_ERROR_TYPE, // error type
  3145. (DWORD) LDPRFMSG_UNABLE_QUERY_VALUE, // event,
  3146. 2, lStatus, __LINE__, 0, 0,
  3147. 2, (LPWSTR) LastCounter, (LPWSTR) NamesKey, NULL);
  3148. OUTPUT_MESSAGE (GetFormatResource (LC_ERR_READLASTPERFLIB), lStatus);
  3149. SetLastError (lStatus);
  3150. TRACE((WINPERF_DBG_TRACE_ERROR),
  3151. (& LoadPerfGuid,
  3152. __LINE__,
  3153. LOADPERF_UPDATEREGISTRY,
  3154. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  3155. lStatus,
  3156. TRACE_WSTR(NamesKey),
  3157. TRACE_WSTR(LastCounter),
  3158. NULL));
  3159. goto UpdateRegExit;
  3160. }
  3161. // get "LastHelp" value now
  3162. dwType = 0;
  3163. dwLastPerflibHelp = 0;
  3164. dwSize = sizeof (dwLastPerflibHelp);
  3165. __try {
  3166. lStatus = RegQueryValueEx (
  3167. hPerflib,
  3168. LastHelp,
  3169. RESERVED,
  3170. & dwType,
  3171. (LPBYTE) & dwLastPerflibHelp,
  3172. & dwSize);
  3173. }
  3174. __except (EXCEPTION_EXECUTE_HANDLER) {
  3175. lStatus = GetExceptionCode();
  3176. }
  3177. if (lStatus != ERROR_SUCCESS) {
  3178. // this request should always succeed, if not then worse things
  3179. // will happen later on, so quit now and avoid the trouble.
  3180. ReportLoadPerfEvent(
  3181. EVENTLOG_ERROR_TYPE, // error type
  3182. (DWORD) LDPRFMSG_UNABLE_QUERY_VALUE, // event,
  3183. 2, lStatus, __LINE__, 0, 0,
  3184. 2, (LPWSTR) LastHelp, (LPWSTR) NamesKey, NULL);
  3185. OUTPUT_MESSAGE (GetFormatResource (LC_ERR_READLASTPERFLIB), lStatus);
  3186. SetLastError (lStatus);
  3187. TRACE((WINPERF_DBG_TRACE_ERROR),
  3188. (& LoadPerfGuid,
  3189. __LINE__,
  3190. LOADPERF_UPDATEREGISTRY,
  3191. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  3192. lStatus,
  3193. TRACE_WSTR(NamesKey),
  3194. TRACE_WSTR(LastHelp),
  3195. NULL));
  3196. goto UpdateRegExit;
  3197. }
  3198. // get "Base Index" value now
  3199. dwType = 0;
  3200. dwPerflibBaseIndex = 0;
  3201. dwSize = sizeof (dwPerflibBaseIndex);
  3202. __try {
  3203. lStatus = RegQueryValueEx (
  3204. hPerflib,
  3205. szBaseIndex,
  3206. RESERVED,
  3207. & dwType,
  3208. (LPBYTE) & dwPerflibBaseIndex,
  3209. & dwSize);
  3210. }
  3211. __except (EXCEPTION_EXECUTE_HANDLER) {
  3212. lStatus = GetExceptionCode();
  3213. }
  3214. if (lStatus != ERROR_SUCCESS) {
  3215. // this request should always succeed, if not then worse things
  3216. // will happen later on, so quit now and avoid the trouble.
  3217. ReportLoadPerfEvent(
  3218. EVENTLOG_ERROR_TYPE, // error type
  3219. (DWORD) LDPRFMSG_UNABLE_QUERY_VALUE, // event,
  3220. 2, lStatus, __LINE__, 0, 0,
  3221. 2, (LPWSTR) szBaseIndex, (LPWSTR) NamesKey, NULL);
  3222. OUTPUT_MESSAGE (GetFormatResource (LC_ERR_READLASTPERFLIB), lStatus);
  3223. SetLastError (lStatus);
  3224. TRACE((WINPERF_DBG_TRACE_ERROR),
  3225. (& LoadPerfGuid,
  3226. __LINE__,
  3227. LOADPERF_UPDATEREGISTRY,
  3228. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  3229. lStatus,
  3230. TRACE_WSTR(NamesKey),
  3231. TRACE_WSTR(szBaseIndex),
  3232. NULL));
  3233. goto UpdateRegExit;
  3234. }
  3235. // get "Version" value now
  3236. dwType = 0;
  3237. dwSize = sizeof (dwSystemVersion);
  3238. __try {
  3239. lStatus = RegQueryValueEx (
  3240. hPerflib,
  3241. VersionStr,
  3242. RESERVED,
  3243. & dwType,
  3244. (LPBYTE) & dwSystemVersion,
  3245. & dwSize);
  3246. }
  3247. __except (EXCEPTION_EXECUTE_HANDLER) {
  3248. lStatus = GetExceptionCode();
  3249. }
  3250. if (lStatus != ERROR_SUCCESS) {
  3251. dwSystemVersion = OLD_VERSION;
  3252. }
  3253. // set the hPerfData to HKEY_PERFORMANCE_DATA for new version
  3254. // if remote machine, then need to connect to it.
  3255. if (dwSystemVersion != OLD_VERSION) {
  3256. hPerfData = HKEY_PERFORMANCE_DATA;
  3257. lStatus = !ERROR_SUCCESS;
  3258. if (ComputerName[0]) {
  3259. // have to do it the old faction way
  3260. dwSystemVersion = OLD_VERSION;
  3261. lStatus = ERROR_SUCCESS;
  3262. }
  3263. } // NEW_VERSION
  3264. // see if this driver's counter names have already been installed
  3265. // by checking to see if LastCounter's value is less than Perflib's
  3266. // Last Counter
  3267. dwType = 0;
  3268. dwLastDriverCounter = 0;
  3269. dwSize = sizeof (dwLastDriverCounter);
  3270. __try {
  3271. lStatus = RegQueryValueEx (
  3272. hDriverPerf,
  3273. LastCounter,
  3274. RESERVED,
  3275. & dwType,
  3276. (LPBYTE) & dwLastDriverCounter,
  3277. & dwSize);
  3278. }
  3279. __except (EXCEPTION_EXECUTE_HANDLER) {
  3280. lStatus = GetExceptionCode();
  3281. }
  3282. if (lStatus == ERROR_SUCCESS) {
  3283. // if key found, then compare with perflib value and exit this
  3284. // procedure if the driver's last counter is <= to perflib's last
  3285. //
  3286. // if key not found, then continue with installation
  3287. // on the assumption that the counters have not been installed
  3288. if (dwLastDriverCounter <= dwLastPerflibCounter) {
  3289. OUTPUT_MESSAGE (GetFormatResource(LC_ERR_ALREADY_IN), lpDriverName);
  3290. SetLastError (ERROR_ALREADY_EXISTS);
  3291. goto UpdateRegExit;
  3292. }
  3293. }
  3294. TRACE((WINPERF_DBG_TRACE_INFO),
  3295. (& LoadPerfGuid,
  3296. __LINE__,
  3297. LOADPERF_UPDATEREGISTRY,
  3298. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  3299. lStatus,
  3300. TRACE_WSTR(lpIniFile),
  3301. TRACE_WSTR(lpDriverName),
  3302. TRACE_DWORD(dwLastPerflibCounter),
  3303. TRACE_DWORD(dwLastPerflibHelp),
  3304. TRACE_DWORD(dwPerflibBaseIndex),
  3305. TRACE_DWORD(dwSystemVersion),
  3306. NULL));
  3307. // set the "busy" indicator under the PERFLIB key
  3308. dwSize = lstrlen(lpDriverName) * sizeof (TCHAR);
  3309. __try {
  3310. lStatus = RegSetValueEx(
  3311. hPerflib,
  3312. Busy,
  3313. RESERVED,
  3314. REG_SZ,
  3315. (LPBYTE) lpDriverName,
  3316. dwSize);
  3317. }
  3318. __except (EXCEPTION_EXECUTE_HANDLER) {
  3319. lStatus = GetExceptionCode();
  3320. }
  3321. if (lStatus != ERROR_SUCCESS) {
  3322. OUTPUT_MESSAGE (GetFormatResource (LC_ERR_UNABLESETBUSY), lStatus);
  3323. SetLastError (lStatus);
  3324. TRACE((WINPERF_DBG_TRACE_ERROR),
  3325. (& LoadPerfGuid,
  3326. __LINE__,
  3327. LOADPERF_UPDATEREGISTRY,
  3328. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  3329. lStatus,
  3330. TRACE_WSTR(NamesKey),
  3331. TRACE_WSTR(Busy),
  3332. NULL));
  3333. goto UpdateRegExit;
  3334. }
  3335. dwLastCounter = dwLastPerflibCounter;
  3336. dwLastHelp = dwLastPerflibHelp;
  3337. // get the list of installed languages on this machine
  3338. if (!GetInstalledLanguageList (hPerflib, &mszLangList)) {
  3339. OUTPUT_MESSAGE (GetFormatResource(LC_ERR_UPDATELANG), GetLastError());
  3340. goto UpdateRegExit;
  3341. }
  3342. if (!UpdateEachLanguage(hPerflib,
  3343. mszLangList,
  3344. & dwLastCounter,
  3345. & dwLastHelp,
  3346. pFirstLang,
  3347. FALSE)) {
  3348. OUTPUT_MESSAGE (GetFormatResource(LC_ERR_UPDATELANG), GetLastError());
  3349. goto UpdateRegExit;
  3350. }
  3351. // increment (by 2) the last counters so they point to the first
  3352. // unused index after the existing names and then
  3353. // set the first driver counters
  3354. dwFirstDriverCounter = dwLastCounter + 2;
  3355. dwFirstDriverHelp = dwLastHelp + 2;
  3356. if ( (dwPerflibBaseIndex < PERFLIB_BASE_INDEX)
  3357. || (dwFirstDriverCounter < dwPerflibBaseIndex)
  3358. || (dwFirstDriverHelp < dwPerflibBaseIndex)) {
  3359. // potential CounterIndex/HelpIndex overlap with Base counters,
  3360. //
  3361. ReportLoadPerfEvent(
  3362. EVENTLOG_ERROR_TYPE, // error type
  3363. (DWORD) LDPRFMSG_REGISTRY_BASEINDEX_CORRUPT, // event,
  3364. 4, dwPerflibBaseIndex, dwFirstDriverCounter, dwFirstDriverHelp, __LINE__,
  3365. 1, lpDriverName, NULL, NULL);
  3366. lStatus = ERROR_BADKEY;
  3367. SetLastError(lStatus);
  3368. TRACE((WINPERF_DBG_TRACE_ERROR),
  3369. (& LoadPerfGuid,
  3370. __LINE__,
  3371. LOADPERF_UPDATEREGISTRY,
  3372. ARG_DEF(ARG_TYPE_WSTR, 1),
  3373. lStatus,
  3374. TRACE_WSTR(lpDriverName),
  3375. TRACE_DWORD(dwPerflibBaseIndex),
  3376. TRACE_DWORD(dwFirstDriverCounter),
  3377. TRACE_DWORD(dwFirstDriverHelp),
  3378. NULL));
  3379. goto UpdateRegExit;
  3380. }
  3381. // load .INI file definitions into language tables
  3382. if (!LoadLanguageLists (lpIniFile, dwFirstDriverCounter , dwFirstDriverHelp,
  3383. pFirstSymbol, pFirstLang)) {
  3384. // error message is displayed by LoadLanguageLists so just abort
  3385. // error is in GetLastError already
  3386. goto UpdateRegExit;
  3387. }
  3388. if (!CreateObjectList (lpIniFile, dwFirstDriverCounter, pFirstSymbol,
  3389. lpszObjectList, plObjectGuidTable, pdwObjectGuidTableSize)) {
  3390. // error message is displayed by CreateObjectList so just abort
  3391. // error is in GetLastError already
  3392. goto UpdateRegExit;
  3393. }
  3394. // all the symbols and definitions have been loaded into internal
  3395. // tables. so now they need to be sorted and merged into a multiSZ string
  3396. // this routine also updates the "last" counters
  3397. if (!SortLanguageTables (pFirstLang, &dwLastCounter, &dwLastHelp)) {
  3398. OUTPUT_MESSAGE (GetFormatResource(LC_UNABLESORTTABLES), GetLastError());
  3399. goto UpdateRegExit;
  3400. }
  3401. if ( (dwLastCounter < dwLastPerflibCounter)
  3402. || (dwLastHelp < dwLastPerflibHelp)) {
  3403. // potential CounterIndex/HelpIndex overlap with Base counters,
  3404. //
  3405. ReportLoadPerfEvent(
  3406. EVENTLOG_ERROR_TYPE, // error type
  3407. (DWORD) LDPRFMSG_REGISTRY_BASEINDEX_CORRUPT, // event,
  3408. 4, dwLastPerflibCounter, dwLastCounter, dwLastHelp, __LINE__,
  3409. 1 , lpDriverName, NULL, NULL);
  3410. lStatus = ERROR_BADKEY;
  3411. SetLastError(lStatus);
  3412. TRACE((WINPERF_DBG_TRACE_ERROR),
  3413. (& LoadPerfGuid,
  3414. __LINE__,
  3415. LOADPERF_UPDATEREGISTRY,
  3416. ARG_DEF(ARG_TYPE_WSTR, 1),
  3417. lStatus,
  3418. TRACE_WSTR(lpDriverName),
  3419. TRACE_DWORD(dwLastPerflibCounter),
  3420. TRACE_DWORD(dwLastPerflibHelp),
  3421. TRACE_DWORD(dwLastCounter),
  3422. TRACE_DWORD(dwLastHelp),
  3423. NULL));
  3424. goto UpdateRegExit;
  3425. }
  3426. if (!UpdateEachLanguage(hPerflib,
  3427. mszLangList,
  3428. & dwLastCounter,
  3429. & dwLastHelp,
  3430. pFirstLang,
  3431. TRUE)) {
  3432. OUTPUT_MESSAGE (GetFormatResource(LC_ERR_UPDATELANG), GetLastError());
  3433. goto UpdateRegExit;
  3434. }
  3435. dwLastPerflibCounter = dwLastCounter;
  3436. dwLastPerflibHelp = dwLastHelp;
  3437. TRACE((WINPERF_DBG_TRACE_INFO),
  3438. (& LoadPerfGuid,
  3439. __LINE__,
  3440. LOADPERF_UPDATEREGISTRY,
  3441. ARG_DEF(ARG_TYPE_WSTR, 1),
  3442. lStatus,
  3443. TRACE_WSTR(lpDriverName),
  3444. TRACE_DWORD(dwFirstDriverCounter),
  3445. TRACE_DWORD(dwFirstDriverHelp),
  3446. TRACE_DWORD(dwLastPerflibCounter),
  3447. TRACE_DWORD(dwLastPerflibHelp),
  3448. NULL));
  3449. if (dwLastCounter < dwFirstDriverCounter) {
  3450. ReportLoadPerfEvent(
  3451. EVENTLOG_ERROR_TYPE, // error type
  3452. (DWORD) LDPRFMSG_CORRUPT_INDEX_RANGE, // event,
  3453. 3, dwFirstDriverCounter, dwLastCounter, __LINE__, 0,
  3454. 2, (LPWSTR) Counters, (LPWSTR) lpDriverKeyPath, NULL);
  3455. goto UpdateRegExit;
  3456. }
  3457. if (dwLastHelp < dwFirstDriverHelp) {
  3458. ReportLoadPerfEvent(
  3459. EVENTLOG_ERROR_TYPE, // error type
  3460. (DWORD) LDPRFMSG_CORRUPT_INDEX_RANGE, // event,
  3461. 3, dwFirstDriverHelp, dwLastHelp, __LINE__, 0,
  3462. 2, (LPWSTR) Help, (LPWSTR) lpDriverKeyPath, NULL);
  3463. goto UpdateRegExit;
  3464. }
  3465. // update last counters for driver and perflib
  3466. // perflib...
  3467. __try {
  3468. lStatus = RegSetValueEx(
  3469. hPerflib,
  3470. LastCounter,
  3471. RESERVED,
  3472. REG_DWORD,
  3473. (LPBYTE) & dwLastPerflibCounter,
  3474. sizeof(DWORD));
  3475. }
  3476. __except (EXCEPTION_EXECUTE_HANDLER) {
  3477. lStatus = GetExceptionCode();
  3478. }
  3479. if (lStatus != ERROR_SUCCESS) {
  3480. ReportLoadPerfEvent(
  3481. EVENTLOG_ERROR_TYPE, // error type
  3482. (DWORD) LDPRFMSG_UNABLE_UPDATE_VALUE, // event,
  3483. 3, lStatus, dwLastPerflibCounter, __LINE__, 0,
  3484. 2, (LPWSTR) LastCounter, (LPWSTR) NamesKey, NULL);
  3485. OUTPUT_MESSAGE (GetFormatResource (LC_UNABLESETVALUE),
  3486. LastCounter, szPerflib);
  3487. TRACE((WINPERF_DBG_TRACE_ERROR),
  3488. (& LoadPerfGuid,
  3489. __LINE__,
  3490. LOADPERF_UPDATEREGISTRY,
  3491. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  3492. lStatus,
  3493. TRACE_WSTR(NamesKey),
  3494. TRACE_WSTR(LastCounter),
  3495. TRACE_DWORD(dwLastPerflibCounter),
  3496. NULL));
  3497. }
  3498. __try {
  3499. lStatus = RegSetValueEx(
  3500. hPerflib,
  3501. LastHelp,
  3502. RESERVED,
  3503. REG_DWORD,
  3504. (LPBYTE) & dwLastPerflibHelp,
  3505. sizeof(DWORD));
  3506. }
  3507. __except (EXCEPTION_EXECUTE_HANDLER) {
  3508. lStatus = GetExceptionCode();
  3509. }
  3510. if (lStatus != ERROR_SUCCESS) {
  3511. ReportLoadPerfEvent(
  3512. EVENTLOG_ERROR_TYPE, // error type
  3513. (DWORD) LDPRFMSG_UNABLE_UPDATE_VALUE, // event,
  3514. 3, lStatus, dwLastPerflibHelp, __LINE__, 0,
  3515. 2, (LPWSTR) LastHelp, (LPWSTR) NamesKey, NULL);
  3516. OUTPUT_MESSAGE (GetFormatResource (LC_UNABLESETVALUE),
  3517. LastHelp, szPerflib);
  3518. TRACE((WINPERF_DBG_TRACE_ERROR),
  3519. (& LoadPerfGuid,
  3520. __LINE__,
  3521. LOADPERF_UPDATEREGISTRY,
  3522. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  3523. lStatus,
  3524. TRACE_WSTR(NamesKey),
  3525. TRACE_WSTR(LastHelp),
  3526. TRACE_DWORD(dwLastPerflibHelp),
  3527. NULL));
  3528. }
  3529. // and the driver
  3530. __try {
  3531. lStatus = RegSetValueEx(
  3532. hDriverPerf,
  3533. LastCounter,
  3534. RESERVED,
  3535. REG_DWORD,
  3536. (LPBYTE) & dwLastPerflibCounter,
  3537. sizeof(DWORD));
  3538. }
  3539. __except (EXCEPTION_EXECUTE_HANDLER) {
  3540. lStatus = GetExceptionCode();
  3541. }
  3542. if (lStatus != ERROR_SUCCESS) {
  3543. ReportLoadPerfEvent(
  3544. EVENTLOG_ERROR_TYPE, // error type
  3545. (DWORD) LDPRFMSG_UNABLE_UPDATE_VALUE, // event,
  3546. 3, lStatus, dwLastPerflibCounter, __LINE__, 0,
  3547. 2, (LPWSTR) LastCounter, (LPWSTR) lpDriverKeyPath, NULL);
  3548. OUTPUT_MESSAGE (GetFormatResource (LC_UNABLESETVALUE),
  3549. LastCounter, lpDriverName);
  3550. TRACE((WINPERF_DBG_TRACE_ERROR),
  3551. (& LoadPerfGuid,
  3552. __LINE__,
  3553. LOADPERF_UPDATEREGISTRY,
  3554. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  3555. lStatus,
  3556. TRACE_WSTR(lpDriverName),
  3557. TRACE_WSTR(LastCounter),
  3558. TRACE_DWORD(dwLastPerflibCounter),
  3559. NULL));
  3560. }
  3561. __try {
  3562. lStatus = RegSetValueEx(
  3563. hDriverPerf,
  3564. LastHelp,
  3565. RESERVED,
  3566. REG_DWORD,
  3567. (LPBYTE) & dwLastPerflibHelp,
  3568. sizeof(DWORD));
  3569. }
  3570. __except (EXCEPTION_EXECUTE_HANDLER) {
  3571. lStatus = GetExceptionCode();
  3572. }
  3573. if (lStatus != ERROR_SUCCESS) {
  3574. ReportLoadPerfEvent(
  3575. EVENTLOG_ERROR_TYPE, // error type
  3576. (DWORD) LDPRFMSG_UNABLE_UPDATE_VALUE, // event,
  3577. 3, lStatus, dwLastPerflibHelp, __LINE__, 0,
  3578. 2, (LPWSTR) LastHelp, (LPWSTR) lpDriverKeyPath, NULL);
  3579. OUTPUT_MESSAGE (GetFormatResource (LC_UNABLESETVALUE),
  3580. LastHelp, lpDriverName);
  3581. TRACE((WINPERF_DBG_TRACE_ERROR),
  3582. (& LoadPerfGuid,
  3583. __LINE__,
  3584. LOADPERF_UPDATEREGISTRY,
  3585. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  3586. lStatus,
  3587. TRACE_WSTR(lpDriverName),
  3588. TRACE_WSTR(LastHelp),
  3589. TRACE_DWORD(dwLastPerflibHelp),
  3590. NULL));
  3591. }
  3592. __try {
  3593. lStatus = RegSetValueEx(
  3594. hDriverPerf,
  3595. cszFirstCounter,
  3596. RESERVED,
  3597. REG_DWORD,
  3598. (LPBYTE) & dwFirstDriverCounter,
  3599. sizeof(DWORD));
  3600. }
  3601. __except (EXCEPTION_EXECUTE_HANDLER) {
  3602. lStatus = GetExceptionCode();
  3603. }
  3604. if (lStatus != ERROR_SUCCESS) {
  3605. ReportLoadPerfEvent(
  3606. EVENTLOG_ERROR_TYPE, // error type
  3607. (DWORD) LDPRFMSG_UNABLE_UPDATE_VALUE, // event,
  3608. 3, lStatus, dwFirstDriverCounter, __LINE__, 0,
  3609. 2, (LPWSTR) cszFirstCounter, (LPWSTR) lpDriverKeyPath, NULL);
  3610. OUTPUT_MESSAGE (GetFormatResource (LC_UNABLESETVALUE),
  3611. cszFirstCounter, lpDriverName);
  3612. TRACE((WINPERF_DBG_TRACE_ERROR),
  3613. (& LoadPerfGuid,
  3614. __LINE__,
  3615. LOADPERF_UPDATEREGISTRY,
  3616. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  3617. lStatus,
  3618. TRACE_WSTR(lpDriverName),
  3619. TRACE_WSTR(cszFirstCounter),
  3620. TRACE_DWORD(dwFirstDriverCounter),
  3621. NULL));
  3622. }
  3623. __try {
  3624. lStatus = RegSetValueEx(
  3625. hDriverPerf,
  3626. FirstHelp,
  3627. RESERVED,
  3628. REG_DWORD,
  3629. (LPBYTE) & dwFirstDriverHelp,
  3630. sizeof(DWORD));
  3631. }
  3632. __except (EXCEPTION_EXECUTE_HANDLER) {
  3633. lStatus = GetExceptionCode();
  3634. }
  3635. if (lStatus != ERROR_SUCCESS) {
  3636. ReportLoadPerfEvent(
  3637. EVENTLOG_ERROR_TYPE, // error type
  3638. (DWORD) LDPRFMSG_UNABLE_UPDATE_VALUE, // event,
  3639. 3, lStatus, dwFirstDriverHelp, __LINE__, 0,
  3640. 2, (LPWSTR) FirstHelp, (LPWSTR) lpDriverKeyPath, NULL);
  3641. OUTPUT_MESSAGE (GetFormatResource (LC_UNABLESETVALUE),
  3642. FirstHelp, lpDriverName);
  3643. TRACE((WINPERF_DBG_TRACE_ERROR),
  3644. (& LoadPerfGuid,
  3645. __LINE__,
  3646. LOADPERF_UPDATEREGISTRY,
  3647. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  3648. lStatus,
  3649. TRACE_WSTR(lpDriverName),
  3650. TRACE_WSTR(FirstHelp),
  3651. TRACE_DWORD(dwFirstDriverHelp),
  3652. NULL));
  3653. }
  3654. if (*lpszObjectList != 0) {
  3655. __try {
  3656. lStatus = RegSetValueEx(
  3657. hDriverPerf,
  3658. szObjectList,
  3659. RESERVED,
  3660. REG_SZ,
  3661. (LPBYTE) lpszObjectList,
  3662. (lstrlen(lpszObjectList) + 1) * sizeof (TCHAR));
  3663. }
  3664. __except (EXCEPTION_EXECUTE_HANDLER) {
  3665. lStatus = GetExceptionCode();
  3666. }
  3667. if (lStatus != ERROR_SUCCESS) {
  3668. ReportLoadPerfEvent(
  3669. EVENTLOG_ERROR_TYPE, // error type
  3670. (DWORD) LDPRFMSG_UNABLE_UPDATE_VALUE, // event,
  3671. 2, lStatus, __LINE__, 0, 0,
  3672. 2, (LPWSTR) szObjectList, (LPWSTR) lpDriverKeyPath, NULL);
  3673. OUTPUT_MESSAGE (GetFormatResource (LC_UNABLESETVALUE),
  3674. szObjectList, lpDriverName);
  3675. TRACE((WINPERF_DBG_TRACE_ERROR),
  3676. (& LoadPerfGuid,
  3677. __LINE__,
  3678. LOADPERF_UPDATEREGISTRY,
  3679. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  3680. lStatus,
  3681. TRACE_WSTR(lpDriverName),
  3682. TRACE_WSTR(szObjectList),
  3683. NULL));
  3684. }
  3685. }
  3686. bStatus = TRUE;
  3687. pdwIndexValues[0] = dwFirstDriverCounter; // first Counter
  3688. pdwIndexValues[1] = dwLastPerflibCounter; // last Counter
  3689. pdwIndexValues[2] = dwFirstDriverHelp; // first Help
  3690. pdwIndexValues[3] = dwLastPerflibHelp; // last Help
  3691. // remove "DisablePerformanceCounter" value so perf counters are re-enabled.
  3692. lStatus = RegDeleteValue (hDriverPerf, szDisablePerformanceCounters);
  3693. // MemoryFree temporary buffers
  3694. UpdateRegExit:
  3695. // clear busy flag
  3696. if (hPerflib) {
  3697. lStatus = RegDeleteValue (
  3698. hPerflib,
  3699. Busy);
  3700. }
  3701. ReleaseMutex(hLoadPerfMutex);
  3702. // MemoryFree temporary buffers
  3703. // free any guid string buffers here
  3704. // TODO: add this code
  3705. if (lpDriverKeyPath) MemoryFree (lpDriverKeyPath);
  3706. if (lpszObjectList) MemoryFree (lpszObjectList);
  3707. if (hDriverPerf) RegCloseKey (hDriverPerf);
  3708. if (hPerflib) RegCloseKey (hPerflib);
  3709. if (mszLangList != NULL) MemoryFree(mszLangList);
  3710. if (hPerfData && hPerfData != HKEY_PERFORMANCE_DATA) {
  3711. RegCloseKey (hPerfData);
  3712. }
  3713. if (hKeyMachine && hKeyMachine != HKEY_LOCAL_MACHINE) {
  3714. RegCloseKey (hKeyMachine) ;
  3715. }
  3716. return bStatus;
  3717. }
  3718. DWORD
  3719. GetMofFileFromIni (
  3720. LPCWSTR lpIniFile,
  3721. LPWSTR MofFilename
  3722. )
  3723. {
  3724. DWORD dwRetSize;
  3725. DWORD dwReturn = ERROR_SUCCESS;
  3726. if (MofFilename) {
  3727. dwRetSize = GetPrivateProfileString (
  3728. szInfo, // info section
  3729. szMofFileName, // Mof Filename value
  3730. szNotFound, // default value
  3731. MofFilename, // output buffer
  3732. MAX_PATH, // buffer size
  3733. lpIniFile); // ini file to read
  3734. if ((lstrcmpi(MofFilename, szNotFound)) != 0) {
  3735. // name found
  3736. TRACE((WINPERF_DBG_TRACE_INFO),
  3737. (& LoadPerfGuid,
  3738. __LINE__,
  3739. LOADPERF_GETMOFFILEFROMINI,
  3740. ARG_DEF(ARG_TYPE_WSTR, 1),
  3741. dwReturn,
  3742. TRACE_WSTR(MofFilename),
  3743. NULL));
  3744. } else {
  3745. // name not found, default returned so return NULL string
  3746. MofFilename[0] = 0;
  3747. dwReturn = ERROR_FILE_NOT_FOUND;
  3748. }
  3749. } else {
  3750. dwReturn = ERROR_INVALID_PARAMETER;
  3751. }
  3752. if (dwReturn != ERROR_SUCCESS) {
  3753. TRACE((WINPERF_DBG_TRACE_ERROR),
  3754. (& LoadPerfGuid,
  3755. __LINE__,
  3756. LOADPERF_GETMOFFILEFROMINI, 0, dwReturn, NULL));
  3757. }
  3758. return dwReturn;
  3759. }
  3760. DWORD
  3761. OpenCounterAndBuildMofFile (
  3762. LPCWSTR lpDriverName,
  3763. LPCWSTR MofFilename,
  3764. PPERFOBJECT_LOOKUP plObjectGuidTable,
  3765. DWORD dwObjectGuidTableSize
  3766. )
  3767. {
  3768. DWORD dwType;
  3769. DWORD dwSize;
  3770. HKEY hKeyMachine = NULL;
  3771. HKEY hDriverPerf = NULL;
  3772. LONG lStatus = ERROR_SUCCESS;
  3773. LPWSTR *lpCounterText;
  3774. LPWSTR *lpDisplayText = NULL; // Localized name strings array
  3775. DWORD dwLastElement;
  3776. WCHAR lpDriverKeyPath[MAX_PATH];
  3777. WCHAR wszPerfLibraryName[MAX_PATH];
  3778. WCHAR wszLibraryExpPath[MAX_PATH];
  3779. WCHAR szProviderName[MAX_PATH];
  3780. DWORD dwProviderNameSize;
  3781. HANDLE hPerfLibrary = NULL;
  3782. CHAR szOpenProcName[MAX_PATH];
  3783. PM_OPEN_PROC *pOpenProc = NULL;
  3784. CHAR szCollectProcName[MAX_PATH];
  3785. PM_COLLECT_PROC *pCollectProc = NULL;
  3786. CHAR szCloseProcName[MAX_PATH];
  3787. PM_CLOSE_PROC *pCloseProc = NULL;
  3788. LPBYTE pPerfBuffer = NULL;
  3789. LPBYTE pPerfBufferArg;
  3790. DWORD dwPerfBufferSize;
  3791. DWORD dwThisObject;
  3792. DWORD dwThisCounterDef;
  3793. WCHAR szMofBuffer[8192*2];
  3794. DWORD dwMofBufferSize;
  3795. HANDLE hMofFile;
  3796. PERF_COUNTER_DLL_INFO PcDllInfo;
  3797. DWORD dwGuidIdx;
  3798. WCHAR wszLocalLang[8];
  3799. PPERF_OBJECT_TYPE pThisObject;
  3800. PPERF_COUNTER_DEFINITION pThisCounterDef;
  3801. // get registry key for this object
  3802. // build driver key path string
  3803. lstrcpy (lpDriverKeyPath, DriverPathRoot);
  3804. lstrcat (lpDriverKeyPath, Slash);
  3805. lstrcat (lpDriverKeyPath, lpDriverName);
  3806. lstrcat (lpDriverKeyPath, Slash);
  3807. lstrcat (lpDriverKeyPath, Performance);
  3808. // check if we need to connect to remote machine
  3809. if (ComputerName[0]) {
  3810. lStatus = !ERROR_SUCCESS;
  3811. try {
  3812. lStatus = RegConnectRegistry (
  3813. (LPTSTR)ComputerName,
  3814. HKEY_LOCAL_MACHINE,
  3815. & hKeyMachine);
  3816. } finally {
  3817. if (lStatus != ERROR_SUCCESS) {
  3818. hKeyMachine = NULL;
  3819. }
  3820. }
  3821. } else {
  3822. hKeyMachine = HKEY_LOCAL_MACHINE;
  3823. }
  3824. // bail out here if unable to open the registry
  3825. if (hKeyMachine == NULL) return lStatus;
  3826. // get ENGLISH string list
  3827. lpCounterText = BuildNameTable (
  3828. hKeyMachine,
  3829. (LPWSTR)L"009", // Use english as the language entry for WBEM
  3830. &dwLastElement);
  3831. if (lpCounterText == NULL) {
  3832. goto MakeMofErrorExit;
  3833. }
  3834. // get LOCAL strings
  3835. // get locale and convert to string first
  3836. memset (wszLocalLang, 0, sizeof(wszLocalLang));
  3837. swprintf (wszLocalLang, (LPCWSTR)L"0%2.2x", (GetSystemDefaultLCID() & 0x000000FF));
  3838. lpDisplayText = BuildNameTable (
  3839. hKeyMachine,
  3840. (LPWSTR)wszLocalLang, // Use local language for strings
  3841. &dwLastElement);
  3842. if (lpDisplayText == NULL) {
  3843. lpDisplayText = BuildNameTable (
  3844. hKeyMachine,
  3845. (LPWSTR)L"009", // then Use english
  3846. &dwLastElement);
  3847. if (lpDisplayText == NULL) {
  3848. goto MakeMofErrorExit;
  3849. }
  3850. }
  3851. // open key to driver's performance key
  3852. __try {
  3853. lStatus = RegOpenKeyEx (
  3854. hKeyMachine,
  3855. lpDriverKeyPath,
  3856. RESERVED,
  3857. KEY_WRITE | KEY_READ,
  3858. & hDriverPerf);
  3859. }
  3860. __except (EXCEPTION_EXECUTE_HANDLER) {
  3861. lStatus = GetExceptionCode();
  3862. }
  3863. if (lStatus != ERROR_SUCCESS) {
  3864. ReportLoadPerfEvent(
  3865. EVENTLOG_ERROR_TYPE, // error type
  3866. (DWORD) LDPRFMSG_UNABLE_OPEN_KEY, // event,
  3867. 2, lStatus, __LINE__, 0, 0,
  3868. 1, (LPWSTR) lpDriverKeyPath, NULL, NULL);
  3869. TRACE((WINPERF_DBG_TRACE_ERROR),
  3870. (& LoadPerfGuid,
  3871. __LINE__,
  3872. LOADPERF_OPENCOUNTERANDBUILDMOFFILE,
  3873. ARG_DEF(ARG_TYPE_WSTR, 1),
  3874. lStatus,
  3875. TRACE_WSTR(lpDriverName),
  3876. NULL));
  3877. goto MakeMofErrorExit;
  3878. }
  3879. // get library name
  3880. dwType = 0;
  3881. dwSize = sizeof(wszPerfLibraryName);
  3882. __try {
  3883. lStatus = RegQueryValueExW (hDriverPerf,
  3884. cszLibrary,
  3885. NULL,
  3886. & dwType,
  3887. (LPBYTE) & wszPerfLibraryName[0],
  3888. & dwSize);
  3889. }
  3890. __except (EXCEPTION_EXECUTE_HANDLER) {
  3891. lStatus = GetExceptionCode();
  3892. }
  3893. if (lStatus == ERROR_SUCCESS) {
  3894. if (dwType == REG_EXPAND_SZ) {
  3895. // expand any environment vars
  3896. dwSize = ExpandEnvironmentStringsW(
  3897. wszPerfLibraryName,
  3898. wszLibraryExpPath,
  3899. MAX_PATH);
  3900. if ((dwSize > MAX_PATH) || (dwSize == 0)) {
  3901. lStatus = ERROR_INVALID_DLL;
  3902. }
  3903. } else if (dwType == REG_SZ) {
  3904. // look for dll and save full file Path
  3905. dwSize = SearchPathW (
  3906. NULL, // use standard system search path
  3907. wszPerfLibraryName,
  3908. NULL,
  3909. MAX_PATH,
  3910. wszLibraryExpPath,
  3911. NULL);
  3912. if ((dwSize > MAX_PATH) || (dwSize == 0)) {
  3913. lStatus = ERROR_INVALID_DLL;
  3914. }
  3915. } else {
  3916. lStatus = ERROR_INVALID_DLL;
  3917. }
  3918. if (lStatus != ERROR_SUCCESS) {
  3919. TRACE((WINPERF_DBG_TRACE_ERROR),
  3920. (& LoadPerfGuid,
  3921. __LINE__,
  3922. LOADPERF_OPENCOUNTERANDBUILDMOFFILE,
  3923. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  3924. lStatus,
  3925. TRACE_WSTR(lpDriverName),
  3926. TRACE_WSTR(wszPerfLibraryName),
  3927. NULL));
  3928. }
  3929. }
  3930. else {
  3931. TRACE((WINPERF_DBG_TRACE_ERROR),
  3932. (& LoadPerfGuid,
  3933. __LINE__,
  3934. LOADPERF_OPENCOUNTERANDBUILDMOFFILE,
  3935. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  3936. lStatus,
  3937. TRACE_WSTR(lpDriverName),
  3938. TRACE_WSTR(cszLibrary),
  3939. NULL));
  3940. }
  3941. // unable to continue if error
  3942. if (lStatus != ERROR_SUCCESS) {
  3943. goto MakeMofErrorExit;
  3944. }
  3945. // get open procedure name
  3946. dwType = 0;
  3947. dwSize = sizeof(szOpenProcName);
  3948. __try {
  3949. lStatus = RegQueryValueExA (hDriverPerf,
  3950. caszOpen,
  3951. NULL,
  3952. & dwType,
  3953. (LPBYTE) & szOpenProcName[0],
  3954. & dwSize);
  3955. }
  3956. __except (EXCEPTION_EXECUTE_HANDLER) {
  3957. lStatus = GetExceptionCode();
  3958. }
  3959. // unable to continue if error
  3960. if (lStatus != ERROR_SUCCESS) {
  3961. TRACE((WINPERF_DBG_TRACE_ERROR),
  3962. (& LoadPerfGuid,
  3963. __LINE__,
  3964. LOADPERF_OPENCOUNTERANDBUILDMOFFILE,
  3965. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_STR, 2),
  3966. lStatus,
  3967. TRACE_WSTR(lpDriverName),
  3968. TRACE_STR(caszOpen),
  3969. NULL));
  3970. goto MakeMofErrorExit;
  3971. }
  3972. // get collect procedure name
  3973. dwType = 0;
  3974. dwSize = sizeof(szCollectProcName);
  3975. __try {
  3976. lStatus = RegQueryValueExA (hDriverPerf,
  3977. caszCollect,
  3978. NULL,
  3979. & dwType,
  3980. (LPBYTE) & szCollectProcName[0],
  3981. & dwSize);
  3982. }
  3983. __except (EXCEPTION_EXECUTE_HANDLER) {
  3984. lStatus = GetExceptionCode();
  3985. }
  3986. // unable to continue if error
  3987. if (lStatus != ERROR_SUCCESS) {
  3988. TRACE((WINPERF_DBG_TRACE_ERROR),
  3989. (& LoadPerfGuid,
  3990. __LINE__,
  3991. LOADPERF_OPENCOUNTERANDBUILDMOFFILE,
  3992. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_STR, 2),
  3993. lStatus,
  3994. TRACE_WSTR(lpDriverName),
  3995. TRACE_STR(caszCollect),
  3996. NULL));
  3997. goto MakeMofErrorExit;
  3998. }
  3999. // get close procedure name
  4000. dwType = 0;
  4001. dwSize = sizeof(szCloseProcName);
  4002. __try {
  4003. lStatus = RegQueryValueExA (hDriverPerf,
  4004. caszClose,
  4005. NULL,
  4006. & dwType,
  4007. (LPBYTE) & szCloseProcName[0],
  4008. & dwSize);
  4009. }
  4010. __except (EXCEPTION_EXECUTE_HANDLER) {
  4011. lStatus = GetExceptionCode();
  4012. }
  4013. // unable to continue if error
  4014. if (lStatus != ERROR_SUCCESS) {
  4015. TRACE((WINPERF_DBG_TRACE_ERROR),
  4016. (& LoadPerfGuid,
  4017. __LINE__,
  4018. LOADPERF_OPENCOUNTERANDBUILDMOFFILE,
  4019. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_STR, 2),
  4020. lStatus,
  4021. TRACE_WSTR(lpDriverName),
  4022. TRACE_STR(caszClose),
  4023. NULL));
  4024. goto MakeMofErrorExit;
  4025. }
  4026. // load perf counter library
  4027. hPerfLibrary = LoadLibraryW (wszPerfLibraryName);
  4028. if (hPerfLibrary == NULL) {
  4029. lStatus = GetLastError();
  4030. TRACE((WINPERF_DBG_TRACE_ERROR),
  4031. (& LoadPerfGuid,
  4032. __LINE__,
  4033. LOADPERF_OPENCOUNTERANDBUILDMOFFILE,
  4034. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  4035. lStatus,
  4036. TRACE_WSTR(lpDriverName),
  4037. TRACE_WSTR(wszPerfLibraryName),
  4038. NULL));
  4039. goto MakeMofErrorExit;
  4040. }
  4041. // get open procedure pointer
  4042. pOpenProc = (PM_OPEN_PROC *) GetProcAddress (
  4043. hPerfLibrary,
  4044. szOpenProcName);
  4045. if (pOpenProc == NULL) {
  4046. lStatus = GetLastError();
  4047. TRACE((WINPERF_DBG_TRACE_ERROR),
  4048. (& LoadPerfGuid,
  4049. __LINE__,
  4050. LOADPERF_OPENCOUNTERANDBUILDMOFFILE,
  4051. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_STR, 2),
  4052. lStatus,
  4053. TRACE_WSTR(lpDriverName),
  4054. TRACE_STR(szOpenProcName),
  4055. NULL));
  4056. goto MakeMofErrorExit;
  4057. }
  4058. // get collect procedure pointer
  4059. pCollectProc = (PM_COLLECT_PROC *) GetProcAddress (
  4060. hPerfLibrary,
  4061. szCollectProcName);
  4062. if (pCollectProc == NULL) {
  4063. lStatus = GetLastError();
  4064. TRACE((WINPERF_DBG_TRACE_ERROR),
  4065. (& LoadPerfGuid,
  4066. __LINE__,
  4067. LOADPERF_OPENCOUNTERANDBUILDMOFFILE,
  4068. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_STR, 2),
  4069. lStatus,
  4070. TRACE_WSTR(lpDriverName),
  4071. TRACE_STR(szCollectProcName),
  4072. NULL));
  4073. goto MakeMofErrorExit;
  4074. }
  4075. // get close procedure pointer
  4076. pCloseProc = (PM_CLOSE_PROC *) GetProcAddress (
  4077. hPerfLibrary,
  4078. szCloseProcName);
  4079. if (pCloseProc == NULL) {
  4080. lStatus = GetLastError();
  4081. TRACE((WINPERF_DBG_TRACE_ERROR),
  4082. (& LoadPerfGuid,
  4083. __LINE__,
  4084. LOADPERF_OPENCOUNTERANDBUILDMOFFILE,
  4085. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_STR, 2),
  4086. lStatus,
  4087. TRACE_WSTR(lpDriverName),
  4088. TRACE_STR(szCloseProcName),
  4089. NULL));
  4090. goto MakeMofErrorExit;
  4091. }
  4092. // call open procedure to initialize the counter
  4093. __try {
  4094. lStatus = (*pOpenProc)((LPWSTR)L"");
  4095. } __except (EXCEPTION_EXECUTE_HANDLER) {
  4096. lStatus = GetExceptionCode();
  4097. }
  4098. // unable to continue if error
  4099. if (lStatus != ERROR_SUCCESS) {
  4100. goto MakeMofErrorExit;
  4101. }
  4102. dwPerfBufferSize = 0;
  4103. // call the collect function to get a buffer
  4104. do {
  4105. // allocate a query buffer to pass to the collect function
  4106. dwPerfBufferSize += 0x8000;
  4107. if (pPerfBuffer == NULL) {
  4108. pPerfBuffer = (LPBYTE) MemoryAllocate (dwPerfBufferSize);
  4109. } else {
  4110. // if buffer is too small, resize and try again
  4111. pPerfBuffer = (LPBYTE) MemoryResize (pPerfBuffer, dwPerfBufferSize);
  4112. }
  4113. if (pPerfBuffer == NULL) {
  4114. goto MakeMofErrorExit;
  4115. }
  4116. dwSize = dwPerfBufferSize;
  4117. dwType = 0; // count of object types
  4118. pPerfBufferArg = pPerfBuffer;
  4119. lStatus = (* pCollectProc) (
  4120. (LPWSTR)L"Global",
  4121. &pPerfBufferArg,
  4122. &dwSize,
  4123. &dwType);
  4124. } while (lStatus == ERROR_MORE_DATA);
  4125. if (lStatus != ERROR_SUCCESS) {
  4126. goto MakeMofErrorExit;
  4127. }
  4128. // create temporary file for writing the MOF to
  4129. hMofFile = CreateFileW (
  4130. MofFilename,
  4131. GENERIC_WRITE,
  4132. 0, // no sharing
  4133. NULL, // default security
  4134. CREATE_ALWAYS, // always start fresh
  4135. FILE_ATTRIBUTE_NORMAL, // nothing special
  4136. NULL); // no template
  4137. if (hMofFile == INVALID_HANDLE_VALUE) {
  4138. // unable to create MOF file
  4139. lStatus = GetLastError();
  4140. TRACE((WINPERF_DBG_TRACE_ERROR),
  4141. (& LoadPerfGuid,
  4142. __LINE__,
  4143. LOADPERF_OPENCOUNTERANDBUILDMOFFILE,
  4144. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  4145. lStatus,
  4146. TRACE_WSTR(lpDriverName),
  4147. TRACE_WSTR(MofFilename),
  4148. NULL));
  4149. goto MakeMofErrorExit;
  4150. }
  4151. lstrcpyW (szProviderName, wszPerfLibraryName);
  4152. dwProviderNameSize = (sizeof(szProviderName) / sizeof(szProviderName[0]));
  4153. dwMofBufferSize = (sizeof(szMofBuffer) / sizeof(szMofBuffer[0]));
  4154. lStatus = GenerateMofHeader (szMofBuffer, (LPTSTR)ComputerName, &dwMofBufferSize);
  4155. if (lStatus == ERROR_SUCCESS) {
  4156. lStatus = WriteWideStringToAnsiFile (hMofFile, szMofBuffer, &dwMofBufferSize);
  4157. }
  4158. PcDllInfo.szWbemProviderName = szProviderName;
  4159. PcDllInfo.szRegistryKey = (LPWSTR)lpDriverName;
  4160. // for each object returned
  4161. pThisObject = (PPERF_OBJECT_TYPE)pPerfBuffer;
  4162. for (dwThisObject = 0; dwThisObject < dwType; dwThisObject++) {
  4163. PcDllInfo.szClassGuid = (LPWSTR)L"";
  4164. // look up class guid string in table passed in
  4165. if (plObjectGuidTable != NULL) {
  4166. dwGuidIdx = 0;
  4167. while (dwGuidIdx < dwObjectGuidTableSize) {
  4168. if (pThisObject->ObjectNameTitleIndex == (DWORD)plObjectGuidTable[dwGuidIdx].PerfObjectId) {
  4169. PcDllInfo.szClassGuid = plObjectGuidTable[dwGuidIdx].GuidString;
  4170. break;
  4171. }
  4172. dwGuidIdx++;
  4173. }
  4174. }
  4175. if (PcDllInfo.szClassGuid[0] == 0) {
  4176. // try the standard list
  4177. PcDllInfo.szClassGuid = (LPWSTR)GetPerfObjectGuid (pThisObject->ObjectNameTitleIndex);
  4178. } else {
  4179. // just leave it blank
  4180. }
  4181. // create WBEM Class object for this perf object
  4182. dwMofBufferSize = (sizeof(szMofBuffer) / sizeof(szMofBuffer[0]));
  4183. lStatus = GenerateMofObject (szMofBuffer, &dwMofBufferSize,
  4184. &PcDllInfo,
  4185. pThisObject, lpCounterText, lpDisplayText, WM_GMO_RAW_DEFINITION);
  4186. if (lStatus == ERROR_SUCCESS) {
  4187. if (lStatus == ERROR_SUCCESS) {
  4188. lStatus = WriteWideStringToAnsiFile (
  4189. hMofFile, szMofBuffer, &dwMofBufferSize);
  4190. }
  4191. // for each counter defined in this object
  4192. pThisCounterDef = FirstCounter (pThisObject);
  4193. for (dwThisCounterDef = 0;
  4194. dwThisCounterDef < pThisObject->NumCounters;
  4195. dwThisCounterDef++) {
  4196. // define a WBEM property
  4197. dwMofBufferSize = (sizeof(szMofBuffer) / sizeof(szMofBuffer[0]));
  4198. lStatus = GenerateMofCounter (szMofBuffer, &dwMofBufferSize,
  4199. pThisCounterDef, lpCounterText,lpDisplayText, WM_GMO_RAW_DEFINITION);
  4200. if (lStatus == ERROR_SUCCESS) {
  4201. lStatus = WriteWideStringToAnsiFile (
  4202. hMofFile, szMofBuffer, &dwMofBufferSize);
  4203. }
  4204. pThisCounterDef = NextCounter (pThisCounterDef);
  4205. }
  4206. dwMofBufferSize = (sizeof(szMofBuffer) / sizeof(szMofBuffer[0]));
  4207. lStatus = GenerateMofObjectTail (szMofBuffer, &dwMofBufferSize);
  4208. if (lStatus == ERROR_SUCCESS) {
  4209. lStatus = WriteWideStringToAnsiFile (
  4210. hMofFile, szMofBuffer, &dwMofBufferSize);
  4211. }
  4212. }
  4213. // end for each object
  4214. pThisObject = NextObject (pThisObject);
  4215. }
  4216. // write end of file
  4217. SetEndOfFile(hMofFile);
  4218. CloseHandle(hMofFile);
  4219. // call close proc
  4220. lStatus = (* pCloseProc)();
  4221. TRACE((WINPERF_DBG_TRACE_INFO),
  4222. (& LoadPerfGuid,
  4223. __LINE__,
  4224. LOADPERF_OPENCOUNTERANDBUILDMOFFILE,
  4225. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2) |
  4226. ARG_DEF(ARG_TYPE_WSTR, 3) | ARG_DEF(ARG_TYPE_STR, 4) |
  4227. ARG_DEF(ARG_TYPE_STR, 5) | ARG_DEF(ARG_TYPE_STR, 6),
  4228. lStatus,
  4229. TRACE_WSTR(lpDriverName),
  4230. TRACE_WSTR(MofFilename),
  4231. TRACE_WSTR(wszPerfLibraryName),
  4232. TRACE_STR(szOpenProcName),
  4233. TRACE_STR(szCollectProcName),
  4234. TRACE_STR(szCloseProcName),
  4235. NULL));
  4236. MakeMofErrorExit:
  4237. // close the registry key if necessary
  4238. if ((hKeyMachine != HKEY_LOCAL_MACHINE) &&
  4239. (hKeyMachine != NULL)) {
  4240. RegCloseKey (hKeyMachine);
  4241. }
  4242. if (hDriverPerf != NULL) RegCloseKey (hDriverPerf);
  4243. if (lpCounterText == NULL) MemoryFree (lpCounterText);
  4244. if (lpDisplayText == NULL) MemoryFree (lpDisplayText);
  4245. // MemoryFree perf counter library
  4246. if (hPerfLibrary != NULL) FreeLibrary (hPerfLibrary);
  4247. // MemoryFree the collection buffer
  4248. if (pPerfBuffer != NULL) MemoryFree (pPerfBuffer);
  4249. // return
  4250. return (DWORD)lStatus;
  4251. }
  4252. LOADPERF_FUNCTION
  4253. InstallPerfDllW (
  4254. IN LPCWSTR szComputerName,
  4255. IN LPCWSTR lpIniFile,
  4256. IN ULONG_PTR dwFlags
  4257. )
  4258. {
  4259. LPWSTR lpDriverName = NULL;
  4260. WCHAR MofFilename[MAX_PATH];
  4261. PERFOBJECT_LOOKUP plObjectGuidTable[16];
  4262. DWORD dwObjectGuidTableSize;
  4263. DWORD dwObjectIndex;
  4264. LANGUAGE_LIST_ELEMENT LangList;
  4265. PSYMBOL_TABLE_ENTRY SymbolTable = NULL;
  4266. DWORD ErrorCode = ERROR_SUCCESS;
  4267. DWORD dwIndexValues[4] = {0,0,0,0};
  4268. HKEY hKeyMachine = HKEY_LOCAL_MACHINE;
  4269. HKEY hKeyDriver = NULL;
  4270. WinPerfStartTrace(NULL);
  4271. bQuietMode = (BOOL)((dwFlags & LOADPERF_FLAGS_DISPLAY_USER_MSGS) == 0);
  4272. // initialize the object GUID table
  4273. memset (plObjectGuidTable, 0, sizeof (plObjectGuidTable));
  4274. dwObjectGuidTableSize = sizeof (plObjectGuidTable) / sizeof (plObjectGuidTable[0]) ;
  4275. if (szComputerName == NULL) {
  4276. ComputerName[0] = 0; // use the local computer
  4277. } else {
  4278. if (lstrlenW(szComputerName) < FILE_NAME_BUFFER_SIZE) {
  4279. lstrcpyW (ComputerName, szComputerName);
  4280. } else {
  4281. ErrorCode = ERROR_INVALID_PARAMETER;
  4282. }
  4283. }
  4284. if ((lpIniFile != NULL) && (ErrorCode == ERROR_SUCCESS)) {
  4285. lpDriverName = MemoryAllocate (MAX_PATH * sizeof (WCHAR));
  4286. if (lpDriverName == NULL) {
  4287. ErrorCode = ERROR_OUTOFMEMORY;
  4288. goto EndOfMain;
  4289. }
  4290. // valid filename (i.e. file exists)
  4291. // get device driver name
  4292. if (!GetDriverName ((LPWSTR)lpIniFile, &lpDriverName)) {
  4293. OUTPUT_MESSAGE (GetFormatResource(LC_DEVNAME_ERR_1), lpIniFile);
  4294. OUTPUT_MESSAGE (GetFormatResource(LC_DEVNAME_ERR_2));
  4295. ErrorCode = GetLastError();
  4296. MemoryFree(lpDriverName);
  4297. lpDriverName = NULL;
  4298. goto EndOfMain;
  4299. }
  4300. hKeyMachine = HKEY_LOCAL_MACHINE;
  4301. if (ComputerName[0]) {
  4302. ErrorCode = RegConnectRegistry (
  4303. (LPTSTR) ComputerName,
  4304. HKEY_LOCAL_MACHINE,
  4305. & hKeyMachine);
  4306. if (ErrorCode != ERROR_SUCCESS) {
  4307. hKeyMachine = HKEY_LOCAL_MACHINE;
  4308. }
  4309. }
  4310. RtlZeroMemory(szServiceDisplayName, MAX_PATH * sizeof(TCHAR));
  4311. RtlZeroMemory(szServiceName, MAX_PATH * sizeof(TCHAR));
  4312. lstrcpy(szServiceName, DriverPathRoot);
  4313. lstrcat(szServiceName, Slash);
  4314. lstrcat(szServiceName, lpDriverName);
  4315. ErrorCode = RegOpenKeyEx(hKeyMachine,
  4316. szServiceName,
  4317. RESERVED,
  4318. KEY_READ | KEY_WRITE,
  4319. & hKeyDriver);
  4320. if (ErrorCode == ERROR_SUCCESS) {
  4321. DWORD dwType = 0;
  4322. DWORD dwBufferSize = MAX_PATH * sizeof(TCHAR);
  4323. __try {
  4324. ErrorCode = RegQueryValueEx(hKeyDriver,
  4325. szDisplayName,
  4326. RESERVED,
  4327. & dwType,
  4328. (LPBYTE) szServiceDisplayName,
  4329. & dwBufferSize);
  4330. }
  4331. __except (EXCEPTION_EXECUTE_HANDLER) {
  4332. ErrorCode = GetExceptionCode();
  4333. }
  4334. }
  4335. if (ErrorCode != ERROR_SUCCESS) {
  4336. lstrcpy(szServiceDisplayName, lpDriverName);
  4337. }
  4338. if (hKeyDriver != NULL) {
  4339. RegCloseKey(hKeyDriver);
  4340. }
  4341. if (hKeyMachine != NULL && hKeyMachine != HKEY_LOCAL_MACHINE) {
  4342. RegCloseKey(hKeyMachine);
  4343. }
  4344. ErrorCode = ERROR_SUCCESS;
  4345. if (!BuildLanguageTables((LPWSTR)lpIniFile, &LangList)) {
  4346. OUTPUT_MESSAGE (GetFormatResource(LC_LANGLIST_ERR), lpIniFile);
  4347. ErrorCode = GetLastError();
  4348. goto EndOfMain;
  4349. }
  4350. if (!LoadIncludeFile((LPWSTR)lpIniFile, &SymbolTable)) {
  4351. // open errors displayed in routine
  4352. ErrorCode = GetLastError();
  4353. goto EndOfMain;
  4354. }
  4355. if (!UpdateRegistry((LPWSTR) lpIniFile,
  4356. lpDriverName,
  4357. & LangList,
  4358. SymbolTable,
  4359. plObjectGuidTable,
  4360. & dwObjectGuidTableSize,
  4361. (LPDWORD) & dwIndexValues)) {
  4362. ErrorCode = GetLastError();
  4363. goto EndOfMain;
  4364. }
  4365. if (ComputerName[0] == 0) { // until remote is supported
  4366. LodctrSetSericeAsTrusted(
  4367. lpIniFile,
  4368. NULL,
  4369. lpDriverName);
  4370. }
  4371. // now it's time to load the MOF for WBEM access
  4372. if (!(dwFlags & LOADPERF_FLAGS_LOAD_REGISTRY_ONLY)) {
  4373. // the didn't say not to, so create if necessary and
  4374. // load the MOF into the CIMOM
  4375. // see if there's a mof file in the Ini file (if so, use that)
  4376. ErrorCode = GetMofFileFromIni (lpIniFile, MofFilename);
  4377. if (ErrorCode == ERROR_FILE_NOT_FOUND) {
  4378. WCHAR wszTempFilename[MAX_PATH];
  4379. MakeTempFileName (lpDriverName, wszTempFilename);
  4380. // otherwise we'll try to make one
  4381. ErrorCode = OpenCounterAndBuildMofFile (
  4382. lpDriverName, wszTempFilename,
  4383. plObjectGuidTable,
  4384. dwObjectGuidTableSize);
  4385. if (ErrorCode == ERROR_SUCCESS) {
  4386. lstrcpyW (MofFilename, wszTempFilename);
  4387. } else {
  4388. // report unable to create mof file
  4389. ReportLoadPerfEvent(
  4390. EVENTLOG_WARNING_TYPE, // error type
  4391. (DWORD) LDPRFMSG_NO_MOF_FILE_CREATED, // event,
  4392. 2, ErrorCode, __LINE__, 0, 0,
  4393. 2, (LPWSTR) lpDriverName, wszTempFilename, NULL);
  4394. TRACE((WINPERF_DBG_TRACE_ERROR),
  4395. (& LoadPerfGuid,
  4396. __LINE__,
  4397. LOADPERF_INSTALLPERFDLL,
  4398. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  4399. ErrorCode,
  4400. TRACE_WSTR(lpDriverName),
  4401. TRACE_WSTR(wszTempFilename),
  4402. NULL));
  4403. }
  4404. }
  4405. // now let's load it into the CIMOM
  4406. if (ErrorCode == ERROR_SUCCESS) {
  4407. ErrorCode = LodctrCompileMofFile ( ComputerName, MofFilename );
  4408. if (ErrorCode != ERROR_SUCCESS) {
  4409. // display error message
  4410. ReportLoadPerfEvent(
  4411. EVENTLOG_WARNING_TYPE, // error type
  4412. (DWORD) LDPRFMSG_NO_MOF_FILE_LOADED, // event,
  4413. 2, ErrorCode, __LINE__, 0, 0,
  4414. 2, (LPWSTR) lpDriverName, MofFilename, NULL);
  4415. TRACE((WINPERF_DBG_TRACE_ERROR),
  4416. (& LoadPerfGuid,
  4417. __LINE__,
  4418. LOADPERF_INSTALLPERFDLL,
  4419. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  4420. ErrorCode,
  4421. TRACE_WSTR(lpDriverName),
  4422. TRACE_WSTR(MofFilename),
  4423. NULL));
  4424. }
  4425. }
  4426. // toss the mof if they don't want it
  4427. if ((ErrorCode == ERROR_SUCCESS) &&
  4428. (dwFlags & LOADPERF_FLAGS_DELETE_MOF_ON_EXIT)) {
  4429. // display error message
  4430. ReportLoadPerfEvent(
  4431. EVENTLOG_WARNING_TYPE, // error type
  4432. (DWORD) LDPRFMSG_CANT_DELETE_MOF, // event,
  4433. 1, __LINE__, 0, 0, 0,
  4434. 1, (LPWSTR) lpDriverName, NULL, NULL);
  4435. }
  4436. // reset the error code to success since all worked before the
  4437. // MOF operations.
  4438. ErrorCode = ERROR_SUCCESS;
  4439. }
  4440. // signal WMI with this change, ignore WMI return error.
  4441. SignalWmiWithNewData (WMI_LODCTR_EVENT);
  4442. } else {
  4443. if (lpIniFile == NULL) {
  4444. OUTPUT_MESSAGE (GetFormatResource(LC_NO_INIFILE), lpIniFile);
  4445. ErrorCode = ERROR_OPEN_FAILED;
  4446. } else {
  4447. //Incorrect Command Format
  4448. // display command line usage
  4449. if (!bQuietMode) {
  4450. DisplayCommandHelp(LC_FIRST_CMD_HELP, LC_LAST_CMD_HELP);
  4451. }
  4452. ErrorCode = ERROR_INVALID_PARAMETER;
  4453. }
  4454. }
  4455. EndOfMain:
  4456. if (ErrorCode != ERROR_SUCCESS) {
  4457. if (ErrorCode == ERROR_ALREADY_EXISTS) {
  4458. ReportLoadPerfEvent(
  4459. EVENTLOG_INFORMATION_TYPE, // error type
  4460. (DWORD) LDPRFMSG_ALREADY_EXIST, // event,
  4461. 1, __LINE__, 0, 0, 0,
  4462. 2, (LPWSTR) lpDriverName, (LPWSTR) szServiceDisplayName, NULL);
  4463. ErrorCode = ERROR_SUCCESS;
  4464. }
  4465. else if (lpDriverName != NULL) {
  4466. ReportLoadPerfEvent(
  4467. EVENTLOG_ERROR_TYPE, // error type
  4468. (DWORD) LDPRFMSG_LOAD_FAILURE, // event,
  4469. 2, ErrorCode, __LINE__, 0, 0,
  4470. 1, (LPWSTR) lpDriverName, NULL, NULL);
  4471. }
  4472. else if (lpIniFile != NULL) {
  4473. ReportLoadPerfEvent(
  4474. EVENTLOG_ERROR_TYPE, // error type
  4475. (DWORD) LDPRFMSG_LOAD_FAILURE, // event,
  4476. 2, ErrorCode, __LINE__, 0, 0,
  4477. 1, (LPWSTR) lpIniFile, NULL, NULL);
  4478. }
  4479. else {
  4480. ReportLoadPerfEvent(
  4481. EVENTLOG_ERROR_TYPE, // error type
  4482. (DWORD) LDPRFMSG_LOAD_FAILURE, // event,
  4483. 2, ErrorCode, __LINE__, 0, 0,
  4484. 0, NULL, NULL, NULL);
  4485. }
  4486. } else {
  4487. // log success message
  4488. ReportLoadPerfEvent(
  4489. EVENTLOG_INFORMATION_TYPE, // error type
  4490. (DWORD) LDPRFMSG_LOAD_SUCCESS, // event,
  4491. 1, __LINE__, 0, 0, 0,
  4492. 2, (LPWSTR) lpDriverName, (LPWSTR) szServiceDisplayName, NULL);
  4493. }
  4494. TRACE((WINPERF_DBG_TRACE_INFO),
  4495. (& LoadPerfGuid,
  4496. __LINE__,
  4497. LOADPERF_INSTALLPERFDLL,
  4498. ARG_DEF(ARG_TYPE_WSTR, 1),
  4499. ErrorCode,
  4500. TRACE_WSTR(lpDriverName),
  4501. NULL));
  4502. for (dwObjectIndex = 0; dwObjectIndex < dwObjectGuidTableSize; dwObjectIndex++) {
  4503. if (plObjectGuidTable[dwObjectIndex].GuidString != NULL) {
  4504. MemoryFree (plObjectGuidTable[dwObjectIndex].GuidString);
  4505. }
  4506. }
  4507. if (lpDriverName) MemoryFree (lpDriverName);
  4508. return (ErrorCode);
  4509. }
  4510. LOADPERF_FUNCTION
  4511. InstallPerfDllA (
  4512. IN LPCSTR szComputerName,
  4513. IN LPCSTR szIniFile,
  4514. IN ULONG_PTR dwFlags
  4515. )
  4516. {
  4517. LPWSTR lpWideComputerName = NULL;
  4518. LPWSTR lpWideFileName = NULL;
  4519. DWORD dwStrLen;
  4520. DWORD lReturn;
  4521. if (szIniFile != NULL) {
  4522. //length of string including terminator
  4523. dwStrLen = lstrlenA(szIniFile) + 1;
  4524. lpWideFileName = MemoryAllocate (dwStrLen * sizeof(WCHAR));
  4525. if (lpWideFileName != NULL) {
  4526. mbstowcs (lpWideFileName, szIniFile, dwStrLen);
  4527. lReturn = ERROR_SUCCESS;
  4528. } else {
  4529. lReturn = ERROR_OUTOFMEMORY;
  4530. }
  4531. } else {
  4532. lReturn = ERROR_INVALID_PARAMETER;
  4533. }
  4534. if (lReturn == ERROR_SUCCESS) {
  4535. if (szComputerName != NULL) {
  4536. dwStrLen = lstrlenA (szComputerName) + 1;
  4537. lpWideComputerName = (LPWSTR)MemoryAllocate (dwStrLen * sizeof(WCHAR));
  4538. if (lpWideComputerName != NULL) {
  4539. mbstowcs (lpWideComputerName, szComputerName, dwStrLen);
  4540. lReturn = ERROR_SUCCESS;
  4541. } else {
  4542. lReturn = ERROR_OUTOFMEMORY;
  4543. }
  4544. } else {
  4545. lpWideComputerName = NULL;
  4546. lReturn = ERROR_SUCCESS;
  4547. }
  4548. }
  4549. if (lReturn == ERROR_SUCCESS) {
  4550. lReturn = InstallPerfDllW (
  4551. lpWideComputerName,
  4552. lpWideFileName,
  4553. dwFlags);
  4554. MemoryFree (lpWideFileName);
  4555. MemoryFree (lpWideComputerName);
  4556. }
  4557. return lReturn;
  4558. }
  4559. LOADPERF_FUNCTION
  4560. LoadPerfCounterTextStringsW (
  4561. IN LPWSTR lpCommandLine,
  4562. IN BOOL bQuietModeArg
  4563. )
  4564. /*++
  4565. LoadPerfCounterTexStringsW
  4566. loads the perf counter strings into the registry and updates
  4567. the perf counter text registry values
  4568. Arguments
  4569. command line string in the following format:
  4570. "/?" displays the usage text
  4571. "file.ini" loads the perf strings found in file.ini
  4572. "\\machine file.ini" loads the perf strings found onto machine
  4573. ReturnValue
  4574. 0 (ERROR_SUCCESS) if command was processed
  4575. Non-Zero if command error was detected.
  4576. --*/
  4577. {
  4578. LPWSTR lpIniFile;
  4579. DWORD ErrorCode = ERROR_SUCCESS;
  4580. ULONG_PTR dwFlags = 0;
  4581. WinPerfStartTrace(NULL);
  4582. dwFlags |= (bQuietModeArg ? 0 : LOADPERF_FLAGS_DISPLAY_USER_MSGS);
  4583. lpIniFile = MemoryAllocate (MAX_PATH * sizeof (TCHAR));
  4584. if (!lpIniFile) {
  4585. return (ERROR_OUTOFMEMORY);
  4586. }
  4587. *lpIniFile = 0;
  4588. // init last error value
  4589. SetLastError (ERROR_SUCCESS);
  4590. // read command line to determine what to do
  4591. if (GetFileFromCommandLine (lpCommandLine, &lpIniFile, &dwFlags)) {
  4592. dwFlags |= LOADPERF_FLAGS_LOAD_REGISTRY_ONLY; // don't do mof's even if they want
  4593. // call installation function
  4594. ErrorCode = InstallPerfDllW (ComputerName, lpIniFile, dwFlags);
  4595. } else {
  4596. //Incorrect Command Format
  4597. // display command line usage
  4598. if (!bQuietModeArg) {
  4599. DisplayCommandHelp(LC_FIRST_CMD_HELP, LC_LAST_CMD_HELP);
  4600. }
  4601. ErrorCode = ERROR_INVALID_PARAMETER;
  4602. }
  4603. if (lpIniFile) MemoryFree (lpIniFile);
  4604. return (ErrorCode);
  4605. }
  4606. LOADPERF_FUNCTION
  4607. LoadPerfCounterTextStringsA (
  4608. IN LPSTR lpAnsiCommandLine,
  4609. IN BOOL bQuietModeArg
  4610. )
  4611. {
  4612. LPWSTR lpWideCommandLine;
  4613. DWORD dwStrLen;
  4614. DWORD lReturn;
  4615. if (lpAnsiCommandLine != NULL) {
  4616. //length of string including terminator
  4617. dwStrLen = lstrlenA(lpAnsiCommandLine) + 1;
  4618. lpWideCommandLine = MemoryAllocate (dwStrLen * sizeof(WCHAR));
  4619. if (lpWideCommandLine != NULL) {
  4620. mbstowcs (lpWideCommandLine, lpAnsiCommandLine, dwStrLen);
  4621. lReturn = LoadPerfCounterTextStringsW (lpWideCommandLine,
  4622. bQuietModeArg );
  4623. MemoryFree (lpWideCommandLine);
  4624. } else {
  4625. lReturn = GetLastError();
  4626. }
  4627. } else {
  4628. lReturn = ERROR_INVALID_PARAMETER;
  4629. }
  4630. return lReturn;
  4631. }
  4632. LOADPERF_FUNCTION
  4633. LoadMofFromInstalledServiceW (
  4634. IN LPCWSTR szServiceName, // service to create mof for
  4635. IN LPCWSTR szMofFilenameArg, // name of file to create
  4636. IN ULONG_PTR dwFlags // flags
  4637. )
  4638. {
  4639. DWORD ErrorCode;
  4640. WCHAR wszTempFilename[MAX_PATH];
  4641. WinPerfStartTrace(NULL);
  4642. if (szServiceName == NULL) {
  4643. ErrorCode = ERROR_INVALID_PARAMETER;
  4644. } else {
  4645. ZeroMemory(wszTempFilename, sizeof(WCHAR) * MAX_PATH);
  4646. if (szMofFilenameArg == NULL) {
  4647. MakeTempFileName (szServiceName, wszTempFilename);
  4648. } else {
  4649. lstrcpyW (wszTempFilename, szMofFilenameArg);
  4650. }
  4651. // otherwise we'll try to make one
  4652. ErrorCode = OpenCounterAndBuildMofFile (
  4653. szServiceName, wszTempFilename,
  4654. NULL, 0L);
  4655. TRACE((WINPERF_DBG_TRACE_INFO),
  4656. (& LoadPerfGuid,
  4657. __LINE__,
  4658. LOADPERF_LOADMOFFROMINSTALLEDSERVICE,
  4659. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  4660. ErrorCode,
  4661. TRACE_WSTR(szServiceName),
  4662. TRACE_WSTR(wszTempFilename),
  4663. NULL));
  4664. // now let's load it into the CIMOM
  4665. if (ErrorCode == ERROR_SUCCESS) {
  4666. ErrorCode = SignalWmiWithNewData (WMI_LODCTR_EVENT);
  4667. } else {
  4668. ReportLoadPerfEvent(
  4669. EVENTLOG_WARNING_TYPE, // error type
  4670. (DWORD) LDPRFMSG_NO_MOF_FILE_CREATED, // event,
  4671. 2, ErrorCode, __LINE__, 0, 0,
  4672. 1, (LPWSTR) szServiceName, NULL, NULL);
  4673. }
  4674. // if everything is going well and the caller
  4675. // wants to delete the file created to contain the MOF
  4676. // then delete it
  4677. if (ErrorCode == ERROR_SUCCESS) {
  4678. if ((dwFlags & LOADPERF_FLAGS_DELETE_MOF_ON_EXIT) && (szMofFilenameArg == NULL)) {
  4679. if (!DeleteFile(wszTempFilename)) {
  4680. ErrorCode = GetLastError();
  4681. }
  4682. }
  4683. } else {
  4684. ReportLoadPerfEvent(
  4685. EVENTLOG_WARNING_TYPE, // error type
  4686. (DWORD) LDPRFMSG_NO_MOF_FILE_LOADED, // event,
  4687. 2, ErrorCode, __LINE__, 0, 0,
  4688. 1, (LPWSTR) szServiceName, NULL, NULL);
  4689. TRACE((WINPERF_DBG_TRACE_WARNING),
  4690. (& LoadPerfGuid,
  4691. __LINE__,
  4692. LOADPERF_LOADMOFFROMINSTALLEDSERVICE,
  4693. ARG_DEF(ARG_TYPE_WSTR, 1),
  4694. ErrorCode,
  4695. TRACE_WSTR(szServiceName),
  4696. NULL));
  4697. }
  4698. }
  4699. return (ErrorCode);
  4700. }
  4701. LOADPERF_FUNCTION
  4702. LoadMofFromInstalledServiceA (
  4703. IN LPCSTR szServiceName, // service to create mof for
  4704. IN LPCSTR szMofFilenameArg, // name of file to create
  4705. IN ULONG_PTR dwFlags // delete mof on exit
  4706. )
  4707. {
  4708. DWORD ErrorCode = ERROR_SUCCESS;
  4709. LPWSTR wszServiceName;
  4710. DWORD dwServiceNameLen;
  4711. LPWSTR wszMofFilename;
  4712. DWORD dwMofFilenameLen;
  4713. if (szServiceName == NULL) {
  4714. ErrorCode = ERROR_INVALID_PARAMETER;
  4715. } else {
  4716. dwServiceNameLen = lstrlenA(szServiceName) + 1;
  4717. wszServiceName = MemoryAllocate (
  4718. dwServiceNameLen * sizeof(WCHAR));
  4719. if (wszServiceName == NULL) {
  4720. ErrorCode = ERROR_OUTOFMEMORY;
  4721. } else {
  4722. mbstowcs (wszServiceName, szServiceName, dwServiceNameLen);
  4723. if (szMofFilenameArg != NULL) {
  4724. dwMofFilenameLen = lstrlenA(szMofFilenameArg) + 1;
  4725. wszMofFilename = MemoryAllocate (dwMofFilenameLen);
  4726. if (wszMofFilename != NULL) {
  4727. mbstowcs (wszMofFilename, szMofFilenameArg, dwMofFilenameLen);
  4728. } else {
  4729. ErrorCode = ERROR_OUTOFMEMORY;
  4730. }
  4731. } else {
  4732. wszMofFilename = NULL;
  4733. }
  4734. if (ErrorCode == ERROR_SUCCESS) {
  4735. ErrorCode = LoadMofFromInstalledServiceW (
  4736. wszServiceName,
  4737. wszMofFilename,
  4738. dwFlags);
  4739. }
  4740. if (wszMofFilename != NULL) MemoryFree (wszMofFilename);
  4741. MemoryFree (wszServiceName);
  4742. }
  4743. }
  4744. return ErrorCode;
  4745. }
  4746. LOADPERF_FUNCTION
  4747. UpdatePerfNameFilesX (
  4748. IN LPCWSTR szNewCtrFilePath, // data file with new base counter strings
  4749. IN LPCWSTR szNewHlpFilePath, // data file with new base counter strings
  4750. IN LPWSTR szLanguageID, // Lang ID to update
  4751. IN ULONG_PTR dwFlags // flags
  4752. )
  4753. {
  4754. DWORD dwReturn = ERROR_SUCCESS;
  4755. LPWSTR szCtrNameIn = NULL;
  4756. LPWSTR szHlpNameIn = NULL;
  4757. LPWSTR szNewCtrStrings = NULL;
  4758. LPWSTR szNewHlpStrings = NULL;
  4759. LPWSTR szNewCtrMSZ = NULL;
  4760. LPWSTR szNewHlpMSZ = NULL;
  4761. WCHAR szSystemPath[MAX_PATH];
  4762. DWORD dwLength;
  4763. LPWSTR *pszNewNameTable = NULL;
  4764. LPWSTR *pszOldNameTable = NULL;
  4765. LPWSTR lpThisName;
  4766. LPWSTR szThisCtrString = NULL;
  4767. LPWSTR szThisHlpString = NULL;
  4768. WCHAR szLangSection[MAX_PATH];
  4769. DWORD dwOldLastEntry = 0;
  4770. DWORD dwNewLastEntry = 0;
  4771. DWORD dwStringSize;
  4772. DWORD dwHlpFileSize = 0, dwCtrFileSize = 0 ;
  4773. DWORD dwThisCounter;
  4774. DWORD dwSize;
  4775. DWORD dwLastBaseValue = 0;
  4776. DWORD dwType;
  4777. DWORD dwIndex;
  4778. HANDLE hCtrFileIn = INVALID_HANDLE_VALUE;
  4779. HANDLE hCtrFileMap = NULL;
  4780. HANDLE hHlpFileIn = INVALID_HANDLE_VALUE;
  4781. HANDLE hHlpFileMap = NULL;
  4782. HKEY hKeyPerflib;
  4783. WinPerfStartTrace(NULL);
  4784. if (szNewCtrFilePath == NULL) dwReturn = ERROR_INVALID_PARAMETER;
  4785. if ((szNewHlpFilePath == NULL) && !(dwFlags & LODCTR_UPNF_RESTORE)) dwReturn = ERROR_INVALID_PARAMETER;
  4786. if (szLanguageID == NULL) dwReturn = ERROR_INVALID_PARAMETER;
  4787. if (dwReturn == ERROR_SUCCESS) {
  4788. TRACE((WINPERF_DBG_TRACE_INFO),
  4789. (& LoadPerfGuid,
  4790. __LINE__,
  4791. LOADPERF_UPDATEPERFNAMEFILES,
  4792. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  4793. ERROR_SUCCESS,
  4794. TRACE_WSTR(szNewCtrFilePath),
  4795. TRACE_WSTR(szLanguageID),
  4796. NULL));
  4797. }
  4798. if ((dwReturn == ERROR_SUCCESS) && !(dwFlags & LODCTR_UPNF_RESTORE)) {
  4799. // save the original files, unless it's a restoration
  4800. MakeBackupCopyOfLanguageFiles (szLanguageID);
  4801. dwLength = ExpandEnvironmentStringsW ((LPCWSTR)L"%windir%\\system32",
  4802. (LPWSTR)szSystemPath, (sizeof(szSystemPath) / sizeof(szSystemPath[0])));
  4803. } else {
  4804. dwLength = 0;
  4805. SetLastError (dwReturn);
  4806. }
  4807. if (dwLength > 0) {
  4808. // create input filenames
  4809. szCtrNameIn = MemoryAllocate (MAX_PATH * 2 * sizeof (WCHAR));
  4810. szHlpNameIn = MemoryAllocate (MAX_PATH * 2 * sizeof (WCHAR));
  4811. if ((szCtrNameIn != NULL) && (szHlpNameIn != NULL)) {
  4812. ExpandEnvironmentStrings (szNewCtrFilePath, szCtrNameIn, (MAX_PATH * 2));
  4813. ExpandEnvironmentStrings (szNewHlpFilePath, szHlpNameIn, (MAX_PATH * 2));
  4814. } else {
  4815. dwReturn = ERROR_OUTOFMEMORY;
  4816. }
  4817. if (dwReturn == ERROR_SUCCESS) {
  4818. // open and map new files
  4819. hCtrFileIn = CreateFile (
  4820. szCtrNameIn, GENERIC_READ,
  4821. FILE_SHARE_READ, NULL, OPEN_EXISTING,
  4822. FILE_ATTRIBUTE_NORMAL, NULL);
  4823. if (hCtrFileIn != INVALID_HANDLE_VALUE) {
  4824. // map file
  4825. dwCtrFileSize = GetFileSize(hCtrFileIn, NULL);
  4826. if (dwCtrFileSize == 0xFFFFFFFF){
  4827. dwReturn =GetLastError();
  4828. }
  4829. hCtrFileMap = CreateFileMapping (
  4830. hCtrFileIn, NULL, PAGE_READONLY, 0, 0, NULL);
  4831. if (hCtrFileMap != NULL) {
  4832. szNewCtrStrings = (LPWSTR)MapViewOfFileEx (
  4833. hCtrFileMap, FILE_MAP_READ, 0, 0, 0, NULL);
  4834. if (szNewCtrStrings == NULL) {
  4835. dwReturn = GetLastError();
  4836. }
  4837. } else {
  4838. dwReturn = GetLastError();
  4839. }
  4840. } else {
  4841. dwReturn = GetLastError();
  4842. }
  4843. } else {
  4844. dwReturn = GetLastError();
  4845. }
  4846. if (dwReturn == ERROR_SUCCESS) {
  4847. // open and map new files
  4848. hHlpFileIn = CreateFile (
  4849. szHlpNameIn, GENERIC_READ,
  4850. FILE_SHARE_READ, NULL, OPEN_EXISTING,
  4851. FILE_ATTRIBUTE_NORMAL, NULL);
  4852. if (hHlpFileIn != INVALID_HANDLE_VALUE) {
  4853. // map file
  4854. dwHlpFileSize = GetFileSize (hHlpFileIn, NULL);
  4855. if (dwHlpFileSize == 0xFFFFFFFF){
  4856. dwReturn =GetLastError();
  4857. }
  4858. hHlpFileMap = CreateFileMapping (
  4859. hHlpFileIn, NULL, PAGE_READONLY, 0, 0, NULL);
  4860. if (hHlpFileMap != NULL) {
  4861. szNewHlpStrings = (LPWSTR)MapViewOfFileEx (
  4862. hHlpFileMap, FILE_MAP_READ, 0, 0, 0, NULL);
  4863. if (szNewHlpStrings == NULL) {
  4864. dwReturn = GetLastError();
  4865. }
  4866. } else {
  4867. dwReturn = GetLastError();
  4868. }
  4869. } else {
  4870. dwReturn = GetLastError();
  4871. }
  4872. } else {
  4873. dwReturn = GetLastError();
  4874. }
  4875. } else if (dwFlags & LODCTR_UPNF_RESTORE) {
  4876. szCtrNameIn = MemoryAllocate (MAX_PATH * 2 * sizeof (WCHAR));
  4877. if (szCtrNameIn != NULL) {
  4878. dwLength = ExpandEnvironmentStringsW (szNewCtrFilePath,
  4879. szCtrNameIn, (sizeof(szSystemPath) / sizeof(szSystemPath[0])));
  4880. dwNewLastEntry = GetPrivateProfileIntW (
  4881. (LPCWSTR)L"Perflib",
  4882. (LPCWSTR)L"Last Help",
  4883. -1,
  4884. szCtrNameIn);
  4885. if (dwNewLastEntry != (DWORD)-1) {
  4886. // get the input file size
  4887. hCtrFileIn = CreateFile (
  4888. szCtrNameIn, GENERIC_READ,
  4889. FILE_SHARE_READ, NULL, OPEN_EXISTING,
  4890. FILE_ATTRIBUTE_NORMAL, NULL);
  4891. if (hCtrFileIn != INVALID_HANDLE_VALUE) {
  4892. // map file
  4893. dwCtrFileSize = GetFileSize (hCtrFileIn, NULL);
  4894. } else {
  4895. dwCtrFileSize = 64 * 1024; // assign 64k if unable to read it
  4896. }
  4897. // load new values from ini file
  4898. szNewCtrStrings = (LPWSTR)MemoryAllocate (dwCtrFileSize * sizeof(WCHAR));
  4899. if (szNewCtrStrings) {
  4900. lstrcpyW (szLangSection, (LPCWSTR)L"Perfstrings_");
  4901. lstrcatW (szLangSection, szLanguageID);
  4902. dwSize = GetPrivateProfileSectionW (
  4903. szLangSection,
  4904. szNewCtrStrings,
  4905. dwCtrFileSize,
  4906. szCtrNameIn);
  4907. if (dwSize == 0) {
  4908. lstrcpyW (szLangSection, (LPCWSTR) L"Perfstrings_009");
  4909. dwSize = GetPrivateProfileSectionW(
  4910. szLangSection,
  4911. szNewCtrStrings,
  4912. dwCtrFileSize,
  4913. szCtrNameIn);
  4914. }
  4915. if (dwSize == 0) {
  4916. dwReturn = ERROR_FILE_INVALID;
  4917. } else {
  4918. // set file sizes
  4919. dwHlpFileSize = 0;
  4920. dwCtrFileSize = (dwSize+2) * sizeof(WCHAR);
  4921. }
  4922. } else {
  4923. dwReturn = ERROR_OUTOFMEMORY;
  4924. }
  4925. } else {
  4926. // unable to open input file or file is invalid
  4927. dwReturn = ERROR_FILE_INVALID;
  4928. }
  4929. } else {
  4930. dwReturn = ERROR_OUTOFMEMORY;
  4931. }
  4932. }
  4933. if ((dwReturn == ERROR_SUCCESS) && (!(dwFlags & LODCTR_UPNF_RESTORE))) {
  4934. // build name table of current strings
  4935. pszOldNameTable = BuildNameTable (
  4936. HKEY_LOCAL_MACHINE,
  4937. szLanguageID,
  4938. &dwOldLastEntry);
  4939. if (pszOldNameTable == NULL) {
  4940. dwReturn = GetLastError();
  4941. }
  4942. dwNewLastEntry = (dwOldLastEntry == 0) ? (PERFLIB_BASE_INDEX)
  4943. : (dwOldLastEntry);
  4944. }
  4945. else if (dwFlags & LODCTR_UPNF_RESTORE) {
  4946. dwOldLastEntry = dwNewLastEntry;
  4947. }
  4948. if (dwReturn == ERROR_SUCCESS) {
  4949. // build name table of new strings
  4950. pszNewNameTable = (LPWSTR *)MemoryAllocate(
  4951. (dwNewLastEntry + 2) * sizeof(LPWSTR)); // allow for index offset
  4952. if (pszNewNameTable != NULL) {
  4953. for (lpThisName = szNewCtrStrings;
  4954. *lpThisName;
  4955. lpThisName += (lstrlen(lpThisName)+1) ) {
  4956. // first string should be an integer (in decimal unicode digits)
  4957. dwThisCounter = wcstoul (lpThisName, NULL, 10);
  4958. if (dwThisCounter == 0) {
  4959. continue; // bad entry, try next
  4960. }
  4961. // point to corresponding counter name
  4962. if (dwFlags & LODCTR_UPNF_RESTORE) {
  4963. // point to string that follows the "=" char
  4964. lpThisName = wcschr (lpThisName, L'=');
  4965. if (lpThisName != NULL) {
  4966. lpThisName++;
  4967. } else {
  4968. continue;
  4969. }
  4970. } else {
  4971. // string is next in MSZ
  4972. lpThisName += (lstrlen(lpThisName)+1);
  4973. }
  4974. // and load array element;
  4975. pszNewNameTable[dwThisCounter] = lpThisName;
  4976. }
  4977. if (!(dwFlags & LODCTR_UPNF_RESTORE)) {
  4978. for (lpThisName = szNewHlpStrings;
  4979. *lpThisName;
  4980. lpThisName += (lstrlen(lpThisName)+1) ) {
  4981. // first string should be an integer (in decimal unicode digits)
  4982. dwThisCounter = wcstoul (lpThisName, NULL, 10);
  4983. if (dwThisCounter == 0) {
  4984. continue; // bad entry, try next
  4985. }
  4986. // point to corresponding counter name
  4987. lpThisName += (lstrlen(lpThisName)+1);
  4988. // and load array element;
  4989. pszNewNameTable[dwThisCounter] = lpThisName;
  4990. }
  4991. }
  4992. // allocate string buffers for the resulting string
  4993. // we want to make sure there's plenty of room so we'll make it
  4994. // the size of the input file + the current buffer
  4995. dwStringSize = dwHlpFileSize;
  4996. dwStringSize += dwCtrFileSize;
  4997. if (pszOldNameTable != NULL) {
  4998. dwStringSize += MemorySize(pszOldNameTable);
  4999. }
  5000. szNewCtrMSZ = MemoryAllocate (dwStringSize);
  5001. szNewHlpMSZ = MemoryAllocate (dwStringSize);
  5002. if ((szNewCtrMSZ == NULL) || (szNewHlpMSZ == NULL)) {
  5003. dwReturn = ERROR_OUTOFMEMORY;
  5004. }
  5005. } else {
  5006. dwReturn = ERROR_OUTOFMEMORY;
  5007. }
  5008. }
  5009. if (dwReturn == ERROR_SUCCESS) {
  5010. // write new strings into registry
  5011. __try {
  5012. dwReturn = RegOpenKeyEx (
  5013. HKEY_LOCAL_MACHINE,
  5014. NamesKey,
  5015. RESERVED,
  5016. KEY_READ,
  5017. & hKeyPerflib);
  5018. }
  5019. __except (EXCEPTION_EXECUTE_HANDLER) {
  5020. dwReturn = GetExceptionCode();
  5021. }
  5022. dwSize = sizeof (dwLastBaseValue);
  5023. dwLastBaseValue = 0;
  5024. if (dwReturn == ERROR_SUCCESS) {
  5025. __try {
  5026. dwReturn = RegQueryValueEx (
  5027. hKeyPerflib,
  5028. szBaseIndex,
  5029. RESERVED,
  5030. & dwType,
  5031. (LPBYTE) & dwLastBaseValue,
  5032. & dwSize);
  5033. }
  5034. __except (EXCEPTION_EXECUTE_HANDLER) {
  5035. dwReturn = GetExceptionCode();
  5036. }
  5037. if (dwLastBaseValue == 0) {
  5038. dwReturn = ERROR_BADDB;
  5039. }
  5040. TRACE((WINPERF_DBG_TRACE_INFO),
  5041. (& LoadPerfGuid,
  5042. __LINE__,
  5043. LOADPERF_UPDATEPERFNAMEFILES,
  5044. ARG_DEF(ARG_TYPE_WSTR, 1),
  5045. dwReturn,
  5046. TRACE_WSTR(szBaseIndex),
  5047. TRACE_DWORD(dwLastBaseValue),
  5048. NULL));
  5049. RegCloseKey (hKeyPerflib);
  5050. }
  5051. }
  5052. else {
  5053. TRACE((WINPERF_DBG_TRACE_ERROR),
  5054. (& LoadPerfGuid,
  5055. __LINE__,
  5056. LOADPERF_UPDATEPERFNAMEFILES,
  5057. ARG_DEF(ARG_TYPE_WSTR, 1),
  5058. dwReturn,
  5059. TRACE_WSTR(NamesKey),
  5060. NULL));
  5061. }
  5062. if (dwReturn == ERROR_SUCCESS) {
  5063. DWORD dwLoopLimit;
  5064. // the strings should be mapped by now
  5065. // pszNewNameTable contains the new strings from the
  5066. // source path and pszOldNameTable contains the strings
  5067. // from the original system. The merge will consist of
  5068. // taking all base values from the new table and the
  5069. // extended values from the old table.
  5070. dwIndex =1;
  5071. szThisCtrString = szNewCtrMSZ;
  5072. szThisHlpString = szNewHlpMSZ;
  5073. // index 1 is a special case and belongs in the counter string
  5074. // after that even numbers (starting w/ #2) go into the counter string
  5075. // and odd numbers (starting w/ #3) go into the help string
  5076. assert (pszNewNameTable[dwIndex] != NULL);
  5077. szThisCtrString += swprintf (szThisCtrString,
  5078. (LPCWSTR)L"%d", dwIndex) + 1;
  5079. szThisCtrString += swprintf (szThisCtrString,
  5080. (LPCWSTR)L"%s", pszNewNameTable[dwIndex]) + 1;
  5081. dwIndex++;
  5082. assert (dwIndex == 2);
  5083. if (dwFlags & LODCTR_UPNF_RESTORE) {
  5084. // restore ALL strings from the input file only if this
  5085. // is a restoration
  5086. dwLoopLimit = dwOldLastEntry;
  5087. } else {
  5088. // only update the system counters from the input file
  5089. dwLoopLimit = dwLastBaseValue;
  5090. }
  5091. TRACE((WINPERF_DBG_TRACE_INFO),
  5092. (& LoadPerfGuid,
  5093. __LINE__,
  5094. LOADPERF_UPDATEPERFNAMEFILES,
  5095. 0,
  5096. ERROR_SUCCESS,
  5097. TRACE_DWORD(dwOldLastEntry),
  5098. TRACE_DWORD(dwLastBaseValue),
  5099. NULL));
  5100. for (/*dwIndex from above*/; dwIndex <= dwLoopLimit; dwIndex++) {
  5101. if (pszNewNameTable[dwIndex] != NULL) {
  5102. TRACE((WINPERF_DBG_TRACE_INFO),
  5103. (& LoadPerfGuid,
  5104. __LINE__,
  5105. LOADPERF_UPDATEPERFNAMEFILES,
  5106. ARG_DEF(ARG_TYPE_WSTR, 1),
  5107. ERROR_SUCCESS,
  5108. TRACE_WSTR(pszNewNameTable[dwIndex]),
  5109. TRACE_DWORD(dwIndex),
  5110. NULL));
  5111. if (dwIndex & 0x01) {
  5112. // then it's a help string
  5113. szThisHlpString += swprintf (szThisHlpString,
  5114. (LPCWSTR)L"%d", dwIndex) + 1;
  5115. szThisHlpString += swprintf (szThisHlpString,
  5116. (LPCWSTR)L"%s", pszNewNameTable[dwIndex]) + 1;
  5117. } else {
  5118. // it's a counter string
  5119. szThisCtrString += swprintf (szThisCtrString,
  5120. (LPCWSTR)L"%d", dwIndex) + 1;
  5121. szThisCtrString += swprintf (szThisCtrString,
  5122. (LPCWSTR)L"%s", pszNewNameTable[dwIndex]) + 1;
  5123. }
  5124. } // else just skip it
  5125. }
  5126. for (/*dwIndex from last run */;dwIndex <= dwOldLastEntry; dwIndex++) {
  5127. if (pszOldNameTable[dwIndex] != NULL) {
  5128. TRACE((WINPERF_DBG_TRACE_INFO),
  5129. (& LoadPerfGuid,
  5130. __LINE__,
  5131. LOADPERF_UPDATEPERFNAMEFILES,
  5132. ARG_DEF(ARG_TYPE_WSTR, 1),
  5133. ERROR_SUCCESS,
  5134. TRACE_WSTR(pszOldNameTable[dwIndex]),
  5135. TRACE_DWORD(dwIndex),
  5136. NULL));
  5137. if (dwIndex & 0x01) {
  5138. // then it's a help string
  5139. szThisHlpString += swprintf (szThisHlpString,
  5140. (LPCWSTR)L"%d", dwIndex) + 1;
  5141. szThisHlpString += swprintf (szThisHlpString,
  5142. (LPCWSTR)L"%s", pszOldNameTable[dwIndex]) + 1;
  5143. } else {
  5144. // it's a counter string
  5145. szThisCtrString += swprintf (szThisCtrString,
  5146. (LPCWSTR)L"%d", dwIndex) + 1;
  5147. szThisCtrString += swprintf (szThisCtrString,
  5148. (LPCWSTR)L"%s", pszOldNameTable[dwIndex]) + 1;
  5149. }
  5150. } // else just skip it
  5151. }
  5152. // terminate the MSZ
  5153. *szThisCtrString++ = 0;
  5154. *szThisHlpString++ = 0;
  5155. }
  5156. // close mapped memory sections:
  5157. if (szNewCtrStrings != NULL) UnmapViewOfFile(szNewCtrStrings);
  5158. if (hCtrFileMap != NULL) CloseHandle(hCtrFileMap);
  5159. if (hCtrFileIn != NULL) CloseHandle(hCtrFileIn);
  5160. if (szNewHlpStrings != NULL) UnmapViewOfFile(szNewHlpStrings);
  5161. if (hHlpFileMap != NULL) CloseHandle(hHlpFileMap);
  5162. if (hHlpFileIn != NULL) CloseHandle(hHlpFileIn);
  5163. if (dwReturn == ERROR_SUCCESS) {
  5164. // write new values to registry
  5165. LONG lStatus;
  5166. WCHAR AddCounterNameBuffer[20];
  5167. WCHAR AddHelpNameBuffer[20];
  5168. lstrcpyW(AddCounterNameBuffer, AddCounterNameStr);
  5169. lstrcatW(AddCounterNameBuffer, szLanguageID);
  5170. lstrcpyW(AddHelpNameBuffer, AddHelpNameStr);
  5171. lstrcatW(AddHelpNameBuffer, szLanguageID);
  5172. // because these are perf counter strings, RegQueryValueEx
  5173. // is used instead of RegSetValueEx as one might expect.
  5174. dwSize = (DWORD)((DWORD_PTR)szThisCtrString - (DWORD_PTR)szNewCtrMSZ);
  5175. __try {
  5176. lStatus = RegQueryValueExW (
  5177. HKEY_PERFORMANCE_DATA,
  5178. AddCounterNameBuffer,
  5179. RESERVED,
  5180. & dwType,
  5181. (LPVOID) szNewCtrMSZ,
  5182. & dwSize);
  5183. }
  5184. __except (EXCEPTION_EXECUTE_HANDLER) {
  5185. lStatus = GetExceptionCode();
  5186. }
  5187. if (lStatus != ERROR_SUCCESS) {
  5188. dwReturn = (DWORD)lStatus;
  5189. TRACE((WINPERF_DBG_TRACE_ERROR),
  5190. (& LoadPerfGuid,
  5191. __LINE__,
  5192. LOADPERF_UPDATEPERFNAMEFILES,
  5193. ARG_DEF(ARG_TYPE_WSTR, 1),
  5194. lStatus,
  5195. TRACE_WSTR(AddCounterNameBuffer),
  5196. TRACE_DWORD(dwSize),
  5197. NULL));
  5198. }
  5199. dwSize = (DWORD)((DWORD_PTR)szThisHlpString - (DWORD_PTR)szNewHlpMSZ);
  5200. __try {
  5201. lStatus = RegQueryValueExW (
  5202. HKEY_PERFORMANCE_DATA,
  5203. AddHelpNameBuffer,
  5204. RESERVED,
  5205. & dwType,
  5206. (LPVOID) szNewHlpMSZ,
  5207. & dwSize);
  5208. }
  5209. __except (EXCEPTION_EXECUTE_HANDLER) {
  5210. lStatus = GetExceptionCode();
  5211. }
  5212. if (lStatus != ERROR_SUCCESS) {
  5213. dwReturn = (DWORD)lStatus;
  5214. TRACE((WINPERF_DBG_TRACE_ERROR),
  5215. (& LoadPerfGuid,
  5216. __LINE__,
  5217. LOADPERF_UPDATEPERFNAMEFILES,
  5218. ARG_DEF(ARG_TYPE_WSTR, 1),
  5219. lStatus,
  5220. TRACE_WSTR(AddHelpNameBuffer),
  5221. TRACE_DWORD(dwSize),
  5222. NULL));
  5223. }
  5224. }
  5225. if (szCtrNameIn != NULL) MemoryFree (szCtrNameIn);
  5226. if (szHlpNameIn != NULL) MemoryFree (szHlpNameIn);
  5227. if (pszNewNameTable != NULL) MemoryFree (pszNewNameTable);
  5228. if (pszOldNameTable != NULL) MemoryFree (pszOldNameTable);
  5229. if (szNewCtrMSZ != NULL) MemoryFree (szNewCtrMSZ);
  5230. if (szNewHlpMSZ != NULL) MemoryFree (szNewHlpMSZ);
  5231. return dwReturn;
  5232. }
  5233. // exported version of the above function
  5234. LOADPERF_FUNCTION
  5235. UpdatePerfNameFilesW (
  5236. IN LPCWSTR szNewCtrFilePath, // data file with new base counter strings
  5237. IN LPCWSTR szNewHlpFilePath, // data file with new base counter strings
  5238. IN LPWSTR szLanguageID, // Lang ID to update
  5239. IN ULONG_PTR dwFlags // flags
  5240. )
  5241. {
  5242. volatile DWORD dwStatus;
  5243. dwStatus = UpdatePerfNameFilesX (
  5244. szNewCtrFilePath, // data file with new base counter strings
  5245. szNewHlpFilePath, // data file with new base counter strings
  5246. szLanguageID, // Lang ID to update
  5247. dwFlags); // flags
  5248. return dwStatus;
  5249. }
  5250. LOADPERF_FUNCTION
  5251. UpdatePerfNameFilesA (
  5252. IN LPCSTR szNewCtrFilePath, // data file with new base counter strings
  5253. IN LPCSTR szNewHlpFilePath, // data file with new base counter strings
  5254. IN LPSTR szLanguageID, // Lang ID to update
  5255. IN ULONG_PTR dwFlags // flags
  5256. )
  5257. {
  5258. DWORD dwError = ERROR_SUCCESS;
  5259. LPWSTR wszNewCtrFilePath = NULL;
  5260. LPWSTR wszNewHlpFilePath = NULL;
  5261. LPWSTR wszLanguageID = NULL;
  5262. DWORD dwLength;
  5263. if (szNewCtrFilePath != NULL) {
  5264. dwLength = lstrlenA (szNewCtrFilePath);
  5265. dwLength += 1; //add term null
  5266. wszNewCtrFilePath = MemoryAllocate (dwLength * sizeof(WCHAR));
  5267. if (wszNewCtrFilePath != NULL) {
  5268. mbstowcs (wszNewCtrFilePath, szNewCtrFilePath, dwLength);
  5269. }
  5270. } else {
  5271. dwError = ERROR_INVALID_PARAMETER;
  5272. }
  5273. if (szNewHlpFilePath != NULL) {
  5274. dwLength = lstrlenA (szNewHlpFilePath);
  5275. dwLength += 1; //add term null
  5276. wszNewHlpFilePath = MemoryAllocate (dwLength * sizeof(WCHAR));
  5277. if (wszNewHlpFilePath != NULL) {
  5278. mbstowcs (wszNewHlpFilePath, szNewHlpFilePath, dwLength);
  5279. }
  5280. } else {
  5281. // this parameter can only be NULL if this flag bit is set.
  5282. if (!(dwFlags & LODCTR_UPNF_RESTORE)) {
  5283. dwError = ERROR_INVALID_PARAMETER;
  5284. } else {
  5285. wszNewHlpFilePath = NULL;
  5286. }
  5287. }
  5288. if (szLanguageID != NULL) {
  5289. dwLength = lstrlenA (szLanguageID);
  5290. dwLength += 1; //add term null
  5291. wszLanguageID= MemoryAllocate (dwLength * sizeof(WCHAR));
  5292. if (wszLanguageID != NULL) {
  5293. mbstowcs (wszLanguageID, szLanguageID, dwLength);
  5294. }
  5295. } else {
  5296. dwError = ERROR_INVALID_PARAMETER;
  5297. }
  5298. if (dwError == ERROR_SUCCESS) {
  5299. dwError = UpdatePerfNameFilesX (
  5300. wszNewCtrFilePath,
  5301. wszNewHlpFilePath,
  5302. wszLanguageID,
  5303. dwFlags);
  5304. }
  5305. if (wszNewCtrFilePath != NULL) MemoryFree (wszNewCtrFilePath);
  5306. if (wszNewHlpFilePath != NULL) MemoryFree (wszNewHlpFilePath);
  5307. if (wszLanguageID != NULL) MemoryFree (wszLanguageID);
  5308. return dwError;
  5309. }
  5310. LOADPERF_FUNCTION
  5311. SetServiceAsTrustedW (
  5312. LPCWSTR szMachineName, // reserved, MBZ
  5313. LPCWSTR szServiceName
  5314. )
  5315. {
  5316. HKEY hKeyService_Perf;
  5317. DWORD dwReturn;
  5318. WCHAR szPerfKeyString[MAX_PATH * 2];
  5319. HKEY hKeyLM = HKEY_LOCAL_MACHINE; // until remote machine access is supported
  5320. WCHAR szLibName[MAX_PATH * 2];
  5321. WCHAR szExpLibName[MAX_PATH * 2];
  5322. WCHAR szFullPathName[MAX_PATH * 2];
  5323. DWORD dwSize, dwType;
  5324. HANDLE hFile;
  5325. DllValidationData dvdLibrary;
  5326. LARGE_INTEGER liSize;
  5327. BOOL bStatus;
  5328. WinPerfStartTrace(NULL);
  5329. if ((szMachineName != NULL) || (szServiceName == NULL)) {
  5330. // reserved for future use
  5331. return ERROR_INVALID_PARAMETER;
  5332. }
  5333. // build path to performance subkey
  5334. lstrcpyW (szPerfKeyString, DriverPathRoot); // SYSTEM\CurrentControlSet\Services
  5335. lstrcatW (szPerfKeyString, Slash);
  5336. lstrcatW (szPerfKeyString, szServiceName);
  5337. lstrcatW (szPerfKeyString, Slash);
  5338. lstrcatW (szPerfKeyString, Performance);
  5339. // open performance key under the service key
  5340. __try {
  5341. dwReturn = RegOpenKeyExW (
  5342. hKeyLM,
  5343. szPerfKeyString,
  5344. 0L,
  5345. KEY_READ | KEY_WRITE,
  5346. & hKeyService_Perf);
  5347. }
  5348. __except (EXCEPTION_EXECUTE_HANDLER) {
  5349. dwReturn = GetExceptionCode();
  5350. }
  5351. if (dwReturn == ERROR_SUCCESS) {
  5352. // get library name
  5353. dwType = 0;
  5354. dwSize = sizeof(szLibName) / sizeof (szLibName[0]);
  5355. __try {
  5356. dwReturn = RegQueryValueExW (
  5357. hKeyService_Perf,
  5358. cszLibrary,
  5359. NULL,
  5360. & dwType,
  5361. (LPBYTE) & szLibName[0],
  5362. & dwSize);
  5363. }
  5364. __except (EXCEPTION_EXECUTE_HANDLER) {
  5365. dwReturn = GetExceptionCode();
  5366. }
  5367. if (dwReturn == ERROR_SUCCESS) {
  5368. // expand path name if necessary
  5369. if (dwType == REG_EXPAND_SZ) {
  5370. dwSize = ExpandEnvironmentStringsW (
  5371. szLibName,
  5372. szExpLibName,
  5373. sizeof(szExpLibName) / sizeof (szExpLibName[0]));
  5374. } else {
  5375. lstrcpyW (szExpLibName, szLibName);
  5376. // dwSize is same as returned from Fn Call.
  5377. }
  5378. if (dwSize != 0) {
  5379. // find DLL file
  5380. dwSize = SearchPathW (
  5381. NULL,
  5382. szExpLibName,
  5383. NULL,
  5384. sizeof(szFullPathName) / sizeof (szFullPathName[0]),
  5385. szFullPathName,
  5386. NULL);
  5387. if (dwSize > 0) {
  5388. hFile = CreateFileW (
  5389. szFullPathName,
  5390. GENERIC_READ,
  5391. FILE_SHARE_READ | FILE_SHARE_WRITE,
  5392. NULL,
  5393. OPEN_EXISTING,
  5394. FILE_ATTRIBUTE_NORMAL,
  5395. NULL);
  5396. if (hFile != INVALID_HANDLE_VALUE) {
  5397. // read file date/time & size
  5398. bStatus = GetFileTime (
  5399. hFile,
  5400. &dvdLibrary.CreationDate,
  5401. NULL,
  5402. NULL);
  5403. if (bStatus) {
  5404. liSize.LowPart = GetFileSize (
  5405. hFile,
  5406. (DWORD *)&liSize.HighPart);
  5407. dvdLibrary.FileSize = liSize.QuadPart;
  5408. // set registry value
  5409. __try {
  5410. dwReturn = RegSetValueExW (
  5411. hKeyService_Perf,
  5412. szLibraryValidationCode,
  5413. 0L,
  5414. REG_BINARY,
  5415. (LPBYTE) & dvdLibrary,
  5416. sizeof(dvdLibrary));
  5417. }
  5418. __except (EXCEPTION_EXECUTE_HANDLER) {
  5419. dwReturn = GetExceptionCode();
  5420. }
  5421. TRACE((WINPERF_DBG_TRACE_INFO),
  5422. (& LoadPerfGuid,
  5423. __LINE__,
  5424. LOADPERF_SETSERVICEASTRUSTED,
  5425. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2) | ARG_DEF(ARG_TYPE_WSTR, 3),
  5426. dwReturn,
  5427. TRACE_WSTR(szServiceName),
  5428. TRACE_WSTR(szExpLibName),
  5429. TRACE_WSTR(szLibraryValidationCode),
  5430. NULL));
  5431. } else {
  5432. dwReturn = GetLastError();
  5433. }
  5434. CloseHandle (hFile);
  5435. } else {
  5436. dwReturn = GetLastError();
  5437. }
  5438. } else {
  5439. dwReturn = ERROR_FILE_NOT_FOUND;
  5440. }
  5441. } else {
  5442. // unable to expand environment strings
  5443. dwReturn = GetLastError();
  5444. }
  5445. }
  5446. else {
  5447. TRACE((WINPERF_DBG_TRACE_ERROR),
  5448. (& LoadPerfGuid,
  5449. __LINE__,
  5450. LOADPERF_SETSERVICEASTRUSTED,
  5451. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  5452. dwReturn,
  5453. TRACE_WSTR(szServiceName),
  5454. TRACE_WSTR(cszLibrary),
  5455. NULL));
  5456. }
  5457. // close key
  5458. RegCloseKey (hKeyService_Perf);
  5459. }
  5460. else {
  5461. TRACE((WINPERF_DBG_TRACE_ERROR),
  5462. (& LoadPerfGuid,
  5463. __LINE__,
  5464. LOADPERF_SETSERVICEASTRUSTED,
  5465. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  5466. dwReturn,
  5467. TRACE_WSTR(szServiceName),
  5468. TRACE_WSTR(Performance),
  5469. NULL));
  5470. }
  5471. return dwReturn;
  5472. }
  5473. LOADPERF_FUNCTION
  5474. SetServiceAsTrustedA (
  5475. LPCSTR szMachineName, // reserved, MBZ
  5476. LPCSTR szServiceName
  5477. )
  5478. {
  5479. LPWSTR lpWideServiceName;
  5480. DWORD dwStrLen;
  5481. DWORD lReturn;
  5482. if ((szMachineName != NULL) || (szServiceName == NULL)) {
  5483. // reserved for future use
  5484. return ERROR_INVALID_PARAMETER;
  5485. }
  5486. if (szServiceName != NULL) {
  5487. //length of string including terminator
  5488. dwStrLen = lstrlenA(szServiceName) + 1;
  5489. lpWideServiceName = MemoryAllocate (dwStrLen * sizeof(WCHAR));
  5490. if (lpWideServiceName != NULL) {
  5491. mbstowcs (lpWideServiceName, szServiceName, dwStrLen);
  5492. lReturn = SetServiceAsTrustedW (NULL, lpWideServiceName);
  5493. MemoryFree (lpWideServiceName);
  5494. } else {
  5495. lReturn = GetLastError();
  5496. }
  5497. } else {
  5498. lReturn = ERROR_INVALID_PARAMETER;
  5499. }
  5500. return lReturn;
  5501. }
  5502. int __cdecl
  5503. My_vfwprintf(
  5504. FILE *str,
  5505. const wchar_t *format,
  5506. va_list argptr
  5507. )
  5508. {
  5509. HANDLE hOut;
  5510. if (str == stderr) {
  5511. hOut = GetStdHandle(STD_ERROR_HANDLE);
  5512. }
  5513. else {
  5514. hOut = GetStdHandle(STD_OUTPUT_HANDLE);
  5515. }
  5516. if ((GetFileType(hOut) & ~FILE_TYPE_REMOTE) == FILE_TYPE_CHAR) {
  5517. DWORD cchWChar;
  5518. WCHAR szBufferMessage[1024];
  5519. vswprintf( szBufferMessage, format, argptr );
  5520. cchWChar = wcslen(szBufferMessage);
  5521. WriteConsoleW(hOut, szBufferMessage, cchWChar, &cchWChar, NULL);
  5522. return cchWChar;
  5523. }
  5524. return vfwprintf(str, format, argptr);
  5525. }