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.

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