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.

774 lines
31 KiB

  1. /*++
  2. Copyright (C) 1995-1999 Microsoft Corporation
  3. Module Name:
  4. wildcard.c
  5. Abstract:
  6. counter name wild card expansion functions
  7. --*/
  8. #include <windows.h>
  9. #include <winperf.h>
  10. #include "mbctype.h"
  11. #include "strsafe.h"
  12. #include "pdh.h"
  13. #include "pdhmsg.h"
  14. #include "pdhidef.h"
  15. #include "pdhdlgs.h"
  16. #include "strings.h"
  17. #include "perftype.h"
  18. #include "perfdata.h"
  19. #pragma warning ( disable : 4213)
  20. DWORD DataSourceTypeA(LPCSTR szDataSource);
  21. DWORD DataSourceTypeW(LPCWSTR szDataSource);
  22. STATIC_BOOL
  23. WildStringMatchW(
  24. LPWSTR szWildString,
  25. LPWSTR szMatchString
  26. )
  27. {
  28. BOOL bReturn;
  29. if (szWildString == NULL) {
  30. // every thing matches a null wild card string
  31. bReturn = TRUE;
  32. }
  33. else if (* szWildString == SPLAT_L) {
  34. // every thing matches this
  35. bReturn = TRUE;
  36. }
  37. else {
  38. // for now just do a case insensitive comparison.
  39. // later, this can be made more selective to support
  40. // partial wildcard string matches
  41. bReturn = (BOOL) (lstrcmpiW(szWildString, szMatchString) == 0);
  42. }
  43. return bReturn;
  44. }
  45. STATIC_PDH_FUNCTION
  46. PdhiExpandWildcardPath(
  47. HLOG hDataSource,
  48. LPCWSTR szWildCardPath,
  49. LPVOID pExpandedPathList,
  50. LPDWORD pcchPathListLength,
  51. DWORD dwFlags,
  52. BOOL bUnicode
  53. )
  54. /*
  55. Flags:
  56. NoExpandCounters
  57. NoExpandInstances
  58. CheckCostlyCounters
  59. */
  60. {
  61. PDH_COUNTER_PATH_ELEMENTS_W pPathElem;
  62. PPDHI_COUNTER_PATH pWildCounterPath = NULL;
  63. PDH_STATUS pdhStatus = ERROR_SUCCESS;
  64. DWORD dwBufferRemaining = 0;
  65. LPVOID szNextUserString = NULL;
  66. DWORD dwPathSize = 0;
  67. DWORD dwSize = 0;
  68. DWORD dwSizeReturned = 0;
  69. DWORD dwRetry;
  70. LPWSTR mszObjectList = NULL;
  71. DWORD dwObjectListSize = 0;
  72. LPWSTR szThisObject;
  73. LPWSTR mszCounterList = NULL;
  74. DWORD dwCounterListSize = 0;
  75. LPWSTR szThisCounter;
  76. LPWSTR mszInstanceList = NULL;
  77. DWORD dwInstanceListSize = 0;
  78. LPWSTR szThisInstance;
  79. LPWSTR szTempPathBuffer = NULL;
  80. DWORD szTempPathBufferSize = SMALL_BUFFER_SIZE;
  81. BOOL bMoreData = FALSE;
  82. BOOL bNoInstances = FALSE;
  83. DWORD dwSuccess = 0;
  84. LIST_ENTRY InstList;
  85. PLIST_ENTRY pHead;
  86. PLIST_ENTRY pNext;
  87. PPDHI_INSTANCE pInst;
  88. PPERF_MACHINE pMachine = NULL;
  89. dwPathSize = lstrlenW(szWildCardPath) + 1;
  90. if (dwPathSize < MAX_PATH) dwPathSize = MAX_PATH;
  91. dwSize = sizeof(PDHI_COUNTER_PATH) + 2 * dwPathSize * sizeof(WCHAR);
  92. pWildCounterPath = G_ALLOC(dwSize);
  93. szTempPathBufferSize = SMALL_BUFFER_SIZE;
  94. szTempPathBuffer = G_ALLOC(szTempPathBufferSize * sizeof(WCHAR));
  95. if (pWildCounterPath == NULL || szTempPathBuffer == NULL) {
  96. // unable to allocate memory so bail out
  97. pdhStatus = PDH_MEMORY_ALLOCATION_FAILURE;
  98. }
  99. else {
  100. __try {
  101. dwBufferRemaining = * pcchPathListLength;
  102. szNextUserString = pExpandedPathList;
  103. }
  104. __except (EXCEPTION_EXECUTE_HANDLER) {
  105. pdhStatus = PDH_INVALID_ARGUMENT;
  106. }
  107. }
  108. if (pdhStatus == ERROR_SUCCESS) {
  109. // Parse wild card Path
  110. if (ParseFullPathNameW(szWildCardPath, & dwSize, pWildCounterPath, FALSE)) {
  111. if (pWildCounterPath->szObjectName == NULL) {
  112. pdhStatus = PDH_INVALID_PATH;
  113. }
  114. else if (* pWildCounterPath->szObjectName == SPLAT_L) {
  115. BOOL bFirstTime = TRUE;
  116. //then the object is wild so get the list
  117. // of objects supported by this machine
  118. dwObjectListSize = SMALL_BUFFER_SIZE; // starting buffer size
  119. dwRetry = 10;
  120. do {
  121. G_FREE(mszObjectList);
  122. mszObjectList = G_ALLOC(dwObjectListSize * sizeof(WCHAR));
  123. if (mszObjectList != NULL) {
  124. pdhStatus = PdhEnumObjectsHW(hDataSource,
  125. pWildCounterPath->szMachineName,
  126. mszObjectList,
  127. & dwObjectListSize,
  128. PERF_DETAIL_WIZARD,
  129. bFirstTime);
  130. if (bFirstTime) bFirstTime = FALSE;
  131. dwRetry --;
  132. }
  133. else {
  134. pdhStatus = PDH_MEMORY_ALLOCATION_FAILURE;
  135. }
  136. }
  137. while (dwRetry && pdhStatus == PDH_MORE_DATA);
  138. }
  139. else {
  140. if (hDataSource == H_REALTIME_DATASOURCE) {
  141. DWORD dwObjectId;
  142. pMachine = GetMachine(pWildCounterPath->szMachineName, 0, PDH_GM_UPDATE_PERFNAME_ONLY);
  143. if (pMachine == NULL) {
  144. pdhStatus = GetLastError();
  145. }
  146. else if (pMachine->dwStatus != ERROR_SUCCESS) {
  147. pdhStatus = pMachine->dwStatus;
  148. pMachine->dwRefCount --;
  149. RELEASE_MUTEX(pMachine->hMutex);
  150. }
  151. else {
  152. dwObjectId = GetObjectId(pMachine, pWildCounterPath->szObjectName, NULL);
  153. pMachine->dwRefCount --;
  154. RELEASE_MUTEX(pMachine->hMutex);
  155. if (dwObjectId == (DWORD) -1) {
  156. pdhStatus = PDH_CSTATUS_NO_OBJECT;
  157. }
  158. else {
  159. DWORD dwGetMachineFlags = (dwFlags & PDH_REFRESHCOUNTERS) ? (PDH_GM_UPDATE_PERFDATA) : (0);
  160. pMachine = GetMachine(pWildCounterPath->szMachineName, dwObjectId, dwGetMachineFlags);
  161. if (pMachine != NULL) {
  162. pMachine->dwRefCount --;
  163. RELEASE_MUTEX(pMachine->hMutex);
  164. }
  165. }
  166. }
  167. }
  168. if (pdhStatus == ERROR_SUCCESS) {
  169. dwObjectListSize = lstrlenW(pWildCounterPath->szObjectName) + 2;
  170. mszObjectList = G_ALLOC(dwObjectListSize * sizeof (WCHAR));
  171. if (mszObjectList != NULL) {
  172. StringCchCopyW(mszObjectList, dwObjectListSize, pWildCounterPath->szObjectName);
  173. // add the MSZ terminator
  174. mszObjectList[dwObjectListSize - 2] = L'\0';
  175. mszObjectList[dwObjectListSize - 1] = L'\0';
  176. pdhStatus = ERROR_SUCCESS;
  177. }
  178. else {
  179. pdhStatus = PDH_MEMORY_ALLOCATION_FAILURE;
  180. }
  181. }
  182. }
  183. }
  184. else {
  185. pdhStatus = PDH_INVALID_PATH;
  186. }
  187. }
  188. if (pdhStatus == ERROR_SUCCESS) {
  189. pPathElem.szMachineName = pWildCounterPath->szMachineName;
  190. // for each object
  191. for (szThisObject = mszObjectList;
  192. * szThisObject != L'\0';
  193. szThisObject += (lstrlenW(szThisObject) + 1)) {
  194. G_FREE(mszCounterList);
  195. G_FREE(mszInstanceList);
  196. mszCounterList = NULL;
  197. mszInstanceList = NULL;
  198. dwCounterListSize = MEDIUM_BUFFER_SIZE; // starting buffer size
  199. dwInstanceListSize = MEDIUM_BUFFER_SIZE; // starting buffer size
  200. dwRetry = 10;
  201. do {
  202. G_FREE(mszCounterList);
  203. G_FREE(mszInstanceList);
  204. mszCounterList = G_ALLOC(dwCounterListSize * sizeof(WCHAR));
  205. mszInstanceList = G_ALLOC(dwInstanceListSize * sizeof(WCHAR));
  206. if (mszCounterList != NULL && mszInstanceList != NULL) {
  207. pdhStatus = PdhEnumObjectItemsHW(hDataSource,
  208. pWildCounterPath->szMachineName,
  209. szThisObject,
  210. mszCounterList,
  211. & dwCounterListSize,
  212. mszInstanceList,
  213. & dwInstanceListSize,
  214. PERF_DETAIL_WIZARD,
  215. 0);
  216. dwRetry--;
  217. }
  218. else {
  219. pdhStatus = PDH_MEMORY_ALLOCATION_FAILURE;
  220. }
  221. }
  222. while (dwRetry && pdhStatus == PDH_MORE_DATA);
  223. pPathElem.szObjectName = szThisObject;
  224. if (pdhStatus == ERROR_SUCCESS) {
  225. if (pWildCounterPath->szCounterName == NULL) {
  226. pdhStatus = PDH_INVALID_PATH;
  227. }
  228. else if ((* pWildCounterPath->szCounterName != SPLAT_L) || (dwFlags & PDH_NOEXPANDCOUNTERS)) {
  229. G_FREE(mszCounterList);
  230. dwCounterListSize = lstrlenW(pWildCounterPath->szCounterName) + 2;
  231. mszCounterList = G_ALLOC(dwCounterListSize * sizeof(WCHAR));
  232. if (mszCounterList != NULL) {
  233. StringCchCopyW(mszCounterList, dwCounterListSize, pWildCounterPath->szCounterName);
  234. mszCounterList[dwCounterListSize - 1] = L'\0';
  235. }
  236. else {
  237. pdhStatus = PDH_MEMORY_ALLOCATION_FAILURE;
  238. }
  239. }
  240. if ((pWildCounterPath->szInstanceName == NULL) && (pdhStatus == ERROR_SUCCESS)){
  241. G_FREE(mszInstanceList);
  242. bNoInstances = TRUE;
  243. dwInstanceListSize = 2;
  244. mszInstanceList = G_ALLOC(dwInstanceListSize * sizeof(WCHAR));
  245. if (mszInstanceList != NULL) {
  246. mszInstanceList[0] = mszInstanceList[1] = L'\0';
  247. }
  248. else {
  249. pdhStatus = PDH_MEMORY_ALLOCATION_FAILURE;
  250. }
  251. }
  252. else if ((* pWildCounterPath->szInstanceName != SPLAT_L) || (dwFlags & PDH_NOEXPANDINSTANCES)) {
  253. G_FREE(mszInstanceList);
  254. dwInstanceListSize = lstrlenW(pWildCounterPath->szInstanceName) + 2;
  255. if (pWildCounterPath->szParentName != NULL) {
  256. dwInstanceListSize += lstrlenW(pWildCounterPath->szParentName) + 1;
  257. }
  258. if (pWildCounterPath->dwIndex != 0 && pWildCounterPath->dwIndex != PERF_NO_UNIQUE_ID) {
  259. dwInstanceListSize += 16;
  260. }
  261. mszInstanceList = G_ALLOC(dwInstanceListSize * sizeof(WCHAR));
  262. if (mszInstanceList != NULL) {
  263. if (pWildCounterPath->szParentName != NULL) {
  264. StringCchPrintfW(mszInstanceList, dwInstanceListSize, L"%ws/%ws",
  265. pWildCounterPath->szParentName, pWildCounterPath->szInstanceName);
  266. }
  267. else {
  268. StringCchCopyW(mszInstanceList, dwInstanceListSize, pWildCounterPath->szInstanceName);
  269. }
  270. if (pWildCounterPath->dwIndex != 0 && pWildCounterPath->dwIndex != PERF_NO_UNIQUE_ID) {
  271. WCHAR szDigits[16];
  272. StringCchCatW(mszInstanceList, dwInstanceListSize, cszPoundSign);
  273. ZeroMemory(szDigits, 16 * sizeof(WCHAR));
  274. _ltow((long) pWildCounterPath->dwIndex, szDigits, 10);
  275. StringCchCatW(mszInstanceList, dwInstanceListSize, szDigits);
  276. }
  277. mszInstanceList [dwInstanceListSize - 1] = L'\0';
  278. }
  279. else {
  280. pdhStatus = PDH_MEMORY_ALLOCATION_FAILURE;
  281. }
  282. }
  283. }
  284. if (pdhStatus != ERROR_SUCCESS) continue;
  285. if (mszInstanceList != NULL) {
  286. if (! bNoInstances && mszInstanceList[0] == L'\0') {
  287. pdhStatus = PDH_CSTATUS_NO_INSTANCE;
  288. continue;
  289. }
  290. InitializeListHead(& InstList);
  291. for (szThisInstance = mszInstanceList;
  292. * szThisInstance != L'\0';
  293. szThisInstance += (lstrlenW(szThisInstance) + 1)) {
  294. PdhiFindInstance(& InstList, szThisInstance, TRUE, &pInst);
  295. }
  296. szThisInstance = mszInstanceList;
  297. do {
  298. if (bNoInstances) {
  299. pPathElem.szInstanceName = NULL;
  300. }
  301. else {
  302. pPathElem.szInstanceName = szThisInstance;
  303. }
  304. pPathElem.szParentInstance = NULL; // included in the instance name
  305. pInst = NULL;
  306. PdhiFindInstance(& InstList, szThisInstance, FALSE, & pInst);
  307. if (pInst == NULL || pInst->dwTotal == 1
  308. || pInst->dwCount <= 1) {
  309. pPathElem.dwInstanceIndex = (DWORD) -1; // included in the instance name
  310. }
  311. else {
  312. pInst->dwCount --;
  313. pPathElem.dwInstanceIndex = pInst->dwCount;
  314. }
  315. for (szThisCounter = mszCounterList;
  316. * szThisCounter != L'\0';
  317. szThisCounter += (lstrlenW(szThisCounter) + 1)) {
  318. pPathElem.szCounterName = szThisCounter;
  319. //make path string and add to list if it will fit
  320. szTempPathBufferSize = SMALL_BUFFER_SIZE;
  321. pdhStatus = PdhMakeCounterPathW(& pPathElem, szTempPathBuffer, & szTempPathBufferSize, 0);
  322. if (pdhStatus == ERROR_SUCCESS) {
  323. // add the string if it will fit
  324. if (bUnicode) {
  325. dwSize = lstrlenW((LPWSTR) szTempPathBuffer) + 1;
  326. if (! bMoreData && (dwSize <= dwBufferRemaining)) {
  327. StringCchCopyW((LPWSTR) szNextUserString, dwBufferRemaining, szTempPathBuffer);
  328. (LPBYTE) szNextUserString += dwSize * sizeof(WCHAR);
  329. dwBufferRemaining -= dwSize;
  330. dwSuccess ++;
  331. }
  332. else {
  333. dwBufferRemaining = 0;
  334. bMoreData = TRUE;
  335. }
  336. }
  337. else {
  338. dwSize = dwBufferRemaining;
  339. if (PdhiConvertUnicodeToAnsi(_getmbcp(),
  340. szTempPathBuffer,
  341. szNextUserString,
  342. & dwSize) == ERROR_SUCCESS) {
  343. (LPBYTE)szNextUserString += dwSize * sizeof(CHAR);
  344. dwBufferRemaining -= dwSize;
  345. dwSuccess ++;
  346. }
  347. else {
  348. dwBufferRemaining = 0;
  349. bMoreData = TRUE;
  350. }
  351. }
  352. dwSizeReturned += dwSize;
  353. } // end if path created OK
  354. } // end for each counter
  355. if (* szThisInstance != L'\0') {
  356. szThisInstance += (lstrlenW(szThisInstance) + 1);
  357. }
  358. }
  359. while (* szThisInstance != L'\0');
  360. if (! IsListEmpty(& InstList)) {
  361. pHead = & InstList;
  362. pNext = pHead->Flink;
  363. while (pNext != pHead) {
  364. pInst = CONTAINING_RECORD(pNext, PDHI_INSTANCE, Entry);
  365. pNext = pNext->Flink;
  366. RemoveEntryList(& pInst->Entry);
  367. G_FREE(pInst);
  368. }
  369. }
  370. } // else no instances to do
  371. } // end for each object found
  372. } // end if object enumeration successful
  373. if (dwSuccess > 0) {
  374. pdhStatus = (bMoreData) ? (PDH_MORE_DATA) : (ERROR_SUCCESS);
  375. }
  376. if (dwSizeReturned > 0) {
  377. dwSize = 1;
  378. if (dwBufferRemaining >= 1) {
  379. if (szNextUserString) {
  380. if (bUnicode) {
  381. * (LPWSTR) szNextUserString = L'\0';
  382. (LPBYTE) szNextUserString += dwSize * sizeof(WCHAR);
  383. }
  384. else {
  385. * (LPSTR) szNextUserString = '\0';
  386. (LPBYTE) szNextUserString += dwSize * sizeof(CHAR);
  387. }
  388. }
  389. }
  390. dwSizeReturned += dwSize;
  391. dwBufferRemaining -= dwSize;
  392. }
  393. * pcchPathListLength = dwSizeReturned;
  394. G_FREE(mszCounterList);
  395. G_FREE(mszInstanceList);
  396. G_FREE(mszObjectList);
  397. G_FREE(pWildCounterPath);
  398. G_FREE(szTempPathBuffer);
  399. if (bMoreData) pdhStatus = PDH_MORE_DATA;
  400. return (pdhStatus);
  401. }
  402. PDH_FUNCTION
  403. PdhExpandCounterPathW(
  404. IN LPCWSTR szWildCardPath,
  405. IN LPWSTR mszExpandedPathList,
  406. IN LPDWORD pcchPathListLength
  407. )
  408. /*++
  409. Expands any wild card characters in the following fields of the
  410. counter path string in the szWildCardPath argument and returns the
  411. matching counter paths in the buffer referenced by the
  412. mszExpandedPathList argument
  413. The input path is defined as one of the following formats:
  414. \\machine\object(parent/instance#index)\counter
  415. \\machine\object(parent/instance)\counter
  416. \\machine\object(instance#index)\counter
  417. \\machine\object(instance)\counter
  418. \\machine\object\counter
  419. \object(parent/instance#index)\counter
  420. \object(parent/instance)\counter
  421. \object(instance#index)\counter
  422. \object(instance)\counter
  423. \object\counter
  424. Input paths that include the machine will be expanded to also
  425. include the machine and use the specified machine to resolve the
  426. wild card matches. Input paths that do not contain a machine name
  427. will use the local machine to resolve wild card matches.
  428. The following fields may contain either a valid name or a wild card
  429. character ("*"). Partial string matches (e.g. "pro*") are not
  430. supported.
  431. parent returns all instances of the specified object that
  432. match the other specified fields
  433. instance returns all instances of the specified object and
  434. parent object if specified
  435. index returns all duplicate matching instance names
  436. counter returns all counters of the specified object
  437. --*/
  438. {
  439. return PdhExpandWildCardPathW(NULL, szWildCardPath, mszExpandedPathList, pcchPathListLength, 0);
  440. }
  441. PDH_FUNCTION
  442. PdhExpandCounterPathA(
  443. IN LPCSTR szWildCardPath,
  444. IN LPSTR mszExpandedPathList,
  445. IN LPDWORD pcchPathListLength
  446. )
  447. {
  448. return PdhExpandWildCardPathA(NULL, szWildCardPath, mszExpandedPathList, pcchPathListLength, 0);
  449. }
  450. PDH_FUNCTION
  451. PdhExpandWildCardPathHW(
  452. IN HLOG hDataSource,
  453. IN LPCWSTR szWildCardPath,
  454. IN LPWSTR mszExpandedPathList,
  455. IN LPDWORD pcchPathListLength,
  456. IN DWORD dwFlags
  457. )
  458. {
  459. PDH_STATUS pdhStatus = ERROR_SUCCESS;
  460. DWORD dwLocalBufferSize;
  461. if ((szWildCardPath == NULL) || (pcchPathListLength == NULL)) {
  462. pdhStatus = PDH_INVALID_ARGUMENT;
  463. }
  464. else {
  465. __try {
  466. if (* szWildCardPath == L'\0' || lstrlenW(szWildCardPath) > PDH_MAX_COUNTER_PATH) {
  467. pdhStatus = PDH_INVALID_ARGUMENT;
  468. }
  469. else {
  470. dwLocalBufferSize = * pcchPathListLength;
  471. if (dwLocalBufferSize > 0) {
  472. if (mszExpandedPathList != NULL) {
  473. mszExpandedPathList[0] = L'\0';
  474. mszExpandedPathList[dwLocalBufferSize - 1] = L'\0';
  475. }
  476. else {
  477. pdhStatus = PDH_INVALID_ARGUMENT;
  478. }
  479. }
  480. }
  481. }
  482. __except (EXCEPTION_EXECUTE_HANDLER) {
  483. pdhStatus = PDH_INVALID_ARGUMENT;
  484. }
  485. }
  486. if (pdhStatus == ERROR_SUCCESS) {
  487. pdhStatus = PdhiExpandWildcardPath(hDataSource,
  488. szWildCardPath,
  489. (LPVOID) mszExpandedPathList,
  490. & dwLocalBufferSize,
  491. dwFlags,
  492. TRUE);
  493. __try {
  494. * pcchPathListLength = dwLocalBufferSize;
  495. }
  496. __except (EXCEPTION_EXECUTE_HANDLER) {
  497. pdhStatus = PDH_INVALID_ARGUMENT;
  498. }
  499. }
  500. return pdhStatus;
  501. }
  502. PDH_FUNCTION
  503. PdhExpandWildCardPathW(
  504. IN LPCWSTR szDataSource,
  505. IN LPCWSTR szWildCardPath,
  506. IN LPWSTR mszExpandedPathList,
  507. IN LPDWORD pcchPathListLength,
  508. IN DWORD dwFlags
  509. )
  510. /*++
  511. Expands any wild card characters in the following fields of the
  512. counter path string in the szWildCardPath argument and returns the
  513. matching counter paths in the buffer referenced by the
  514. mszExpandedPathList argument
  515. The input path is defined as one of the following formats:
  516. \\machine\object(parent/instance#index)\counter
  517. \\machine\object(parent/instance)\counter
  518. \\machine\object(instance#index)\counter
  519. \\machine\object(instance)\counter
  520. \\machine\object\counter
  521. \object(parent/instance#index)\counter
  522. \object(parent/instance)\counter
  523. \object(instance#index)\counter
  524. \object(instance)\counter
  525. \object\counter
  526. Input paths that include the machine will be expanded to also
  527. include the machine and use the specified machine to resolve the
  528. wild card matches. Input paths that do not contain a machine name
  529. will use the local machine to resolve wild card matches.
  530. The following fields may contain either a valid name or a wild card
  531. character ("*"). Partial string matches (e.g. "pro*") are not
  532. supported.
  533. parent returns all instances of the specified object that
  534. match the other specified fields
  535. instance returns all instances of the specified object and
  536. parent object if specified
  537. index returns all duplicate matching instance names
  538. counter returns all counters of the specified object
  539. --*/
  540. {
  541. PDH_STATUS pdhStatus = ERROR_SUCCESS;
  542. DWORD dwLocalBufferSize;
  543. DWORD dwDataSource = 0;
  544. HLOG hDataSource = H_REALTIME_DATASOURCE;
  545. __try {
  546. if (szDataSource != NULL) {
  547. // test for read access to the name
  548. if (* szDataSource == L'\0') {
  549. pdhStatus = PDH_INVALID_ARGUMENT;
  550. }
  551. else if (lstrlenW(szDataSource) > PDH_MAX_DATASOURCE_PATH) {
  552. pdhStatus = PDH_INVALID_ARGUMENT;
  553. }
  554. } // else NULL is a valid arg
  555. if (pdhStatus == ERROR_SUCCESS) {
  556. dwDataSource = DataSourceTypeW(szDataSource);
  557. dwLocalBufferSize = * pcchPathListLength;
  558. }
  559. }
  560. __except (EXCEPTION_EXECUTE_HANDLER) {
  561. pdhStatus = PDH_INVALID_ARGUMENT;
  562. }
  563. if (pdhStatus == ERROR_SUCCESS) {
  564. if (dwDataSource == DATA_SOURCE_WBEM) {
  565. hDataSource = H_WBEM_DATASOURCE;
  566. }
  567. else if (dwDataSource == DATA_SOURCE_LOGFILE) {
  568. DWORD dwLogType = 0;
  569. pdhStatus = PdhOpenLogW(szDataSource,
  570. PDH_LOG_READ_ACCESS | PDH_LOG_OPEN_EXISTING,
  571. & dwLogType,
  572. NULL,
  573. 0,
  574. NULL,
  575. & hDataSource);
  576. }
  577. if (pdhStatus == ERROR_SUCCESS) {
  578. pdhStatus = PdhExpandWildCardPathHW(hDataSource,
  579. szWildCardPath,
  580. mszExpandedPathList,
  581. pcchPathListLength,
  582. dwFlags);
  583. if (dwDataSource == DATA_SOURCE_LOGFILE) {
  584. PdhCloseLog(hDataSource, 0);
  585. }
  586. }
  587. }
  588. return pdhStatus;
  589. }
  590. PDH_FUNCTION
  591. PdhExpandWildCardPathHA(
  592. IN HLOG hDataSource,
  593. IN LPCSTR szWildCardPath,
  594. IN LPSTR mszExpandedPathList,
  595. IN LPDWORD pcchPathListLength,
  596. IN DWORD dwFlags
  597. )
  598. {
  599. LPWSTR szWideWildCardPath = NULL;
  600. PDH_STATUS pdhStatus = ERROR_SUCCESS;
  601. DWORD dwLocalBufferSize;
  602. if ((szWildCardPath == NULL) || (pcchPathListLength == NULL)) {
  603. pdhStatus = PDH_INVALID_ARGUMENT;
  604. }
  605. else if (* szWildCardPath == '\0') {
  606. pdhStatus = PDH_INVALID_ARGUMENT;
  607. }
  608. else {
  609. __try {
  610. dwLocalBufferSize = * pcchPathListLength;
  611. if (dwLocalBufferSize > 0) {
  612. if (mszExpandedPathList != NULL) {
  613. mszExpandedPathList[0] = L'\0';
  614. mszExpandedPathList[dwLocalBufferSize - 1] = L'\0';
  615. }
  616. else {
  617. pdhStatus = PDH_INVALID_ARGUMENT;
  618. }
  619. }
  620. if (pdhStatus == ERROR_SUCCESS) {
  621. if (* szWildCardPath == '\0' || lstrlenA(szWildCardPath) > PDH_MAX_COUNTER_PATH) {
  622. pdhStatus = PDH_INVALID_ARGUMENT;
  623. }
  624. else {
  625. szWideWildCardPath = PdhiMultiByteToWideChar(_getmbcp(), (LPSTR) szWildCardPath);
  626. if (szWideWildCardPath == NULL) {
  627. pdhStatus = PDH_MEMORY_ALLOCATION_FAILURE;
  628. }
  629. }
  630. }
  631. }
  632. __except (EXCEPTION_EXECUTE_HANDLER) {
  633. pdhStatus = PDH_INVALID_ARGUMENT;
  634. }
  635. }
  636. if (pdhStatus == ERROR_SUCCESS) {
  637. pdhStatus = PdhiExpandWildcardPath(hDataSource,
  638. szWideWildCardPath,
  639. (LPVOID) mszExpandedPathList,
  640. & dwLocalBufferSize,
  641. dwFlags,
  642. FALSE);
  643. __try {
  644. * pcchPathListLength = dwLocalBufferSize;
  645. }
  646. __except (EXCEPTION_EXECUTE_HANDLER) {
  647. pdhStatus = PDH_INVALID_ARGUMENT;
  648. }
  649. }
  650. G_FREE(szWideWildCardPath);
  651. return pdhStatus;
  652. }
  653. PDH_FUNCTION
  654. PdhExpandWildCardPathA(
  655. IN LPCSTR szDataSource,
  656. IN LPCSTR szWildCardPath,
  657. IN LPSTR mszExpandedPathList,
  658. IN LPDWORD pcchPathListLength,
  659. IN DWORD dwFlags
  660. )
  661. {
  662. PDH_STATUS pdhStatus = ERROR_SUCCESS;
  663. HLOG hDataSource = H_REALTIME_DATASOURCE;
  664. DWORD dwDataSource = 0;
  665. __try {
  666. if (szDataSource != NULL) {
  667. // test for read access to the name
  668. if (* szDataSource == 0) {
  669. pdhStatus = PDH_INVALID_ARGUMENT;
  670. }
  671. else if (lstrlenA(szDataSource) > PDH_MAX_DATASOURCE_PATH) {
  672. pdhStatus = PDH_INVALID_ARGUMENT;
  673. }
  674. } // else NULL is a valid arg
  675. if (pdhStatus == ERROR_SUCCESS) {
  676. dwDataSource = DataSourceTypeA(szDataSource);
  677. }
  678. }
  679. __except (EXCEPTION_EXECUTE_HANDLER) {
  680. pdhStatus = PDH_INVALID_ARGUMENT;
  681. }
  682. if (pdhStatus == ERROR_SUCCESS) {
  683. if (dwDataSource == DATA_SOURCE_WBEM) {
  684. hDataSource = H_WBEM_DATASOURCE;
  685. }
  686. else if (dwDataSource == DATA_SOURCE_LOGFILE) {
  687. DWORD dwLogType = 0;
  688. pdhStatus = PdhOpenLogA(szDataSource,
  689. PDH_LOG_READ_ACCESS | PDH_LOG_OPEN_EXISTING,
  690. & dwLogType,
  691. NULL,
  692. 0,
  693. NULL,
  694. & hDataSource);
  695. }
  696. if (pdhStatus == ERROR_SUCCESS) {
  697. pdhStatus = PdhExpandWildCardPathHA(hDataSource,
  698. szWildCardPath,
  699. mszExpandedPathList,
  700. pcchPathListLength,
  701. dwFlags);
  702. if (dwDataSource == DATA_SOURCE_LOGFILE) {
  703. PdhCloseLog(hDataSource, 0);
  704. }
  705. }
  706. }
  707. return pdhStatus;
  708. }