Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

719 lines
21 KiB

  1. #define _PassportExport_
  2. #include "PassportExport.h"
  3. #include <string.h>
  4. #include <tchar.h>
  5. #include "PassportPerf.h"
  6. #include "PassportPerfObjects.h"
  7. #include "PerfSharedMemory.h"
  8. #include "PerfUtils.h"
  9. #include <loadperf.h>
  10. #include <crtdbg.h>
  11. #define PASSPORT_NAME_KEY _T("SYSTEM\\CurrentControlSet\\Services\\%s\\Performance")
  12. #define UNLOAD_NAME _T("unlodctr %s")
  13. #define LOAD_NAME _T("lodctr ")
  14. #define INI_EXT _T(".ini")
  15. #define NAME_KEY_LEN (sizeof(PASSPORT_NAME_KEY)/sizeof(TCHAR))
  16. #define UNLOAD_NAME_LEN (sizeof(UNLOAD_NAME)/sizeof(TCHAR))
  17. #define LOAD_NAME_LEN (sizeof(LOAD_NAME)/sizeof(TCHAR))
  18. #define INI_EXT_LEN (sizeof(INI_EXT)/sizeof(TCHAR))
  19. DWORD dwOpenCount = 0; // count of "Open" threads
  20. BOOL bInitOK = FALSE; // true = DLL initialized OK
  21. //-------------------------------------------------------------
  22. //
  23. // OpenPassportPerformanceData
  24. //
  25. // Arguments:
  26. // Pointer to object ID of each device to be opened (VGA)
  27. //
  28. // Return Value: always ERROR_SUCCESS
  29. //
  30. //-------------------------------------------------------------
  31. DWORD APIENTRY OpenPassportPerformanceData(LPWSTR lpDeviceNames)
  32. {
  33. TCHAR lpszBuffer[MAX_PATH];
  34. TCHAR *lpKeyName;
  35. LONG status;
  36. HKEY hKeyDriverPerf;
  37. DWORD dwFirstCounter = 0, dwFirstHelp = 0,
  38. dwLastCounter = 0, dwLastHelp = 0,
  39. dwNumCounters = 0,
  40. size = 0, i;
  41. // here we need to find out the number of counters (remeber,
  42. // this code not support counter instances) from the registry
  43. if (dwOpenCount == 0)
  44. {
  45. for (i = 0; i < NUM_PERFMON_OBJECTS; i++)
  46. {
  47. DWORD dwStrLen;
  48. _ASSERT(g_PObject[i]);
  49. g_PObject[i]->PSM = new PerfSharedMemory();
  50. if (g_PObject[i]->PSM == NULL)
  51. {
  52. g_PObject[i]->active = FALSE;
  53. continue;
  54. }
  55. // get counter and help index base values from registry
  56. // Open key to registry entry
  57. // read First Counter and First Help values
  58. dwStrLen = lstrlen(g_PObject[i]->szPassportName);
  59. if ((NAME_KEY_LEN + dwStrLen) > (MAX_PATH+2))
  60. {
  61. //
  62. // The buffer size is MAX_PATH
  63. // PASSPORT_NAME_KEY has %s in it, which will be replaced by g_PObject[i]->szPassportName
  64. // So the length checking should be MAX_PATH + 2. THe NULL space is included in NAME_KEY_LEN.
  65. //
  66. lpKeyName = new TCHAR [ NAME_KEY_LEN + dwStrLen - 2];
  67. if (NULL == lpKeyName) {
  68. g_PObject[i]->active = FALSE;
  69. continue;
  70. }
  71. } else {
  72. lpKeyName = &lpszBuffer[0];
  73. }
  74. wsprintf(lpKeyName, PASSPORT_NAME_KEY, g_PObject[i]->szPassportName);
  75. status = RegOpenKeyEx (
  76. HKEY_LOCAL_MACHINE,
  77. lpszBuffer,
  78. 0L,
  79. KEY_READ,
  80. &hKeyDriverPerf);
  81. if (lpKeyName != &lpszBuffer[0]) {
  82. delete [] lpKeyName;
  83. lpKeyName = NULL;
  84. }
  85. if (status != ERROR_SUCCESS)
  86. {
  87. delete g_PObject[i]->PSM;
  88. g_PObject[i]->PSM = NULL;
  89. g_PObject[i]->active = FALSE;
  90. continue;
  91. }
  92. size = sizeof (DWORD);
  93. status = RegQueryValueEx(
  94. hKeyDriverPerf,
  95. _T("First Counter"),
  96. 0L,
  97. NULL,
  98. (LPBYTE)&dwFirstCounter,
  99. &size);
  100. if (status != ERROR_SUCCESS)
  101. {
  102. delete g_PObject[i]->PSM;
  103. g_PObject[i]->PSM = NULL;
  104. g_PObject[i]->active = FALSE;
  105. RegCloseKey(hKeyDriverPerf);
  106. continue;
  107. }
  108. status = RegQueryValueEx(
  109. hKeyDriverPerf,
  110. _T("First Help"),
  111. 0L,
  112. NULL,
  113. (LPBYTE)&dwFirstHelp,
  114. &size);
  115. if (status != ERROR_SUCCESS)
  116. {
  117. delete g_PObject[i]->PSM;
  118. g_PObject[i]->PSM = NULL;
  119. g_PObject[i]->active = FALSE;
  120. RegCloseKey(hKeyDriverPerf);
  121. continue;
  122. }
  123. status = RegQueryValueEx(
  124. hKeyDriverPerf,
  125. _T("Last Counter"),
  126. 0L,
  127. NULL,
  128. (LPBYTE)&dwLastCounter,
  129. &size);
  130. if (status != ERROR_SUCCESS)
  131. {
  132. delete g_PObject[i]->PSM;
  133. g_PObject[i]->PSM = NULL;
  134. g_PObject[i]->active = FALSE;
  135. RegCloseKey(hKeyDriverPerf);
  136. continue;
  137. }
  138. status = RegQueryValueEx(
  139. hKeyDriverPerf,
  140. _T("Last Help"),
  141. 0L,
  142. NULL,
  143. (LPBYTE)&dwLastHelp,
  144. &size);
  145. if (status != ERROR_SUCCESS)
  146. {
  147. delete g_PObject[i]->PSM;
  148. g_PObject[i]->PSM = NULL;
  149. g_PObject[i]->active = FALSE;
  150. RegCloseKey(hKeyDriverPerf);
  151. continue;
  152. }
  153. dwNumCounters = (dwLastCounter - dwFirstCounter) / 2;
  154. RegCloseKey(hKeyDriverPerf);
  155. if (!g_PObject[i]->PSM->initialize(
  156. dwNumCounters,
  157. dwFirstCounter,
  158. dwFirstHelp))
  159. {
  160. delete g_PObject[i]->PSM;
  161. g_PObject[i]->PSM = NULL;
  162. g_PObject[i]->active = FALSE;
  163. continue;
  164. }
  165. for (DWORD j = 0; j < g_PObject[i]->dwNumDefaultCounterTypes; j++)
  166. {
  167. g_PObject[i]->PSM->setDefaultCounterType(
  168. g_PObject[i]->defaultCounterTypes[j].dwIndex,
  169. g_PObject[i]->defaultCounterTypes[j].dwDefaultType);
  170. }
  171. (void)g_PObject[i]->PSM->OpenSharedMemory(
  172. g_PObject[i]->lpcszPassportPerfBlock, FALSE);
  173. g_PObject[i]->active = TRUE;
  174. }
  175. }
  176. dwOpenCount++;
  177. return ERROR_SUCCESS;
  178. }
  179. //
  180. // rotate amoung objects and skip uninstalled objects
  181. //
  182. void ObjectRotate(DWORD *pi)
  183. {
  184. if (NUM_PERFMON_OBJECTS == 1)
  185. {
  186. return;
  187. }
  188. if (NUM_PERFMON_OBJECTS == 2)
  189. {
  190. if (g_PObject[!(*pi)]->active)
  191. {
  192. *pi = !(*pi);
  193. }
  194. return;
  195. }
  196. DWORD oldI = *pi;
  197. DWORD dwMod = NUM_PERFMON_OBJECTS;
  198. do
  199. {
  200. *pi = (*pi + 1) % dwMod;
  201. }
  202. while ((*pi != oldI) && (!g_PObject[*pi]->active));
  203. return;
  204. }
  205. //-------------------------------------------------------------
  206. //
  207. // CollectPassportPerformanceData
  208. //
  209. // Arguments:
  210. // IN LPWSTR lpValueName
  211. // pointer to a wide character string passed by registry.
  212. // IN OUT LPVOID *lppData
  213. // IN: pointer to the address of the buffer to receive the completed
  214. // PerfDataBlock and subordinate structures. This routine will
  215. // append its data to the buffer starting at the point referenced
  216. // by *lppData.
  217. // OUT: points to the first byte after the data structure added by this
  218. // routine. This routine updated the value at lppdata after appending
  219. // its data.
  220. // IN OUT LPDWORD lpcbTotalBytes
  221. // IN: the address of the DWORD that tells the size in bytes of the
  222. // buffer referenced by the lppData argument
  223. // OUT: the number of bytes added by this routine is written to the
  224. // DWORD pointed to by this argument
  225. // IN OUT LPDWORD NumObjectTypes
  226. // IN: the address of the DWORD to receive the number of objects added
  227. // by this routine
  228. // OUT: the number of objects added by this routine is written to the
  229. // DWORD pointed to by this argument
  230. //
  231. // Return Value:
  232. // ERROR_MORE_DATA if buffer passed is too small to hold data
  233. // any error conditions encountered are reported to the event log if
  234. // event logging is enabled.
  235. // ERROR_SUCCESS if success or any other error. Errors, however are
  236. // also reported to the event log.
  237. //
  238. //-------------------------------------------------------------
  239. DWORD APIENTRY CollectPassportPerformanceData(
  240. IN LPWSTR lpValueName,
  241. IN OUT LPVOID *lppData,
  242. IN OUT LPDWORD lpcbTotalBytes,
  243. IN OUT LPDWORD lpNumObjectTypes)
  244. {
  245. //DebugBreak();
  246. DWORD rv = ERROR_SUCCESS,
  247. dwQueryType = 0;
  248. static DWORD i = 0;
  249. //
  250. // This is an exported routine. We need to verify the input parameters
  251. //
  252. if ((lpcbTotalBytes == NULL) || (lpNumObjectTypes == NULL)) {
  253. //
  254. // Are we allowed to return this error code?
  255. //
  256. return ERROR_INVALID_PARAMETER;
  257. }
  258. if (dwOpenCount <= 0 || !g_PObject[i] || !g_PObject[i]->active)
  259. {
  260. *lpcbTotalBytes = (DWORD) 0;
  261. *lpNumObjectTypes = (DWORD) 0;
  262. ObjectRotate(&i);
  263. return ERROR_SUCCESS; // yes, this is a successful exit
  264. }
  265. _ASSERT(g_PObject[i]->PSM);
  266. if (!g_PObject[i]->PSM->checkQuery(lpValueName))
  267. {
  268. *lpcbTotalBytes = (DWORD) 0;
  269. *lpNumObjectTypes = (DWORD) 0;
  270. ObjectRotate(&i);
  271. return ERROR_SUCCESS;
  272. }
  273. (void)g_PObject[i]->PSM->OpenSharedMemory(
  274. g_PObject[i]->lpcszPassportPerfBlock, FALSE);
  275. if (*lpcbTotalBytes < g_PObject[i]->PSM->spaceNeeded())
  276. {
  277. *lpcbTotalBytes = (DWORD) 0;
  278. *lpNumObjectTypes = (DWORD) 0;
  279. ObjectRotate(&i);
  280. return ERROR_MORE_DATA;
  281. }
  282. if (!g_PObject[i]->PSM->writeData(lppData, lpcbTotalBytes))
  283. {
  284. *lpcbTotalBytes = (DWORD) 0;
  285. *lpNumObjectTypes = (DWORD) 0;
  286. ObjectRotate(&i);
  287. return ERROR_SUCCESS;
  288. }
  289. *lpNumObjectTypes = 1;
  290. ObjectRotate(&i);
  291. return ERROR_SUCCESS;
  292. }
  293. //-------------------------------------------------------------
  294. //
  295. // ClosePassportPerformanceData
  296. //
  297. //-------------------------------------------------------------
  298. DWORD APIENTRY ClosePassportPerformanceData()
  299. {
  300. dwOpenCount--;
  301. if (dwOpenCount <= 0)
  302. {
  303. for (DWORD i = 0; i < NUM_PERFMON_OBJECTS; i++)
  304. {
  305. _ASSERT(g_PObject[i]);
  306. _ASSERT(g_PObject[i]->PSM);
  307. if (g_PObject[i]->active)
  308. g_PObject[i]->PSM->CloseSharedMemory();
  309. delete g_PObject[i]->PSM;
  310. g_PObject[i]->PSM = NULL;
  311. }
  312. }
  313. return ERROR_SUCCESS;
  314. }
  315. //-------------------------------------------------------------
  316. //
  317. // DllUnregisterServer
  318. //
  319. //-------------------------------------------------------------
  320. STDAPI DllUnregisterServer(void)
  321. {
  322. TCHAR lpszBuffer[MAX_PATH];
  323. TCHAR *pTmpBuffer;
  324. DWORD dwFileNameLen;
  325. DWORD dwBufLength;
  326. LONG result = 0;
  327. // BUGBUG the counter ini file must be in the same directory as
  328. // the dll
  329. // note: this "unlodctr " MUST be added to the buffer first,
  330. // else UnloadPerfCounterTextStrings() fails. WHY? Literally,
  331. // UnloadPerfCounterTextStrings first parameter is the Command
  332. // Line of the unlodctr.exe application -- eeech!
  333. for (DWORD i = 0; i < NUM_PERFMON_OBJECTS; i++)
  334. {
  335. _ASSERT(g_PObject[i]);
  336. dwFileNameLen = lstrlen(g_PObject[i]->szPassportPerfIniFile);
  337. if ((dwFileNameLen + UNLOAD_NAME_LEN) > MAX_PATH - 2)
  338. {
  339. //
  340. // 2 is for %s
  341. //
  342. pTmpBuffer = new TCHAR [dwFileNameLen + UNLOAD_NAME_LEN - 2];
  343. if (!pTmpBuffer)
  344. {
  345. //
  346. // Afraid of being break the caller. Just return E_UNEXPECTED as original codes dealing with error
  347. // from UnloadPerfCounterTextStrings.
  348. //
  349. return E_UNEXPECTED;
  350. }
  351. dwBufLength = dwFileNameLen + UNLOAD_NAME_LEN - 2;
  352. } else {
  353. pTmpBuffer = lpszBuffer;
  354. dwBufLength = MAX_PATH;
  355. }
  356. wsprintf(pTmpBuffer, UNLOAD_NAME, g_PObject[i]->szPassportPerfIniFile);
  357. __try {
  358. result = UnloadPerfCounterTextStrings(pTmpBuffer,FALSE);
  359. }
  360. __except( EXCEPTION_EXECUTE_HANDLER )
  361. {
  362. ;
  363. }
  364. if (result != ERROR_SUCCESS)
  365. {
  366. if (pTmpBuffer != lpszBuffer)
  367. {
  368. delete [] pTmpBuffer;
  369. }
  370. return (E_UNEXPECTED);
  371. }
  372. dwFileNameLen = lstrlen(g_PObject[i]->szPassportName);
  373. if ((dwFileNameLen + NAME_KEY_LEN) > dwBufLength - 2)
  374. {
  375. if (pTmpBuffer != lpszBuffer)
  376. {
  377. delete [] pTmpBuffer;
  378. }
  379. pTmpBuffer = new TCHAR [dwFileNameLen + NAME_KEY_LEN - 2];
  380. if (!pTmpBuffer)
  381. {
  382. //
  383. // Afraid of being break the caller. Just return E_UNEXPECTED as original codes dealing with error
  384. // from UnloadPerfCounterTextStrings.
  385. //
  386. return E_UNEXPECTED;
  387. }
  388. dwBufLength = dwFileNameLen + NAME_KEY_LEN - 2;
  389. }
  390. wsprintf(pTmpBuffer, PASSPORT_NAME_KEY, g_PObject[i]->szPassportName);
  391. LONG regError = RegDeleteKey(HKEY_LOCAL_MACHINE,lpszBuffer);
  392. if (regError != ERROR_SUCCESS)
  393. {
  394. if (pTmpBuffer != lpszBuffer)
  395. {
  396. delete [] pTmpBuffer;
  397. }
  398. return (E_UNEXPECTED);
  399. }
  400. //
  401. // If buffer is big enough for the above wsprintf(), it must be big enough for this one
  402. //
  403. wsprintf(&lpszBuffer[0],_T("SYSTEM\\CurrentControlSet\\Services\\%s"),
  404. g_PObject[i]->szPassportName);
  405. regError = RegDeleteKey(HKEY_LOCAL_MACHINE,lpszBuffer);
  406. if (pTmpBuffer != lpszBuffer)
  407. {
  408. delete [] pTmpBuffer;
  409. pTmpBuffer = NULL;
  410. }
  411. if (regError != ERROR_SUCCESS)
  412. {
  413. return (E_UNEXPECTED);
  414. }
  415. }
  416. return (S_OK);
  417. }
  418. //-------------------------------------------------------------
  419. //
  420. // DllRegisterServer
  421. //
  422. //-------------------------------------------------------------
  423. STDAPI DllRegisterServer(void)
  424. {
  425. DWORD dwAllocBufferLength=MAX_PATH;
  426. TCHAR lpszBuffer[MAX_PATH];
  427. TCHAR *tmpStr = NULL;
  428. HKEY hkResult1; // address of handle of open key
  429. HKEY hkResult2; // address of handle of open key
  430. HKEY hkResult3; // address of handle of open key
  431. DWORD ulOptions=0;
  432. REGSAM samDesired=KEY_ALL_ACCESS;
  433. DWORD Reserved=0;
  434. DWORD dwTypesSupported=7;
  435. DWORD dwCatagoryCount=1;
  436. LONG result = 0;
  437. DWORD dwStrLen;
  438. (void) DllUnregisterServer();
  439. for (DWORD i = 0; i < NUM_PERFMON_OBJECTS; i++)
  440. {
  441. _ASSERT(g_PObject[i]);
  442. // Get DLL File Location
  443. // 1 is for \ not the NULL
  444. DWORD dwFileLen = lstrlen(g_PObject[i]->szPassportPerfDll)+1;
  445. dwStrLen = GetCurrentDirectory(MAX_PATH - dwFileLen, &lpszBuffer[0]);
  446. if (!dwStrLen) {
  447. goto Error;
  448. }
  449. if (dwStrLen > (MAX_PATH - dwFileLen)) {
  450. //
  451. // NULL is included in dwStrLen.
  452. //
  453. dwStrLen += dwFileLen;
  454. tmpStr = new TCHAR [dwStrLen];
  455. if (!tmpStr) {
  456. goto Error;
  457. }
  458. dwAllocBufferLength = dwStrLen;
  459. dwStrLen = GetCurrentDirectory(dwAllocBufferLength, tmpStr);
  460. if (!dwStrLen) {
  461. goto Error;
  462. }
  463. } else {
  464. tmpStr = lpszBuffer;
  465. }
  466. _tcscat(tmpStr, _T("\\"));
  467. _tcscat(tmpStr, g_PObject[i]->szPassportPerfDll);
  468. // perfmon Registry Settings
  469. if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  470. _T("SYSTEM\\CurrentControlSet\\Services"),
  471. ulOptions,samDesired,&hkResult1)!=ERROR_SUCCESS)
  472. goto Error;
  473. if (RegCreateKey(hkResult1,g_PObject[i]->szPassportName,
  474. &hkResult2)!=ERROR_SUCCESS)
  475. {
  476. RegCloseKey(hkResult1);
  477. goto Error;
  478. }
  479. if (RegCreateKey(hkResult2,_T("Performance"),&hkResult3)!=ERROR_SUCCESS)
  480. {
  481. RegCloseKey(hkResult1);
  482. RegCloseKey(hkResult2);
  483. goto Error;
  484. }
  485. if (RegSetValueEx(hkResult3,_T("Library"),
  486. Reserved,REG_EXPAND_SZ,
  487. (UCHAR*)tmpStr,(dwFileLen+dwStrLen+1)* sizeof(TCHAR))!=ERROR_SUCCESS)
  488. {
  489. RegCloseKey(hkResult1);
  490. RegCloseKey(hkResult2);
  491. RegCloseKey(hkResult3);
  492. goto Error;
  493. }
  494. if (RegSetValueEx(hkResult3, _T("Open"),Reserved,
  495. REG_SZ,(UCHAR*)PASSPORT_PERF_OPEN,
  496. (_tcslen(PASSPORT_PERF_OPEN) + 1)* sizeof(TCHAR))!=ERROR_SUCCESS)
  497. {
  498. RegCloseKey(hkResult1);
  499. RegCloseKey(hkResult2);
  500. RegCloseKey(hkResult3);
  501. goto Error;
  502. }
  503. if (RegSetValueEx(hkResult3,_T("Collect"),Reserved,
  504. REG_SZ,(UCHAR*)PASSPORT_PERF_COLLECT,
  505. ((_tcslen(PASSPORT_PERF_COLLECT)+1)* sizeof(TCHAR)))!=ERROR_SUCCESS)
  506. {
  507. RegCloseKey(hkResult1);
  508. RegCloseKey(hkResult2);
  509. RegCloseKey(hkResult3);
  510. goto Error;
  511. }
  512. if (RegSetValueEx(hkResult3,_T("Close"),Reserved,
  513. REG_SZ,(CONST BYTE *)PASSPORT_PERF_CLOSE,
  514. ((_tcslen(PASSPORT_PERF_CLOSE)+1)* sizeof(TCHAR)))!=ERROR_SUCCESS)
  515. {
  516. RegCloseKey(hkResult1);
  517. RegCloseKey(hkResult2);
  518. RegCloseKey(hkResult3);
  519. goto Error;
  520. }
  521. RegCloseKey(hkResult1);
  522. RegCloseKey(hkResult2);
  523. RegCloseKey(hkResult3);
  524. //if (RegCloseKey(hkResult1)!=ERROR_SUCCESS)
  525. // goto Error;
  526. //if (RegCloseKey(hkResult2)!=ERROR_SUCCESS)
  527. // goto Error;
  528. //if (RegCloseKey(hkResult3)!=ERROR_SUCCESS)
  529. // goto Error;
  530. // BUGBUG the counter ini file must be in the same directory as
  531. // the dll
  532. // note: this "lodctr " MUST be added to the buffer first,
  533. // else LoadPerfCounterTextStrings() fails. WHY? Literally,
  534. // LoadPerfCounterTextStrings first parameter is the Command
  535. // Line of the lodctr.exe application -- eeech!
  536. //
  537. // Both LOAD_NAME_LEN & INI_EXT_LEN include the NULL. So -1.
  538. //
  539. dwFileLen = lstrlen(g_PObject[i]->szPassportPerfIniFile) + LOAD_NAME_LEN + INI_EXT_LEN - 1;
  540. if (dwFileLen > dwAllocBufferLength) {
  541. //
  542. // Allocate memory
  543. //
  544. if (tmpStr != lpszBuffer) {
  545. delete [] tmpStr;
  546. }
  547. tmpStr = new TCHAR [dwFileLen];
  548. if (!tmpStr) {
  549. goto Error;
  550. }
  551. }
  552. _tcscpy(tmpStr, LOAD_NAME);
  553. _tcscat(tmpStr,g_PObject[i]->szPassportPerfIniFile);
  554. _tcscat(tmpStr, INI_EXT);
  555. __try {
  556. result = LoadPerfCounterTextStrings(lpszBuffer,FALSE);
  557. }
  558. __except( EXCEPTION_EXECUTE_HANDLER )
  559. {
  560. ;
  561. }
  562. if (tmpStr != lpszBuffer) {
  563. delete [] tmpStr;
  564. tmpStr = NULL;
  565. }
  566. if (result != ERROR_SUCCESS)
  567. {
  568. goto Error;
  569. }
  570. }
  571. return(S_OK);
  572. Error:
  573. if (tmpStr && (tmpStr != lpszBuffer) ) {
  574. delete [] tmpStr;
  575. }
  576. return(E_UNEXPECTED);
  577. }
  578. //-------------------------------------------------------------
  579. //
  580. //
  581. //
  582. //-------------------------------------------------------------