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.

1980 lines
64 KiB

  1. /*++
  2. Copyright (c) 1991-1999 Microsoft Corporation
  3. Module Name:
  4. unlodctr.c
  5. Abstract:
  6. Program to remove the counter names belonging to the driver specified
  7. in the command line and update the registry accordingly
  8. Author:
  9. Bob Watson (a-robw) 12 Feb 93
  10. Revision History:
  11. Bob Watson (bobw) 10 Mar 99 added event log messages
  12. --*/
  13. #ifndef UNICODE
  14. #define UNICODE 1
  15. #endif
  16. #ifndef _UNICODE
  17. #define _UNICODE 1
  18. #endif
  19. //
  20. // "C" Include files
  21. //
  22. #include <nt.h>
  23. #include <ntrtl.h>
  24. #include <nturtl.h>
  25. #include <stdio.h>
  26. #include <stdlib.h>
  27. #include <string.h>
  28. //
  29. // Windows Include files
  30. //
  31. #include <windows.h>
  32. #define __LOADPERF__
  33. #include <loadperf.h>
  34. #include <tchar.h>
  35. #include "wmistr.h"
  36. #include "evntrace.h"
  37. //
  38. // local include files
  39. //
  40. #include "winperfp.h"
  41. #include "common.h"
  42. #include "unlodctr.h"
  43. #include "mofcomp.h"
  44. #include "ldprfmsg.h"
  45. // version number for NT 1.0
  46. #define OLD_VERSION 0x010000
  47. static DWORD dwSystemVersion; // PerfLib version number
  48. static DWORD dwHelpItems; // number of explain text items
  49. static DWORD dwCounterItems; // number of counter text items
  50. static DWORD dwLastCounter;
  51. static DWORD dwLastHelp;
  52. static TCHAR ComputerName[MAX_PATH];
  53. static TCHAR szServiceDisplayName[MAX_PATH];
  54. static HKEY hPerfData; // handle to remote machine HKEY_PERFORMANCE_DATA
  55. static BOOL bQuietMode = TRUE; // quiet means no _tprintf's
  56. #define OUTPUT_MESSAGE if (!bQuietMode) _tprintf
  57. static
  58. LPTSTR
  59. *BuildNameTable(
  60. IN HKEY hKeyPerflib, // handle to perflib key with counter names
  61. IN LPTSTR lpszLangId, // unicode value of Language subkey
  62. OUT PDWORD pdwLastItem, // size of array in elements
  63. OUT HKEY *hKeyNames,
  64. OUT LPTSTR CounterNameBuffer, // New version counter name key
  65. OUT LPTSTR HelpNameBuffer // New version help name key
  66. )
  67. /*++
  68. BuildNameTable
  69. Caches the counter names and explain text to accelerate name lookups
  70. for display.
  71. Arguments:
  72. hKeyPerflib
  73. Handle to an open registry (this can be local or remote.) and
  74. is the value returned by RegConnectRegistry or a default key.
  75. lpszLangId
  76. The unicode id of the language to look up. (default is 009)
  77. pdwLastItem
  78. The last array element
  79. Return Value:
  80. pointer to an allocated table. (the caller must free it when finished!)
  81. the table is an array of pointers to zero terminated TEXT strings.
  82. A NULL pointer is returned if an error occured. (error value is
  83. available using the GetLastError function).
  84. The structure of the buffer returned is:
  85. Array of pointers to zero terminated strings consisting of
  86. pdwLastItem elements
  87. MULTI_SZ string containing counter id's and names returned from
  88. registry for the specified language
  89. MULTI_SZ string containing explain text id's and explain text strings
  90. as returned by the registry for the specified language
  91. The structures listed above are contiguous so that they may be freed
  92. by a single "free" call when finished with them, however only the
  93. array elements are intended to be used.
  94. --*/
  95. {
  96. LPTSTR *lpReturnValue; // returned pointer to buffer
  97. LPTSTR *lpCounterId; //
  98. LPTSTR lpCounterNames; // pointer to Names buffer returned by reg.
  99. LPTSTR lpHelpText ; // pointet to exlpain buffer returned by reg.
  100. LPTSTR lpThisName; // working pointer
  101. BOOL bStatus; // return status from TRUE/FALSE fn. calls
  102. LONG lWin32Status; // return status from fn. calls
  103. DWORD dwValueType; // value type of buffer returned by reg.
  104. DWORD dwArraySize; // size of pointer array in bytes
  105. DWORD dwBufferSize; // size of total buffer in bytes
  106. DWORD dwCounterSize; // size of counter text buffer in bytes
  107. DWORD dwHelpSize; // size of help text buffer in bytes
  108. DWORD dwThisCounter; // working counter
  109. DWORD dwLastId; // largest ID value used by explain/counter text
  110. DWORD dwLastCounterIdUsed;
  111. DWORD dwLastHelpIdUsed;
  112. LPTSTR lpValueNameString; // pointer to buffer conatining subkey name
  113. //initialize pointers to NULL
  114. lpValueNameString = NULL;
  115. lpReturnValue = NULL;
  116. // check for null arguments and insert defaults if necessary
  117. if (!lpszLangId) {
  118. lpszLangId = (LPTSTR)DefaultLangId;
  119. }
  120. if (hKeyNames) {
  121. *hKeyNames = NULL;
  122. } else {
  123. SetLastError (ERROR_BAD_ARGUMENTS);
  124. return NULL;
  125. }
  126. // use the greater of Help items or Counter Items to size array
  127. if (dwHelpItems >= dwCounterItems) {
  128. dwLastId = dwHelpItems;
  129. } else {
  130. dwLastId = dwCounterItems;
  131. }
  132. // array size is # of elements (+ 1, since names are "1" based)
  133. // times the size of a pointer
  134. dwArraySize = (dwLastId + 1) * sizeof(LPTSTR);
  135. // allocate string buffer for language ID key string
  136. dwBufferSize = sizeof(TCHAR) * lstrlen(NamesKey)
  137. + sizeof(TCHAR) * lstrlen(Slash)
  138. + sizeof(TCHAR) * lstrlen(lpszLangId)
  139. + sizeof(TCHAR);
  140. lpValueNameString = MemoryAllocate(dwBufferSize);
  141. if (!lpValueNameString) {
  142. lWin32Status = ERROR_OUTOFMEMORY;
  143. ReportLoadPerfEvent(
  144. EVENTLOG_ERROR_TYPE, // error type
  145. (DWORD) LDPRFMSG_MEMORY_ALLOCATION_FAILURE, // event,
  146. 1, __LINE__, 0, 0, 0,
  147. 0, NULL, NULL, NULL);
  148. TRACE((WINPERF_DBG_TRACE_ERROR),
  149. (& LoadPerfGuid,
  150. __LINE__,
  151. LOADPERF_UNLODCTR_BUILDNAMETABLE,
  152. 0,
  153. lWin32Status,
  154. NULL));
  155. goto BNT_BAILOUT;
  156. }
  157. if (dwSystemVersion == OLD_VERSION) {
  158. lWin32Status = RegOpenKeyEx ( // get handle to this key in the
  159. hKeyPerflib, // registry
  160. lpszLangId,
  161. RESERVED,
  162. KEY_READ | KEY_WRITE,
  163. hKeyNames);
  164. } else {
  165. // *hKeyNames = HKEY_PERFORMANCE_DATA;
  166. *hKeyNames = hPerfData;
  167. lstrcpy (CounterNameBuffer, CounterNameStr);
  168. lstrcat (CounterNameBuffer, lpszLangId);
  169. lstrcpy (HelpNameBuffer, HelpNameStr);
  170. lstrcat (HelpNameBuffer, lpszLangId);
  171. lWin32Status = ERROR_SUCCESS;
  172. }
  173. if (lWin32Status != ERROR_SUCCESS) {
  174. ReportLoadPerfEvent(
  175. EVENTLOG_ERROR_TYPE, // error type
  176. (DWORD) LDPRFMSG_UNABLE_ACCESS_STRINGS, // event,
  177. 2, lWin32Status, __LINE__, 0, 0,
  178. 1, lpszLangId, NULL, NULL);
  179. TRACE((WINPERF_DBG_TRACE_ERROR),
  180. (& LoadPerfGuid,
  181. __LINE__,
  182. LOADPERF_UNLODCTR_BUILDNAMETABLE,
  183. ARG_DEF(ARG_TYPE_WSTR, 1),
  184. lWin32Status,
  185. TRACE_WSTR(lpszLangId),
  186. NULL));
  187. goto BNT_BAILOUT;
  188. }
  189. // get size of counter names
  190. dwBufferSize = 0;
  191. __try {
  192. lWin32Status = RegQueryValueEx (
  193. * hKeyNames,
  194. dwSystemVersion == OLD_VERSION ? Counters : CounterNameBuffer,
  195. RESERVED,
  196. & dwValueType,
  197. NULL,
  198. & dwBufferSize);
  199. }
  200. __except (EXCEPTION_EXECUTE_HANDLER) {
  201. lWin32Status = GetExceptionCode();
  202. }
  203. if (lWin32Status != ERROR_SUCCESS) {
  204. ReportLoadPerfEvent(
  205. EVENTLOG_ERROR_TYPE, // error type
  206. (DWORD) LDPRFMSG_UNABLE_READ_COUNTER_STRINGS, // event,
  207. 4, lWin32Status, dwSystemVersion, dwBufferSize, __LINE__,
  208. 1, lpszLangId, NULL, NULL);
  209. TRACE((WINPERF_DBG_TRACE_ERROR),
  210. (& LoadPerfGuid,
  211. __LINE__,
  212. LOADPERF_UNLODCTR_BUILDNAMETABLE,
  213. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  214. lWin32Status,
  215. TRACE_WSTR(lpszLangId),
  216. TRACE_WSTR(Counters),
  217. TRACE_DWORD(dwSystemVersion),
  218. TRACE_DWORD(dwBufferSize),
  219. NULL));
  220. goto BNT_BAILOUT;
  221. }
  222. dwCounterSize = dwBufferSize;
  223. // get size of help text
  224. dwBufferSize = 0;
  225. __try {
  226. lWin32Status = RegQueryValueEx (
  227. * hKeyNames,
  228. dwSystemVersion == OLD_VERSION ? Help : HelpNameBuffer,
  229. RESERVED,
  230. & dwValueType,
  231. NULL,
  232. & dwBufferSize);
  233. }
  234. __except (EXCEPTION_EXECUTE_HANDLER) {
  235. lWin32Status = GetExceptionCode();
  236. }
  237. if (lWin32Status != ERROR_SUCCESS) {
  238. ReportLoadPerfEvent(
  239. EVENTLOG_ERROR_TYPE, // error type
  240. (DWORD) LDPRFMSG_UNABLE_READ_HELP_STRINGS, // event,
  241. 4, lWin32Status, dwSystemVersion, dwBufferSize, __LINE__,
  242. 1, lpszLangId, NULL, NULL);
  243. TRACE((WINPERF_DBG_TRACE_ERROR),
  244. (& LoadPerfGuid,
  245. __LINE__,
  246. LOADPERF_UNLODCTR_BUILDNAMETABLE,
  247. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  248. lWin32Status,
  249. TRACE_WSTR(lpszLangId),
  250. TRACE_WSTR(Help),
  251. TRACE_DWORD(dwSystemVersion),
  252. TRACE_DWORD(dwBufferSize),
  253. NULL));
  254. goto BNT_BAILOUT;
  255. }
  256. dwHelpSize = dwBufferSize;
  257. // allocate buffer with room for pointer array, counter name
  258. // strings and help name strings
  259. lpReturnValue = MemoryAllocate(dwArraySize + dwCounterSize + dwHelpSize);
  260. if (!lpReturnValue) {
  261. ReportLoadPerfEvent(
  262. EVENTLOG_ERROR_TYPE, // error type
  263. (DWORD) LDPRFMSG_MEMORY_ALLOCATION_FAILURE, // event,
  264. 4, dwArraySize, dwCounterSize, dwHelpSize, __LINE__,
  265. 0, NULL, NULL, NULL);
  266. lWin32Status = ERROR_OUTOFMEMORY;
  267. TRACE((WINPERF_DBG_TRACE_ERROR),
  268. (& LoadPerfGuid,
  269. __LINE__,
  270. LOADPERF_UNLODCTR_BUILDNAMETABLE,
  271. 0,
  272. lWin32Status,
  273. TRACE_DWORD(dwArraySize),
  274. TRACE_DWORD(dwCounterSize),
  275. TRACE_DWORD(dwHelpSize),
  276. NULL));
  277. goto BNT_BAILOUT;
  278. }
  279. // initialize pointers into buffer
  280. lpCounterId = lpReturnValue;
  281. lpCounterNames = (LPTSTR)((LPBYTE)lpCounterId + dwArraySize);
  282. lpHelpText = (LPTSTR)((LPBYTE)lpCounterNames + dwCounterSize);
  283. // read counter names into buffer. Counter names will be stored as
  284. // a MULTI_SZ string in the format of "###" "Name"
  285. dwBufferSize = dwCounterSize;
  286. __try {
  287. lWin32Status = RegQueryValueEx (
  288. * hKeyNames,
  289. dwSystemVersion == OLD_VERSION ? Counters : CounterNameBuffer,
  290. RESERVED,
  291. & dwValueType,
  292. (LPVOID)lpCounterNames,
  293. & dwBufferSize);
  294. }
  295. __except (EXCEPTION_EXECUTE_HANDLER) {
  296. lWin32Status = GetExceptionCode();
  297. }
  298. if (lWin32Status != ERROR_SUCCESS) {
  299. ReportLoadPerfEvent(
  300. EVENTLOG_ERROR_TYPE, // error type
  301. (DWORD) LDPRFMSG_UNABLE_READ_COUNTER_STRINGS, // event,
  302. 4, lWin32Status, dwSystemVersion, dwBufferSize, __LINE__,
  303. 1, lpszLangId, NULL, NULL);
  304. TRACE((WINPERF_DBG_TRACE_ERROR),
  305. (& LoadPerfGuid,
  306. __LINE__,
  307. LOADPERF_UNLODCTR_BUILDNAMETABLE,
  308. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  309. lWin32Status,
  310. TRACE_WSTR(lpszLangId),
  311. TRACE_WSTR(Counters),
  312. TRACE_DWORD(dwSystemVersion),
  313. TRACE_DWORD(dwBufferSize),
  314. NULL));
  315. goto BNT_BAILOUT;
  316. }
  317. // read explain text into buffer. Counter names will be stored as
  318. // a MULTI_SZ string in the format of "###" "Text..."
  319. dwBufferSize = dwHelpSize;
  320. __try {
  321. lWin32Status = RegQueryValueEx (
  322. * hKeyNames,
  323. dwSystemVersion == OLD_VERSION ? Help : HelpNameBuffer,
  324. RESERVED,
  325. & dwValueType,
  326. (LPVOID)lpHelpText,
  327. & dwBufferSize);
  328. }
  329. __except (EXCEPTION_EXECUTE_HANDLER) {
  330. lWin32Status = GetExceptionCode();
  331. }
  332. if (lWin32Status != ERROR_SUCCESS) {
  333. ReportLoadPerfEvent(
  334. EVENTLOG_ERROR_TYPE, // error type
  335. (DWORD) LDPRFMSG_UNABLE_READ_HELP_STRINGS, // event,
  336. 4, lWin32Status, dwSystemVersion, dwBufferSize, __LINE__,
  337. 1, lpszLangId, NULL, NULL);
  338. TRACE((WINPERF_DBG_TRACE_ERROR),
  339. (& LoadPerfGuid,
  340. __LINE__,
  341. LOADPERF_UNLODCTR_BUILDNAMETABLE,
  342. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  343. lWin32Status,
  344. TRACE_WSTR(lpszLangId),
  345. TRACE_WSTR(Help),
  346. TRACE_DWORD(dwSystemVersion),
  347. TRACE_DWORD(dwBufferSize),
  348. NULL));
  349. goto BNT_BAILOUT;
  350. }
  351. dwLastCounterIdUsed = 0;
  352. dwLastHelpIdUsed = 0;
  353. // load counter array items, by locating each text string
  354. // in the returned buffer and loading the
  355. // address of it in the corresponding pointer array element.
  356. for (lpThisName = lpCounterNames;
  357. *lpThisName;
  358. lpThisName += (lstrlen(lpThisName)+1) ) {
  359. // first string should be an integer (in decimal digit characters)
  360. // so translate to an integer for use in array element identification
  361. do {
  362. bStatus = StringToInt (lpThisName, &dwThisCounter);
  363. if (!bStatus) {
  364. ReportLoadPerfEvent(
  365. EVENTLOG_WARNING_TYPE, // error type
  366. (DWORD) LDPRFMSG_REGISTRY_CORRUPT_MULTI_SZ, // event,
  367. 1, __LINE__, 0, 0, 0,
  368. 2, CounterNameBuffer, lpThisName, NULL);
  369. TRACE((WINPERF_DBG_TRACE_WARNING),
  370. (& LoadPerfGuid,
  371. __LINE__,
  372. LOADPERF_UNLODCTR_BUILDNAMETABLE,
  373. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  374. ERROR_BADKEY,
  375. TRACE_WSTR(Counters),
  376. TRACE_WSTR(lpThisName),
  377. NULL));
  378. lpThisName += (lstrlen(lpThisName) + 1);
  379. }
  380. }
  381. while ((! bStatus) && (* lpThisName));
  382. if (! bStatus) {
  383. lWin32Status = ERROR_BADKEY;
  384. goto BNT_BAILOUT; // bad entry
  385. }
  386. if (dwThisCounter > dwCounterItems || dwThisCounter > dwLastId) {
  387. lWin32Status = ERROR_BADKEY;
  388. ReportLoadPerfEvent(
  389. EVENTLOG_ERROR_TYPE, // error type
  390. (DWORD) LDPRFMSG_REGISTRY_COUNTER_STRINGS_CORRUPT, // event,
  391. 4, dwThisCounter, dwCounterItems, dwLastId, __LINE__,
  392. 1, lpThisName, NULL, NULL);
  393. TRACE((WINPERF_DBG_TRACE_ERROR),
  394. (& LoadPerfGuid,
  395. __LINE__,
  396. LOADPERF_UNLODCTR_BUILDNAMETABLE,
  397. ARG_DEF(ARG_TYPE_WSTR, 1),
  398. ERROR_BADKEY,
  399. TRACE_WSTR(lpThisName),
  400. TRACE_DWORD(dwThisCounter),
  401. TRACE_DWORD(dwCounterItems),
  402. TRACE_DWORD(dwHelpItems),
  403. NULL));
  404. goto BNT_BAILOUT;
  405. }
  406. // point to corresponding counter name which follows the id number
  407. // string.
  408. lpThisName += (lstrlen(lpThisName) + 1);
  409. // and load array element with pointer to string
  410. lpCounterId[dwThisCounter] = lpThisName;
  411. if (dwThisCounter > dwLastCounterIdUsed) dwLastCounterIdUsed = dwThisCounter;
  412. }
  413. // repeat the above for the explain text strings
  414. for (lpThisName = lpHelpText;
  415. *lpThisName;
  416. lpThisName += (lstrlen(lpThisName)+1) ) {
  417. // first string should be an integer (in decimal unicode digits)
  418. do {
  419. bStatus = StringToInt (lpThisName, &dwThisCounter);
  420. if (! bStatus) {
  421. ReportLoadPerfEvent(
  422. EVENTLOG_WARNING_TYPE, // error type
  423. (DWORD) LDPRFMSG_REGISTRY_CORRUPT_MULTI_SZ, // event,
  424. 1, __LINE__, 0, 0, 0,
  425. 2, HelpNameBuffer, lpThisName, NULL);
  426. TRACE((WINPERF_DBG_TRACE_WARNING),
  427. (& LoadPerfGuid,
  428. __LINE__,
  429. LOADPERF_UNLODCTR_BUILDNAMETABLE,
  430. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  431. ERROR_BADKEY,
  432. TRACE_WSTR(Help),
  433. TRACE_WSTR(lpThisName),
  434. NULL));
  435. lpThisName += (lstrlen(lpThisName) + 1);
  436. }
  437. }
  438. while ((! bStatus) && (* lpThisName));
  439. if (!bStatus) {
  440. lWin32Status = ERROR_BADKEY;
  441. goto BNT_BAILOUT; // bad entry
  442. }
  443. if (dwThisCounter > dwHelpItems || dwThisCounter > dwLastId) {
  444. lWin32Status = ERROR_BADKEY;
  445. ReportLoadPerfEvent(
  446. EVENTLOG_ERROR_TYPE, // error type
  447. (DWORD) LDPRFMSG_REGISTRY_COUNTER_STRINGS_CORRUPT, // event,
  448. 4, dwThisCounter, dwHelpItems, dwLastId, __LINE__,
  449. 1, lpThisName, NULL, NULL);
  450. TRACE((WINPERF_DBG_TRACE_ERROR),
  451. (& LoadPerfGuid,
  452. __LINE__,
  453. LOADPERF_UNLODCTR_BUILDNAMETABLE,
  454. ARG_DEF(ARG_TYPE_WSTR, 1),
  455. ERROR_BADKEY,
  456. TRACE_WSTR(lpThisName),
  457. TRACE_DWORD(dwThisCounter),
  458. TRACE_DWORD(dwCounterItems),
  459. TRACE_DWORD(dwHelpItems),
  460. NULL));
  461. goto BNT_BAILOUT;
  462. }
  463. // point to corresponding counter name
  464. lpThisName += (lstrlen(lpThisName)+1);
  465. // and load array element;
  466. lpCounterId[dwThisCounter] = lpThisName;
  467. if (dwThisCounter > dwLastHelpIdUsed) dwLastHelpIdUsed= dwThisCounter;
  468. }
  469. TRACE((WINPERF_DBG_TRACE_INFO),
  470. (& LoadPerfGuid,
  471. __LINE__,
  472. LOADPERF_UNLODCTR_BUILDNAMETABLE,
  473. 0,
  474. ERROR_SUCCESS,
  475. TRACE_DWORD(dwLastId),
  476. TRACE_DWORD(dwLastCounterIdUsed),
  477. TRACE_DWORD(dwLastHelpIdUsed),
  478. TRACE_DWORD(dwCounterItems),
  479. TRACE_DWORD(dwHelpItems),
  480. NULL));
  481. if (dwLastHelpIdUsed > dwLastId) {
  482. ReportLoadPerfEvent(
  483. EVENTLOG_ERROR_TYPE, // error type
  484. (DWORD) LDPRFMSG_REGISTRY_INDEX_CORRUPT, // event,
  485. 3, dwLastId, dwLastHelpIdUsed, __LINE__, 0,
  486. 0, NULL, NULL, NULL);
  487. lWin32Status = ERROR_BADKEY;
  488. goto BNT_BAILOUT; // bad registry
  489. }
  490. // if the last item arugment was used, then load the last ID value in it
  491. if (pdwLastItem) *pdwLastItem = dwLastId;
  492. // free the temporary buffer used
  493. if (lpValueNameString) {
  494. MemoryFree((LPVOID)lpValueNameString);
  495. }
  496. // exit returning the pointer to the buffer
  497. return lpReturnValue;
  498. BNT_BAILOUT:
  499. if (lWin32Status != ERROR_SUCCESS) {
  500. // if lWin32Status has error, then set last error value to it,
  501. // otherwise assume that last error already has value in it
  502. SetLastError (lWin32Status);
  503. }
  504. // free buffers used by this routine
  505. if (lpValueNameString) {
  506. MemoryFree((LPVOID)lpValueNameString);
  507. }
  508. if (lpReturnValue) {
  509. MemoryFree((LPVOID)lpReturnValue);
  510. }
  511. return NULL;
  512. } // BuildNameTable
  513. static
  514. BOOL
  515. GetDriverFromCommandLine (
  516. LPTSTR lpCommandLine,
  517. HKEY * hKeyMachine,
  518. LPTSTR lpDriverName,
  519. HKEY * hDriverPerf,
  520. HKEY * hKeyDriver
  521. )
  522. /*++
  523. GetDriverFromCommandLine
  524. locates the first argument in the command line string (after the
  525. image name) and checks to see if
  526. a) it's there
  527. b) it's the name of a device driver listed in the
  528. Registry\Machine\System\CurrentControlSet\Services key
  529. in the registry and it has a "Performance" subkey
  530. c) that the "First Counter" value under the Performance subkey
  531. is defined.
  532. if all these criteria are true, then the routine returns TRUE and
  533. passes the pointer to the driver name back in the argument. If any
  534. one of them fail, then NULL is returned in the DriverName arg and
  535. the routine returns FALSE
  536. Arguments
  537. lpDriverName
  538. the address of a LPTSTR to recive the pointer to the driver name
  539. hDriverPerf
  540. the key to the driver's performance subkey
  541. Return Value
  542. TRUE if a valid driver was found in the command line
  543. FALSE if not (see above)
  544. --*/
  545. {
  546. LPTSTR lpDriverKey = NULL; // buffer to build driver key name in
  547. LONG lStatus;
  548. DWORD dwFirstCounter;
  549. DWORD dwSize;
  550. DWORD dwType;
  551. TCHAR LocalComputerName[MAX_PATH];
  552. DWORD NameBuffer;
  553. INT iNumArgs;
  554. BOOL bComputerName = FALSE;
  555. BOOL bReturn = FALSE;
  556. if (!lpDriverName || !hDriverPerf) {
  557. SetLastError (ERROR_BAD_ARGUMENTS);
  558. goto Cleanup;
  559. }
  560. *hDriverPerf = NULL;
  561. // an argument was found so see if it's a driver
  562. lpDriverKey = MemoryAllocate(MAX_PATH * sizeof (TCHAR));
  563. if (!lpDriverKey) {
  564. SetLastError (ERROR_OUTOFMEMORY);
  565. goto Cleanup;
  566. }
  567. lstrcpy(lpDriverName, GetItemFromString (lpCommandLine, 3, TEXT(' ')));
  568. lstrcpy(ComputerName, GetItemFromString (lpCommandLine, 2, TEXT(' ')));
  569. // check for usage
  570. if (ComputerName[1] == TEXT('?')) {
  571. if (!bQuietMode) {
  572. DisplayCommandHelp (UC_FIRST_CMD_HELP, UC_LAST_CMD_HELP);
  573. }
  574. SetLastError (ERROR_SUCCESS);
  575. goto Cleanup;
  576. }
  577. // no /? so process args read
  578. if (lstrlen(lpDriverName) == 0) {
  579. // then no computer name is specifed so assume the local computer
  580. // and the driver name is listed in the computer name param
  581. if (lstrlen(ComputerName) == 0) {
  582. iNumArgs = 1; // command line only
  583. } else {
  584. lstrcpy (lpDriverName, ComputerName);
  585. ComputerName[0] = 0;
  586. ComputerName[1] = 0;
  587. iNumArgs = 2;
  588. }
  589. } else {
  590. if (lstrlen(ComputerName) == 0) {
  591. // this case is impossible since the driver name is after the computer name
  592. iNumArgs = 1;
  593. } else {
  594. iNumArgs = 3;
  595. }
  596. }
  597. // check if there is any computer name
  598. if (ComputerName[0] == TEXT('\\') &&
  599. ComputerName[1] == TEXT('\\')) {
  600. // see if the specified computer is THIS computer and remove
  601. // name if it is
  602. NameBuffer = sizeof (LocalComputerName) / sizeof (TCHAR);
  603. GetComputerName(LocalComputerName, &NameBuffer);
  604. if (!lstrcmpi(LocalComputerName, &ComputerName[2])) {
  605. // same name as local computer name
  606. ComputerName[0] = TEXT('\0');
  607. }
  608. bComputerName = TRUE;
  609. } else {
  610. // this is a driver name
  611. ComputerName[0] = TEXT('\0');
  612. }
  613. if (iNumArgs >= 2) {
  614. if (ComputerName[0]) {
  615. lStatus = !ERROR_SUCCESS;
  616. try {
  617. lStatus = RegConnectRegistry (
  618. (LPTSTR) ComputerName,
  619. HKEY_LOCAL_MACHINE,
  620. hKeyMachine);
  621. } finally {
  622. if (lStatus != ERROR_SUCCESS) {
  623. SetLastError (lStatus);
  624. *hKeyMachine = NULL;
  625. OUTPUT_MESSAGE (GetFormatResource(UC_CONNECT_PROBLEM),
  626. ComputerName, lStatus);
  627. }
  628. }
  629. if (lStatus != ERROR_SUCCESS)
  630. goto Cleanup;
  631. } else {
  632. *hKeyMachine = HKEY_LOCAL_MACHINE;
  633. }
  634. if (lstrlen(lpDriverName) > (MAX_PATH / 2)) {
  635. // then it's too long to make a path out of
  636. dwSize = 0;
  637. } else {
  638. lstrcpy (lpDriverKey, DriverPathRoot);
  639. lstrcat (lpDriverKey, Slash);
  640. lstrcat (lpDriverKey, lpDriverName);
  641. dwSize = lstrlen(lpDriverKey);
  642. }
  643. if ((dwSize > 0) && (dwSize < MAX_PATH)) {
  644. lStatus = RegOpenKeyEx (
  645. * hKeyMachine,
  646. lpDriverKey,
  647. RESERVED,
  648. KEY_READ | KEY_WRITE,
  649. hKeyDriver);
  650. }
  651. lStatus = ERROR_SUCCESS;
  652. RtlZeroMemory(lpDriverKey, MAX_PATH * sizeof(TCHAR));
  653. if (lstrlen(lpDriverName) > (MAX_PATH / 2)) {
  654. // then it's too long to make a path out of
  655. dwSize = 0;
  656. } else {
  657. lstrcpy (lpDriverKey, DriverPathRoot);
  658. lstrcat (lpDriverKey, Slash);
  659. lstrcat (lpDriverKey, lpDriverName);
  660. lstrcat (lpDriverKey, Slash);
  661. lstrcat (lpDriverKey, Performance);
  662. dwSize = lstrlen(lpDriverKey);
  663. }
  664. if ((dwSize > 0) && (dwSize < MAX_PATH)) {
  665. lStatus = RegOpenKeyEx (
  666. *hKeyMachine,
  667. lpDriverKey,
  668. RESERVED,
  669. KEY_READ | KEY_WRITE,
  670. hDriverPerf);
  671. } else {
  672. // driver name is too long
  673. lStatus = ERROR_INVALID_PARAMETER;
  674. }
  675. if (lStatus == ERROR_SUCCESS) {
  676. //
  677. // this driver has a performance section so see if its
  678. // counters are installed by checking the First Counter
  679. // value key for a valid return. If it returns a value
  680. // then chances are, it has some counters installed, if
  681. // not, then display a message and quit.
  682. //
  683. dwType = 0;
  684. dwSize = sizeof (dwFirstCounter);
  685. __try {
  686. lStatus = RegQueryValueEx (
  687. * hDriverPerf,
  688. cszFirstCounter,
  689. RESERVED,
  690. & dwType,
  691. (LPBYTE)&dwFirstCounter,
  692. & dwSize);
  693. }
  694. __except (EXCEPTION_EXECUTE_HANDLER) {
  695. lStatus = GetExceptionCode();
  696. }
  697. if (lStatus == ERROR_SUCCESS) {
  698. // counter names are installed so return success
  699. SetLastError (ERROR_SUCCESS);
  700. bReturn = TRUE;
  701. } else {
  702. // counter names are probably not installed so return FALSE
  703. OUTPUT_MESSAGE (GetFormatResource (UC_NOTINSTALLED), lpDriverName);
  704. *lpDriverName = TEXT('\0'); // remove driver name
  705. SetLastError (ERROR_BADKEY);
  706. }
  707. } else { // key not found
  708. if (lStatus != ERROR_INVALID_PARAMETER) {
  709. OUTPUT_MESSAGE (GetFormatResource (UC_DRIVERNOTFOUND),
  710. lpDriverKey, lStatus);
  711. } else {
  712. OUTPUT_MESSAGE (GetFormatResource (UC_BAD_DRIVER_NAME), 0);
  713. }
  714. SetLastError (lStatus);
  715. }
  716. } else {
  717. if (!bQuietMode) {
  718. DisplayCommandHelp (UC_FIRST_CMD_HELP, UC_LAST_CMD_HELP);
  719. }
  720. SetLastError (ERROR_INVALID_PARAMETER);
  721. }
  722. Cleanup:
  723. if (lpDriverKey != NULL) MemoryFree(lpDriverKey);
  724. if (bReturn) {
  725. TRACE((WINPERF_DBG_TRACE_INFO),
  726. (& LoadPerfGuid,
  727. __LINE__,
  728. LOADPERF_GETDRIVERFROMCOMMANDLINE,
  729. ARG_DEF(ARG_TYPE_WSTR, 1),
  730. ERROR_SUCCESS,
  731. TRACE_WSTR(lpDriverName),
  732. NULL));
  733. }
  734. else {
  735. TRACE((WINPERF_DBG_TRACE_ERROR),
  736. (& LoadPerfGuid,
  737. __LINE__,
  738. LOADPERF_GETDRIVERFROMCOMMANDLINE,
  739. 0,
  740. GetLastError(),
  741. NULL));
  742. }
  743. return bReturn;
  744. }
  745. static
  746. LONG
  747. FixNames (
  748. HANDLE hKeyLang,
  749. LPTSTR *lpOldNameTable,
  750. IN LPTSTR lpszLangId, // unicode value of Language subkey
  751. DWORD dwLastItem,
  752. DWORD dwFirstNameToRemove,
  753. DWORD dwLastNameToRemove
  754. )
  755. {
  756. LONG lStatus;
  757. LPTSTR lpNameBuffer = NULL;
  758. LPTSTR lpHelpBuffer = NULL;
  759. DWORD dwTextIndex, dwSize, dwValueType;
  760. LPTSTR lpNextHelpText;
  761. LPTSTR lpNextNameText;
  762. TCHAR AddHelpNameBuffer[40];
  763. TCHAR AddCounterNameBuffer[40];
  764. // allocate space for the array of new text it will point
  765. // into the text buffer returned in the lpOldNameTable buffer)
  766. lpNameBuffer = MemoryAllocate(MemorySize(lpOldNameTable));
  767. lpHelpBuffer = MemoryAllocate(MemorySize(lpOldNameTable));
  768. if (!lpNameBuffer || !lpHelpBuffer) {
  769. lStatus = ERROR_OUTOFMEMORY;
  770. goto UCN_FinishLang;
  771. }
  772. // remove this driver's counters from array
  773. for (dwTextIndex = dwFirstNameToRemove;
  774. dwTextIndex <= dwLastNameToRemove;
  775. dwTextIndex++) {
  776. if (dwTextIndex > dwLastItem)
  777. break;
  778. lpOldNameTable[dwTextIndex] = NULL;
  779. }
  780. lpNextHelpText = lpHelpBuffer;
  781. lpNextNameText = lpNameBuffer;
  782. // build new Multi_SZ strings from New Table
  783. for (dwTextIndex = 0; dwTextIndex <= dwLastItem; dwTextIndex++){
  784. if (lpOldNameTable[dwTextIndex]) {
  785. // if there's a text string at that index, then ...
  786. if ((dwTextIndex & 0x1) && dwTextIndex != 1) { // ODD number == Help Text
  787. lpNextHelpText +=
  788. _stprintf (lpNextHelpText, (LPCTSTR)TEXT("%d"), dwTextIndex) + 1;
  789. lpNextHelpText +=
  790. _stprintf (lpNextHelpText, (LPCTSTR)TEXT("%s"),
  791. lpOldNameTable[dwTextIndex]) + 1;
  792. if (dwTextIndex > dwLastHelp){
  793. dwLastHelp = dwTextIndex;
  794. }
  795. } else { // EVEN number == counter name text
  796. lpNextNameText +=
  797. _stprintf (lpNextNameText, (LPCTSTR)TEXT("%d"), dwTextIndex) + 1;
  798. lpNextNameText +=
  799. _stprintf (lpNextNameText, (LPCTSTR)TEXT("%s"),
  800. lpOldNameTable[dwTextIndex]) + 1;
  801. if (dwTextIndex > dwLastCounter){
  802. dwLastCounter = dwTextIndex;
  803. }
  804. }
  805. }
  806. } // for dwTextIndex
  807. TRACE((WINPERF_DBG_TRACE_INFO),
  808. (& LoadPerfGuid,
  809. __LINE__,
  810. LOADPERF_FIXNAMES,
  811. ARG_DEF(ARG_TYPE_WSTR, 1),
  812. ERROR_SUCCESS,
  813. TRACE_WSTR(lpszLangId),
  814. TRACE_DWORD(dwLastItem),
  815. TRACE_DWORD(dwLastCounter),
  816. TRACE_DWORD(dwLastHelp),
  817. TRACE_DWORD(dwCounterItems),
  818. TRACE_DWORD(dwHelpItems),
  819. TRACE_DWORD(dwFirstNameToRemove),
  820. TRACE_DWORD(dwLastNameToRemove),
  821. NULL));
  822. if ( (dwLastCounter < PERFLIB_BASE_INDEX - 1)
  823. || (dwLastHelp < PERFLIB_BASE_INDEX)) {
  824. ReportLoadPerfEvent(
  825. EVENTLOG_ERROR_TYPE, // error type
  826. (DWORD) LDPRFMSG_REGISTRY_BASEINDEX_CORRUPT, // event,
  827. 4, PERFLIB_BASE_INDEX, dwLastCounter, dwLastHelp, __LINE__,
  828. 1, (LPWSTR) Performance, NULL, NULL);
  829. lStatus = ERROR_BADKEY;
  830. goto UCN_FinishLang;
  831. }
  832. // add MULTI_SZ terminating NULL
  833. *lpNextNameText++ = TEXT ('\0');
  834. *lpNextHelpText++ = TEXT ('\0');
  835. // update counter name text buffer
  836. dwSize = (DWORD)((LPBYTE)lpNextNameText - (LPBYTE)lpNameBuffer);
  837. if (dwSystemVersion == OLD_VERSION) {
  838. lStatus = RegSetValueEx (
  839. hKeyLang,
  840. Counters,
  841. RESERVED,
  842. REG_MULTI_SZ,
  843. (LPBYTE)lpNameBuffer,
  844. dwSize);
  845. } else {
  846. lstrcpy (AddCounterNameBuffer, AddCounterNameStr);
  847. lstrcat (AddCounterNameBuffer, lpszLangId);
  848. __try {
  849. lStatus = RegQueryValueEx (
  850. hKeyLang,
  851. AddCounterNameBuffer,
  852. RESERVED,
  853. & dwValueType,
  854. (LPBYTE)lpNameBuffer,
  855. & dwSize);
  856. }
  857. __except (EXCEPTION_EXECUTE_HANDLER) {
  858. lStatus = GetExceptionCode();
  859. }
  860. }
  861. if (lStatus != ERROR_SUCCESS) {
  862. ReportLoadPerfEvent(
  863. EVENTLOG_ERROR_TYPE, // error type
  864. (DWORD) LDPRFMSG_UNABLE_UPDATE_COUNTER_STRINGS, // event,
  865. 3, lStatus, dwSize, __LINE__, 0,
  866. 1, lpszLangId, NULL, NULL);
  867. OUTPUT_MESSAGE (GetFormatResource(UC_UNABLELOADLANG),
  868. Counters, lpszLangId, lStatus);
  869. TRACE((WINPERF_DBG_TRACE_ERROR),
  870. (& LoadPerfGuid,
  871. __LINE__,
  872. LOADPERF_FIXNAMES,
  873. ARG_DEF(ARG_TYPE_WSTR, 1),
  874. lStatus,
  875. TRACE_WSTR(Counters),
  876. TRACE_DWORD(dwSize),
  877. NULL));
  878. goto UCN_FinishLang;
  879. }
  880. dwSize = (DWORD)((LPBYTE)lpNextHelpText - (LPBYTE)lpHelpBuffer);
  881. if (dwSystemVersion == OLD_VERSION) {
  882. lStatus = RegSetValueEx (
  883. hKeyLang,
  884. Help,
  885. RESERVED,
  886. REG_MULTI_SZ,
  887. (LPBYTE)lpHelpBuffer,
  888. dwSize);
  889. } else {
  890. lstrcpy (AddHelpNameBuffer, AddHelpNameStr);
  891. lstrcat (AddHelpNameBuffer, lpszLangId);
  892. __try {
  893. lStatus = RegQueryValueEx (
  894. hKeyLang,
  895. AddHelpNameBuffer,
  896. RESERVED,
  897. & dwValueType,
  898. (LPBYTE)lpHelpBuffer,
  899. & dwSize);
  900. }
  901. __except (EXCEPTION_EXECUTE_HANDLER) {
  902. lStatus = GetExceptionCode();
  903. }
  904. }
  905. if (lStatus != ERROR_SUCCESS) {
  906. ReportLoadPerfEvent(
  907. EVENTLOG_ERROR_TYPE, // error type
  908. (DWORD) LDPRFMSG_UNABLE_UPDATE_HELP_STRINGS, // event,
  909. 3, lStatus, dwSize, __LINE__, 0,
  910. 1, lpszLangId, NULL, NULL);
  911. OUTPUT_MESSAGE (GetFormatResource(UC_UNABLELOADLANG),
  912. Help, lpszLangId, lStatus);
  913. TRACE((WINPERF_DBG_TRACE_ERROR),
  914. (& LoadPerfGuid,
  915. __LINE__,
  916. LOADPERF_FIXNAMES,
  917. ARG_DEF(ARG_TYPE_WSTR, 1),
  918. lStatus,
  919. TRACE_WSTR(Help),
  920. TRACE_DWORD(dwSize),
  921. NULL));
  922. goto UCN_FinishLang;
  923. }
  924. UCN_FinishLang:
  925. if (lpNameBuffer)
  926. MemoryFree(lpNameBuffer);
  927. if (lpHelpBuffer)
  928. MemoryFree(lpHelpBuffer);
  929. MemoryFree(lpOldNameTable);
  930. if (dwSystemVersion == OLD_VERSION) {
  931. RegCloseKey (hKeyLang);
  932. }
  933. return lStatus;
  934. }
  935. static
  936. LONG
  937. UnloadCounterNames (
  938. HKEY hKeyMachine,
  939. HKEY hDriverPerf,
  940. HKEY hKeyDriver,
  941. LPTSTR lpDriverName
  942. )
  943. /*++
  944. UnloadCounterNames
  945. removes the names and explain text for the driver referenced by
  946. hDriverPerf and updates the first and last counter values accordingly
  947. update process:
  948. - set "updating" flag under Perflib to name of driver being modified
  949. - FOR each language under perflib key
  950. -- load current counter names and explain text into array of
  951. pointers
  952. -- look at all drivers and copy their names and text into a new
  953. buffer adjusting for the removed counter's entries keeping
  954. track of the lowest entry copied. (the names for the driver
  955. to be removed will not be copied, of course)
  956. -- update each driver's "first" and "last" index values
  957. -- copy all other entries from 0 to the lowest copied (i.e. the
  958. system counters)
  959. -- build a new MULIT_SZ string of help text and counter names
  960. -- load new strings into registry
  961. - update perflibl "last" counters
  962. - delete updating flag
  963. ******************************************************
  964. * *
  965. * NOTE: FUNDAMENTAL ASSUMPTION..... *
  966. * *
  967. * this routine assumes that: *
  968. * *
  969. * ALL COUNTER NAMES are even numbered and *
  970. * ALL HELP TEXT STRINGS are odd numbered *
  971. * *
  972. ******************************************************
  973. Arguments
  974. hKeyMachine
  975. handle to HKEY_LOCAL_MACHINE node of registry on system to
  976. remove counters from
  977. hDrivefPerf
  978. handle to registry key of driver to be de-installed
  979. lpDriverName
  980. name of driver being de-installed
  981. Return Value
  982. DOS Error code.
  983. ERROR_SUCCESS if all went OK
  984. error value if not.
  985. --*/
  986. {
  987. HKEY hPerflib;
  988. HKEY hServices;
  989. HKEY hKeyLang;
  990. LONG lStatus;
  991. DWORD dwLangIndex;
  992. DWORD dwSize;
  993. DWORD dwType;
  994. DWORD dwLastItem;
  995. DWORD dwRemLastDriverCounter;
  996. DWORD dwRemFirstDriverCounter;
  997. DWORD dwRemLastDriverHelp;
  998. DWORD dwRemFirstDriverHelp;
  999. DWORD dwFirstNameToRemove;
  1000. DWORD dwLastNameToRemove;
  1001. DWORD dwLastNameInTable;
  1002. LPTSTR *lpOldNameTable;
  1003. LPTSTR lpLangName = NULL;
  1004. LPTSTR lpThisDriver = NULL;
  1005. BOOL bPerflibUpdated = FALSE;
  1006. DWORD dwBufferSize; // size of total buffer in bytes
  1007. TCHAR CounterNameBuffer [40];
  1008. TCHAR HelpNameBuffer [40];
  1009. HANDLE hFileMapping = NULL;
  1010. DWORD MapFileSize;
  1011. SECURITY_ATTRIBUTES SecAttr;
  1012. TCHAR MapFileName[] = TEXT("Perflib Busy");
  1013. DWORD *lpData;
  1014. LONG_PTR TempFileHandle = -1;
  1015. if (LoadPerfGrabMutex() == FALSE) {
  1016. return (GetLastError());
  1017. }
  1018. RtlZeroMemory(szServiceDisplayName, MAX_PATH * sizeof(TCHAR));
  1019. if (hKeyDriver != NULL) {
  1020. dwBufferSize = MAX_PATH * sizeof(TCHAR);
  1021. lStatus = RegQueryValueEx(hKeyDriver,
  1022. szDisplayName,
  1023. RESERVED,
  1024. & dwType,
  1025. (LPBYTE) szServiceDisplayName,
  1026. & dwBufferSize);
  1027. if (lStatus != ERROR_SUCCESS) {
  1028. lstrcpy(szServiceDisplayName, lpDriverName);
  1029. }
  1030. }
  1031. else {
  1032. lstrcpy(szServiceDisplayName, lpDriverName);
  1033. }
  1034. __try {
  1035. lStatus = RegOpenKeyEx(
  1036. hKeyMachine,
  1037. DriverPathRoot,
  1038. RESERVED,
  1039. KEY_READ | KEY_WRITE,
  1040. & hServices);
  1041. }
  1042. __except (EXCEPTION_EXECUTE_HANDLER) {
  1043. lStatus = GetExceptionCode();
  1044. }
  1045. if (lStatus != ERROR_SUCCESS) {
  1046. ReportLoadPerfEvent(
  1047. EVENTLOG_ERROR_TYPE, // error type
  1048. (DWORD) LDPRFMSG_UNABLE_OPEN_KEY, // event,
  1049. 2, lStatus, __LINE__, 0, 0,
  1050. 1, (LPWSTR) DriverPathRoot, NULL, NULL);
  1051. OUTPUT_MESSAGE (GetFormatResource(UC_UNABLEOPENKEY),
  1052. DriverPathRoot, lStatus);
  1053. TRACE((WINPERF_DBG_TRACE_ERROR),
  1054. (& LoadPerfGuid,
  1055. __LINE__,
  1056. LOADPERF_UNLOADCOUNTERNAMES,
  1057. ARG_DEF(ARG_TYPE_WSTR, 1),
  1058. lStatus,
  1059. TRACE_WSTR(DriverPathRoot),
  1060. NULL));
  1061. ReleaseMutex(hLoadPerfMutex);
  1062. return lStatus;
  1063. }
  1064. // open registry handle to perflib key
  1065. __try {
  1066. lStatus = RegOpenKeyEx (
  1067. hKeyMachine,
  1068. NamesKey,
  1069. RESERVED,
  1070. KEY_READ | KEY_WRITE,
  1071. & hPerflib);
  1072. }
  1073. __except (EXCEPTION_EXECUTE_HANDLER) {
  1074. lStatus = GetExceptionCode();
  1075. }
  1076. if (lStatus != ERROR_SUCCESS) {
  1077. ReportLoadPerfEvent(
  1078. EVENTLOG_ERROR_TYPE, // error type
  1079. (DWORD) LDPRFMSG_UNABLE_OPEN_KEY, // event,
  1080. 2, lStatus, __LINE__, 0, 0,
  1081. 1, (LPWSTR) NamesKey, NULL, NULL);
  1082. OUTPUT_MESSAGE (GetFormatResource(UC_UNABLEOPENKEY),
  1083. NamesKey, lStatus);
  1084. TRACE((WINPERF_DBG_TRACE_ERROR),
  1085. (& LoadPerfGuid,
  1086. __LINE__,
  1087. LOADPERF_UNLOADCOUNTERNAMES,
  1088. ARG_DEF(ARG_TYPE_WSTR, 1),
  1089. lStatus,
  1090. TRACE_WSTR(NamesKey),
  1091. NULL));
  1092. ReleaseMutex(hLoadPerfMutex);
  1093. return lStatus;
  1094. }
  1095. __try {
  1096. lStatus = RegSetValueEx (
  1097. hPerflib,
  1098. Busy,
  1099. RESERVED,
  1100. REG_SZ,
  1101. (LPBYTE) lpDriverName,
  1102. lstrlen(lpDriverName) * sizeof(TCHAR));
  1103. }
  1104. __except (EXCEPTION_EXECUTE_HANDLER) {
  1105. lStatus = GetExceptionCode();
  1106. }
  1107. if (lStatus != ERROR_SUCCESS) {
  1108. OUTPUT_MESSAGE (GetFormatResource(UC_UNABLESETVALUE),
  1109. Busy, NamesKey, lStatus);
  1110. TRACE((WINPERF_DBG_TRACE_ERROR),
  1111. (& LoadPerfGuid,
  1112. __LINE__,
  1113. LOADPERF_UNLOADCOUNTERNAMES,
  1114. ARG_DEF(ARG_TYPE_WSTR, 1),
  1115. lStatus,
  1116. TRACE_WSTR(Busy),
  1117. NULL));
  1118. RegCloseKey (hPerflib);
  1119. ReleaseMutex(hLoadPerfMutex);
  1120. return lStatus;
  1121. }
  1122. // query registry to get number of Explain text items
  1123. dwBufferSize = sizeof (dwHelpItems);
  1124. __try {
  1125. lStatus = RegQueryValueEx (
  1126. hPerflib,
  1127. LastHelp,
  1128. RESERVED,
  1129. & dwType,
  1130. (LPBYTE) & dwHelpItems,
  1131. & dwBufferSize);
  1132. }
  1133. __except (EXCEPTION_EXECUTE_HANDLER) {
  1134. lStatus = GetExceptionCode();
  1135. }
  1136. if ((lStatus != ERROR_SUCCESS) || (dwType != REG_DWORD)) {
  1137. ReportLoadPerfEvent(
  1138. EVENTLOG_ERROR_TYPE, // error type
  1139. (DWORD) LDPRFMSG_UNABLE_READ_VALUE, // event,
  1140. 2, lStatus, __LINE__, 0, 0,
  1141. 1, (LPWSTR) LastHelp, NULL, NULL);
  1142. TRACE((WINPERF_DBG_TRACE_ERROR),
  1143. (& LoadPerfGuid,
  1144. __LINE__,
  1145. LOADPERF_UNLOADCOUNTERNAMES,
  1146. ARG_DEF(ARG_TYPE_WSTR, 1),
  1147. lStatus,
  1148. TRACE_WSTR(LastHelp),
  1149. NULL));
  1150. RegCloseKey (hPerflib);
  1151. ReleaseMutex(hLoadPerfMutex);
  1152. return lStatus;
  1153. }
  1154. // query registry to get number of counter and object name items
  1155. dwBufferSize = sizeof (dwCounterItems);
  1156. __try {
  1157. lStatus = RegQueryValueEx (
  1158. hPerflib,
  1159. LastCounter,
  1160. RESERVED,
  1161. & dwType,
  1162. (LPBYTE) & dwCounterItems,
  1163. & dwBufferSize);
  1164. }
  1165. __except (EXCEPTION_EXECUTE_HANDLER) {
  1166. lStatus = GetExceptionCode();
  1167. }
  1168. if ((lStatus != ERROR_SUCCESS) || (dwType != REG_DWORD)) {
  1169. ReportLoadPerfEvent(
  1170. EVENTLOG_ERROR_TYPE, // error type
  1171. (DWORD) LDPRFMSG_UNABLE_READ_VALUE, // event,
  1172. 2, lStatus, __LINE__, 0, 0,
  1173. 1, (LPWSTR) LastCounter, NULL, NULL);
  1174. TRACE((WINPERF_DBG_TRACE_ERROR),
  1175. (& LoadPerfGuid,
  1176. __LINE__,
  1177. LOADPERF_UNLOADCOUNTERNAMES,
  1178. ARG_DEF(ARG_TYPE_WSTR, 1),
  1179. lStatus,
  1180. TRACE_WSTR(LastCounter),
  1181. NULL));
  1182. RegCloseKey (hPerflib);
  1183. ReleaseMutex(hLoadPerfMutex);
  1184. return lStatus;
  1185. }
  1186. dwLastNameInTable = dwHelpItems;
  1187. if (dwLastNameInTable < dwCounterItems) dwLastNameInTable = dwCounterItems;
  1188. // query registry to get PerfLib system version
  1189. dwBufferSize = sizeof (dwSystemVersion);
  1190. __try {
  1191. lStatus = RegQueryValueEx (
  1192. hPerflib,
  1193. VersionStr,
  1194. RESERVED,
  1195. & dwType,
  1196. (LPBYTE) & dwSystemVersion,
  1197. & dwBufferSize);
  1198. }
  1199. __except (EXCEPTION_EXECUTE_HANDLER) {
  1200. lStatus = GetExceptionCode();
  1201. }
  1202. if ((lStatus != ERROR_SUCCESS) || (dwType != REG_DWORD)) {
  1203. // Key not there, must be NT 1.0 version
  1204. dwSystemVersion = OLD_VERSION;
  1205. }
  1206. // set the hPerfData to HKEY_PERFORMANCE_DATA for new version
  1207. // if remote machine, then need to connect to it.
  1208. if (dwSystemVersion != OLD_VERSION) {
  1209. lStatus = !ERROR_SUCCESS;
  1210. hPerfData = HKEY_PERFORMANCE_DATA;
  1211. if (ComputerName[0]) {
  1212. // have to do it the old faction way
  1213. dwSystemVersion = OLD_VERSION;
  1214. lStatus = ERROR_SUCCESS;
  1215. }
  1216. } // NEW_VERSION
  1217. // allocate temporary String buffer
  1218. lpLangName = MemoryAllocate(MAX_PATH * sizeof(TCHAR));
  1219. lpThisDriver = MemoryAllocate(MAX_PATH * sizeof(TCHAR));
  1220. if (!lpLangName || !lpThisDriver) {
  1221. ReportLoadPerfEvent(
  1222. EVENTLOG_ERROR_TYPE, // error type
  1223. (DWORD) LDPRFMSG_MEMORY_ALLOCATION_FAILURE, // event,
  1224. 1, __LINE__, 0, 0, 0,
  1225. 0, NULL, NULL, NULL);
  1226. TRACE((WINPERF_DBG_TRACE_ERROR),
  1227. (& LoadPerfGuid,
  1228. __LINE__,
  1229. LOADPERF_UNLOADCOUNTERNAMES,
  1230. 0,
  1231. ERROR_OUTOFMEMORY,
  1232. NULL));
  1233. lStatus = ERROR_OUTOFMEMORY;
  1234. goto UCN_ExitPoint;
  1235. }
  1236. // Get the values that are in use by the driver to be removed
  1237. dwSize = sizeof (dwRemLastDriverCounter);
  1238. __try {
  1239. lStatus = RegQueryValueEx (
  1240. hDriverPerf,
  1241. LastCounter,
  1242. RESERVED,
  1243. & dwType,
  1244. (LPBYTE) & dwRemLastDriverCounter,
  1245. & dwSize);
  1246. }
  1247. __except (EXCEPTION_EXECUTE_HANDLER) {
  1248. lStatus = GetExceptionCode();
  1249. }
  1250. if (lStatus != ERROR_SUCCESS) {
  1251. ReportLoadPerfEvent(
  1252. EVENTLOG_ERROR_TYPE, // error type
  1253. (DWORD) LDPRFMSG_UNABLE_READ_VALUE, // event,
  1254. 2, lStatus, __LINE__, 0, 0,
  1255. 1, (LPWSTR) LastCounter, NULL, NULL);
  1256. OUTPUT_MESSAGE (GetFormatResource (UC_UNABLEREADVALUE),
  1257. lpDriverName, LastCounter, lStatus);
  1258. TRACE((WINPERF_DBG_TRACE_ERROR),
  1259. (& LoadPerfGuid,
  1260. __LINE__,
  1261. LOADPERF_UNLOADCOUNTERNAMES,
  1262. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  1263. lStatus,
  1264. TRACE_WSTR(lpDriverName),
  1265. TRACE_WSTR(LastCounter),
  1266. NULL));
  1267. goto UCN_ExitPoint;
  1268. }
  1269. dwSize = sizeof (dwRemFirstDriverCounter);
  1270. __try {
  1271. lStatus = RegQueryValueEx (
  1272. hDriverPerf,
  1273. cszFirstCounter,
  1274. RESERVED,
  1275. & dwType,
  1276. (LPBYTE) & dwRemFirstDriverCounter,
  1277. & dwSize);
  1278. }
  1279. __except (EXCEPTION_EXECUTE_HANDLER) {
  1280. lStatus = GetExceptionCode();
  1281. }
  1282. if (lStatus != ERROR_SUCCESS) {
  1283. ReportLoadPerfEvent(
  1284. EVENTLOG_ERROR_TYPE, // error type
  1285. (DWORD) LDPRFMSG_UNABLE_READ_VALUE, // event,
  1286. 2, lStatus, __LINE__, 0, 0,
  1287. 1, (LPWSTR) cszFirstCounter, NULL, NULL);
  1288. OUTPUT_MESSAGE (GetFormatResource (UC_UNABLEREADVALUE),
  1289. lpDriverName, cszFirstCounter, lStatus);
  1290. TRACE((WINPERF_DBG_TRACE_ERROR),
  1291. (& LoadPerfGuid,
  1292. __LINE__,
  1293. LOADPERF_UNLOADCOUNTERNAMES,
  1294. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  1295. lStatus,
  1296. TRACE_WSTR(lpDriverName),
  1297. TRACE_WSTR(cszFirstCounter),
  1298. NULL));
  1299. goto UCN_ExitPoint;
  1300. }
  1301. dwSize = sizeof (dwRemLastDriverHelp);
  1302. __try {
  1303. lStatus = RegQueryValueEx(
  1304. hDriverPerf,
  1305. LastHelp,
  1306. RESERVED,
  1307. & dwType,
  1308. (LPBYTE) & dwRemLastDriverHelp,
  1309. & dwSize);
  1310. }
  1311. __except (EXCEPTION_EXECUTE_HANDLER) {
  1312. lStatus = GetExceptionCode();
  1313. }
  1314. if (lStatus != ERROR_SUCCESS) {
  1315. ReportLoadPerfEvent(
  1316. EVENTLOG_ERROR_TYPE, // error type
  1317. (DWORD) LDPRFMSG_UNABLE_READ_VALUE, // event,
  1318. 2, lStatus, __LINE__, 0, 0,
  1319. 1, (LPWSTR) LastHelp, NULL, NULL);
  1320. OUTPUT_MESSAGE (GetFormatResource (UC_UNABLEREADVALUE),
  1321. lpDriverName, LastHelp, lStatus);
  1322. TRACE((WINPERF_DBG_TRACE_ERROR),
  1323. (& LoadPerfGuid,
  1324. __LINE__,
  1325. LOADPERF_UNLOADCOUNTERNAMES,
  1326. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  1327. lStatus,
  1328. TRACE_WSTR(lpDriverName),
  1329. TRACE_WSTR(LastHelp),
  1330. NULL));
  1331. goto UCN_ExitPoint;
  1332. }
  1333. dwSize = sizeof (dwRemFirstDriverHelp);
  1334. __try {
  1335. lStatus = RegQueryValueEx (
  1336. hDriverPerf,
  1337. FirstHelp,
  1338. RESERVED,
  1339. & dwType,
  1340. (LPBYTE) & dwRemFirstDriverHelp,
  1341. & dwSize);
  1342. }
  1343. __except (EXCEPTION_EXECUTE_HANDLER) {
  1344. lStatus = GetExceptionCode();
  1345. }
  1346. if (lStatus != ERROR_SUCCESS) {
  1347. ReportLoadPerfEvent(
  1348. EVENTLOG_ERROR_TYPE, // error type
  1349. (DWORD) LDPRFMSG_UNABLE_READ_VALUE, // event,
  1350. 2, lStatus, __LINE__, 0, 0,
  1351. 1, (LPWSTR) FirstHelp, NULL, NULL);
  1352. OUTPUT_MESSAGE (GetFormatResource (UC_UNABLEREADVALUE),
  1353. lpDriverName, FirstHelp, lStatus);
  1354. TRACE((WINPERF_DBG_TRACE_ERROR),
  1355. (& LoadPerfGuid,
  1356. __LINE__,
  1357. LOADPERF_UNLOADCOUNTERNAMES,
  1358. ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
  1359. lStatus,
  1360. TRACE_WSTR(lpDriverName),
  1361. TRACE_WSTR(FirstHelp),
  1362. NULL));
  1363. goto UCN_ExitPoint;
  1364. }
  1365. TRACE((WINPERF_DBG_TRACE_INFO),
  1366. (& LoadPerfGuid,
  1367. __LINE__,
  1368. LOADPERF_UNLOADCOUNTERNAMES,
  1369. ARG_DEF(ARG_TYPE_WSTR, 1),
  1370. lStatus,
  1371. TRACE_WSTR(lpDriverName),
  1372. TRACE_DWORD(dwLastNameInTable),
  1373. TRACE_DWORD(dwCounterItems),
  1374. TRACE_DWORD(dwHelpItems),
  1375. TRACE_DWORD(dwRemFirstDriverCounter),
  1376. TRACE_DWORD(dwRemLastDriverCounter),
  1377. TRACE_DWORD(dwRemFirstDriverHelp),
  1378. TRACE_DWORD(dwRemLastDriverHelp),
  1379. NULL));
  1380. // get the first and last counters to define block of names used
  1381. // by this device
  1382. dwFirstNameToRemove = (dwRemFirstDriverCounter <= dwRemFirstDriverHelp ?
  1383. dwRemFirstDriverCounter : dwRemFirstDriverHelp);
  1384. dwLastNameToRemove = (dwRemLastDriverCounter >= dwRemLastDriverHelp ?
  1385. dwRemLastDriverCounter : dwRemLastDriverHelp);
  1386. dwLastCounter = dwLastHelp = 0;
  1387. // create the file mapping
  1388. SecAttr.nLength = sizeof (SecAttr);
  1389. SecAttr.bInheritHandle = TRUE;
  1390. SecAttr.lpSecurityDescriptor = NULL;
  1391. MapFileSize = sizeof(DWORD);
  1392. hFileMapping = CreateFileMapping ((HANDLE)TempFileHandle, &SecAttr,
  1393. PAGE_READWRITE, (DWORD_PTR)0, MapFileSize, (LPCTSTR)MapFileName);
  1394. if (hFileMapping) {
  1395. lpData = MapViewOfFile (hFileMapping,
  1396. FILE_MAP_ALL_ACCESS, 0L, 0L, 0L);
  1397. if (lpData) {
  1398. *lpData = 1L;
  1399. UnmapViewOfFile (lpData);
  1400. } else {
  1401. lStatus = GetLastError();
  1402. }
  1403. } else {
  1404. lStatus = GetLastError();
  1405. }
  1406. if (lStatus != ERROR_SUCCESS) {
  1407. OUTPUT_MESSAGE (GetFormatResource (UC_UNABLEREADVALUE),
  1408. lpDriverName, FirstHelp, lStatus);
  1409. TRACE((WINPERF_DBG_TRACE_ERROR),
  1410. (& LoadPerfGuid,
  1411. __LINE__,
  1412. LOADPERF_UNLOADCOUNTERNAMES,
  1413. ARG_DEF(ARG_TYPE_WSTR, 1),
  1414. lStatus,
  1415. TRACE_WSTR(lpDriverName),
  1416. NULL));
  1417. goto UCN_ExitPoint;
  1418. }
  1419. // do each language under perflib
  1420. if (dwSystemVersion == OLD_VERSION) {
  1421. for (dwLangIndex = 0, dwSize = MemorySize(lpLangName);
  1422. (RegEnumKey(hPerflib, dwLangIndex, lpLangName, dwSize)) == ERROR_SUCCESS;
  1423. dwLangIndex++, dwSize = MemorySize(lpLangName)) {
  1424. OUTPUT_MESSAGE (GetFormatResource (UC_DOINGLANG), lpLangName);
  1425. lpOldNameTable = BuildNameTable (hPerflib, lpLangName,
  1426. &dwLastItem, &hKeyLang, CounterNameBuffer, HelpNameBuffer);
  1427. if (lpOldNameTable) {
  1428. if (dwLastItem <= dwLastNameInTable) {
  1429. // registry is OK so continue
  1430. if ((lStatus = FixNames (
  1431. hKeyLang,
  1432. lpOldNameTable,
  1433. lpLangName,
  1434. dwLastItem,
  1435. dwFirstNameToRemove,
  1436. dwLastNameToRemove)) == ERROR_SUCCESS) {
  1437. bPerflibUpdated = TRUE;
  1438. }
  1439. } else {
  1440. // registry has been corrupted so abort
  1441. lStatus = ERROR_BADDB;
  1442. break;
  1443. }
  1444. } else { // unable to unload names for this language
  1445. // display error message
  1446. lStatus = GetLastError();
  1447. }
  1448. } // end for (more languages)
  1449. } // end of OLD_VERSION
  1450. else {
  1451. CHAR *pSystemRoot;
  1452. WIN32_FIND_DATA FindFileInfo ;
  1453. HANDLE hFindFile ;
  1454. CHAR FileName[128];
  1455. WCHAR wFileName[128];
  1456. WCHAR LangId[10];
  1457. WCHAR *pLangId;
  1458. DWORD dwIdx;
  1459. pSystemRoot = getenv ("SystemRoot");
  1460. if (pSystemRoot == NULL) {
  1461. // unable to find systemroot so try windir
  1462. pSystemRoot = getenv ("windir");
  1463. }
  1464. if (pSystemRoot != NULL) {
  1465. strcpy(FileName, pSystemRoot);
  1466. strcat(FileName, "\\system32\\perfc???.dat");
  1467. } else {
  1468. // unable to look up the windows directory so
  1469. // try searching from the root of the boot drive
  1470. strcpy(FileName, "C:\\perfc???.dat");
  1471. }
  1472. mbstowcs(wFileName, FileName, strlen(FileName) + 1);
  1473. hFindFile = FindFirstFile ((LPCTSTR)wFileName, &FindFileInfo) ;
  1474. if (!hFindFile || hFindFile == INVALID_HANDLE_VALUE) {
  1475. lStatus = GetLastError();
  1476. } else {
  1477. do {
  1478. // get langid
  1479. // start at lang id # of file name based on the format
  1480. // perfxyyy.dat
  1481. // where x= h for help file, c for counter names
  1482. // y= hex digits of language ID
  1483. //
  1484. dwIdx = 0;
  1485. pLangId = &FindFileInfo.cFileName[0];
  1486. // go to lang ID code in filename (yyy above)
  1487. for (dwIdx = 0; (dwIdx < 5) && (*pLangId++ > 0); dwIdx++);
  1488. if (*pLangId > 0) {
  1489. // get lang ID from file name
  1490. LangId[0] = *pLangId++;
  1491. LangId[1] = *pLangId++;
  1492. LangId[2] = *pLangId++;
  1493. LangId[3] = L'\0';
  1494. } else {
  1495. continue; // on to next file
  1496. }
  1497. OUTPUT_MESSAGE (GetFormatResource (UC_DOINGLANG), LangId);
  1498. lpOldNameTable = BuildNameTable (hPerflib, LangId,
  1499. &dwLastItem, &hKeyLang, CounterNameBuffer, HelpNameBuffer);
  1500. if (lpOldNameTable) {
  1501. if (dwLastItem <= dwLastNameInTable) {
  1502. // registry is OK so continue
  1503. if ((lStatus = FixNames (
  1504. hKeyLang,
  1505. lpOldNameTable,
  1506. LangId,
  1507. dwLastItem,
  1508. dwFirstNameToRemove,
  1509. dwLastNameToRemove)) == ERROR_SUCCESS) {
  1510. bPerflibUpdated = TRUE;
  1511. }
  1512. } else {
  1513. lStatus = ERROR_BADDB;
  1514. break;
  1515. }
  1516. } else { // unable to unload names for this language
  1517. lStatus = GetLastError();
  1518. }
  1519. } while (FindNextFile(hFindFile, &FindFileInfo));
  1520. }
  1521. FindClose (hFindFile);
  1522. } // end of NEW_VERSION
  1523. if ((bPerflibUpdated) && (lStatus == ERROR_SUCCESS)) {
  1524. // update perflib's "last" values
  1525. dwSize = sizeof (dwLastCounter);
  1526. __try {
  1527. lStatus = RegSetValueEx (
  1528. hPerflib,
  1529. LastCounter,
  1530. RESERVED,
  1531. REG_DWORD,
  1532. (LPBYTE) & dwLastCounter,
  1533. dwSize);
  1534. }
  1535. __except (EXCEPTION_EXECUTE_HANDLER) {
  1536. lStatus = GetExceptionCode();
  1537. }
  1538. if (lStatus == ERROR_SUCCESS) {
  1539. dwSize = sizeof (dwLastHelp);
  1540. __try {
  1541. lStatus = RegSetValueEx (
  1542. hPerflib,
  1543. LastHelp,
  1544. RESERVED,
  1545. REG_DWORD,
  1546. (LPBYTE) & dwLastHelp,
  1547. dwSize);
  1548. }
  1549. __except (EXCEPTION_EXECUTE_HANDLER) {
  1550. lStatus = GetExceptionCode();
  1551. }
  1552. if (lStatus != ERROR_SUCCESS) {
  1553. ReportLoadPerfEvent(
  1554. EVENTLOG_ERROR_TYPE, // error type
  1555. (DWORD) LDPRFMSG_UNABLE_UPDATE_VALUE, // event,
  1556. 3, lStatus, dwLastHelp, __LINE__, 0,
  1557. 2, (LPWSTR) LastHelp, (LPWSTR) NamesKey, NULL);
  1558. TRACE((WINPERF_DBG_TRACE_ERROR),
  1559. (& LoadPerfGuid,
  1560. __LINE__,
  1561. LOADPERF_UNLOADCOUNTERNAMES,
  1562. ARG_DEF(ARG_TYPE_WSTR, 1),
  1563. lStatus,
  1564. TRACE_WSTR(LastHelp),
  1565. TRACE_DWORD(dwLastHelp),
  1566. NULL));
  1567. }
  1568. }
  1569. else {
  1570. ReportLoadPerfEvent(
  1571. EVENTLOG_ERROR_TYPE, // error type
  1572. (DWORD) LDPRFMSG_UNABLE_UPDATE_VALUE, // event,
  1573. 3, lStatus, dwLastCounter, __LINE__, 0,
  1574. 2, (LPWSTR) LastCounter, (LPWSTR) NamesKey, NULL);
  1575. TRACE((WINPERF_DBG_TRACE_ERROR),
  1576. (& LoadPerfGuid,
  1577. __LINE__,
  1578. LOADPERF_UNLOADCOUNTERNAMES,
  1579. ARG_DEF(ARG_TYPE_WSTR, 1),
  1580. lStatus,
  1581. TRACE_WSTR(LastCounter),
  1582. TRACE_DWORD(dwLastCounter),
  1583. NULL));
  1584. }
  1585. if (lStatus == ERROR_SUCCESS) {
  1586. ReportLoadPerfEvent(
  1587. EVENTLOG_INFORMATION_TYPE, // error type
  1588. (DWORD) LDPRFMSG_UNLOAD_SUCCESS, // event,
  1589. 3, dwLastCounter, dwLastHelp, __LINE__, 0,
  1590. 2, (LPWSTR) lpDriverName, (LPWSTR) szServiceDisplayName, NULL);
  1591. TRACE((WINPERF_DBG_TRACE_INFO),
  1592. (& LoadPerfGuid,
  1593. __LINE__,
  1594. LOADPERF_UNLOADCOUNTERNAMES,
  1595. ARG_DEF(ARG_TYPE_WSTR, 1),
  1596. lStatus,
  1597. TRACE_WSTR(lpDriverName),
  1598. TRACE_DWORD(dwLastCounter),
  1599. TRACE_DWORD(dwLastHelp),
  1600. NULL));
  1601. RegDeleteValue (hDriverPerf, cszFirstCounter);
  1602. RegDeleteValue (hDriverPerf, LastCounter);
  1603. RegDeleteValue (hDriverPerf, FirstHelp);
  1604. RegDeleteValue (hDriverPerf, LastHelp);
  1605. RegDeleteValue (hDriverPerf, szObjectList);
  1606. RegDeleteValue (hDriverPerf, szLibraryValidationCode);
  1607. }
  1608. }
  1609. UCN_ExitPoint:
  1610. RegDeleteValue (hPerflib, Busy);
  1611. RegCloseKey (hPerflib);
  1612. RegCloseKey (hServices);
  1613. if (lpLangName) MemoryFree(lpLangName);
  1614. if (lpThisDriver) MemoryFree(lpThisDriver);
  1615. if (hFileMapping) {
  1616. CloseHandle (hFileMapping);
  1617. }
  1618. if (lStatus != ERROR_SUCCESS) {
  1619. ReportLoadPerfEvent(
  1620. EVENTLOG_ERROR_TYPE, // error type
  1621. (DWORD) LDPRFMSG_UNLOAD_FAILURE, // event,
  1622. 2, lStatus, __LINE__, 0, 0,
  1623. 2, (LPWSTR) lpDriverName, (LPWSTR) szServiceDisplayName, NULL);
  1624. TRACE((WINPERF_DBG_TRACE_ERROR),
  1625. (& LoadPerfGuid,
  1626. __LINE__,
  1627. LOADPERF_UNLOADCOUNTERNAMES,
  1628. ARG_DEF(ARG_TYPE_WSTR, 1),
  1629. lStatus,
  1630. TRACE_WSTR(lpDriverName),
  1631. NULL));
  1632. }
  1633. ReleaseMutex(hLoadPerfMutex);
  1634. return lStatus;
  1635. }
  1636. LOADPERF_FUNCTION
  1637. UnloadPerfCounterTextStringsW (
  1638. IN LPWSTR lpCommandLine,
  1639. IN BOOL bQuietModeArg
  1640. )
  1641. /*++
  1642. UnloadPerfCounterTextStringsW
  1643. entry point to Counter Name Unloader
  1644. Arguments
  1645. command line string in the format:
  1646. "/?" displays the usage help
  1647. "driver" driver containing the performance counters
  1648. "\\machine driver" removes the counters from the driver on \\machine
  1649. ReturnValue
  1650. 0 (ERROR_SUCCESS) if command was processed
  1651. Non-Zero if command error was detected.
  1652. --*/
  1653. {
  1654. LPTSTR lpDriverName = NULL; // name of driver to delete from perflib
  1655. HKEY hDriverPerf = NULL; // handle to performance sub-key of driver
  1656. HKEY hMachineKey = NULL; // handle to remote machine HKEY_LOCAL_MACHINE
  1657. HKEY hKeyDriver = NULL;
  1658. DWORD dwStatus = ERROR_SUCCESS; // return status of fn. calls
  1659. WinPerfStartTrace(NULL);
  1660. lpDriverName = (LPTSTR)MemoryAllocate(MAX_PATH * sizeof(TCHAR));
  1661. bQuietMode = bQuietModeArg;
  1662. if (lpDriverName != NULL) {
  1663. if (! GetDriverFromCommandLine(
  1664. lpCommandLine, & hMachineKey,
  1665. lpDriverName, & hDriverPerf, & hKeyDriver)) {
  1666. // error message was printed in routine if there was an error
  1667. dwStatus = GetLastError();
  1668. goto Exit0;
  1669. }
  1670. } else {
  1671. dwStatus = ERROR_OUTOFMEMORY;
  1672. goto Exit0;
  1673. }
  1674. OUTPUT_MESSAGE(GetFormatResource(UC_REMOVINGDRIVER), lpDriverName);
  1675. // removes names and explain text for driver in lpDriverName
  1676. // displays error messages for errors encountered
  1677. dwStatus = (DWORD) UnloadCounterNames(hMachineKey,
  1678. hDriverPerf, hKeyDriver, lpDriverName);
  1679. if (dwStatus == ERROR_SUCCESS) {
  1680. SignalWmiWithNewData (WMI_UNLODCTR_EVENT);
  1681. }
  1682. Exit0:
  1683. TRACE((WINPERF_DBG_TRACE_INFO),
  1684. (& LoadPerfGuid,
  1685. __LINE__,
  1686. LOADPERF_UNLOADPERFCOUNTERTEXTSTRINGS,
  1687. ARG_DEF(ARG_TYPE_WSTR, 1),
  1688. dwStatus,
  1689. TRACE_WSTR(lpDriverName),
  1690. NULL));
  1691. if (lpDriverName != NULL) MemoryFree(lpDriverName);
  1692. if (hDriverPerf)
  1693. RegCloseKey (hDriverPerf);
  1694. if (hMachineKey != HKEY_LOCAL_MACHINE && hMachineKey != NULL) {
  1695. RegCloseKey (hMachineKey);
  1696. }
  1697. if (hPerfData != HKEY_PERFORMANCE_DATA && hPerfData != NULL) {
  1698. RegCloseKey (hPerfData);
  1699. }
  1700. return dwStatus;
  1701. }
  1702. LOADPERF_FUNCTION
  1703. UnloadPerfCounterTextStringsA (
  1704. IN LPSTR lpAnsiCommandLine,
  1705. IN BOOL bQuietModeArg
  1706. )
  1707. {
  1708. LPWSTR lpWideCommandLine;
  1709. DWORD dwStrLen;
  1710. DWORD lReturn;
  1711. if (lpAnsiCommandLine != 0) { // to catch bogus parameters
  1712. //length of string including terminator
  1713. dwStrLen = lstrlenA(lpAnsiCommandLine) + 1;
  1714. lpWideCommandLine = GlobalAlloc (GPTR, (dwStrLen * sizeof(WCHAR)));
  1715. if (lpWideCommandLine != NULL) {
  1716. mbstowcs (lpWideCommandLine, lpAnsiCommandLine, dwStrLen);
  1717. lReturn = UnloadPerfCounterTextStringsW(lpWideCommandLine,
  1718. bQuietModeArg );
  1719. GlobalFree (lpWideCommandLine);
  1720. } else {
  1721. lReturn = GetLastError();
  1722. }
  1723. } else {
  1724. lReturn = ERROR_INVALID_PARAMETER;
  1725. }
  1726. return lReturn;
  1727. }