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.

5196 lines
161 KiB

  1. /*****************************************************************************\
  2. Copyright (c) Microsoft Corporation. All rights reserved.
  3. \*****************************************************************************/
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <tchar.h>
  7. #include <nt.h>
  8. #include <ntrtl.h>
  9. #include <nturtl.h>
  10. #include <windows.h>
  11. #include <winbase.h>
  12. #include <userenv.h>
  13. #include <wmistr.h>
  14. #include <evntrace.h>
  15. #include <pdh.h>
  16. #include <pdhp.h>
  17. #include <pdhmsg.h>
  18. #include <wincrypt.h>
  19. #include <shlwapi.h>
  20. #include "plogman.h"
  21. #include "pdhdlgs.h"
  22. HANDLE hPdhPlaMutex = NULL;
  23. /*****************************************************************************\
  24. Strings
  25. \*****************************************************************************/
  26. // Common
  27. LPCWSTR szCollection = L"Collection Name";
  28. LPCWSTR szKey = L"Key";
  29. LPCWSTR szRunAs = L"Run As";
  30. LPCWSTR szSysmonLog = L"SysmonLog";
  31. LPCWSTR szCurrentState = L"Current State";
  32. LPCWSTR szLogType = L"Log Type";
  33. LPCWSTR szLogBaseName = L"Log File Base Name";
  34. LPCWSTR szStart = L"Start";
  35. LPCWSTR szStop = L"Stop";
  36. LPCWSTR szRestart = L"Restart";
  37. LPCWSTR szLogMaxSize = L"Log File Max Size";
  38. LPCWSTR szCurrentLogFile = L"Current Log File Name";
  39. LPCWSTR szLogSerialNumber = L"Log File Serial Number";
  40. LPCWSTR szLogAutoFormat = L"Log File Auto Format";
  41. LPCWSTR szComment = L"Comment";
  42. LPCWSTR szEOFCmd = L"EOF Command File";
  43. LPCWSTR szLogFolder = L"Log File Folder";
  44. LPCWSTR szLogFileType = L"Log File Type";
  45. LPCWSTR szRepeatSchedule = L"Repeat Schedule";
  46. LPCWSTR szRepeatScheduleBegin = L"Repeat Schedule Start";
  47. LPCWSTR szRepeatScheduleEnd = L"Repeat Schedule Stop";
  48. LPCWSTR szCreateNewFile = L"Create New File";
  49. LPCWSTR szDatastoreAttributes = L"Data Store Attributes";
  50. // Trace
  51. LPCWSTR szTraceProviderCount = L"Trace Provider Count";
  52. LPCWSTR szTraceBufferSize = L"Trace Buffer Size";
  53. LPCWSTR szTraceBufferMin = L"Trace Buffer Min Count";
  54. LPCWSTR szTraceBufferMax = L"Trace Buffer Max Count";
  55. LPCWSTR szTraceFlushInterval = L"Trace Buffer Flush Interval";
  56. LPCWSTR szTraceFlags = L"Trace Flags";
  57. LPCWSTR szTraceProviderList = L"Trace Provider List";
  58. LPCWSTR szTraceProviderFlags = L"Trace Provider Flags";
  59. LPCWSTR szTraceProviderLevels = L"Trace Provider Levels";
  60. LPCWSTR szTraceMode = L"Trace Mode";
  61. LPCWSTR szTraceLoggerName = L"Trace Logger Name";
  62. // Performance
  63. LPCWSTR szPerfCounterList = L"Counter List";
  64. LPCWSTR szSqlBaseName = L"Sql Log Base Name";
  65. LPCWSTR szSampleInterval = L"Sample Interval";
  66. /*****************************************************************************/
  67. extern "C"
  68. {
  69. LPWSTR
  70. PlaiStringDuplicate( LPWSTR sz )
  71. {
  72. LPWSTR szDup = NULL;
  73. __try {
  74. if( NULL != sz ){
  75. size_t cbSize = ( _tcslen( sz ) + 1 ) * sizeof(WCHAR);
  76. szDup = (LPWSTR)G_ALLOC( cbSize );
  77. if( NULL != szDup ){
  78. StringCbCopy( szDup, cbSize, sz );
  79. }
  80. }
  81. } __except (EXCEPTION_EXECUTE_HANDLER) {
  82. G_FREE( szDup );
  83. szDup = NULL;
  84. }
  85. return szDup;
  86. }
  87. }
  88. #define CHECK_NAMES( szName, szCom, strCom ) \
  89. if( szName == NULL ){ \
  90. pdhStatus = PDH_MEMORY_ALLOCATION_FAILURE; \
  91. goto cleanup; \
  92. } \
  93. if( NULL != strCom && NULL == szCom ){ \
  94. pdhStatus = PDH_MEMORY_ALLOCATION_FAILURE; \
  95. goto cleanup; \
  96. }
  97. PDH_FUNCTION
  98. PlaiErrorToPdhStatus( DWORD dwStatus )
  99. {
  100. switch( dwStatus ){
  101. case ERROR_SUCCESS: return ERROR_SUCCESS;
  102. case ERROR_FILE_NOT_FOUND: return PDH_PLA_COLLECTION_NOT_FOUND;
  103. case ERROR_SERVICE_ALREADY_RUNNING: return PDH_PLA_COLLECTION_ALREADY_RUNNING;
  104. case ERROR_DIRECTORY: return PDH_PLA_ERROR_FILEPATH;
  105. case ERROR_OUTOFMEMORY: return PDH_MEMORY_ALLOCATION_FAILURE;
  106. case ERROR_NOT_ENOUGH_MEMORY: return PDH_MEMORY_ALLOCATION_FAILURE;
  107. case ERROR_NO_DATA: return PDH_NO_DATA;
  108. case ERROR_ACCESS_DENIED: return PDH_ACCESS_DENIED;
  109. case WBEM_E_NOT_FOUND: return PDH_WBEM_ERROR;
  110. case E_FAIL: return PDH_WBEM_ERROR;
  111. case WBEM_E_PROVIDER_FAILURE: return PDH_WBEM_ERROR;
  112. case WBEM_E_OUT_OF_MEMORY: return PDH_MEMORY_ALLOCATION_FAILURE;
  113. case ERROR_BAD_NETPATH: return PDH_ACCESS_DENIED;
  114. case WBEM_E_ACCESS_DENIED: return PDH_ACCESS_DENIED;
  115. default: return PDH_INVALID_DATA;
  116. }
  117. }
  118. ULONG
  119. PlaMszStrLenA( LPSTR mszString )
  120. {
  121. ULONG nLength = 0;
  122. ULONG nTotalLength = 0;
  123. LPSTR strScan = mszString;
  124. if( mszString == NULL ){
  125. return 0;
  126. }
  127. while( *strScan != '\0' ){
  128. nLength = (strlen( strScan )+1);
  129. strScan += nLength;
  130. nTotalLength += nLength;
  131. }
  132. return (nTotalLength*sizeof(char) + (sizeof(char) * 2));
  133. }
  134. ULONG
  135. PlaMszStrLenW( LPWSTR mszString )
  136. {
  137. ULONG nLength = 0;
  138. ULONG nTotalLength = 0;
  139. LPTSTR strScan = mszString;
  140. if( mszString == NULL ){
  141. return 0;
  142. }
  143. while( *strScan != L'\0' ){
  144. nLength = (wcslen( strScan )+1);
  145. strScan += nLength;
  146. nTotalLength += nLength;
  147. }
  148. return (nTotalLength*sizeof(WCHAR) + (sizeof(WCHAR)));
  149. }
  150. _inline BOOL
  151. PlaiIsStringEmpty( LPWSTR str )
  152. {
  153. if( NULL == str ){
  154. return TRUE;
  155. }
  156. if( L'\0' == *str ){
  157. return TRUE;
  158. }
  159. return FALSE;
  160. }
  161. _inline BOOL
  162. PlaiIsCharWhitespace( WCHAR ch )
  163. {
  164. switch( ch ){
  165. case L' ':
  166. case L'\r':
  167. case L'\n':
  168. case L'\t':
  169. return TRUE;
  170. default:
  171. return FALSE;
  172. }
  173. }
  174. PDH_FUNCTION
  175. Plaiatow( LPSTR strA, LPWSTR &strW )
  176. {
  177. if( NULL == strA ){
  178. strW = NULL;
  179. return ERROR_SUCCESS;
  180. }
  181. strW = (LPWSTR)G_ALLOC( (strlen(strA)+1) * sizeof(WCHAR) );
  182. if( strW ){
  183. mbstowcs( strW, strA, (strlen(strA)+1) );
  184. return ERROR_SUCCESS;
  185. }
  186. strW = NULL;
  187. return PDH_MEMORY_ALLOCATION_FAILURE;
  188. }
  189. ULONG
  190. Plaihextoi( LPWSTR s )
  191. {
  192. long len;
  193. ULONG num, base, hex;
  194. if ( PlaiIsStringEmpty( s ) ) {
  195. return 0;
  196. }
  197. len = (long) wcslen(s);
  198. if (len == 0) {
  199. return 0;
  200. }
  201. hex = 0;
  202. base = 1;
  203. num = 0;
  204. while (-- len >= 0) {
  205. if (s[len] >= L'0' && s[len] <= L'9'){
  206. num = s[len] - L'0';
  207. }else if (s[len] >= L'a' && s[len] <= L'f'){
  208. num = (s[len] - L'a') + 10;
  209. }else if (s[len] >= L'A' && s[len] <= L'F'){
  210. num = (s[len] - L'A') + 10;
  211. }else if( s[len] == L'x' || s[len] == L'X'){
  212. break;
  213. }else{
  214. continue;
  215. }
  216. hex += num * base;
  217. base = base * 16;
  218. }
  219. return hex;
  220. }
  221. PDH_FUNCTION
  222. PlaiTranslateKernelFlags( LPDWORD pdwInternal, LPDWORD pdwReal )
  223. {
  224. if( *pdwReal & EVENT_TRACE_FLAG_PROCESS ){
  225. *pdwInternal |= PLA_TLI_ENABLE_PROCESS_TRACE;
  226. }
  227. if( *pdwReal & EVENT_TRACE_FLAG_THREAD ){
  228. *pdwInternal |= PLA_TLI_ENABLE_THREAD_TRACE;
  229. }
  230. if( *pdwReal & EVENT_TRACE_FLAG_MEMORY_PAGE_FAULTS ){
  231. *pdwInternal |= PLA_TLI_ENABLE_MEMMAN_TRACE;
  232. }
  233. if( *pdwReal & EVENT_TRACE_FLAG_MEMORY_HARD_FAULTS ){
  234. *pdwInternal |= PLA_TLI_ENABLE_MEMMAN_TRACE;
  235. }
  236. if( *pdwReal & EVENT_TRACE_FLAG_DISK_IO ){
  237. *pdwInternal |= PLA_TLI_ENABLE_DISKIO_TRACE;
  238. }
  239. if( *pdwReal & EVENT_TRACE_FLAG_NETWORK_TCPIP ){
  240. *pdwInternal |= PLA_TLI_ENABLE_NETWORK_TCPIP_TRACE;
  241. }
  242. if( *pdwReal & EVENT_TRACE_FLAG_DISK_FILE_IO ){
  243. *pdwInternal |= PLA_TLI_ENABLE_FILEIO_TRACE;
  244. }
  245. return ERROR_SUCCESS;
  246. }
  247. BOOL
  248. PlaiIsLocalComputer( LPWSTR strComputer )
  249. {
  250. if( PlaiIsStringEmpty( strComputer ) ){
  251. return TRUE;
  252. }else{
  253. LPWSTR str = strComputer;
  254. WCHAR buffer[MAX_COMPUTERNAME_LENGTH+1];
  255. DWORD dwSize = MAX_COMPUTERNAME_LENGTH+1;
  256. BOOL bResult;
  257. bResult = GetComputerName( buffer, &dwSize );
  258. if( bResult ){
  259. while( *str == L'\\' ){
  260. str++;
  261. }
  262. return (_wcsicmp( buffer, str ) == 0);
  263. }else{
  264. return TRUE;
  265. }
  266. }
  267. return FALSE;
  268. }
  269. /*****************************************************************************/
  270. DWORD
  271. PlaiUpdateServiceMode( LPTSTR strComputer )
  272. {
  273. DWORD dwStatus = ERROR_SUCCESS;
  274. BOOL bStatus;
  275. PDH_STATUS pdhStatus;
  276. SC_HANDLE hSC = NULL;
  277. SC_HANDLE hService = NULL;
  278. QUERY_SERVICE_CONFIG* pServiceConfig = NULL;
  279. DWORD dwSize = 0;
  280. BOOL bAutoStart = FALSE;
  281. PDH_PLA_INFO_W info;
  282. LPWSTR mszCollections = NULL;
  283. pdhStatus = PdhPlaEnumCollections( strComputer, &dwSize, mszCollections );
  284. if( ERROR_SUCCESS == pdhStatus || PDH_INSUFFICIENT_BUFFER == pdhStatus ){
  285. mszCollections = (LPWSTR)G_ALLOC( dwSize * sizeof(TCHAR) );
  286. if( mszCollections ){
  287. LPTSTR strCollection;
  288. pdhStatus = PdhPlaEnumCollections( strComputer, &dwSize, mszCollections );
  289. if( ERROR_SUCCESS == pdhStatus && NULL != mszCollections ){
  290. dwSize = sizeof( PDH_PLA_INFO_W );
  291. strCollection = mszCollections;
  292. while( *strCollection != L'\0' ){
  293. info.dwMask = PLA_INFO_FLAG_BEGIN;
  294. strCollection += ( wcslen( strCollection ) + 1 );
  295. pdhStatus = PdhPlaGetInfoW( strCollection, strComputer, &dwSize, &info );
  296. if( ERROR_SUCCESS == pdhStatus ){
  297. if( (info.dwMask & PLA_INFO_FLAG_BEGIN) &&
  298. info.ptLogBeginTime.dwAutoMode != PLA_AUTO_MODE_NONE ){
  299. bAutoStart = TRUE;
  300. break;
  301. }
  302. }
  303. }
  304. }
  305. }else{
  306. dwStatus = ERROR_OUTOFMEMORY;
  307. }
  308. }else{
  309. dwStatus = ERROR_FILE_NOT_FOUND;
  310. }
  311. if( ERROR_SUCCESS != dwStatus ){
  312. goto cleanup;
  313. }
  314. hSC = OpenSCManager ( strComputer, NULL, GENERIC_READ );
  315. if (hSC == NULL) {
  316. dwStatus = GetLastError();
  317. goto cleanup;
  318. }
  319. BOOL bUpdate = FALSE;
  320. dwSize = 4096;
  321. pServiceConfig = (QUERY_SERVICE_CONFIG*)G_ALLOC( dwSize );
  322. if( NULL == pServiceConfig ){
  323. dwStatus = ERROR_OUTOFMEMORY;
  324. goto cleanup;
  325. }
  326. ZeroMemory( pServiceConfig, dwSize );
  327. hService = OpenService (
  328. hSC,
  329. szSysmonLog,
  330. SERVICE_CHANGE_CONFIG | SERVICE_QUERY_CONFIG | SERVICE_START
  331. );
  332. if( NULL == hService ){
  333. dwStatus = GetLastError();
  334. goto cleanup;
  335. }
  336. bStatus = QueryServiceConfig (
  337. hService,
  338. pServiceConfig,
  339. dwSize,
  340. &dwSize
  341. );
  342. if( !bStatus ){
  343. dwStatus = GetLastError();
  344. goto cleanup;
  345. }
  346. if ( bAutoStart ) {
  347. if ( SERVICE_DEMAND_START == pServiceConfig->dwStartType ) {
  348. bUpdate = TRUE;
  349. }
  350. } else {
  351. if ( SERVICE_AUTO_START == pServiceConfig->dwStartType ) {
  352. bUpdate = TRUE;
  353. }
  354. }
  355. if( bUpdate ){
  356. SC_ACTION ServiceControlAction[3];
  357. SERVICE_FAILURE_ACTIONS FailActions;
  358. bStatus = ChangeServiceConfig (
  359. hService,
  360. SERVICE_NO_CHANGE,
  361. (bAutoStart ? SERVICE_AUTO_START : SERVICE_DEMAND_START),
  362. SERVICE_NO_CHANGE,
  363. NULL,
  364. NULL,
  365. NULL,
  366. NULL,
  367. NULL,
  368. NULL,
  369. NULL
  370. );
  371. if( !bStatus ){
  372. dwStatus = GetLastError();
  373. goto cleanup;
  374. }
  375. ZeroMemory( ServiceControlAction, sizeof(SC_ACTION) * 3 );
  376. ZeroMemory( &FailActions, sizeof(SERVICE_FAILURE_ACTIONS) );
  377. if ( bAutoStart ) {
  378. ServiceControlAction[0].Type = SC_ACTION_RESTART;
  379. ServiceControlAction[1].Type = SC_ACTION_RESTART;
  380. ServiceControlAction[2].Type = SC_ACTION_RESTART;
  381. } else {
  382. ServiceControlAction[0].Type = SC_ACTION_NONE;
  383. ServiceControlAction[1].Type = SC_ACTION_NONE;
  384. ServiceControlAction[2].Type = SC_ACTION_NONE;
  385. }
  386. FailActions.dwResetPeriod = 60;
  387. FailActions.cActions = 3;
  388. FailActions.lpsaActions = ServiceControlAction;
  389. bStatus = ChangeServiceConfig2(
  390. hService,
  391. SERVICE_CONFIG_FAILURE_ACTIONS,
  392. &FailActions
  393. );
  394. if ( ! bStatus ) {
  395. dwStatus = GetLastError();
  396. }
  397. }
  398. cleanup:
  399. G_FREE( mszCollections );
  400. G_FREE( pServiceConfig );
  401. if( NULL != hService ){
  402. CloseServiceHandle (hService);
  403. }
  404. if( NULL != hSC ){
  405. CloseServiceHandle (hSC);
  406. }
  407. return dwStatus;
  408. }
  409. DWORD
  410. PlaiGetServiceState (
  411. LPCWSTR szComputerName,
  412. DWORD& rdwState
  413. )
  414. {
  415. DWORD dwStatus = ERROR_SUCCESS;
  416. SERVICE_STATUS ssData;
  417. SC_HANDLE hSC;
  418. SC_HANDLE hLogService;
  419. rdwState = 0; // Error by default.
  420. // open SC database
  421. hSC = OpenSCManagerW ( szComputerName, NULL, SC_MANAGER_CONNECT);
  422. if (hSC != NULL) {
  423. // open service
  424. hLogService = OpenServiceW (
  425. hSC,
  426. szSysmonLog,
  427. SERVICE_INTERROGATE );
  428. if (hLogService != NULL) {
  429. if ( ControlService (
  430. hLogService,
  431. SERVICE_CONTROL_INTERROGATE,
  432. &ssData)) {
  433. rdwState = ssData.dwCurrentState;
  434. } else {
  435. dwStatus = GetLastError();
  436. rdwState = SERVICE_STOPPED;
  437. }
  438. CloseServiceHandle (hLogService);
  439. } else {
  440. dwStatus = GetLastError();
  441. }
  442. CloseServiceHandle (hSC);
  443. } else {
  444. dwStatus = GetLastError();
  445. }
  446. if ( ERROR_SERVICE_NOT_ACTIVE == dwStatus || ERROR_SERVICE_REQUEST_TIMEOUT == dwStatus ) {
  447. rdwState = SERVICE_STOPPED;
  448. dwStatus = ERROR_SUCCESS;
  449. }
  450. return dwStatus;
  451. }
  452. PDH_FUNCTION
  453. PlaiSynchronize( LPCWSTR szComputerName )
  454. {
  455. // If the service is running, tell it to synchronize itself,
  456. // Check the state afterwards to see if it got the message.
  457. // If stop pending or stopped, wait until the service is
  458. // stopped and then attempt to start it. The service
  459. // synchronizes itself from the registry when it is started.
  460. // Return ERROR_SUCCESS for success, other for failure.
  461. SC_HANDLE hSC = NULL;
  462. SC_HANDLE hLogService = NULL;
  463. SERVICE_STATUS ssData;
  464. DWORD dwCurrentState;
  465. DWORD dwTimeout = 25;
  466. DWORD dwStatus = ERROR_SUCCESS;
  467. dwStatus = PlaiGetServiceState ( szComputerName, dwCurrentState );
  468. if ( ERROR_SUCCESS == dwStatus && 0 != dwCurrentState ) {
  469. // open SC database
  470. hSC = OpenSCManagerW ( szComputerName, NULL, SC_MANAGER_CONNECT);
  471. if ( NULL != hSC ) {
  472. // open service
  473. hLogService = OpenServiceW (
  474. hSC,
  475. szSysmonLog,
  476. SERVICE_USER_DEFINED_CONTROL
  477. | SERVICE_START );
  478. if ( NULL != hLogService ) {
  479. if ( ( SERVICE_STOPPED != dwCurrentState )
  480. && ( SERVICE_STOP_PENDING != dwCurrentState ) ) {
  481. // Wait 100 milliseconds before synchronizing service,
  482. // to ensure that registry values are written.
  483. _sleep ( 100 );
  484. ControlService (
  485. hLogService,
  486. PLA_SERVICE_CONTROL_SYNCHRONIZE,
  487. &ssData);
  488. dwCurrentState = ssData.dwCurrentState;
  489. }
  490. // Make sure that the ControlService call reached the service
  491. // while it was in run state.
  492. if ( ( SERVICE_STOPPED == dwCurrentState )
  493. || ( SERVICE_STOP_PENDING == dwCurrentState ) ) {
  494. if ( SERVICE_STOP_PENDING == dwCurrentState ) {
  495. // wait for the service to stop before starting it.
  496. while ( --dwTimeout && ERROR_SUCCESS == dwStatus ) {
  497. dwStatus = PlaiGetServiceState ( szComputerName, dwCurrentState );
  498. if ( SERVICE_STOP_PENDING == dwCurrentState ) {
  499. _sleep(200);
  500. } else {
  501. break;
  502. }
  503. }
  504. }
  505. dwTimeout = 25;
  506. if ( SERVICE_STOPPED == dwCurrentState ) {
  507. if ( StartService (hLogService, 0, NULL) ) {
  508. // wait for the service to start or stop
  509. // before returning
  510. while ( --dwTimeout && ERROR_SUCCESS == dwStatus ) {
  511. dwStatus = PlaiGetServiceState ( szComputerName, dwCurrentState );
  512. if ( SERVICE_START_PENDING == dwCurrentState ) {
  513. _sleep(200);
  514. } else {
  515. break;
  516. }
  517. }
  518. } else {
  519. dwStatus = GetLastError();
  520. }
  521. }
  522. }
  523. }
  524. CloseServiceHandle ( hLogService );
  525. } else {
  526. dwStatus = GetLastError();
  527. }
  528. CloseServiceHandle (hSC);
  529. } else {
  530. dwStatus = GetLastError();
  531. }
  532. if( 0 == dwCurrentState || ERROR_SUCCESS != dwStatus ){
  533. return PDH_PLA_SERVICE_ERROR;
  534. }
  535. return ERROR_SUCCESS;
  536. }
  537. /*****************************************************************************\
  538. PdhPlaSchedule
  539. Sets the start/stop attributes of a log query
  540. Arguments:
  541. LPTSTR strName
  542. Log Name
  543. LPTSTR strComputer
  544. Computer to connect to
  545. DWORD fType
  546. PLA_AUTO_MODE_NONE Sets schedule to manual start if pInfo->StartTime is non-zero
  547. Sets schedule to manula stop if pInfo->EndTime is non-zero and
  548. Stops logger if it is running
  549. PLA_AUTO_MODE_AT Uses pInfo for start and end times
  550. PLA_AUTO_MODE_AFTER Sets the logger to run for a specified
  551. period. Does not start the logger.
  552. Uses pInfo->SampleCount for interval type
  553. PLA_TT_UTYPE_SECONDS
  554. PLA_TT_UTYPE_MINUTES
  555. PLA_TT_UTYPE_HOURS
  556. PLA_TT_UTYPE_DAYS
  557. PPDH_TIME_INFO pInfo
  558. Start and Stop times
  559. Return:
  560. PDH_INVALID_ARGUMENT
  561. A required argument is missing or incorrect.
  562. PDH_PLA_COLLECTION_ALREADY_RUNNING
  563. The Query is currently running, no action taken
  564. PDH_PLA_ERROR_SCHEDULE_OVERLAP
  565. The start and stop times overlap.
  566. PDH_PLA_COLLECTION_NOT_FOUND
  567. Query does not exist
  568. PDH_PLA_ERROR_SCHEDULE_ELAPSED
  569. The end time has elapsed
  570. ERROR_SUCCESS
  571. \*****************************************************************************/
  572. PDH_FUNCTION
  573. PlaiSchedule(
  574. LPWSTR strComputer,
  575. HKEY hkeyQuery,
  576. DWORD fType,
  577. PPDH_TIME_INFO pInfo
  578. )
  579. {
  580. PDH_STATUS pdhStatus = ERROR_SUCCESS;
  581. PLA_TIME_INFO stiData;
  582. DWORD dwRegValue;
  583. RegFlushKey( hkeyQuery );
  584. // Make sure its not already running
  585. pdhStatus = PlaiReadRegistryDwordValue(
  586. hkeyQuery,
  587. szCurrentState,
  588. &dwRegValue );
  589. if( ERROR_SUCCESS == pdhStatus ){
  590. if( PLA_QUERY_RUNNING == dwRegValue ){
  591. DWORD dwState;
  592. PlaiGetServiceState( strComputer, dwState );
  593. if( dwState != SERVICE_STOPPED ){
  594. RegCloseKey( hkeyQuery );
  595. return PDH_PLA_COLLECTION_ALREADY_RUNNING;
  596. }
  597. }
  598. }
  599. memset (&stiData, 0, sizeof(stiData));
  600. switch( fType ){
  601. case PLA_AUTO_MODE_NONE:
  602. stiData.wDataType = PLA_TT_DTYPE_DATETIME;
  603. stiData.dwAutoMode = PLA_AUTO_MODE_NONE;
  604. PlaiRemoveRepeat( hkeyQuery );
  605. stiData.llDateTime = MIN_TIME_VALUE;
  606. if( pInfo->StartTime ){
  607. stiData.wTimeType = PLA_TT_TTYPE_START;
  608. pdhStatus = PlaiWriteRegistryPlaTime ( hkeyQuery, szStart, &stiData );
  609. }
  610. if( pInfo->EndTime ){
  611. stiData.wTimeType = PLA_TT_TTYPE_STOP;
  612. pdhStatus = PlaiWriteRegistryPlaTime ( hkeyQuery, szStop, &stiData );
  613. }
  614. break;
  615. case PLA_AUTO_MODE_AT:
  616. {
  617. SYSTEMTIME stLocalTime;
  618. FILETIME ftLocalTime;
  619. LONGLONG llLocalTime;
  620. // get local time
  621. GetLocalTime (&stLocalTime);
  622. SystemTimeToFileTime (&stLocalTime, &ftLocalTime);
  623. llLocalTime =
  624. (((ULONGLONG) ftLocalTime.dwHighDateTime) << 32) +
  625. ftLocalTime.dwLowDateTime;
  626. if( pInfo->StartTime && pInfo->EndTime ){
  627. if( pInfo->StartTime > pInfo->EndTime ){
  628. return PDH_PLA_ERROR_SCHEDULE_OVERLAP;
  629. }
  630. }
  631. stiData.wDataType = PLA_TT_DTYPE_DATETIME;
  632. stiData.dwAutoMode = PLA_AUTO_MODE_AT;
  633. if( pInfo->StartTime ){
  634. stiData.wTimeType = PLA_TT_TTYPE_START;
  635. stiData.llDateTime = pInfo->StartTime;
  636. pdhStatus = PlaiWriteRegistryPlaTime ( hkeyQuery, szStart, &stiData );
  637. if( ! pInfo->EndTime && pInfo->StartTime < llLocalTime ){
  638. PLA_TIME_INFO stiStopData;
  639. pdhStatus = PlaiReadRegistryPlaTime( hkeyQuery, szStop, &stiStopData );
  640. if( ERROR_SUCCESS == pdhStatus && stiStopData.dwAutoMode == PLA_AUTO_MODE_NONE ){
  641. stiStopData.llDateTime = MAX_TIME_VALUE;
  642. PlaiWriteRegistryPlaTime( hkeyQuery, szStop, &stiStopData );
  643. }
  644. }else if( ! pInfo->EndTime ){
  645. PLA_TIME_INFO stiStopData;
  646. pdhStatus = PlaiReadRegistryPlaTime ( hkeyQuery, szStop, &stiStopData );
  647. if( ERROR_SUCCESS == pdhStatus ){
  648. if( PLA_AUTO_MODE_NONE == stiStopData.dwAutoMode ){
  649. stiData.wTimeType = PLA_TT_TTYPE_STOP;
  650. stiData.llDateTime = MAX_TIME_VALUE;
  651. stiData.dwAutoMode = PLA_AUTO_MODE_NONE;
  652. pdhStatus = PlaiWriteRegistryPlaTime ( hkeyQuery, szStop, &stiData );
  653. }
  654. }
  655. }
  656. }
  657. if( pInfo->EndTime ){
  658. if( pInfo->EndTime < llLocalTime ){
  659. return PDH_PLA_ERROR_SCHEDULE_ELAPSED;
  660. }
  661. stiData.wTimeType = PLA_TT_TTYPE_STOP;
  662. stiData.llDateTime = pInfo->EndTime;
  663. pdhStatus = PlaiWriteRegistryPlaTime ( hkeyQuery, szStop, &stiData );
  664. }
  665. }
  666. break;
  667. case PLA_AUTO_MODE_AFTER:
  668. stiData.wTimeType = PLA_TT_TTYPE_STOP;
  669. stiData.wDataType = PLA_TT_DTYPE_UNITS;
  670. stiData.dwAutoMode = PLA_AUTO_MODE_AFTER;
  671. stiData.dwValue = (DWORD)pInfo->EndTime;
  672. stiData.dwUnitType = pInfo->SampleCount;
  673. pdhStatus = PlaiWriteRegistryPlaTime ( hkeyQuery, szStop, &stiData );
  674. break;
  675. default:
  676. return PDH_INVALID_ARGUMENT;
  677. }
  678. return pdhStatus;
  679. }
  680. PDH_FUNCTION
  681. PlaiRemoveRepeat( HKEY hkeyQuery )
  682. {
  683. PLA_TIME_INFO info;
  684. PDH_STATUS pdhStatus;
  685. ZeroMemory( &info, sizeof( PLA_TIME_INFO ) );
  686. pdhStatus = PlaiWriteRegistryPlaTime ( hkeyQuery, szRepeatSchedule, &info );
  687. return pdhStatus;
  688. }
  689. PDH_FUNCTION
  690. PdhPlaScheduleA(
  691. LPSTR strName,
  692. LPSTR strComputer,
  693. DWORD fType,
  694. PPDH_TIME_INFO pInfo
  695. )
  696. {
  697. PDH_STATUS pdhStatus;
  698. LPWSTR wstrName = NULL;
  699. LPWSTR wstrComputer = NULL;
  700. VALIDATE_QUERY( strName );
  701. pdhStatus = Plaiatow( strComputer, wstrComputer );
  702. if( ERROR_SUCCESS == pdhStatus ){
  703. pdhStatus = Plaiatow( strName, wstrName );
  704. if( ERROR_SUCCESS == pdhStatus ){
  705. pdhStatus = PdhPlaScheduleW( wstrName, wstrComputer, fType, pInfo );
  706. }
  707. }
  708. G_FREE( wstrComputer );
  709. G_FREE( wstrName );
  710. return pdhStatus;
  711. }
  712. PDH_FUNCTION
  713. PdhPlaScheduleW(
  714. LPWSTR strName,
  715. LPWSTR strComputer,
  716. DWORD fType,
  717. PPDH_TIME_INFO pInfo
  718. )
  719. {
  720. PDH_STATUS pdhStatus = ERROR_SUCCESS;
  721. HKEY hkeyQuery = NULL;
  722. VALIDATE_QUERY( strName );
  723. LPWSTR szName = PlaiStringDuplicate( strName );
  724. LPWSTR szComputer = PlaiStringDuplicate( strComputer );
  725. CHECK_NAMES( szName, szComputer, strComputer );
  726. PDH_TIME_INFO TimeInfo;
  727. __try {
  728. if( NULL != pInfo ){
  729. memcpy( &TimeInfo, pInfo, sizeof(PDH_TIME_INFO) );
  730. }else{
  731. pdhStatus = PDH_INVALID_ARGUMENT;
  732. }
  733. } __except (EXCEPTION_EXECUTE_HANDLER) {
  734. pdhStatus = PDH_INVALID_ARGUMENT;
  735. }
  736. CHECK_STATUS( pdhStatus );
  737. pdhStatus = PlaiConnectAndLockQuery ( szComputer, szName, hkeyQuery );
  738. if( ERROR_SUCCESS == pdhStatus ){
  739. pdhStatus = PlaiSchedule( szComputer, hkeyQuery, fType, &TimeInfo );
  740. RELEASE_MUTEX(hPdhPlaMutex);
  741. }
  742. if ( NULL != hkeyQuery ) {
  743. RegCloseKey ( hkeyQuery );
  744. }
  745. if( SUCCEEDED( pdhStatus ) ){
  746. pdhStatus = PlaiSynchronize( szComputer );
  747. PlaiUpdateServiceMode( szComputer );
  748. }
  749. __try {
  750. memcpy( pInfo, &TimeInfo, sizeof(PDH_TIME_INFO) );
  751. } __except (EXCEPTION_EXECUTE_HANDLER) {
  752. pdhStatus = PDH_INVALID_ARGUMENT;
  753. }
  754. cleanup:
  755. G_FREE( szName );
  756. G_FREE( szComputer );
  757. return pdhStatus;
  758. }
  759. /*****************************************************************************\
  760. PdhPlaGetSchedule
  761. Arguments:
  762. LPTSTR strName
  763. Log Name
  764. LPTSTR strComputer
  765. Computer to connect to
  766. Return:
  767. ERROR_SUCCESS
  768. \*****************************************************************************/
  769. PDH_FUNCTION
  770. PdhPlaGetScheduleA(
  771. LPSTR strName,
  772. LPSTR strComputer,
  773. LPDWORD pdwTypeStart,
  774. LPDWORD pdwTypeStop,
  775. PPDH_TIME_INFO pInfo
  776. )
  777. {
  778. return PDH_NOT_IMPLEMENTED;
  779. }
  780. PDH_FUNCTION
  781. PdhPlaGetScheduleW(
  782. LPWSTR strName,
  783. LPWSTR strComputer,
  784. LPDWORD pdwTypeStart,
  785. LPDWORD pdwTypeStop,
  786. PPDH_TIME_INFO pInfo
  787. )
  788. {
  789. PDH_STATUS pdhStatus = ERROR_SUCCESS;
  790. HKEY hkeyQuery = NULL;
  791. BOOL bMutex = FALSE;
  792. VALIDATE_QUERY( strName );
  793. LPWSTR szName = PlaiStringDuplicate( strName );
  794. LPWSTR szComputer = PlaiStringDuplicate( strComputer );
  795. CHECK_NAMES( szName, szComputer, strComputer );
  796. DWORD dwTypeStart;
  797. DWORD dwTypeStop;
  798. PDH_TIME_INFO TimeInfo;
  799. pdhStatus = PlaiConnectAndLockQuery ( szComputer, szName, hkeyQuery, FALSE );
  800. if ( ERROR_SUCCESS == pdhStatus ) {
  801. PLA_TIME_INFO ptiStartInfo;
  802. PLA_TIME_INFO ptiStopInfo;
  803. PLA_TIME_INFO ptiRepeatInfo;
  804. ZeroMemory( &TimeInfo, sizeof(PDH_TIME_INFO) );
  805. bMutex = TRUE;
  806. pdhStatus = PlaiReadRegistryPlaTime ( hkeyQuery, szRepeatSchedule, &ptiRepeatInfo );
  807. if( ERROR_SUCCESS == pdhStatus && PLA_AUTO_MODE_CALENDAR == ptiRepeatInfo.dwAutoMode ){
  808. dwTypeStart = PLA_AUTO_MODE_CALENDAR;
  809. pdhStatus = PlaiReadRegistryPlaTime ( hkeyQuery, szRepeatScheduleBegin, &ptiStartInfo );
  810. if( ERROR_SUCCESS != pdhStatus ){
  811. pdhStatus = PlaiReadRegistryPlaTime ( hkeyQuery, szStart, &ptiStartInfo );
  812. }
  813. CHECK_STATUS( pdhStatus );
  814. pdhStatus = PlaiReadRegistryPlaTime ( hkeyQuery, szRepeatScheduleEnd, &ptiStopInfo );
  815. if( ERROR_SUCCESS != pdhStatus ){
  816. pdhStatus = PlaiReadRegistryPlaTime ( hkeyQuery, szStop, &ptiStopInfo );
  817. }
  818. CHECK_STATUS( pdhStatus );
  819. dwTypeStop = ptiStopInfo.dwAutoMode;
  820. }else{
  821. pdhStatus = PlaiReadRegistryPlaTime ( hkeyQuery, szStart, &ptiStartInfo );
  822. CHECK_STATUS( pdhStatus );
  823. dwTypeStart = ptiStartInfo.dwAutoMode;
  824. pdhStatus = PlaiReadRegistryPlaTime ( hkeyQuery, szStop, &ptiStopInfo );
  825. CHECK_STATUS( pdhStatus );
  826. dwTypeStop = ptiStopInfo.dwAutoMode;
  827. }
  828. __try {
  829. pInfo->StartTime = ptiStartInfo.llDateTime;
  830. pInfo->EndTime = ptiStopInfo.llDateTime;
  831. *pdwTypeStart = dwTypeStart;
  832. *pdwTypeStop = dwTypeStop;
  833. } __except (EXCEPTION_EXECUTE_HANDLER) {
  834. pdhStatus = PDH_INVALID_ARGUMENT;
  835. }
  836. }
  837. cleanup:
  838. if( bMutex ){
  839. RELEASE_MUTEX(hPdhPlaMutex);
  840. }
  841. if ( NULL != hkeyQuery ) {
  842. RegCloseKey ( hkeyQuery );
  843. }
  844. G_FREE( szName );
  845. G_FREE( szComputer );
  846. return pdhStatus;
  847. }
  848. /*****************************************************************************\
  849. PdhPlaStart
  850. Starts a log query
  851. Arguments:
  852. LPTSTR strName
  853. Log Name
  854. LPTSTR strComputer
  855. Computer to connect to
  856. Return:
  857. PDH_PLA_COLLECTION_ALREADY_RUNNING
  858. The Query is currently running, no action taken
  859. PDH_INVALID_ARGUMENT
  860. The query does not exist
  861. PDH_PLA_ERROR_SCHEDULE_ELAPSED
  862. The query was scheduled to stop in the past, no action taken
  863. ERROR_SUCCESS
  864. \*****************************************************************************/
  865. PDH_FUNCTION
  866. PdhPlaStartA( LPSTR strName, LPSTR strComputer )
  867. {
  868. PDH_STATUS pdhStatus;
  869. LPWSTR wstrName = NULL;
  870. LPWSTR wstrComputer = NULL;
  871. VALIDATE_QUERY( strName );
  872. pdhStatus = Plaiatow( strComputer, wstrComputer );
  873. if( ERROR_SUCCESS == pdhStatus ){
  874. pdhStatus = Plaiatow( strName, wstrName );
  875. if( ERROR_SUCCESS == pdhStatus ){
  876. pdhStatus = PdhPlaStartW( wstrName, wstrComputer );
  877. }
  878. }
  879. G_FREE( wstrComputer );
  880. G_FREE( wstrName );
  881. return pdhStatus;
  882. }
  883. PDH_FUNCTION
  884. PdhPlaStartW( LPWSTR strName, LPWSTR strComputer )
  885. {
  886. PDH_STATUS pdhStatus = ERROR_SUCCESS;
  887. HKEY hkeyQuery = NULL;
  888. VALIDATE_QUERY( strName );
  889. LPWSTR szName = PlaiStringDuplicate( strName );
  890. LPWSTR szComputer = PlaiStringDuplicate( strComputer );
  891. CHECK_NAMES( szName, szComputer, strComputer );
  892. pdhStatus = PlaiConnectAndLockQuery ( szComputer, szName, hkeyQuery );
  893. if ( ERROR_SUCCESS == pdhStatus ) {
  894. PLA_TIME_INFO stiData;
  895. PLA_TIME_INFO stiStopData;
  896. DWORD dwRegValue;
  897. // Make sure its not already running
  898. pdhStatus = PlaiReadRegistryDwordValue(
  899. hkeyQuery,
  900. szCurrentState,
  901. &dwRegValue );
  902. if( ERROR_SUCCESS == pdhStatus ){
  903. if( PLA_QUERY_RUNNING == dwRegValue ){
  904. DWORD dwState;
  905. PlaiGetServiceState( szComputer, dwState );
  906. if( dwState != SERVICE_STOPPED ){
  907. RegCloseKey( hkeyQuery );
  908. RELEASE_MUTEX(hPdhPlaMutex);
  909. return PDH_PLA_COLLECTION_ALREADY_RUNNING;
  910. }
  911. }
  912. }
  913. //Make sure it was not set to stop in the past
  914. pdhStatus = PlaiReadRegistryPlaTime ( hkeyQuery, szStop, &stiStopData );
  915. if( ERROR_SUCCESS == pdhStatus ) {
  916. if ( PLA_AUTO_MODE_AT == stiStopData.dwAutoMode ) {
  917. SYSTEMTIME stLocalTime;
  918. FILETIME ftLocalTime;
  919. LONGLONG llLocalTime;
  920. // get local time
  921. GetLocalTime (&stLocalTime);
  922. SystemTimeToFileTime (&stLocalTime, &ftLocalTime);
  923. llLocalTime =
  924. (((ULONGLONG) ftLocalTime.dwHighDateTime) << 32) +
  925. ftLocalTime.dwLowDateTime;
  926. if ( llLocalTime > stiStopData.llDateTime ) {
  927. RELEASE_MUTEX(hPdhPlaMutex);
  928. RegCloseKey( hkeyQuery );
  929. return PDH_PLA_ERROR_SCHEDULE_ELAPSED;
  930. }
  931. }
  932. }
  933. memset (&stiData, 0, sizeof(stiData));
  934. stiData.wTimeType = PLA_TT_TTYPE_START;
  935. stiData.wDataType = PLA_TT_DTYPE_DATETIME;
  936. stiData.dwAutoMode = PLA_AUTO_MODE_NONE;
  937. stiData.llDateTime = MIN_TIME_VALUE;
  938. PlaiRemoveRepeat( hkeyQuery );
  939. pdhStatus = PlaiWriteRegistryPlaTime ( hkeyQuery, szStart, &stiData );
  940. if( PLA_AUTO_MODE_NONE == stiStopData.dwAutoMode ){
  941. stiData.wTimeType = PLA_TT_TTYPE_STOP;
  942. stiData.llDateTime = MAX_TIME_VALUE;
  943. pdhStatus = PlaiWriteRegistryPlaTime ( hkeyQuery, szStop, &stiData );
  944. }
  945. if ( ERROR_SUCCESS == pdhStatus ) {
  946. dwRegValue = PLA_QUERY_START_PENDING;
  947. pdhStatus = PlaiWriteRegistryDwordValue (
  948. hkeyQuery,
  949. szCurrentState,
  950. &dwRegValue );
  951. }
  952. // Set LastModified
  953. if ( ERROR_SUCCESS == pdhStatus ) {
  954. pdhStatus = PlaiWriteRegistryLastModified ( hkeyQuery );
  955. }
  956. RELEASE_MUTEX(hPdhPlaMutex);
  957. // Start the service on the target machine
  958. if ( SUCCEEDED( pdhStatus ) ) {
  959. pdhStatus = PlaiSynchronize( szComputer );
  960. if( ERROR_SUCCESS == pdhStatus ){
  961. DWORD dwTimeOut = 25;
  962. while( --dwTimeOut > 0 ){
  963. pdhStatus = PlaiReadRegistryDwordValue(
  964. hkeyQuery,
  965. szCurrentState,
  966. &dwRegValue
  967. );
  968. if( ERROR_SUCCESS == pdhStatus && dwRegValue != PLA_QUERY_RUNNING ){
  969. pdhStatus = PDH_PLA_ERROR_NOSTART;
  970. }else{
  971. pdhStatus = ERROR_SUCCESS;
  972. break;
  973. }
  974. _sleep(200);
  975. }
  976. }
  977. }
  978. }
  979. if ( NULL != hkeyQuery ) {
  980. RegCloseKey ( hkeyQuery );
  981. }
  982. cleanup:
  983. G_FREE( szName );
  984. G_FREE( szComputer );
  985. return pdhStatus;
  986. }
  987. /*****************************************************************************\
  988. PdhPlaStop
  989. Stops a log query
  990. Arguments:
  991. LPTSTR strName
  992. Log Name
  993. LPTSTR strComputer
  994. Computer to connect to
  995. Return:
  996. PDH_INVALID_ARGUMENT
  997. The query does not exist
  998. ERROR_SUCCESS
  999. \*****************************************************************************/
  1000. PDH_FUNCTION
  1001. PdhPlaStopA( LPSTR strName, LPSTR strComputer )
  1002. {
  1003. PDH_STATUS pdhStatus;
  1004. LPWSTR wstrName = NULL;
  1005. LPWSTR wstrComputer = NULL;
  1006. VALIDATE_QUERY( strName );
  1007. pdhStatus = Plaiatow( strComputer, wstrComputer );
  1008. if( ERROR_SUCCESS == pdhStatus ){
  1009. pdhStatus = Plaiatow( strName, wstrName );
  1010. if( ERROR_SUCCESS == pdhStatus ){
  1011. pdhStatus = PdhPlaStopW( wstrName, wstrComputer );
  1012. }
  1013. }
  1014. G_FREE( wstrComputer );
  1015. G_FREE( wstrName );
  1016. return pdhStatus;
  1017. }
  1018. PDH_FUNCTION
  1019. PdhPlaStopW( LPWSTR strName, LPWSTR strComputer )
  1020. {
  1021. PDH_STATUS pdhStatus = ERROR_SUCCESS;
  1022. HKEY hkeyQuery = NULL;
  1023. VALIDATE_QUERY( strName );
  1024. LPWSTR szName = PlaiStringDuplicate( strName );
  1025. LPWSTR szComputer = PlaiStringDuplicate( strComputer );
  1026. CHECK_NAMES( szName, szComputer, strComputer );
  1027. pdhStatus = PlaiConnectAndLockQuery( szComputer, szName, hkeyQuery );
  1028. if ( ERROR_SUCCESS == pdhStatus ) {
  1029. PLA_TIME_INFO stiData;
  1030. DWORD dwRestartMode = 0;
  1031. DWORD dwState;
  1032. pdhStatus = PlaiReadRegistryDwordValue(
  1033. hkeyQuery,
  1034. szCurrentState,
  1035. &dwState );
  1036. if( ERROR_SUCCESS == pdhStatus ){
  1037. if( PLA_QUERY_STOPPED != dwState ){
  1038. PlaiGetServiceState( szComputer, dwState );
  1039. if( dwState == SERVICE_STOPPED ){
  1040. dwState = PLA_QUERY_STOPPED;
  1041. PlaiWriteRegistryDwordValue ( hkeyQuery, szCurrentState, &dwState );
  1042. }
  1043. }
  1044. }
  1045. // If query is set to restart on end, clear the restart flag.
  1046. pdhStatus = PlaiReadRegistryDwordValue ( hkeyQuery, szRestart, &dwRestartMode );
  1047. if ( ERROR_SUCCESS == pdhStatus && PLA_AUTO_MODE_NONE != dwRestartMode ) {
  1048. dwRestartMode = PLA_AUTO_MODE_NONE;
  1049. pdhStatus = PlaiWriteRegistryDwordValue ( hkeyQuery, szRestart, &dwRestartMode );
  1050. }
  1051. PlaiRemoveRepeat( hkeyQuery );
  1052. // Set stop mode to manual, stop time to MIN_TIME_VALUE
  1053. if ( ERROR_SUCCESS == pdhStatus ) {
  1054. memset (&stiData, 0, sizeof(stiData));
  1055. stiData.wTimeType = PLA_TT_TTYPE_STOP;
  1056. stiData.wDataType = PLA_TT_DTYPE_DATETIME;
  1057. stiData.dwAutoMode = PLA_AUTO_MODE_NONE;
  1058. stiData.llDateTime = MIN_TIME_VALUE;
  1059. pdhStatus = PlaiWriteRegistryPlaTime ( hkeyQuery, szStop, &stiData );
  1060. }
  1061. // If start time mode set to manual, set the value to MAX_TIME_VALUE
  1062. if ( ERROR_SUCCESS == pdhStatus ) {
  1063. pdhStatus = PlaiReadRegistryPlaTime ( hkeyQuery, szStart, &stiData );
  1064. if ( ERROR_SUCCESS == pdhStatus && PLA_AUTO_MODE_NONE == stiData.dwAutoMode ) {
  1065. stiData.llDateTime = MAX_TIME_VALUE;
  1066. pdhStatus = PlaiWriteRegistryPlaTime ( hkeyQuery, szStart, &stiData );
  1067. }
  1068. }
  1069. PlaiWriteRegistryLastModified ( hkeyQuery );
  1070. RELEASE_MUTEX(hPdhPlaMutex);
  1071. if ( SUCCEEDED( pdhStatus ) ) {
  1072. pdhStatus = PlaiSynchronize ( szComputer );
  1073. }
  1074. }
  1075. cleanup:
  1076. if ( NULL != hkeyQuery ) {
  1077. RegCloseKey ( hkeyQuery );
  1078. }
  1079. G_FREE( szName );
  1080. G_FREE( szComputer );
  1081. return pdhStatus;
  1082. }
  1083. /*****************************************************************************\
  1084. PdhPlaCreate
  1085. Creates a new log query
  1086. Arguments:
  1087. LPTSTR strName
  1088. Log Name
  1089. LPTSTR strComputer
  1090. Computer to connect to
  1091. DWORD fType
  1092. PLA_COUNTER_LOG
  1093. PLA_TRACE_LOG
  1094. Return:
  1095. ERROR_ALREADY_EXISTS
  1096. The Query is currently running, no action taken
  1097. ERROR_SUCCESS
  1098. \*****************************************************************************/
  1099. PDH_FUNCTION
  1100. PlaiInitializeNewQuery(
  1101. HKEY hkeyLogQueries,
  1102. HKEY& rhKeyQuery,
  1103. LPCWSTR strComputer,
  1104. LPCWSTR strName
  1105. )
  1106. {
  1107. DWORD dwStatus = ERROR_SUCCESS;
  1108. PDH_STATUS pdhStatus = ERROR_SUCCESS;
  1109. DWORD dwDisposition = 0;
  1110. DWORD dwValue;
  1111. PLA_TIME_INFO stiData;
  1112. PLA_VERSION version;
  1113. pdhStatus = PdhiPlaGetVersion( strComputer, &version );
  1114. if( ERROR_SUCCESS == pdhStatus && version.dwBuild > 2195 ){
  1115. GUID guid;
  1116. UNICODE_STRING strGUID;
  1117. dwStatus = UuidCreate( &guid );
  1118. if( !( dwStatus == RPC_S_OK || dwStatus == RPC_S_UUID_LOCAL_ONLY ) ){
  1119. return PlaiErrorToPdhStatus( dwStatus );
  1120. }
  1121. dwStatus = RtlStringFromGUID( guid, &strGUID );
  1122. if( ERROR_SUCCESS != dwStatus ){
  1123. return PlaiErrorToPdhStatus( dwStatus );
  1124. }
  1125. dwStatus = RegCreateKeyExW (
  1126. hkeyLogQueries,
  1127. strGUID.Buffer,
  1128. 0,
  1129. NULL,
  1130. 0,
  1131. KEY_READ|KEY_WRITE,
  1132. NULL,
  1133. &rhKeyQuery,
  1134. &dwDisposition
  1135. );
  1136. RtlFreeUnicodeString( &strGUID );
  1137. pdhStatus = PlaiErrorToPdhStatus( dwStatus );
  1138. }else{
  1139. dwStatus = RegCreateKeyExW (
  1140. hkeyLogQueries,
  1141. strName,
  1142. 0,
  1143. NULL,
  1144. 0,
  1145. KEY_READ|KEY_WRITE,
  1146. NULL,
  1147. &rhKeyQuery,
  1148. &dwDisposition
  1149. );
  1150. pdhStatus = PlaiErrorToPdhStatus( dwStatus );
  1151. }
  1152. if ( ERROR_SUCCESS == pdhStatus ) {
  1153. PlaiWriteRegistryStringValue( rhKeyQuery, szCollection, REG_SZ, strName, 0 );
  1154. dwValue = PLA_QUERY_STOPPED;
  1155. pdhStatus = PlaiWriteRegistryDwordValue (
  1156. rhKeyQuery,
  1157. szCurrentState,
  1158. &dwValue );
  1159. if ( ERROR_SUCCESS == pdhStatus ) {
  1160. // Initialize the log type to "new" to indicate partially created logs
  1161. dwValue = PLA_NEW_LOG;
  1162. pdhStatus = PlaiWriteRegistryDwordValue (
  1163. rhKeyQuery,
  1164. szLogType,
  1165. &dwValue );
  1166. PlaiWriteRegistryStringValue( rhKeyQuery, szLogBaseName, REG_SZ, strName, 0 );
  1167. memset (&stiData, 0, sizeof(stiData));
  1168. stiData.wTimeType = PLA_TT_TTYPE_START;
  1169. stiData.wDataType = PLA_TT_DTYPE_DATETIME;
  1170. stiData.dwAutoMode = PLA_AUTO_MODE_NONE;
  1171. stiData.llDateTime = MIN_TIME_VALUE;
  1172. pdhStatus = PlaiWriteRegistryPlaTime ( rhKeyQuery, szStart, &stiData );
  1173. stiData.wTimeType = PLA_TT_TTYPE_STOP;
  1174. pdhStatus = PlaiWriteRegistryPlaTime ( rhKeyQuery, szStop, &stiData );
  1175. memset (&stiData, 0, sizeof(stiData));
  1176. stiData.dwAutoMode = PLA_AUTO_MODE_NONE;
  1177. PlaiWriteRegistryPlaTime( rhKeyQuery, szCreateNewFile, &stiData );
  1178. dwValue = 0;
  1179. PlaiWriteRegistryDwordValue( rhKeyQuery, szRestart, &dwValue );
  1180. dwValue = PLA_QUERY_STOPPED;
  1181. PlaiWriteRegistryDwordValue( rhKeyQuery, szCurrentState, &dwValue );
  1182. dwValue = PLA_DISK_MAX_SIZE;
  1183. PlaiWriteRegistryDwordValue( rhKeyQuery, szLogMaxSize, &dwValue );
  1184. dwValue = 1;
  1185. PlaiWriteRegistryDwordValue( rhKeyQuery, szLogSerialNumber, &dwValue );
  1186. dwValue = 1;
  1187. PlaiWriteRegistryDwordValue( rhKeyQuery, szLogAutoFormat, &dwValue );
  1188. PlaiWriteRegistryStringValue( rhKeyQuery, szComment, REG_SZ, NULL, 0 );
  1189. PlaiWriteRegistryStringValue( rhKeyQuery, szEOFCmd, REG_SZ, NULL, 0 );
  1190. if( PlaiIsStringEmpty( (LPWSTR)strComputer ) ){
  1191. LPWSTR strDrive = _wgetenv( L"SystemDrive" );
  1192. if( strDrive != NULL && wcslen(strDrive) < 5 ){
  1193. WCHAR buffer[16];
  1194. StringCchPrintf( buffer, 16, L"%s\\PerfLogs", strDrive );
  1195. PlaiWriteRegistryStringValue( rhKeyQuery, szLogFolder, REG_SZ, buffer, 0 );
  1196. }
  1197. }else{
  1198. PlaiWriteRegistryStringValue( rhKeyQuery, szLogFolder, REG_SZ, L"%SystemDrive%\\PerfLogs", 0 );
  1199. }
  1200. }
  1201. }
  1202. return pdhStatus;
  1203. }
  1204. PDH_FUNCTION
  1205. PlaiCreateCounterQuery( HKEY hkeyQuery )
  1206. {
  1207. PDH_STATUS pdhStatus;
  1208. DWORD dwValue;
  1209. dwValue = PLA_BIN_FILE;
  1210. pdhStatus = PlaiWriteRegistryDwordValue( hkeyQuery, szLogFileType, &dwValue );
  1211. PLA_TIME_INFO stiData;
  1212. stiData.wTimeType = PLA_TT_TTYPE_SAMPLE;
  1213. stiData.dwAutoMode = PLA_AUTO_MODE_AFTER;
  1214. stiData.wDataType = PLA_TT_DTYPE_UNITS;
  1215. stiData.dwUnitType = PLA_TT_UTYPE_SECONDS;
  1216. stiData.dwValue = 0x000F;
  1217. pdhStatus = PlaiWriteRegistryPlaTime( hkeyQuery, szSampleInterval, &stiData );
  1218. PlaiWriteRegistryStringValue( hkeyQuery, szPerfCounterList, REG_MULTI_SZ, NULL, 0 );
  1219. pdhStatus = PlaiWriteRegistryLastModified ( hkeyQuery );
  1220. dwValue = PLA_DATASTORE_SIZE_KB|PLA_DATASTORE_APPEND;
  1221. PlaiWriteRegistryDwordValue( hkeyQuery, szDatastoreAttributes, &dwValue );
  1222. PlaiWriteRegistryStringValue(hkeyQuery, szPerfCounterList, REG_MULTI_SZ, NULL, 0 );
  1223. return ERROR_SUCCESS;
  1224. }
  1225. PDH_FUNCTION
  1226. PlaiCreateTraceQuery( HKEY hkeyQuery )
  1227. {
  1228. PDH_STATUS pdhStatus;
  1229. DWORD dwValue;
  1230. dwValue = 0;
  1231. pdhStatus = PlaiWriteRegistryDwordValue( hkeyQuery, szTraceProviderCount, &dwValue );
  1232. dwValue = 128;
  1233. PlaiWriteRegistryDwordValue( hkeyQuery, szTraceBufferSize, &dwValue );
  1234. dwValue = 8;
  1235. PlaiWriteRegistryDwordValue( hkeyQuery, szTraceBufferMin, &dwValue );
  1236. dwValue = 32;
  1237. PlaiWriteRegistryDwordValue( hkeyQuery, szTraceBufferMax, &dwValue );
  1238. dwValue = 0;
  1239. PlaiWriteRegistryDwordValue( hkeyQuery, szTraceFlushInterval, &dwValue );
  1240. dwValue = 0;
  1241. PlaiWriteRegistryDwordValue( hkeyQuery, szTraceMode, &dwValue );
  1242. PlaiWriteRegistryStringValue( hkeyQuery, szTraceProviderList, REG_MULTI_SZ, NULL, 0 );
  1243. dwValue =
  1244. PLA_TLI_ENABLE_KERNEL_TRACE |
  1245. PLA_TLI_ENABLE_PROCESS_TRACE |
  1246. PLA_TLI_ENABLE_THREAD_TRACE |
  1247. PLA_TLI_ENABLE_DISKIO_TRACE |
  1248. PLA_TLI_ENABLE_NETWORK_TCPIP_TRACE;
  1249. dwValue = PLA_DATASTORE_SIZE_MB|PLA_DATASTORE_APPEND;
  1250. PlaiWriteRegistryDwordValue( hkeyQuery, szDatastoreAttributes, &dwValue );
  1251. PlaiWriteRegistryDwordValue( hkeyQuery, szTraceFlags, &dwValue );
  1252. dwValue = PLA_SEQ_TRACE_FILE;
  1253. PlaiWriteRegistryDwordValue( hkeyQuery, szLogFileType, &dwValue );
  1254. PlaiWriteRegistryLastModified ( hkeyQuery );
  1255. return ERROR_SUCCESS;
  1256. }
  1257. PDH_FUNCTION
  1258. PdhPlaCreateA( LPSTR /*strName*/, LPSTR /*strComputer*/, PPDH_PLA_INFO_A /*pInfo*/ )
  1259. {
  1260. return PDH_NOT_IMPLEMENTED;
  1261. }
  1262. PDH_FUNCTION
  1263. PdhPlaCreateW( LPWSTR strName, LPWSTR strComputer, PPDH_PLA_INFO_W pInfo )
  1264. {
  1265. PDH_STATUS pdhStatus;
  1266. PDH_STATUS pdhWarning = ERROR_SUCCESS;
  1267. HKEY hkeyQuery = NULL;
  1268. HKEY rhkeyLogQueries = NULL;
  1269. BOOL bMutex = FALSE;
  1270. VALIDATE_QUERY( strName );
  1271. LPWSTR szName = PlaiStringDuplicate( strName );
  1272. LPWSTR szComputer = PlaiStringDuplicate( strComputer );
  1273. CHECK_NAMES( szName, szComputer, strComputer );
  1274. pdhStatus = PlaiScanForInvalidChar( szName );
  1275. CHECK_STATUS(pdhStatus);
  1276. pdhStatus = PlaiConnectAndLockQuery( szComputer, szName, hkeyQuery );
  1277. if( ERROR_SUCCESS == pdhStatus ){
  1278. bMutex = TRUE;
  1279. pdhStatus = PDH_PLA_ERROR_ALREADY_EXISTS;
  1280. goto cleanup;
  1281. }
  1282. pdhStatus = PdhPlaValidateInfoW( szName, szComputer, pInfo );
  1283. switch( SEVERITY(pdhStatus) ){
  1284. case STATUS_SEVERITY_ERROR:
  1285. goto cleanup;
  1286. case STATUS_SEVERITY_WARNING:
  1287. pdhWarning = pdhStatus;
  1288. pdhStatus = ERROR_SUCCESS;
  1289. }
  1290. pdhStatus = PlaiConnectToRegistry( szComputer, rhkeyLogQueries, TRUE );
  1291. if( ERROR_SUCCESS == pdhStatus ){
  1292. DWORD dwStatus;
  1293. dwStatus = WAIT_FOR_AND_LOCK_MUTEX(hPdhPlaMutex);
  1294. if( ERROR_SUCCESS == dwStatus || WAIT_ABANDONED == dwStatus ){
  1295. bMutex = TRUE;
  1296. pdhStatus = PlaiInitializeNewQuery (
  1297. rhkeyLogQueries,
  1298. hkeyQuery,
  1299. szComputer,
  1300. szName
  1301. );
  1302. switch( pInfo->dwType ){
  1303. case PLA_COUNTER_LOG:
  1304. pdhStatus = PlaiCreateCounterQuery( hkeyQuery );
  1305. break;
  1306. case PLA_TRACE_LOG:
  1307. pdhStatus = PlaiCreateTraceQuery( hkeyQuery );
  1308. break;
  1309. }
  1310. }else{
  1311. pdhStatus = PlaiErrorToPdhStatus( dwStatus );
  1312. }
  1313. }
  1314. if( ERROR_SUCCESS == pdhStatus ){
  1315. pdhStatus = PlaiSetInfo( szComputer, hkeyQuery, pInfo );
  1316. }
  1317. if( bMutex ){
  1318. RELEASE_MUTEX(hPdhPlaMutex);
  1319. bMutex = FALSE;
  1320. }
  1321. __try {
  1322. if( ERROR_SUCCESS == pdhStatus && (pInfo->dwMask & PLA_INFO_FLAG_USER) ){
  1323. pdhStatus = PdhPlaSetRunAsW( szName, szComputer, pInfo->strUser, pInfo->strPassword );
  1324. }
  1325. } __except (EXCEPTION_EXECUTE_HANDLER) {
  1326. pdhStatus = PDH_INVALID_ARGUMENT;
  1327. }
  1328. if( ERROR_SUCCESS == pdhStatus ){
  1329. DWORD dwStatus;
  1330. dwStatus = WAIT_FOR_AND_LOCK_MUTEX(hPdhPlaMutex);
  1331. if( ERROR_SUCCESS == dwStatus || WAIT_ABANDONED == dwStatus ){
  1332. DWORD dwValue;
  1333. bMutex = TRUE;
  1334. switch( pInfo->dwType ){
  1335. case PLA_COUNTER_LOG:
  1336. dwValue = PLA_COUNTER_LOG;
  1337. pdhStatus = PlaiWriteRegistryDwordValue( hkeyQuery, szLogType, &dwValue );
  1338. break;
  1339. case PLA_TRACE_LOG:
  1340. dwValue = PLA_TRACE_LOG;
  1341. pdhStatus = PlaiWriteRegistryDwordValue( hkeyQuery, szLogType, &dwValue );
  1342. break;
  1343. }
  1344. }else{
  1345. pdhStatus = PlaiErrorToPdhStatus( dwStatus );
  1346. }
  1347. }
  1348. cleanup:
  1349. if( bMutex ){
  1350. RELEASE_MUTEX(hPdhPlaMutex);
  1351. }
  1352. if ( NULL != hkeyQuery ) {
  1353. RegCloseKey ( hkeyQuery );
  1354. }
  1355. if( SUCCEEDED( pdhStatus ) ){
  1356. pdhStatus = PlaiSynchronize( szComputer );
  1357. DWORD dwMask;
  1358. __try {
  1359. dwMask = pInfo->dwMask;
  1360. } __except (EXCEPTION_EXECUTE_HANDLER) {
  1361. pdhStatus = PDH_INVALID_ARGUMENT;
  1362. }
  1363. if( ERROR_SUCCESS == pdhStatus && (dwMask & PLA_INFO_FLAG_BEGIN) ){
  1364. PlaiUpdateServiceMode( szComputer );
  1365. }
  1366. }else if( PDH_PLA_ERROR_ALREADY_EXISTS != pdhStatus ){
  1367. PdhPlaDeleteW( szName, szComputer );
  1368. }
  1369. if( ERROR_SUCCESS == pdhStatus ){
  1370. pdhStatus = pdhWarning;
  1371. }
  1372. G_FREE( szName );
  1373. G_FREE( szComputer );
  1374. return pdhStatus;
  1375. }
  1376. /*****************************************************************************\
  1377. PdhPlaDelete
  1378. Deletes an existing log query
  1379. Arguments:
  1380. LPTSTR strName
  1381. Log Name
  1382. LPTSTR strComputer
  1383. Computer to connect to
  1384. Return:
  1385. ERROR_SUCCESS
  1386. \*****************************************************************************/
  1387. PDH_FUNCTION
  1388. PdhPlaDeleteA( LPSTR strName, LPSTR strComputer )
  1389. {
  1390. PDH_STATUS pdhStatus;
  1391. LPWSTR wstrName = NULL;
  1392. LPWSTR wstrComputer = NULL;
  1393. VALIDATE_QUERY( strName );
  1394. pdhStatus = Plaiatow( strComputer, wstrComputer );
  1395. if( ERROR_SUCCESS == pdhStatus ){
  1396. pdhStatus = Plaiatow( strName, wstrName );
  1397. if( ERROR_SUCCESS == pdhStatus ){
  1398. pdhStatus = PdhPlaDeleteW( wstrName, wstrComputer );
  1399. }
  1400. }
  1401. G_FREE( wstrComputer );
  1402. G_FREE( wstrName );
  1403. return pdhStatus;
  1404. }
  1405. PDH_FUNCTION
  1406. PdhPlaDeleteW( LPWSTR strName, LPWSTR strComputer )
  1407. {
  1408. DWORD dwStatus = ERROR_SUCCESS;
  1409. PDH_STATUS pdhStatus;
  1410. HKEY hkeyLogQueries = NULL;
  1411. VALIDATE_QUERY( strName );
  1412. LPWSTR szName = PlaiStringDuplicate( strName );
  1413. LPWSTR szComputer = PlaiStringDuplicate( strComputer );
  1414. CHECK_NAMES( szName, szComputer, strComputer );
  1415. pdhStatus = PlaiConnectToRegistry ( szComputer, hkeyLogQueries, TRUE );
  1416. if( ERROR_SUCCESS == pdhStatus ){
  1417. dwStatus = WAIT_FOR_AND_LOCK_MUTEX( hPdhPlaMutex );
  1418. if( ERROR_SUCCESS == dwStatus || WAIT_ABANDONED == dwStatus ){
  1419. DWORD nCollections = 0;
  1420. DWORD nMaxSubKeyLength = 0;
  1421. dwStatus = RegQueryInfoKey(
  1422. hkeyLogQueries,
  1423. NULL,
  1424. NULL,
  1425. NULL,
  1426. &nCollections,
  1427. &nMaxSubKeyLength,
  1428. NULL,
  1429. NULL,
  1430. NULL,
  1431. NULL,
  1432. NULL,
  1433. NULL
  1434. );
  1435. if( ERROR_SUCCESS == dwStatus ){
  1436. LPWSTR strCollection;
  1437. LPWSTR strQueryName = NULL;
  1438. DWORD dwQueryName = 0;
  1439. HKEY hkeyQuery = NULL;
  1440. DWORD dwSize = (sizeof(WCHAR)*(nMaxSubKeyLength+1));
  1441. strCollection = (LPWSTR)G_ALLOC( dwSize );
  1442. if( strCollection ){
  1443. BOOL bFound = FALSE;
  1444. for( ULONG i = 0; i<nCollections; i++ ){
  1445. dwStatus = RegEnumKey( hkeyLogQueries, i, strCollection, dwSize );
  1446. if( ERROR_SUCCESS == dwStatus ) {
  1447. dwStatus = RegOpenKeyExW (
  1448. hkeyLogQueries,
  1449. strCollection,
  1450. 0,
  1451. KEY_READ|KEY_WRITE,
  1452. &hkeyQuery
  1453. );
  1454. if( ERROR_SUCCESS == dwStatus && !PlaiIsStringEmpty( strCollection ) ){
  1455. if( !_wcsicmp( strCollection, strName ) ){
  1456. bFound = TRUE;
  1457. }else{
  1458. PlaiReadRegistryStringValue( hkeyQuery, szCollection, READ_REG_MUI, &strQueryName, &dwQueryName );
  1459. if( !PlaiIsStringEmpty( strQueryName ) ){
  1460. if( !_wcsicmp( strQueryName, szName ) ){
  1461. bFound = TRUE;
  1462. }
  1463. }
  1464. }
  1465. if( bFound ){
  1466. DWORD dwState;
  1467. dwStatus = PlaiReadRegistryDwordValue(
  1468. hkeyQuery,
  1469. szCurrentState,
  1470. &dwState );
  1471. if( ERROR_SUCCESS == dwStatus ){
  1472. if( PLA_QUERY_RUNNING == dwState ){
  1473. PlaiGetServiceState( szComputer, dwState );
  1474. if( dwState != SERVICE_STOPPED ){
  1475. dwStatus = ERROR_SERVICE_ALREADY_RUNNING;
  1476. }
  1477. }
  1478. }
  1479. if( ERROR_SUCCESS == dwStatus ){
  1480. RegCloseKey( hkeyQuery );
  1481. dwStatus = RegDeleteKey( hkeyLogQueries, strCollection );
  1482. }
  1483. break;
  1484. }
  1485. dwStatus = ERROR_FILE_NOT_FOUND;
  1486. if ( NULL != hkeyQuery ) {
  1487. RegCloseKey ( hkeyQuery );
  1488. }
  1489. }
  1490. }
  1491. }
  1492. G_FREE( strQueryName );
  1493. G_FREE( strCollection );
  1494. }else{
  1495. dwStatus = ERROR_OUTOFMEMORY;
  1496. }
  1497. }
  1498. }
  1499. RegCloseKey ( hkeyLogQueries );
  1500. RELEASE_MUTEX(hPdhPlaMutex);
  1501. }else{
  1502. return pdhStatus;
  1503. }
  1504. if( ERROR_SUCCESS == dwStatus ){
  1505. PlaiSynchronize( szComputer );
  1506. PlaiUpdateServiceMode( szComputer );
  1507. }
  1508. cleanup:
  1509. G_FREE( szName );
  1510. G_FREE( szComputer );
  1511. return PlaiErrorToPdhStatus( dwStatus );
  1512. }
  1513. /*****************************************************************************\
  1514. PdhPlaSetItemList
  1515. Sets the list of Items for a log query
  1516. Arguments:
  1517. LPTSTR strName
  1518. Log Name
  1519. LPTSTR strComputer
  1520. Computer to connect to
  1521. LPTSTR mszItems
  1522. Multistring of the Items for the query to collect. Any
  1523. existing Items will be overwritten.
  1524. ULONG length
  1525. Length of the mszItems buffer
  1526. Return:
  1527. PDH_INVALID_ARGUMENT
  1528. The query does not exist or pItems->dwType != Log Type
  1529. ERROR_SUCCESS
  1530. \*****************************************************************************/
  1531. PDH_FUNCTION
  1532. PlaiIsKernel( LPWSTR mszGuid, BOOL* pbKernel, ULONG* pnCount )
  1533. {
  1534. DWORD dwStatus;
  1535. LPTSTR strGuid = mszGuid;
  1536. UNICODE_STRING strKernel;
  1537. *pbKernel = FALSE;
  1538. *pnCount = 0;
  1539. dwStatus = RtlStringFromGUID( SystemTraceControlGuid, &strKernel );
  1540. if( ERROR_SUCCESS != dwStatus ){
  1541. return PlaiErrorToPdhStatus( dwStatus );
  1542. }
  1543. if( NULL != mszGuid ){
  1544. while( *strGuid != L'\0' ){
  1545. if( ! wcscmp( strGuid, strKernel.Buffer ) ){
  1546. *pbKernel = TRUE;
  1547. }
  1548. strGuid += (wcslen( strGuid) + 1 );
  1549. (*pnCount)++;
  1550. }
  1551. }
  1552. RtlFreeUnicodeString( &strKernel );
  1553. return PlaiErrorToPdhStatus( dwStatus );
  1554. }
  1555. PDH_FUNCTION
  1556. PlaiSetItemList(
  1557. HKEY hkeyQuery,
  1558. PPDH_PLA_ITEM_W pItems
  1559. )
  1560. {
  1561. PDH_STATUS pdhStatus;
  1562. DWORD dwValue;
  1563. pdhStatus = PlaiReadRegistryDwordValue( hkeyQuery, szLogType, &dwValue );
  1564. __try {
  1565. if( ERROR_SUCCESS == pdhStatus &&
  1566. (dwValue != pItems->dwType &&
  1567. PLA_NEW_LOG != dwValue) ){
  1568. pdhStatus = PDH_PLA_ERROR_TYPE_MISMATCH;
  1569. }
  1570. if( ERROR_SUCCESS == pdhStatus ){
  1571. switch( pItems->dwType ){
  1572. case PLA_TRACE_LOG:
  1573. {
  1574. BOOL bKernel;
  1575. ULONG nCount;
  1576. pdhStatus = PlaiIsKernel( pItems->strProviders, &bKernel, &nCount );
  1577. if( ERROR_SUCCESS != pdhStatus ){
  1578. return pdhStatus;
  1579. }
  1580. if( bKernel ){
  1581. if( nCount == 1 ){
  1582. DWORD dwFlags = Plaihextoi( pItems->strFlags );
  1583. DWORD dwInternal = 0;
  1584. pdhStatus = PlaiTranslateKernelFlags( &dwInternal, &dwFlags );
  1585. pdhStatus = PlaiWriteRegistryDwordValue(
  1586. hkeyQuery,
  1587. szTraceFlags,
  1588. &dwInternal
  1589. );
  1590. pdhStatus = PlaiWriteRegistryStringValue(
  1591. hkeyQuery,
  1592. szTraceProviderList,
  1593. REG_MULTI_SZ,
  1594. NULL,
  1595. 0
  1596. );
  1597. }else{
  1598. return PDH_INVALID_ARGUMENT;
  1599. }
  1600. }else{
  1601. DWORD dwFlags = 0;
  1602. pdhStatus = PlaiWriteRegistryDwordValue(
  1603. hkeyQuery,
  1604. szTraceFlags,
  1605. &dwFlags
  1606. );
  1607. pdhStatus = PlaiWriteRegistryStringValue(
  1608. hkeyQuery,
  1609. szTraceProviderList,
  1610. REG_MULTI_SZ,
  1611. pItems->strProviders,
  1612. PlaMszStrLenW( pItems->strProviders )
  1613. );
  1614. }
  1615. pdhStatus = PlaiWriteRegistryStringValue(
  1616. hkeyQuery,
  1617. szTraceProviderFlags,
  1618. REG_MULTI_SZ,
  1619. pItems->strFlags,
  1620. PlaMszStrLenW( pItems->strFlags )
  1621. );
  1622. pdhStatus = PlaiWriteRegistryStringValue(
  1623. hkeyQuery,
  1624. szTraceProviderLevels,
  1625. REG_MULTI_SZ,
  1626. pItems->strLevels,
  1627. PlaMszStrLenW( pItems->strLevels )
  1628. );
  1629. break;
  1630. }
  1631. case PLA_COUNTER_LOG:
  1632. {
  1633. if( PLA_ENGLISH ){
  1634. pdhStatus = PlaiWriteRegistryStringValue(
  1635. hkeyQuery,
  1636. szPerfCounterList,
  1637. REG_MULTI_SZ,
  1638. pItems->strCounters,
  1639. PlaMszStrLenW( pItems->strCounters )
  1640. );
  1641. }else{
  1642. LPWSTR strCounter = pItems->strCounters;
  1643. pdhStatus = PlaiWriteRegistryStringValue(
  1644. hkeyQuery,
  1645. szPerfCounterList,
  1646. REG_MULTI_SZ,
  1647. L"\0",
  1648. sizeof(WCHAR)
  1649. );
  1650. if( ERROR_SUCCESS == pdhStatus && NULL != strCounter ){
  1651. PDH_PLA_ITEM_W Counter;
  1652. Counter.dwType = PLA_COUNTER_LOG;
  1653. while( *strCounter != L'\0' ){
  1654. Counter.strCounters = strCounter;
  1655. pdhStatus = PlaiAddItem( hkeyQuery, &Counter );
  1656. if( ERROR_SUCCESS != pdhStatus ){
  1657. break;
  1658. }
  1659. strCounter += (wcslen(strCounter)+1);
  1660. }
  1661. }
  1662. }
  1663. }
  1664. break;
  1665. }
  1666. }
  1667. } __except (EXCEPTION_EXECUTE_HANDLER) {
  1668. pdhStatus = PDH_INVALID_ARGUMENT;
  1669. }
  1670. return pdhStatus;
  1671. }
  1672. PDH_FUNCTION
  1673. PdhPlaSetItemListA(
  1674. LPSTR /*strName*/,
  1675. LPSTR /*strComputer*/,
  1676. PPDH_PLA_ITEM_A /*pItems*/
  1677. )
  1678. {
  1679. return PDH_NOT_IMPLEMENTED;
  1680. }
  1681. PDH_FUNCTION
  1682. PdhPlaSetItemListW(
  1683. LPWSTR strName,
  1684. LPWSTR strComputer,
  1685. PPDH_PLA_ITEM_W pItems
  1686. )
  1687. {
  1688. PDH_STATUS pdhStatus;
  1689. HKEY hkeyQuery = NULL;
  1690. VALIDATE_QUERY( strName );
  1691. LPWSTR szName = PlaiStringDuplicate( strName );
  1692. LPWSTR szComputer = PlaiStringDuplicate( strComputer );
  1693. CHECK_NAMES( szName, szComputer, strComputer );
  1694. pdhStatus = PlaiConnectAndLockQuery( szComputer, szName, hkeyQuery );
  1695. if( ERROR_SUCCESS == pdhStatus ){
  1696. pdhStatus = PlaiSetItemList( hkeyQuery, pItems );
  1697. }
  1698. RELEASE_MUTEX(hPdhPlaMutex);
  1699. if ( NULL != hkeyQuery ) {
  1700. RegCloseKey ( hkeyQuery );
  1701. }
  1702. cleanup:
  1703. G_FREE( szName );
  1704. G_FREE( szComputer );
  1705. return pdhStatus;
  1706. }
  1707. /*****************************************************************************\
  1708. PdhPlaAddItem
  1709. Sets the list of items ( counters or providers ) for a log query
  1710. Arguments:
  1711. LPTSTR strName
  1712. Log Name
  1713. LPTSTR strComputer
  1714. Computer to connect to
  1715. LPTSTR strItem
  1716. A single item to be added to the list of Items or providers
  1717. the query will collect
  1718. Return:
  1719. PDH_MEMORY_ALLOCATION_FAILURE
  1720. The total list of items will not fit in the available
  1721. memory.
  1722. PDH_PLA_COLLECTION_NOT_FOUND
  1723. The query does not exist
  1724. ERROR_SUCCESS
  1725. \*****************************************************************************/
  1726. PDH_FUNCTION
  1727. PlaiRegAddItem(
  1728. HKEY hkeyQuery,
  1729. LPCWSTR strList,
  1730. LPWSTR strItem
  1731. )
  1732. {
  1733. PDH_STATUS pdhStatus = ERROR_SUCCESS;
  1734. LPWSTR strOldList = NULL;
  1735. LPWSTR strNewList = NULL;
  1736. DWORD dwNewDataSize = ( wcslen( strItem ) ) * sizeof(WCHAR);
  1737. DWORD dwOldDataSize = 0;
  1738. DWORD dwTermSize = sizeof(WCHAR) * 2;
  1739. if( PlaiIsStringEmpty( strItem ) ){
  1740. return PDH_INVALID_ARGUMENT;
  1741. }
  1742. if( ERROR_SUCCESS == pdhStatus ){
  1743. pdhStatus = PlaiReadRegistryStringValue( hkeyQuery, strList, 0, &strOldList, &dwOldDataSize );
  1744. strNewList = (LPWSTR)G_ALLOC( dwOldDataSize + dwNewDataSize + dwTermSize);
  1745. if( NULL == strNewList ){
  1746. G_FREE( strOldList );
  1747. return PDH_MEMORY_ALLOCATION_FAILURE;
  1748. }
  1749. ZeroMemory( strNewList, dwOldDataSize + dwNewDataSize + dwTermSize );
  1750. if( dwOldDataSize ){
  1751. memcpy( strNewList, strOldList, dwOldDataSize );
  1752. memcpy( (((PUCHAR)strNewList) + (dwOldDataSize-sizeof(WCHAR))), strItem, dwNewDataSize );
  1753. }else{
  1754. memcpy( strNewList, strItem, dwNewDataSize );
  1755. }
  1756. pdhStatus = PlaiWriteRegistryStringValue(
  1757. hkeyQuery,
  1758. strList,
  1759. REG_MULTI_SZ,
  1760. strNewList,
  1761. (dwOldDataSize + dwNewDataSize + sizeof(WCHAR))
  1762. );
  1763. }
  1764. G_FREE( strOldList );
  1765. G_FREE( strNewList );
  1766. return pdhStatus;
  1767. }
  1768. PDH_FUNCTION
  1769. PlaiAddItem(
  1770. HKEY hkeyQuery,
  1771. PPDH_PLA_ITEM_W pItem
  1772. )
  1773. {
  1774. PDH_STATUS pdhStatus;
  1775. DWORD dwValue;
  1776. pdhStatus = PlaiReadRegistryDwordValue( hkeyQuery, szLogType, &dwValue );
  1777. __try {
  1778. if( ERROR_SUCCESS == pdhStatus && dwValue != pItem->dwType && PLA_NEW_LOG != dwValue ){
  1779. pdhStatus = PDH_PLA_ERROR_TYPE_MISMATCH;
  1780. }
  1781. if( ERROR_SUCCESS == pdhStatus ){
  1782. switch( pItem->dwType ){
  1783. case PLA_TRACE_LOG:
  1784. {
  1785. BOOL bKernel;
  1786. ULONG nCount;
  1787. pdhStatus = PlaiIsKernel( pItem->strProviders, &bKernel, &nCount );
  1788. if( ERROR_SUCCESS == pdhStatus ){
  1789. if( bKernel ){
  1790. DWORD dwFlags = Plaihextoi( pItem->strFlags );
  1791. pdhStatus = PlaiWriteRegistryDwordValue(
  1792. hkeyQuery,
  1793. szTraceFlags,
  1794. &dwFlags
  1795. );
  1796. pdhStatus = PlaiWriteRegistryStringValue(
  1797. hkeyQuery,
  1798. szTraceProviderList,
  1799. REG_MULTI_SZ,
  1800. NULL,
  1801. 0
  1802. );
  1803. }else{
  1804. DWORD dwFlags = 0;
  1805. pdhStatus = PlaiWriteRegistryDwordValue(
  1806. hkeyQuery,
  1807. szTraceFlags,
  1808. &dwFlags
  1809. );
  1810. pdhStatus = PlaiRegAddItem( hkeyQuery, szTraceProviderList, pItem->strProviders );
  1811. if( ERROR_SUCCESS == pdhStatus ){
  1812. pdhStatus = PlaiRegAddItem( hkeyQuery, szTraceProviderFlags, pItem->strFlags );
  1813. if( ERROR_SUCCESS == pdhStatus ){
  1814. pdhStatus = PlaiRegAddItem( hkeyQuery, szTraceProviderLevels, pItem->strLevels );
  1815. }
  1816. }
  1817. }
  1818. }
  1819. }
  1820. break;
  1821. case PLA_COUNTER_LOG:
  1822. {
  1823. if( PLA_ENGLISH ){
  1824. pdhStatus = PlaiRegAddItem( hkeyQuery, szPerfCounterList, pItem->strCounters );
  1825. }else{
  1826. LPWSTR strLocaleCounter = pItem->strCounters;
  1827. LPWSTR strEnglishCounter = NULL;
  1828. DWORD dwSize = MAX_PATH;
  1829. strEnglishCounter = (LPWSTR)G_ALLOC( dwSize*sizeof(WCHAR) );
  1830. if( NULL != strEnglishCounter ){
  1831. pdhStatus = PdhTranslate009CounterW( strLocaleCounter, strEnglishCounter, &dwSize );
  1832. if( PDH_MORE_DATA == pdhStatus ){
  1833. LPTSTR strBuffer = (LPWSTR)G_REALLOC( strEnglishCounter, (dwSize*sizeof(WCHAR)) );
  1834. if( NULL != strBuffer ){
  1835. strEnglishCounter = strBuffer;
  1836. pdhStatus = PdhTranslate009CounterW( strLocaleCounter, strEnglishCounter, &dwSize );
  1837. }else{
  1838. pdhStatus = PDH_MEMORY_ALLOCATION_FAILURE;
  1839. }
  1840. }
  1841. if( ERROR_SUCCESS == pdhStatus ){
  1842. pdhStatus = PlaiRegAddItem( hkeyQuery, szPerfCounterList, strEnglishCounter );
  1843. }else{
  1844. pdhStatus = PlaiRegAddItem( hkeyQuery, szPerfCounterList, pItem->strCounters );
  1845. }
  1846. G_FREE( strEnglishCounter );
  1847. }else{
  1848. pdhStatus = PDH_MEMORY_ALLOCATION_FAILURE;
  1849. }
  1850. }
  1851. }
  1852. }
  1853. }
  1854. } __except (EXCEPTION_EXECUTE_HANDLER) {
  1855. pdhStatus = PDH_INVALID_ARGUMENT;
  1856. }
  1857. return pdhStatus;
  1858. }
  1859. PDH_FUNCTION
  1860. PdhPlaAddItemA(
  1861. LPSTR strName,
  1862. LPSTR strComputer,
  1863. PPDH_PLA_ITEM_A pItem
  1864. )
  1865. {
  1866. return PDH_NOT_IMPLEMENTED;
  1867. }
  1868. PDH_FUNCTION
  1869. PdhPlaAddItemW(
  1870. LPWSTR strName,
  1871. LPWSTR strComputer,
  1872. PPDH_PLA_ITEM_W pItem
  1873. )
  1874. {
  1875. PDH_STATUS pdhStatus = ERROR_SUCCESS;
  1876. HKEY hkeyQuery = NULL;
  1877. VALIDATE_QUERY( strName );
  1878. LPWSTR szName = PlaiStringDuplicate( strName );
  1879. LPWSTR szComputer = PlaiStringDuplicate( strComputer );
  1880. CHECK_NAMES( szName, szComputer, strComputer );
  1881. pdhStatus = PlaiConnectAndLockQuery( szComputer, szName, hkeyQuery );
  1882. if( ERROR_SUCCESS == pdhStatus ){
  1883. pdhStatus = PlaiAddItem( hkeyQuery, pItem );
  1884. RELEASE_MUTEX(hPdhPlaMutex);
  1885. }
  1886. cleanup:
  1887. if ( NULL != hkeyQuery ) {
  1888. RegCloseKey ( hkeyQuery );
  1889. }
  1890. G_FREE( szName );
  1891. G_FREE( szComputer );
  1892. return pdhStatus;
  1893. }
  1894. /*****************************************************************************\
  1895. PdhPlaRemoveAllItems
  1896. Removes all entries for the list of Items the log query will collect
  1897. Arguments:
  1898. LPTSTR strName
  1899. Log Name
  1900. LPTSTR strComputer
  1901. Computer to connect to
  1902. Return:
  1903. PDH_INVALID_ARGUMENT
  1904. The query does not exist
  1905. ERROR_SUCCESS
  1906. \*****************************************************************************/
  1907. PDH_FUNCTION
  1908. PdhPlaRemoveAllItemsA( LPSTR strName, LPSTR strComputer )
  1909. {
  1910. PDH_STATUS pdhStatus;
  1911. LPWSTR wstrName = NULL;
  1912. LPWSTR wstrComputer = NULL;
  1913. VALIDATE_QUERY( strName );
  1914. pdhStatus = Plaiatow( strComputer, wstrComputer );
  1915. if( ERROR_SUCCESS == pdhStatus ){
  1916. pdhStatus = Plaiatow( strName, wstrName );
  1917. if( ERROR_SUCCESS == pdhStatus ){
  1918. pdhStatus = PdhPlaRemoveAllItemsW( wstrName, wstrComputer );
  1919. }
  1920. }
  1921. G_FREE( wstrComputer );
  1922. G_FREE( wstrName );
  1923. return pdhStatus;
  1924. }
  1925. PDH_FUNCTION
  1926. PdhPlaRemoveAllItemsW(
  1927. LPWSTR strName,
  1928. LPWSTR strComputer
  1929. )
  1930. {
  1931. PDH_STATUS pdhStatus;
  1932. HKEY hkeyQuery = NULL;
  1933. VALIDATE_QUERY( strName );
  1934. LPWSTR szName = PlaiStringDuplicate( strName );
  1935. LPWSTR szComputer = PlaiStringDuplicate( strComputer );
  1936. CHECK_NAMES( szName, szComputer, strComputer );
  1937. pdhStatus = PlaiConnectAndLockQuery( szComputer, szName, hkeyQuery );
  1938. if( ERROR_SUCCESS == pdhStatus ){
  1939. DWORD dwValue;
  1940. pdhStatus = PlaiReadRegistryDwordValue( hkeyQuery, szLogType, &dwValue );
  1941. if( ERROR_SUCCESS == pdhStatus ){
  1942. switch( dwValue ){
  1943. case PLA_TRACE_LOG:
  1944. pdhStatus = PlaiWriteRegistryStringValue(
  1945. hkeyQuery,
  1946. szTraceProviderList,
  1947. REG_MULTI_SZ, L"\0",
  1948. sizeof(WCHAR)
  1949. );
  1950. pdhStatus = PlaiWriteRegistryStringValue(
  1951. hkeyQuery,
  1952. szTraceProviderFlags,
  1953. REG_MULTI_SZ, L"\0",
  1954. sizeof(WCHAR)
  1955. );
  1956. pdhStatus = PlaiWriteRegistryStringValue(
  1957. hkeyQuery,
  1958. szTraceProviderLevels,
  1959. REG_MULTI_SZ, L"\0",
  1960. sizeof(WCHAR)
  1961. );
  1962. break;
  1963. case PLA_COUNTER_LOG:
  1964. pdhStatus = PlaiWriteRegistryStringValue(
  1965. hkeyQuery,
  1966. szPerfCounterList,
  1967. REG_MULTI_SZ,
  1968. L"\0",
  1969. sizeof(WCHAR)
  1970. );
  1971. break;
  1972. }
  1973. }
  1974. RELEASE_MUTEX(hPdhPlaMutex);
  1975. }
  1976. cleanup:
  1977. if ( NULL != hkeyQuery ) {
  1978. RegCloseKey ( hkeyQuery );
  1979. }
  1980. G_FREE( szName );
  1981. G_FREE( szComputer );
  1982. return pdhStatus;
  1983. }
  1984. /*****************************************************************************\
  1985. PdhPlaGetInfo
  1986. Fills the PDH_PLA_INFO structure with the properties of the requested
  1987. log query.
  1988. Arguments:
  1989. LPTSTR strName
  1990. Log Name
  1991. LPTSTR strComputer
  1992. Computer to connect to
  1993. PPDH_PLA_INFO pInfo
  1994. Information block
  1995. Return:
  1996. PDH_INVALID_ARGUMENT
  1997. The query does not exist
  1998. ERROR_SUCCESS
  1999. \*****************************************************************************/
  2000. PDH_FUNCTION
  2001. PlaiAssignInfoString(
  2002. LPWSTR strName,
  2003. HKEY hkeyQuery,
  2004. PPDH_PLA_INFO_W pInfo,
  2005. LPDWORD dwTotalSize,
  2006. LPWSTR& strCopy,
  2007. DWORD dwBufferSize,
  2008. DWORD dwMask,
  2009. DWORD dwQueryMask,
  2010. LPCTSTR szKey,
  2011. DWORD dwRegFlag
  2012. )
  2013. {
  2014. LPWSTR strKeyValue = NULL;
  2015. LPWSTR strInfo = NULL;
  2016. PDH_STATUS pdhStatus = ERROR_SUCCESS;
  2017. DWORD dwKeySize = 0;
  2018. BOOL bRead = TRUE;
  2019. VALIDATE_QUERY( strName );
  2020. if( pInfo != NULL ){
  2021. if( !(dwQueryMask & dwMask) ){
  2022. bRead = FALSE;
  2023. }
  2024. }
  2025. if( bRead ){
  2026. pdhStatus = PlaiReadRegistryStringValue( hkeyQuery, szKey, dwRegFlag, &strKeyValue, &dwKeySize );
  2027. if( (ERROR_SUCCESS == pdhStatus) &&
  2028. (!PlaiIsStringEmpty(strKeyValue)) &&
  2029. (dwKeySize > sizeof(WCHAR)) ){
  2030. *dwTotalSize += dwKeySize;
  2031. }else if( dwMask == PLA_INFO_FLAG_USER ){
  2032. G_FREE( strKeyValue );
  2033. strKeyValue = (LPWSTR)G_ALLOC(PLA_ACCOUNT_BUFFER*sizeof(WCHAR) );
  2034. if( strKeyValue != NULL ){
  2035. dwKeySize = LoadStringW(
  2036. (HINSTANCE)ThisDLLHandle,
  2037. IDS_DEFAULT_ACCOUNT,
  2038. strKeyValue,
  2039. PLA_ACCOUNT_BUFFER
  2040. );
  2041. if( dwKeySize ){
  2042. dwKeySize = BYTE_SIZE( strKeyValue ) + sizeof(WCHAR);
  2043. *dwTotalSize += dwKeySize;
  2044. }
  2045. }else{
  2046. bRead = FALSE;
  2047. }
  2048. }else if( (dwMask == PLA_INFO_FLAG_LOGGERNAME) ||
  2049. ((dwMask == PLA_INFO_FLAG_FILENAME) && (ERROR_SUCCESS != pdhStatus)) ){
  2050. G_FREE( strKeyValue );
  2051. dwKeySize = BYTE_SIZE( strName ) + sizeof(WCHAR);
  2052. *dwTotalSize += dwKeySize;
  2053. strKeyValue = (LPWSTR)G_ALLOC(dwKeySize);
  2054. if( NULL != strKeyValue && !PlaiIsStringEmpty( strName ) ){
  2055. StringCbCopy( strKeyValue, dwKeySize, strName );
  2056. }else{
  2057. bRead = FALSE;
  2058. }
  2059. }else{
  2060. dwKeySize = 0;
  2061. }
  2062. }
  2063. if( pInfo != NULL && bRead ){
  2064. if( dwKeySize && (dwBufferSize >= *dwTotalSize) ){
  2065. memcpy( (void*)strCopy, (void*)strKeyValue, dwKeySize );
  2066. strInfo = strCopy;
  2067. strCopy = (LPWSTR)((PUCHAR)strCopy + dwKeySize );
  2068. }
  2069. __try{
  2070. switch( dwMask ){
  2071. case PLA_INFO_FLAG_COUNTERS:
  2072. pInfo->dwMask |= PLA_INFO_FLAG_COUNTERS;
  2073. pInfo->Perf.piCounterList.strCounters = strInfo;
  2074. break;
  2075. case PLA_INFO_FLAG_SQLNAME:
  2076. pInfo->dwMask |= PLA_INFO_FLAG_SQLNAME;
  2077. pInfo->strSqlName = strInfo;
  2078. break;
  2079. case PLA_INFO_FLAG_FILENAME:
  2080. pInfo->dwMask |= PLA_INFO_FLAG_FILENAME;
  2081. pInfo->strBaseFileName = strInfo;
  2082. break;
  2083. case PLA_INFO_FLAG_PROVIDERS:
  2084. pInfo->dwMask |= PLA_INFO_FLAG_PROVIDERS;
  2085. pInfo->Trace.piProviderList.strProviders = strInfo;
  2086. break;
  2087. case PLA_INFO_FLAG_LOGGERNAME:
  2088. pInfo->dwMask |= PLA_INFO_FLAG_LOGGERNAME;
  2089. pInfo->Trace.strLoggerName = strInfo;
  2090. break;
  2091. case PLA_INFO_FLAG_USER:
  2092. pInfo->dwMask |= PLA_INFO_FLAG_USER;
  2093. pInfo->strUser = strInfo;
  2094. break;
  2095. case PLA_INFO_FLAG_DEFAULTDIR:
  2096. pInfo->dwMask |= PLA_INFO_FLAG_DEFAULTDIR;
  2097. pInfo->strDefaultDir = strInfo;
  2098. break;
  2099. }
  2100. } __except (EXCEPTION_EXECUTE_HANDLER) {
  2101. }
  2102. }
  2103. G_FREE( strKeyValue );
  2104. return ERROR_SUCCESS;
  2105. }
  2106. PDH_FUNCTION
  2107. PdhPlaGetInfoA(
  2108. LPSTR /*strName*/,
  2109. LPSTR /*strComputer*/,
  2110. LPDWORD /*pdwBufferSize*/,
  2111. PPDH_PLA_INFO_A /*pInfo*/
  2112. )
  2113. {
  2114. return PDH_NOT_IMPLEMENTED;
  2115. }
  2116. PDH_FUNCTION
  2117. PdhPlaGetInfoW(
  2118. LPWSTR strName,
  2119. LPWSTR strComputer,
  2120. LPDWORD pdwBufferSize,
  2121. PPDH_PLA_INFO_W pInfo
  2122. )
  2123. {
  2124. PDH_STATUS pdhStatus = ERROR_SUCCESS;
  2125. HKEY hkeyQuery = NULL;
  2126. DWORD dwSize = 0;
  2127. LPWSTR strCopy = NULL;
  2128. LPWSTR strKey = NULL;
  2129. DWORD dwKeySize = 0;
  2130. DWORD dwMask = 0;
  2131. VALIDATE_QUERY( strName );
  2132. DWORD dwBufferSize;
  2133. __try {
  2134. dwBufferSize = *pdwBufferSize;
  2135. if( pInfo != NULL ){
  2136. dwMask = pInfo->dwMask;
  2137. pInfo->dwMask = 0;
  2138. }
  2139. } __except (EXCEPTION_EXECUTE_HANDLER) {
  2140. pdhStatus = PDH_INVALID_ARGUMENT;
  2141. }
  2142. CHECK_STATUS( pdhStatus );
  2143. LPWSTR szName = PlaiStringDuplicate( strName );
  2144. LPWSTR szComputer = PlaiStringDuplicate( strComputer );
  2145. CHECK_NAMES( szName, szComputer, strComputer );
  2146. pdhStatus = PlaiConnectAndLockQuery( szComputer, szName, hkeyQuery, FALSE );
  2147. if( ERROR_SUCCESS == pdhStatus ){
  2148. DWORD dwType = 0;
  2149. dwSize = sizeof(PDH_PLA_INFO_W);
  2150. if( pInfo == NULL ){
  2151. dwBufferSize = 0;
  2152. }else{
  2153. strCopy = (LPWSTR)( (PUCHAR)pInfo+ sizeof(PDH_PLA_INFO_W) );
  2154. }
  2155. PlaiReadRegistryDwordValue( hkeyQuery, szLogType, &dwType );
  2156. if( pInfo != NULL ){
  2157. __try {
  2158. if( dwMask & PLA_INFO_FLAG_TYPE ){
  2159. pInfo->dwMask |= PLA_INFO_FLAG_TYPE;
  2160. pInfo->dwType = dwType;
  2161. }
  2162. if( dwMask & PLA_INFO_FLAG_AUTOFORMAT ){
  2163. pdhStatus = PlaiReadRegistryDwordValue( hkeyQuery, szLogAutoFormat, &pInfo->dwAutoNameFormat );
  2164. if( ERROR_SUCCESS == pdhStatus ){
  2165. pInfo->dwMask |= PLA_INFO_FLAG_AUTOFORMAT;
  2166. }
  2167. }
  2168. if( dwMask & PLA_INFO_FLAG_SRLNUMBER ){
  2169. pdhStatus = PlaiReadRegistryDwordValue( hkeyQuery, szLogSerialNumber, &pInfo->dwLogFileSerialNumber );
  2170. if( ERROR_SUCCESS == pdhStatus ){
  2171. pInfo->dwMask |= PLA_INFO_FLAG_SRLNUMBER;
  2172. }
  2173. }
  2174. if( dwMask & PLA_INFO_FLAG_REPEAT ){
  2175. pdhStatus = PlaiReadRegistryPlaTime( hkeyQuery, szRepeatSchedule, &pInfo->ptRepeat );
  2176. if( ERROR_SUCCESS == pdhStatus ){
  2177. pInfo->dwMask |= PLA_INFO_FLAG_REPEAT;
  2178. }
  2179. }
  2180. if( dwMask & PLA_INFO_FLAG_STATUS ){
  2181. pdhStatus = PlaiReadRegistryDwordValue( hkeyQuery, szCurrentState, &pInfo->dwStatus );
  2182. if( ERROR_SUCCESS == pdhStatus ){
  2183. pInfo->dwMask |= PLA_INFO_FLAG_STATUS;
  2184. }
  2185. }
  2186. if( dwMask & PLA_INFO_FLAG_FORMAT ){
  2187. pdhStatus = PlaiReadRegistryDwordValue( hkeyQuery, szLogFileType, &pInfo->dwFileFormat );
  2188. if( ERROR_SUCCESS == pdhStatus ){
  2189. pInfo->dwMask |= PLA_INFO_FLAG_FORMAT;
  2190. }
  2191. }
  2192. if( dwMask & PLA_INFO_FLAG_DATASTORE ){
  2193. pdhStatus = PlaiReadRegistryDwordValue( hkeyQuery, szDatastoreAttributes, &pInfo->dwDatastoreAttributes );
  2194. if( ERROR_SUCCESS == pdhStatus ){
  2195. pInfo->dwMask |= PLA_INFO_FLAG_DATASTORE;
  2196. }
  2197. }
  2198. if( dwMask & PLA_INFO_FLAG_CRTNEWFILE ){
  2199. pdhStatus = PlaiReadRegistryPlaTime( hkeyQuery, szCreateNewFile, &pInfo->ptCreateNewFile);
  2200. if( ERROR_SUCCESS == pdhStatus ){
  2201. pInfo->dwMask |= PLA_INFO_FLAG_CRTNEWFILE;
  2202. }
  2203. }
  2204. if( dwMask & PLA_INFO_FLAG_END ){
  2205. pdhStatus = PlaiReadRegistryPlaTime( hkeyQuery, szStop, &pInfo->ptLogEndTime );
  2206. if( ERROR_SUCCESS == pdhStatus ){
  2207. pInfo->dwMask |= PLA_INFO_FLAG_END;
  2208. }
  2209. }
  2210. if( dwMask & PLA_INFO_FLAG_BEGIN ){
  2211. pdhStatus = PlaiReadRegistryPlaTime( hkeyQuery, szStart, &pInfo->ptLogBeginTime );
  2212. if( ERROR_SUCCESS == pdhStatus ){
  2213. pInfo->dwMask |= PLA_INFO_FLAG_BEGIN;
  2214. }
  2215. }
  2216. } __except (EXCEPTION_EXECUTE_HANDLER) {
  2217. pdhStatus = PDH_INVALID_ARGUMENT;
  2218. }
  2219. }
  2220. pdhStatus = PlaiAssignInfoString( szName, hkeyQuery, pInfo, &dwSize, strCopy, dwBufferSize,
  2221. PLA_INFO_FLAG_FILENAME, dwMask, szLogBaseName, READ_REG_MUI );
  2222. pdhStatus = PlaiAssignInfoString( szName, hkeyQuery, pInfo, &dwSize, strCopy, dwBufferSize,
  2223. PLA_INFO_FLAG_USER, dwMask, szRunAs, 0 );
  2224. pdhStatus = PlaiAssignInfoString( szName, hkeyQuery, pInfo, &dwSize, strCopy, dwBufferSize,
  2225. PLA_INFO_FLAG_DEFAULTDIR, dwMask, szLogFolder, READ_REG_MUI );
  2226. __try {
  2227. switch( dwType ){
  2228. case PLA_TRACE_LOG: // Trace Fields
  2229. if( NULL != pInfo ){
  2230. if( dwMask & PLA_INFO_FLAG_MODE ){
  2231. pdhStatus = PlaiReadRegistryDwordValue( hkeyQuery, szTraceMode, &pInfo->Trace.dwMode );
  2232. if( ERROR_SUCCESS == pdhStatus ){
  2233. pInfo->dwMask |= PLA_INFO_FLAG_MODE;
  2234. }
  2235. }
  2236. if( dwMask & PLA_INFO_FLAG_BUFFERSIZE ){
  2237. pdhStatus = PlaiReadRegistryDwordValue( hkeyQuery, szTraceBufferSize, &pInfo->Trace.dwBufferSize );
  2238. if( ERROR_SUCCESS == pdhStatus ){
  2239. pInfo->dwMask |= PLA_INFO_FLAG_BUFFERSIZE;
  2240. }
  2241. }
  2242. if( dwMask & PLA_INFO_FLAG_PROVIDERS ){
  2243. pInfo->Trace.piProviderList.dwType = PLA_TRACE_LOG;
  2244. }
  2245. }
  2246. pdhStatus = PlaiAssignInfoString( szName, hkeyQuery, pInfo, &dwSize, strCopy, dwBufferSize,
  2247. PLA_INFO_FLAG_PROVIDERS, dwMask, szTraceProviderList, 0 );
  2248. pdhStatus = PlaiAssignInfoString( szName, hkeyQuery, pInfo, &dwSize, strCopy, dwBufferSize,
  2249. PLA_INFO_FLAG_LOGGERNAME, dwMask, szTraceLoggerName, 0 );
  2250. break;
  2251. case PLA_COUNTER_LOG: // Performance Fields
  2252. if( NULL != pInfo ){
  2253. if( dwMask & PLA_INFO_FLAG_COUNTERS ){
  2254. pInfo->Perf.piCounterList.dwType = PLA_COUNTER_LOG;
  2255. }
  2256. }
  2257. pdhStatus = PlaiAssignInfoString( szName, hkeyQuery, pInfo, &dwSize, strCopy, dwBufferSize,
  2258. PLA_INFO_FLAG_COUNTERS, dwMask, szPerfCounterList, 0 );
  2259. pdhStatus = PlaiAssignInfoString( szName, hkeyQuery, pInfo, &dwSize, strCopy, dwBufferSize,
  2260. PLA_INFO_FLAG_SQLNAME, dwMask, szSqlBaseName, 0 );
  2261. break;
  2262. }
  2263. } __except (EXCEPTION_EXECUTE_HANDLER) {
  2264. pdhStatus = PDH_INVALID_ARGUMENT;
  2265. }
  2266. RELEASE_MUTEX(hPdhPlaMutex);
  2267. }
  2268. if ( NULL != hkeyQuery ) {
  2269. RegCloseKey ( hkeyQuery );
  2270. }
  2271. __try {
  2272. *pdwBufferSize = dwSize;
  2273. } __except (EXCEPTION_EXECUTE_HANDLER) {
  2274. pdhStatus = PDH_INVALID_ARGUMENT;
  2275. }
  2276. cleanup:
  2277. G_FREE( szName );
  2278. G_FREE( szComputer );
  2279. return pdhStatus;
  2280. }
  2281. /*****************************************************************************\
  2282. PdhPlaSetInfo
  2283. Sets the information in the log query to the parameters in the
  2284. PDH_PLA_INFO block according to the info mask.
  2285. Arguments:
  2286. LPTSTR strName
  2287. Log Name
  2288. LPTSTR strComputer
  2289. Computer to connect to
  2290. PPDH_PLA_INFO pInfo
  2291. Information block
  2292. Return:
  2293. PDH_INVALID_ARGUMENT
  2294. The query does not exist or pInfo is NULL
  2295. ERROR_SUCCESS
  2296. \*****************************************************************************/
  2297. PDH_FUNCTION
  2298. PlaiSetInfo(
  2299. LPWSTR strComputer,
  2300. HKEY hkeyQuery,
  2301. PPDH_PLA_INFO_W pInfo
  2302. )
  2303. {
  2304. PDH_STATUS pdhStatus = ERROR_SUCCESS;
  2305. DWORD dwType = 0;
  2306. DWORD dwFormat = 0;
  2307. DWORD dwDatastoreAttributes = 0;
  2308. __try {
  2309. // General Fields
  2310. if( pInfo->dwMask & PLA_INFO_FLAG_AUTOFORMAT ){
  2311. pdhStatus = PlaiWriteRegistryDwordValue( hkeyQuery, szLogAutoFormat, &pInfo->dwAutoNameFormat );
  2312. }
  2313. if( pInfo->dwMask & PLA_INFO_FLAG_REPEAT ){
  2314. pdhStatus = PlaiWriteRegistryPlaTime( hkeyQuery, szRepeatSchedule, &pInfo->ptRepeat );
  2315. }
  2316. if( pInfo->dwMask & PLA_INFO_FLAG_RUNCOMMAND ){
  2317. pdhStatus = PlaiWriteRegistryStringValue( hkeyQuery, szEOFCmd, REG_SZ, pInfo->strCommandFileName, 0 );
  2318. }
  2319. if( pInfo->dwMask & PLA_INFO_FLAG_CRTNEWFILE ){
  2320. pdhStatus = PlaiWriteRegistryPlaTime( hkeyQuery, szCreateNewFile, &pInfo->ptCreateNewFile );
  2321. }
  2322. if( pInfo->dwMask & PLA_INFO_FLAG_MAXLOGSIZE ){
  2323. pdhStatus = PlaiWriteRegistryDwordValue( hkeyQuery, szLogMaxSize, &pInfo->dwMaxLogSize );
  2324. }
  2325. if( pInfo->dwMask & (PLA_INFO_FLAG_SQLNAME|PLA_INFO_FLAG_FILENAME|PLA_INFO_FLAG_DEFAULTDIR) ){
  2326. if( pInfo->dwMask & PLA_INFO_FLAG_FORMAT ){
  2327. dwFormat = pInfo->dwFileFormat;
  2328. pdhStatus = ERROR_SUCCESS;
  2329. }else{
  2330. pdhStatus = PlaiReadRegistryDwordValue( hkeyQuery, szLogFileType, &dwFormat );
  2331. }
  2332. if( (ERROR_SUCCESS == pdhStatus) && (PLA_SQL_LOG == dwFormat) ){
  2333. if( pInfo->dwMask & PLA_INFO_FLAG_SQLNAME ){
  2334. pdhStatus = PlaiWriteRegistryStringValue( hkeyQuery, szSqlBaseName, REG_SZ, pInfo->strSqlName, 0 );
  2335. }else if( pInfo->dwMask & PLA_INFO_FLAG_FILENAME ){
  2336. pdhStatus = PlaiWriteRegistryStringValue( hkeyQuery, szSqlBaseName, REG_SZ, pInfo->strBaseFileName, 0 );
  2337. }else if( pInfo->dwMask & PLA_INFO_FLAG_DEFAULTDIR ){
  2338. pdhStatus = PlaiWriteRegistryStringValue( hkeyQuery, szSqlBaseName, REG_SZ, pInfo->strDefaultDir, 0 );
  2339. }
  2340. }else{
  2341. if( pInfo->dwMask & PLA_INFO_FLAG_SQLNAME ){
  2342. pdhStatus = PlaiWriteRegistryStringValue( hkeyQuery, szSqlBaseName, REG_SZ, pInfo->strSqlName, 0 );
  2343. }
  2344. if( pInfo->dwMask & PLA_INFO_FLAG_FILENAME ){
  2345. pdhStatus = PlaiWriteRegistryStringValue( hkeyQuery, szLogBaseName, REG_SZ, pInfo->strBaseFileName, 0 );
  2346. }
  2347. if( pInfo->dwMask & PLA_INFO_FLAG_DEFAULTDIR ){
  2348. pdhStatus = PlaiWriteRegistryStringValue( hkeyQuery, szLogFolder, REG_SZ, pInfo->strDefaultDir, 0 );
  2349. }
  2350. }
  2351. }
  2352. if( pInfo->dwMask & PLA_INFO_FLAG_TYPE ){
  2353. // Do not write it to the registry because it may be a new collection
  2354. dwType = pInfo->dwType;
  2355. }else{
  2356. PlaiReadRegistryDwordValue( hkeyQuery, szLogType, &dwType );
  2357. }
  2358. switch( dwType ){
  2359. case PLA_TRACE_LOG: // Trace Fields
  2360. if( pInfo->dwMask & PLA_INFO_FLAG_FORMAT ){
  2361. dwFormat = pInfo->dwFileFormat;
  2362. switch( dwFormat ){
  2363. case PLA_BIN_FILE: dwFormat = PLA_SEQ_TRACE_FILE; break;
  2364. case PLA_BIN_CIRC_FILE: dwFormat = PLA_CIRC_TRACE_FILE; break;
  2365. }
  2366. pdhStatus = PlaiWriteRegistryDwordValue( hkeyQuery, szLogFileType, &dwFormat );
  2367. }else{
  2368. PlaiReadRegistryDwordValue( hkeyQuery, szLogFileType, &dwFormat );
  2369. }
  2370. if( pInfo->dwMask & PLA_INFO_FLAG_DATASTORE ){
  2371. if( ! (pInfo->dwDatastoreAttributes & PLA_DATASTORE_APPEND_MASK ) ){
  2372. if( dwFormat == PLA_SEQ_TRACE_FILE ){
  2373. pInfo->dwDatastoreAttributes |= PLA_DATASTORE_APPEND;
  2374. }else{
  2375. pInfo->dwDatastoreAttributes |= PLA_DATASTORE_OVERWRITE;
  2376. }
  2377. }
  2378. if( ! (pInfo->dwDatastoreAttributes & PLA_DATASTORE_SIZE_MASK ) ){
  2379. pInfo->dwDatastoreAttributes |= PLA_DATASTORE_SIZE_MB;
  2380. }
  2381. pdhStatus = PlaiWriteRegistryDwordValue( hkeyQuery, szDatastoreAttributes, &pInfo->dwDatastoreAttributes );
  2382. }
  2383. if( pInfo->dwMask & PLA_INFO_FLAG_BUFFERSIZE ){
  2384. pdhStatus = PlaiWriteRegistryDwordValue( hkeyQuery, szTraceBufferSize, &pInfo->Trace.dwBufferSize );
  2385. }
  2386. if( pInfo->dwMask & PLA_INFO_FLAG_MINBUFFERS ){
  2387. pdhStatus = PlaiWriteRegistryDwordValue( hkeyQuery, szTraceBufferMin, &pInfo->Trace.dwMinimumBuffers );
  2388. }
  2389. if( pInfo->dwMask & PLA_INFO_FLAG_MAXBUFFERS ){
  2390. pdhStatus = PlaiWriteRegistryDwordValue( hkeyQuery, szTraceBufferMax, &pInfo->Trace.dwMaximumBuffers );
  2391. }
  2392. if( pInfo->dwMask & PLA_INFO_FLAG_FLUSHTIMER ){
  2393. pdhStatus = PlaiWriteRegistryDwordValue( hkeyQuery, szTraceFlushInterval, &pInfo->Trace.dwFlushTimer );
  2394. }
  2395. if( pInfo->dwMask & PLA_INFO_FLAG_MODE ){
  2396. pdhStatus = PlaiWriteRegistryDwordValue( hkeyQuery, szTraceMode, &pInfo->Trace.dwMode );
  2397. }
  2398. if( pInfo->dwMask & PLA_INFO_FLAG_LOGGERNAME ){
  2399. pdhStatus = PlaiWriteRegistryStringValue( hkeyQuery, szTraceLoggerName, REG_SZ, pInfo->Trace.strLoggerName, 0 );
  2400. }
  2401. if( pInfo->dwMask & PLA_INFO_FLAG_PROVIDERS ){
  2402. pdhStatus = PlaiSetItemList( hkeyQuery, &pInfo->Trace.piProviderList );
  2403. }
  2404. break;
  2405. case PLA_COUNTER_LOG: // Performance Fields
  2406. if( pInfo->dwMask & PLA_INFO_FLAG_FORMAT ){
  2407. dwFormat = pInfo->dwFileFormat;
  2408. switch( dwFormat ){
  2409. case PLA_CIRC_TRACE_FILE: dwFormat = PLA_BIN_CIRC_FILE; break;
  2410. case PLA_SEQ_TRACE_FILE: dwFormat = PLA_BIN_FILE; break;
  2411. }
  2412. pdhStatus = PlaiWriteRegistryDwordValue( hkeyQuery, szLogFileType, &dwFormat );
  2413. }else{
  2414. PlaiReadRegistryDwordValue( hkeyQuery, szLogFileType, &dwFormat );
  2415. }
  2416. if( pInfo->dwMask & PLA_INFO_FLAG_DATASTORE ){
  2417. if( PLA_SQL_LOG == dwFormat ){
  2418. pInfo->dwDatastoreAttributes = (pInfo->dwDatastoreAttributes & 0xFFFFFF00) |
  2419. PLA_DATASTORE_APPEND | PLA_DATASTORE_SIZE_ONE_RECORD;
  2420. }else{
  2421. if( ! (pInfo->dwDatastoreAttributes & PLA_DATASTORE_APPEND_MASK ) ){
  2422. if( dwFormat == PLA_BIN_FILE ){
  2423. dwDatastoreAttributes |= PLA_DATASTORE_APPEND;
  2424. }else{
  2425. dwDatastoreAttributes |= PLA_DATASTORE_OVERWRITE;
  2426. }
  2427. }
  2428. if( ! (pInfo->dwDatastoreAttributes & PLA_DATASTORE_SIZE_MASK ) ){
  2429. dwDatastoreAttributes |= PLA_DATASTORE_SIZE_KB;
  2430. }
  2431. }
  2432. pdhStatus = PlaiWriteRegistryDwordValue( hkeyQuery, szDatastoreAttributes, &pInfo->dwDatastoreAttributes );
  2433. }
  2434. if( pInfo->dwMask & PLA_INFO_FLAG_MAXLOGSIZE ){
  2435. DWORD dwMaxSize = pInfo->dwMaxLogSize;
  2436. PlaiReadRegistryDwordValue( hkeyQuery, szDatastoreAttributes, &dwDatastoreAttributes );
  2437. if( (dwDatastoreAttributes & PLA_DATASTORE_SIZE_MASK) == PLA_DATASTORE_SIZE_KB ){
  2438. dwMaxSize *= 1024;
  2439. }
  2440. pdhStatus = PlaiWriteRegistryDwordValue( hkeyQuery, szLogMaxSize, &dwMaxSize );
  2441. }
  2442. if( pInfo->dwMask & PLA_INFO_FLAG_INTERVAL ){
  2443. pdhStatus = PlaiWriteRegistryPlaTime( hkeyQuery, szSampleInterval, &pInfo->Perf.ptSampleInterval );
  2444. }
  2445. if( pInfo->dwMask & PLA_INFO_FLAG_COUNTERS ){
  2446. pdhStatus = PlaiSetItemList( hkeyQuery, &pInfo->Perf.piCounterList );
  2447. }
  2448. break;
  2449. case PLA_ALERT:
  2450. break;
  2451. }
  2452. if( (pInfo->dwMask & PLA_INFO_FLAG_BEGIN) || (pInfo->dwMask & PLA_INFO_FLAG_END) ){
  2453. PDH_TIME_INFO info;
  2454. ZeroMemory( &info, sizeof(PDH_TIME_INFO) );
  2455. if(pInfo->dwMask & PLA_INFO_FLAG_BEGIN){
  2456. info.StartTime = pInfo->ptLogBeginTime.llDateTime;
  2457. }
  2458. if(pInfo->dwMask & PLA_INFO_FLAG_END){
  2459. info.EndTime = pInfo->ptLogEndTime.llDateTime;
  2460. }
  2461. pdhStatus = PlaiSchedule(
  2462. strComputer,
  2463. hkeyQuery,
  2464. PLA_AUTO_MODE_AT,
  2465. &info
  2466. );
  2467. }
  2468. } __except (EXCEPTION_EXECUTE_HANDLER) {
  2469. pdhStatus = PDH_INVALID_ARGUMENT;
  2470. }
  2471. return pdhStatus;
  2472. }
  2473. PDH_FUNCTION
  2474. PdhPlaSetInfoA(
  2475. LPSTR /*strName*/,
  2476. LPSTR /*strComputer*/,
  2477. PPDH_PLA_INFO_A /*pInfo*/
  2478. )
  2479. {
  2480. return PDH_NOT_IMPLEMENTED;
  2481. }
  2482. PDH_FUNCTION
  2483. PdhPlaSetInfoW(
  2484. LPWSTR strName,
  2485. LPWSTR strComputer,
  2486. PPDH_PLA_INFO_W pInfo
  2487. )
  2488. {
  2489. PDH_STATUS pdhStatus;
  2490. PDH_STATUS pdhWarning = ERROR_SUCCESS;
  2491. HKEY hkeyQuery = NULL;
  2492. DWORD dwMask;
  2493. VALIDATE_QUERY( strName );
  2494. LPWSTR szName = PlaiStringDuplicate( strName );
  2495. LPWSTR szComputer = PlaiStringDuplicate( strComputer );
  2496. CHECK_NAMES( szName, szComputer, strComputer );
  2497. if( NULL == pInfo ){
  2498. return PDH_INVALID_ARGUMENT;
  2499. }
  2500. pdhStatus = PdhPlaValidateInfoW( szName, szComputer, pInfo );
  2501. switch( SEVERITY(pdhStatus) ){
  2502. case STATUS_SEVERITY_ERROR:
  2503. goto cleanup;
  2504. case STATUS_SEVERITY_WARNING:
  2505. pdhWarning = pdhStatus;
  2506. pdhStatus = ERROR_SUCCESS;
  2507. }
  2508. __try{
  2509. dwMask = pInfo->dwMask;
  2510. if( dwMask & PLA_INFO_FLAG_USER ){
  2511. pdhStatus = PdhPlaSetRunAs( szName, szComputer, pInfo->strUser, pInfo->strPassword );
  2512. }
  2513. } __except (EXCEPTION_EXECUTE_HANDLER) {
  2514. pdhStatus = PDH_INVALID_ARGUMENT;
  2515. }
  2516. CHECK_STATUS(pdhStatus);
  2517. pdhStatus = PlaiConnectAndLockQuery( szComputer, szName, hkeyQuery );
  2518. if( ERROR_SUCCESS == pdhStatus ){
  2519. if( ERROR_SUCCESS == pdhStatus ){
  2520. pdhStatus = PlaiSetInfo( szComputer, hkeyQuery, pInfo );
  2521. }
  2522. PlaiWriteRegistryLastModified ( hkeyQuery );
  2523. RELEASE_MUTEX(hPdhPlaMutex);
  2524. if( SUCCEEDED( pdhStatus ) ){
  2525. pdhStatus = PlaiSynchronize( szComputer );
  2526. if( SUCCEEDED( pdhStatus ) && ( dwMask & PLA_INFO_FLAG_BEGIN) ){
  2527. PlaiUpdateServiceMode( szComputer );
  2528. }
  2529. }
  2530. }
  2531. cleanup:
  2532. if ( NULL != hkeyQuery ) {
  2533. RegCloseKey ( hkeyQuery );
  2534. }
  2535. if( ERROR_SUCCESS == pdhStatus ){
  2536. pdhStatus = pdhWarning;
  2537. }
  2538. G_FREE( szName );
  2539. G_FREE( szComputer );
  2540. return pdhStatus;
  2541. }
  2542. /*****************************************************************************\
  2543. PdhPlaValidateInfo
  2544. Checks the PDH_PLA_INFO structure for valid fields. Only checks the fields
  2545. specified by the mask. Returns on first invalid field and set the mask
  2546. to the invalid field
  2547. Arguments:
  2548. LPTSTR strName
  2549. Log Name, if NULL checks for valid argument only
  2550. LPTSTR strComputer
  2551. Computer to connect to
  2552. PPDH_PLA_INFO pInfo
  2553. Information block
  2554. Return:
  2555. PDH_INVALID_ARGUMENT
  2556. One of the fields is invalid. Specified by the pInfo->dwMask
  2557. PDH_LOG_TYPE_NOT_FOUND
  2558. There is a mismatch between log type and specified parameters
  2559. PDH_INVALID_ARGUMENT
  2560. Arguments passed are not valid
  2561. ERROR_SUCCESS
  2562. \*****************************************************************************/
  2563. PDH_FUNCTION
  2564. PlaiCheckFile( LPWSTR strFileLocation, BOOL bDirOnly )
  2565. {
  2566. DWORD dwFile;
  2567. DWORD dwStatus = ERROR_SUCCESS;
  2568. LPWSTR strFile = NULL;
  2569. __try{
  2570. if( strFileLocation == NULL ){
  2571. return PDH_INVALID_ARGUMENT;
  2572. }
  2573. dwFile = BYTE_SIZE( strFileLocation ) + sizeof(WCHAR);
  2574. strFile = (LPWSTR)G_ALLOC( dwFile );
  2575. if( NULL == strFile ){
  2576. dwStatus = ERROR_OUTOFMEMORY;
  2577. goto cleanup;
  2578. }
  2579. StringCbCopy( strFile, dwFile, strFileLocation );
  2580. if( bDirOnly ){
  2581. LPWSTR sz = strFile;
  2582. sz += wcslen( strFile );
  2583. while( sz > strFile ){
  2584. if( *sz == L'\\' ){
  2585. *sz = L'\0';
  2586. break;
  2587. }
  2588. sz--;
  2589. }
  2590. }
  2591. dwFile = GetFileAttributes( strFile );
  2592. if( (DWORD)-1 == dwFile ){
  2593. dwStatus = GetLastError();
  2594. }
  2595. if( ERROR_SUCCESS == dwStatus && bDirOnly ){
  2596. if( ! (dwFile & FILE_ATTRIBUTE_DIRECTORY) ){
  2597. dwStatus = ERROR_DIRECTORY;
  2598. }
  2599. }
  2600. } __except (EXCEPTION_EXECUTE_HANDLER) {
  2601. dwStatus = ERROR_INVALID_PARAMETER;
  2602. }
  2603. cleanup:
  2604. G_FREE( strFile );
  2605. return PlaiErrorToPdhStatus( dwStatus );
  2606. }
  2607. PDH_FUNCTION
  2608. PdhPlaValidateInfoA(
  2609. LPSTR /*strName*/,
  2610. LPSTR /*strComputer*/,
  2611. PPDH_PLA_INFO_A /*pInfo*/
  2612. )
  2613. {
  2614. return PDH_NOT_IMPLEMENTED;
  2615. }
  2616. #define VALIDATE_TYPE( type, flag ) \
  2617. if( dwType != PLA_NEW_LOG && dwType != type ){ \
  2618. dwErrorMask |= flag; \
  2619. bTypeMismatch = TRUE; \
  2620. }else{ \
  2621. dwType = type; \
  2622. } \
  2623. #define PROBE_STRING( sz, flag ) \
  2624. __try { \
  2625. if( NULL != sz ){ \
  2626. size_t string_size = wcslen( sz ); \
  2627. }else{ \
  2628. dwErrorMask |= flag; \
  2629. } \
  2630. } __except (EXCEPTION_EXECUTE_HANDLER) { \
  2631. dwErrorMask |= flag; \
  2632. } \
  2633. PDH_FUNCTION
  2634. PdhPlaValidateInfoW(
  2635. LPWSTR strName,
  2636. LPWSTR strComputer,
  2637. PPDH_PLA_INFO_W pInfo
  2638. )
  2639. {
  2640. PDH_STATUS pdhStatus = ERROR_SUCCESS;
  2641. DWORD dwWarningMask = 0;
  2642. DWORD dwErrorMask = 0;
  2643. DWORD dwType = PLA_NEW_LOG;
  2644. DWORD dwFormat = 0;
  2645. PVOID pBuffer = NULL;
  2646. PPDH_PLA_INFO_W pCurrentInfo = NULL;
  2647. BOOL bTypeMismatch = FALSE;
  2648. DWORD dwMask;
  2649. if( NULL == pInfo ){
  2650. return PDH_INVALID_ARGUMENT;
  2651. }
  2652. LPWSTR szName = PlaiStringDuplicate( strName );
  2653. LPWSTR szComputer = PlaiStringDuplicate( strComputer );
  2654. CHECK_NAMES( szName, szComputer, strComputer );
  2655. __try{
  2656. dwMask = pInfo->dwMask;
  2657. } __except (EXCEPTION_EXECUTE_HANDLER) {
  2658. pdhStatus = PDH_INVALID_ARGUMENT;
  2659. }
  2660. CHECK_STATUS(pdhStatus);
  2661. if( szName != NULL ){
  2662. DWORD dwInfoSize = 0;
  2663. if( wcslen( szName ) > PLA_MAX_COLLECTION_NAME ){
  2664. pdhStatus = PDH_PLA_ERROR_NAME_TOO_LONG;
  2665. }
  2666. CHECK_STATUS(pdhStatus);
  2667. pdhStatus = PdhPlaGetInfoW( szName, szComputer, &dwInfoSize, pCurrentInfo );
  2668. if( ERROR_SUCCESS == pdhStatus ){
  2669. pCurrentInfo = (PPDH_PLA_INFO)G_ALLOC(dwInfoSize);
  2670. if( NULL != pCurrentInfo ){
  2671. pCurrentInfo->dwMask = PLA_INFO_FLAG_ALL;
  2672. pdhStatus = PdhPlaGetInfoW( szName, szComputer, &dwInfoSize, pCurrentInfo );
  2673. if( pCurrentInfo->dwMask & PLA_INFO_FLAG_USER ){
  2674. if( !PlaiIsStringEmpty( pCurrentInfo->strUser ) ){
  2675. WCHAR buffer[PLA_ACCOUNT_BUFFER];
  2676. LoadStringW( (HINSTANCE)ThisDLLHandle, IDS_DEFAULT_ACCOUNT, buffer, PLA_ACCOUNT_BUFFER );
  2677. if( ! (dwMask & PLA_INFO_FLAG_USER) && wcscmp( buffer, pCurrentInfo->strUser ) != 0 ){
  2678. pdhStatus = PDH_ACCESS_DENIED;
  2679. }
  2680. }
  2681. }
  2682. if( pCurrentInfo->dwMask & PLA_INFO_FLAG_TYPE ){
  2683. dwType = pCurrentInfo->dwType;
  2684. }
  2685. }
  2686. CHECK_STATUS(pdhStatus);
  2687. }else{
  2688. // collection does not exist yet
  2689. pdhStatus = ERROR_SUCCESS;
  2690. }
  2691. }
  2692. __try{
  2693. if( dwMask & PLA_INFO_FLAG_TYPE ){
  2694. VALIDATE_TYPE( pInfo->dwType, PLA_INFO_FLAG_TYPE );
  2695. switch( pInfo->dwType ){
  2696. case PLA_COUNTER_LOG:
  2697. case PLA_TRACE_LOG:
  2698. case PLA_ALERT:
  2699. break;
  2700. default:
  2701. dwErrorMask |= PLA_INFO_FLAG_TYPE;
  2702. }
  2703. dwType = pInfo->dwType;
  2704. }
  2705. } __except (EXCEPTION_EXECUTE_HANDLER) {
  2706. pdhStatus = PDH_INVALID_ARGUMENT;
  2707. }
  2708. CHECK_STATUS(pdhStatus);
  2709. __try{
  2710. if( dwMask & PLA_INFO_FLAG_FORMAT ){
  2711. dwFormat = pInfo->dwFileFormat;
  2712. switch( dwType ){
  2713. case PLA_COUNTER_LOG:
  2714. switch( (pInfo->dwFileFormat&0x0000FFFF) ){
  2715. case PLA_CSV_FILE:
  2716. case PLA_TSV_FILE:
  2717. case PLA_BIN_FILE:
  2718. case PLA_BIN_CIRC_FILE:
  2719. case PLA_SQL_LOG:
  2720. break;
  2721. default:
  2722. dwErrorMask |= PLA_INFO_FLAG_FORMAT;
  2723. }
  2724. break;
  2725. case PLA_TRACE_LOG:
  2726. switch( (pInfo->dwFileFormat&0x0000FFFF) ){
  2727. // These will get translated to the correct flag
  2728. case PLA_BIN_FILE:
  2729. case PLA_BIN_CIRC_FILE:
  2730. case PLA_CIRC_TRACE_FILE:
  2731. case PLA_SEQ_TRACE_FILE:
  2732. break;
  2733. default:
  2734. dwErrorMask |= PLA_INFO_FLAG_FORMAT;
  2735. }
  2736. break;
  2737. default:
  2738. switch( (pInfo->dwFileFormat&0x0000FFFF) ){
  2739. case PLA_CSV_FILE:
  2740. case PLA_TSV_FILE:
  2741. case PLA_BIN_FILE:
  2742. case PLA_BIN_CIRC_FILE:
  2743. case PLA_CIRC_TRACE_FILE:
  2744. case PLA_SEQ_TRACE_FILE:
  2745. case PLA_SQL_LOG:
  2746. break;
  2747. default:
  2748. dwErrorMask |= PLA_INFO_FLAG_FORMAT;
  2749. }
  2750. break;
  2751. }
  2752. }else if( NULL != pCurrentInfo ){
  2753. if( pCurrentInfo->dwMask & PLA_INFO_FLAG_FORMAT ){
  2754. dwFormat = pCurrentInfo->dwFileFormat;
  2755. }
  2756. }
  2757. } __except (EXCEPTION_EXECUTE_HANDLER) {
  2758. pdhStatus = PDH_INVALID_ARGUMENT;
  2759. }
  2760. CHECK_STATUS(pdhStatus);
  2761. if( dwMask & PLA_INFO_FLAG_COUNTERS ){
  2762. PPDH_COUNTER_PATH_ELEMENTS pdhElements = NULL;
  2763. VALIDATE_TYPE( PLA_COUNTER_LOG, PLA_INFO_FLAG_COUNTERS );
  2764. __try {
  2765. LPWSTR strCounter = pInfo->Perf.piCounterList.strCounters;
  2766. DWORD dwCounters = 0;
  2767. if( NULL == strCounter ){
  2768. dwErrorMask |= PLA_INFO_FLAG_COUNTERS;
  2769. }else{
  2770. pBuffer = G_ALLOC(1024);
  2771. pdhElements = (PPDH_COUNTER_PATH_ELEMENTS)pBuffer;
  2772. if( pdhElements == NULL ){
  2773. pdhStatus = PDH_MEMORY_ALLOCATION_FAILURE;
  2774. }
  2775. CHECK_STATUS(pdhStatus);
  2776. while( *strCounter != L'\0' ){
  2777. DWORD dwSize = (DWORD)G_SIZE(pBuffer);
  2778. ZeroMemory( pdhElements, dwSize );
  2779. pdhStatus = PdhParseCounterPath( strCounter, pdhElements, &dwSize, 0 );
  2780. switch(pdhStatus){
  2781. case PDH_MORE_DATA:
  2782. case PDH_MEMORY_ALLOCATION_FAILURE:
  2783. case PDH_INSUFFICIENT_BUFFER:
  2784. case ERROR_SUCCESS:
  2785. pdhStatus = ERROR_SUCCESS;
  2786. break;
  2787. default:
  2788. pInfo->dwReserved1 = dwCounters;
  2789. dwErrorMask |= PLA_INFO_FLAG_COUNTERS;
  2790. }
  2791. if( ERROR_SUCCESS != pdhStatus ){
  2792. pdhStatus = ERROR_SUCCESS;
  2793. break;
  2794. }
  2795. dwCounters++;
  2796. strCounter += (wcslen(strCounter)+1);
  2797. }
  2798. }
  2799. } __except (EXCEPTION_EXECUTE_HANDLER) {
  2800. dwErrorMask |= PLA_INFO_FLAG_COUNTERS;
  2801. }
  2802. }
  2803. if( dwMask & PLA_INFO_FLAG_PROVIDERS ){
  2804. VALIDATE_TYPE( PLA_TRACE_LOG, PLA_INFO_FLAG_PROVIDERS );
  2805. __try {
  2806. LPWSTR strProvider = pInfo->Trace.piProviderList.strProviders;
  2807. if( NULL == strProvider ){
  2808. dwErrorMask |= PLA_INFO_FLAG_PROVIDERS;
  2809. }else{
  2810. while( *strProvider != L'\0' ){
  2811. strProvider += (wcslen(strProvider)+1);
  2812. }
  2813. }
  2814. } __except (EXCEPTION_EXECUTE_HANDLER) {
  2815. dwErrorMask |= PLA_INFO_FLAG_PROVIDERS;
  2816. }
  2817. }
  2818. if( dwMask & PLA_INFO_FLAG_DEFAULTDIR ){
  2819. __try {
  2820. ULONG dwSize;
  2821. dwSize = wcslen( pInfo->strDefaultDir );
  2822. if( dwSize > MAX_PATH ){
  2823. dwErrorMask |= PLA_INFO_FLAG_DEFAULTDIR;
  2824. }
  2825. } __except (EXCEPTION_EXECUTE_HANDLER) {
  2826. dwErrorMask |= PLA_INFO_FLAG_DEFAULTDIR;
  2827. }
  2828. }
  2829. if( dwMask & PLA_INFO_FLAG_FILENAME ){
  2830. __try {
  2831. ULONG dwSize;
  2832. dwSize = wcslen( pInfo->strBaseFileName );
  2833. if( dwSize > PLA_MAX_COLLECTION_NAME ){
  2834. dwErrorMask |= PLA_INFO_FLAG_FILENAME;
  2835. }
  2836. } __except (EXCEPTION_EXECUTE_HANDLER) {
  2837. dwErrorMask |= PLA_INFO_FLAG_FILENAME;
  2838. }
  2839. }
  2840. if( dwMask & PLA_INFO_CREATE_FILENAME ){
  2841. DWORD dwSize = MAX_PATH;
  2842. WCHAR buffer[MAX_PATH];
  2843. __try {
  2844. DWORD dwOriginalType = 0;
  2845. BOOL bHaveType = (pInfo->dwMask & PLA_INFO_FLAG_TYPE);
  2846. if( ! bHaveType ){
  2847. pInfo->dwMask |= PLA_INFO_FLAG_TYPE;
  2848. dwOriginalType = pInfo->dwType;
  2849. pInfo->dwType = dwType;
  2850. }
  2851. pdhStatus = PdhPlaGetLogFileNameW( szName, szComputer, pInfo, 0, &dwSize, buffer );
  2852. if( !bHaveType ){
  2853. pInfo->dwMask &= ~PLA_INFO_FLAG_TYPE;
  2854. pInfo->dwType = dwOriginalType;
  2855. }
  2856. } __except (EXCEPTION_EXECUTE_HANDLER) {
  2857. dwWarningMask |= PLA_INFO_FLAG_FILENAME;
  2858. }
  2859. switch( pdhStatus ){
  2860. case ERROR_SUCCESS:
  2861. {
  2862. if( PlaiIsLocalComputer( szComputer ) ){
  2863. if( PLA_SQL_LOG != dwFormat ){
  2864. pdhStatus = PlaiCheckFile( buffer, TRUE );
  2865. if( ERROR_SUCCESS != pdhStatus ){
  2866. dwWarningMask |= PLA_INFO_FLAG_FILENAME;
  2867. pdhStatus = ERROR_SUCCESS;
  2868. }
  2869. }
  2870. }
  2871. }
  2872. case PDH_INVALID_ARGUMENT:
  2873. case PDH_PLA_VALIDATION_ERROR:
  2874. case PDH_INSUFFICIENT_BUFFER:
  2875. pdhStatus = ERROR_SUCCESS;
  2876. break;
  2877. case PDH_PLA_ERROR_FILEPATH:
  2878. default:
  2879. dwErrorMask |= PLA_INFO_FLAG_FILENAME;
  2880. pdhStatus = ERROR_SUCCESS;
  2881. }
  2882. }
  2883. __try{
  2884. if( dwMask & PLA_INFO_FLAG_MODE ){
  2885. VALIDATE_TYPE( PLA_TRACE_LOG, PLA_INFO_FLAG_MODE );
  2886. switch( pInfo->Trace.dwMode & 0x0000000F ){
  2887. case EVENT_TRACE_FILE_MODE_NONE:
  2888. case EVENT_TRACE_FILE_MODE_SEQUENTIAL:
  2889. case EVENT_TRACE_FILE_MODE_CIRCULAR:
  2890. case EVENT_TRACE_FILE_MODE_NEWFILE:
  2891. break;
  2892. default:
  2893. dwErrorMask = PLA_INFO_FLAG_MODE;
  2894. }
  2895. if( (pInfo->Trace.dwMode & EVENT_TRACE_REAL_TIME_MODE) &&
  2896. (pInfo->Trace.dwMode & EVENT_TRACE_PRIVATE_LOGGER_MODE ) ){
  2897. dwErrorMask |= PLA_INFO_FLAG_MODE;
  2898. }
  2899. }
  2900. } __except (EXCEPTION_EXECUTE_HANDLER) {
  2901. pdhStatus = PDH_INVALID_ARGUMENT;
  2902. }
  2903. CHECK_STATUS(pdhStatus);
  2904. __try{
  2905. if( dwMask & PLA_INFO_FLAG_REPEAT ){
  2906. LONGLONG llBegin = 0;
  2907. LONGLONG llEnd = 0;
  2908. PPDH_PLA_INFO_W pCheckInfo;
  2909. if( pInfo->ptRepeat.dwAutoMode == PLA_AUTO_MODE_CALENDAR ){
  2910. if( dwMask & PLA_INFO_FLAG_BEGIN ){
  2911. pCheckInfo = pInfo;
  2912. }else{
  2913. pCheckInfo = pCurrentInfo;
  2914. }
  2915. if( NULL != pCheckInfo ){
  2916. if( pCheckInfo->dwMask & PLA_INFO_FLAG_BEGIN ){
  2917. if( pCheckInfo->ptLogBeginTime.dwAutoMode != PLA_AUTO_MODE_AT ){
  2918. dwErrorMask |= PLA_INFO_FLAG_REPEAT;
  2919. }else{
  2920. llBegin = pCheckInfo->ptLogBeginTime.llDateTime;
  2921. }
  2922. }
  2923. }
  2924. if( dwMask & PLA_INFO_FLAG_END ){
  2925. pCheckInfo = pInfo;
  2926. }else{
  2927. pCheckInfo = pCurrentInfo;
  2928. }
  2929. if( NULL != pCheckInfo ){
  2930. if( pCheckInfo->dwMask & PLA_INFO_FLAG_END ){
  2931. if( pCheckInfo->ptLogEndTime.dwAutoMode != PLA_AUTO_MODE_AT ){
  2932. dwErrorMask |= PLA_INFO_FLAG_REPEAT;
  2933. }else{
  2934. llEnd = pCheckInfo->ptLogEndTime.llDateTime;
  2935. }
  2936. }
  2937. }
  2938. if( 0 == llBegin || 0 == llEnd || ((llEnd - llBegin) >= FILE_TICS_PER_DAY) ){
  2939. dwErrorMask |= PLA_INFO_FLAG_REPEAT;
  2940. }
  2941. }
  2942. }
  2943. if( dwMask & PLA_INFO_FLAG_DATASTORE ){
  2944. switch( pInfo->dwDatastoreAttributes & PLA_DATASTORE_APPEND_MASK ){
  2945. case 0:
  2946. case PLA_DATASTORE_APPEND:
  2947. if( (dwType == PLA_TRACE_LOG && dwFormat != PLA_SEQ_TRACE_FILE ) ||
  2948. (dwType == PLA_COUNTER_LOG && dwFormat != PLA_BIN_FILE ) ){
  2949. dwErrorMask |= PLA_INFO_FLAG_DATASTORE;
  2950. }
  2951. break;
  2952. case PLA_DATASTORE_OVERWRITE:
  2953. if( dwFormat == PLA_SQL_LOG ){
  2954. dwErrorMask |= PLA_INFO_FLAG_DATASTORE;
  2955. }
  2956. break;
  2957. default:
  2958. dwErrorMask |= PLA_INFO_FLAG_DATASTORE;
  2959. }
  2960. switch( pInfo->dwDatastoreAttributes & PLA_DATASTORE_SIZE_MASK ){
  2961. case 0:
  2962. case PLA_DATASTORE_SIZE_ONE_RECORD:
  2963. case PLA_DATASTORE_SIZE_MB:
  2964. case PLA_DATASTORE_SIZE_KB:
  2965. break;
  2966. default:
  2967. dwErrorMask |= PLA_INFO_FLAG_DATASTORE;
  2968. }
  2969. }
  2970. } __except (EXCEPTION_EXECUTE_HANDLER) {
  2971. pdhStatus = PDH_INVALID_ARGUMENT;
  2972. }
  2973. CHECK_STATUS(pdhStatus);
  2974. if( dwMask & PLA_INFO_FLAG_SQLNAME ){
  2975. VALIDATE_TYPE( PLA_COUNTER_LOG, PLA_INFO_FLAG_SQLNAME );
  2976. if( dwFormat != 0 && dwFormat != PLA_SQL_LOG ){
  2977. dwErrorMask |= PLA_INFO_FLAG_SQLNAME;
  2978. }else{
  2979. dwFormat = PLA_SQL_LOG;
  2980. }
  2981. PROBE_STRING( pInfo->strSqlName, PLA_INFO_FLAG_SQLNAME );
  2982. }
  2983. if( dwMask & PLA_INFO_FLAG_LOGGERNAME ){
  2984. VALIDATE_TYPE( PLA_TRACE_LOG, PLA_INFO_FLAG_LOGGERNAME );
  2985. PROBE_STRING( pInfo->Trace.strLoggerName, PLA_INFO_FLAG_LOGGERNAME );
  2986. }
  2987. if( dwMask & PLA_INFO_FLAG_USER ){
  2988. PROBE_STRING( pInfo->strUser, PLA_INFO_FLAG_USER );
  2989. __try{
  2990. if( NULL != pInfo->strPassword ){
  2991. size_t size = wcslen( pInfo->strPassword );
  2992. }
  2993. } __except (EXCEPTION_EXECUTE_HANDLER) {
  2994. dwErrorMask |= PLA_INFO_FLAG_USER;
  2995. }
  2996. }
  2997. __try{
  2998. if( dwMask & PLA_INFO_FLAG_INTERVAL ){
  2999. LONGLONG llMS;
  3000. VALIDATE_TYPE( PLA_COUNTER_LOG, PLA_INFO_FLAG_INTERVAL );
  3001. pdhStatus = PlaTimeInfoToMilliSeconds (&pInfo->Perf.ptSampleInterval, &llMS );
  3002. // 45 days in milliseconds = 1000*60*60*24*45 = 0xE7BE2C00
  3003. if( (ERROR_SUCCESS != pdhStatus) || (llMS > (0xE7BE2C00)) || (llMS < 1000) ){
  3004. dwErrorMask |= PLA_INFO_FLAG_INTERVAL;
  3005. pdhStatus = ERROR_SUCCESS;
  3006. }
  3007. }
  3008. if( dwMask & PLA_INFO_FLAG_BUFFERSIZE ){
  3009. VALIDATE_TYPE( PLA_TRACE_LOG, PLA_INFO_FLAG_BUFFERSIZE );
  3010. if( pInfo->Trace.dwBufferSize < 1 || pInfo->Trace.dwBufferSize > 1024 ){
  3011. dwErrorMask |= PLA_INFO_FLAG_BUFFERSIZE;
  3012. }
  3013. }
  3014. if( dwMask & PLA_INFO_FLAG_MINBUFFERS ){
  3015. VALIDATE_TYPE( PLA_TRACE_LOG, PLA_INFO_FLAG_MINBUFFERS );
  3016. if( pInfo->Trace.dwMinimumBuffers < 2 || pInfo->Trace.dwMinimumBuffers > 400 ){
  3017. dwErrorMask |= PLA_INFO_FLAG_MINBUFFERS;
  3018. }
  3019. }
  3020. if( dwMask & PLA_INFO_FLAG_MAXBUFFERS ){
  3021. VALIDATE_TYPE( PLA_TRACE_LOG, PLA_INFO_FLAG_MAXBUFFERS );
  3022. if( pInfo->Trace.dwMaximumBuffers < 2 || pInfo->Trace.dwMaximumBuffers > 400 ){
  3023. dwErrorMask |= PLA_INFO_FLAG_MAXBUFFERS;
  3024. }
  3025. }
  3026. if( dwMask & PLA_INFO_FLAG_FLUSHTIMER ){
  3027. VALIDATE_TYPE( PLA_TRACE_LOG, PLA_INFO_FLAG_FLUSHTIMER );
  3028. if( pInfo->Trace.dwFlushTimer < 1 ){
  3029. dwErrorMask |= PLA_INFO_FLAG_FLUSHTIMER;
  3030. }
  3031. }
  3032. if( dwMask & PLA_INFO_FLAG_MAXLOGSIZE ){
  3033. if( pInfo->dwMaxLogSize != PLA_DISK_MAX_SIZE ){
  3034. if( dwType == PLA_COUNTER_LOG ){
  3035. if( !( pInfo->dwMaxLogSize >= 1 && pInfo->dwMaxLogSize < 0x00000400) ){
  3036. dwErrorMask = PLA_INFO_FLAG_MAXLOGSIZE;
  3037. }
  3038. }else{
  3039. if( !(pInfo->dwMaxLogSize >=1 && pInfo->dwMaxLogSize < 0xFFFFFFFF) ){
  3040. dwErrorMask |= PLA_INFO_FLAG_MAXLOGSIZE;
  3041. }
  3042. }
  3043. }
  3044. }
  3045. if( dwMask & PLA_INFO_FLAG_AUTOFORMAT ){
  3046. switch( pInfo->dwAutoNameFormat ){
  3047. case PLA_SLF_NAME_NONE:
  3048. case PLA_SLF_NAME_MMDDHH:
  3049. case PLA_SLF_NAME_NNNNNN:
  3050. case PLA_SLF_NAME_YYYYDDD:
  3051. case PLA_SLF_NAME_YYYYMM:
  3052. case PLA_SLF_NAME_YYYYMMDD:
  3053. case PLA_SLF_NAME_YYYYMMDDHH:
  3054. case PLA_SLF_NAME_MMDDHHMM:
  3055. break;
  3056. default:
  3057. dwErrorMask |= PLA_INFO_FLAG_AUTOFORMAT;
  3058. }
  3059. }
  3060. } __except (EXCEPTION_EXECUTE_HANDLER) {
  3061. pdhStatus = PDH_INVALID_ARGUMENT;
  3062. }
  3063. CHECK_STATUS(pdhStatus);
  3064. if( dwMask & PLA_INFO_FLAG_RUNCOMMAND ){
  3065. PROBE_STRING( pInfo->strCommandFileName, PLA_INFO_FLAG_RUNCOMMAND );
  3066. __try {
  3067. if( NULL == szComputer ){
  3068. if( PLA_SQL_LOG != dwFormat ){
  3069. pdhStatus = PlaiCheckFile( pInfo->strCommandFileName, FALSE );
  3070. if( ERROR_SUCCESS != pdhStatus ){
  3071. dwWarningMask |= PLA_INFO_FLAG_RUNCOMMAND;
  3072. pdhStatus = ERROR_SUCCESS;
  3073. }
  3074. }
  3075. }
  3076. } __except (EXCEPTION_EXECUTE_HANDLER) {
  3077. dwErrorMask = PLA_INFO_FLAG_RUNCOMMAND;
  3078. }
  3079. }
  3080. cleanup:
  3081. G_FREE( pBuffer );
  3082. G_FREE( pCurrentInfo );
  3083. G_FREE( szName );
  3084. G_FREE( szComputer );
  3085. if( 0 != dwWarningMask ){
  3086. pInfo->dwReserved2 = dwWarningMask;
  3087. pdhStatus = PDH_PLA_VALIDATION_WARNING;
  3088. }
  3089. if( 0 != dwErrorMask ){
  3090. pInfo->dwMask = dwErrorMask;
  3091. if( dwErrorMask & PLA_INFO_FLAG_FILENAME ){
  3092. pdhStatus = PDH_PLA_ERROR_FILEPATH;
  3093. }else{
  3094. pdhStatus = PDH_PLA_VALIDATION_ERROR;
  3095. }
  3096. }
  3097. if( TRUE == bTypeMismatch ){
  3098. pdhStatus = PDH_PLA_ERROR_TYPE_MISMATCH;
  3099. }
  3100. return pdhStatus;
  3101. }
  3102. /*****************************************************************************\
  3103. PdhiPlaRunAs
  3104. Authenticate as saved user
  3105. Arguments:
  3106. LPTSTR strKey
  3107. Guid string
  3108. Return:
  3109. PDH_INVALID_ARGUMENT
  3110. The query does not exist
  3111. ERROR_SUCCESS
  3112. \*****************************************************************************/
  3113. PDH_FUNCTION
  3114. PdhiPlaRunAs(
  3115. LPWSTR strName,
  3116. LPWSTR strComputer,
  3117. HANDLE* hToken
  3118. )
  3119. {
  3120. PDH_STATUS pdhStatus;
  3121. LPWSTR strKey = NULL;
  3122. LPWSTR strRunAs = NULL;
  3123. DWORD dwKeySize = 0;
  3124. DWORD dwSize = 0;
  3125. HKEY hkeyQuery = NULL;
  3126. HANDLE hUserToken = NULL;
  3127. VALIDATE_QUERY( strName );
  3128. LPWSTR szName = PlaiStringDuplicate( strName );
  3129. LPWSTR szComputer = PlaiStringDuplicate( strComputer );
  3130. CHECK_NAMES( szName, szComputer, strComputer );
  3131. if( hToken != NULL ){
  3132. __try{
  3133. *hToken = NULL;
  3134. } __except (EXCEPTION_EXECUTE_HANDLER) {
  3135. pdhStatus = PDH_INVALID_ARGUMENT;
  3136. }
  3137. }
  3138. pdhStatus = PlaiConnectAndLockQuery( szComputer, szName, hkeyQuery );
  3139. if( ERROR_SUCCESS == pdhStatus ){
  3140. pdhStatus = PlaiReadRegistryStringValue( hkeyQuery, szRunAs, 0, &strRunAs, &dwSize );
  3141. if( PDH_PLA_COLLECTION_NOT_FOUND == pdhStatus || PlaiIsStringEmpty(strRunAs) ){
  3142. // The key is missing so return success
  3143. pdhStatus = ERROR_SUCCESS;
  3144. goto cleanup;
  3145. }
  3146. if( ERROR_SUCCESS == pdhStatus ){
  3147. BOOL bResult;
  3148. DATA_BLOB crypt;
  3149. DATA_BLOB data;
  3150. LPWSTR strUser = NULL;
  3151. LPWSTR strDomain = NULL;
  3152. LPWSTR strPassword = NULL;
  3153. LPWSTR strScan = strRunAs;
  3154. strUser = strScan;
  3155. while( *strScan != L'\0' ){
  3156. if( *strScan == L'\\' ){
  3157. *strScan = L'\0';
  3158. strScan++;
  3159. strDomain = strUser;
  3160. strUser = strScan;
  3161. break;
  3162. }
  3163. strScan++;
  3164. }
  3165. pdhStatus = PlaiReadRegistryStringValue( hkeyQuery, szKey, READ_REG_BLOB, &strKey, &dwKeySize );
  3166. if( ERROR_SUCCESS == pdhStatus && !PlaiIsStringEmpty( strKey ) ){
  3167. HANDLE hNetToken = NULL;
  3168. crypt.cbData = dwKeySize;
  3169. crypt.pbData = (BYTE*)strKey;
  3170. bResult= LogonUserW(
  3171. L"NetworkService",
  3172. L"NT AUTHORITY",
  3173. L"",
  3174. LOGON32_LOGON_SERVICE,
  3175. LOGON32_PROVIDER_WINNT50,
  3176. &hNetToken
  3177. );
  3178. if( bResult == TRUE ){
  3179. bResult = ImpersonateLoggedOnUser( hNetToken );
  3180. }
  3181. if( bResult != TRUE ){
  3182. pdhStatus = PlaiErrorToPdhStatus( GetLastError() );
  3183. }
  3184. ZeroMemory( &data, sizeof(DATA_BLOB) );
  3185. bResult = CryptUnprotectData( &crypt, NULL, NULL, NULL, NULL, CRYPTPROTECT_UI_FORBIDDEN, &data );
  3186. if( bResult == FALSE ){
  3187. pdhStatus = PlaiErrorToPdhStatus( GetLastError() );
  3188. }else{
  3189. strPassword = (LPWSTR)data.pbData;
  3190. pdhStatus = ERROR_SUCCESS;
  3191. }
  3192. bResult = RevertToSelf();
  3193. if( NULL != hNetToken ){
  3194. CloseHandle(hNetToken);
  3195. }
  3196. }else{
  3197. strPassword = _T("");
  3198. }
  3199. if( ERROR_SUCCESS == pdhStatus ){
  3200. bResult= LogonUserW(
  3201. strUser,
  3202. strDomain,
  3203. strPassword,
  3204. LOGON32_LOGON_NETWORK_CLEARTEXT,
  3205. LOGON32_PROVIDER_DEFAULT,
  3206. &hUserToken
  3207. );
  3208. if( bResult == TRUE ){
  3209. bResult = ImpersonateLoggedOnUser( hUserToken );
  3210. CloseHandle( hUserToken );
  3211. if( bResult == TRUE ){
  3212. bResult= LogonUserW(
  3213. strUser,
  3214. strDomain,
  3215. strPassword,
  3216. LOGON32_LOGON_INTERACTIVE,
  3217. LOGON32_PROVIDER_DEFAULT,
  3218. &hUserToken
  3219. );
  3220. if( bResult && hToken != NULL ){
  3221. __try{
  3222. *hToken = hUserToken;
  3223. } __except (EXCEPTION_EXECUTE_HANDLER) {
  3224. pdhStatus = PDH_INVALID_ARGUMENT;
  3225. }
  3226. }
  3227. }
  3228. }
  3229. if( bResult == FALSE ){
  3230. pdhStatus = PlaiErrorToPdhStatus( GetLastError() );
  3231. }
  3232. }
  3233. if( data.cbData > 0 ){
  3234. ZeroMemory( data.pbData, data.cbData );
  3235. LocalFree( data.pbData );
  3236. }
  3237. }
  3238. }
  3239. cleanup:
  3240. RELEASE_MUTEX(hPdhPlaMutex);
  3241. G_FREE( szName );
  3242. G_FREE( szComputer );
  3243. G_FREE( strRunAs );
  3244. G_FREE( strKey );
  3245. if ( NULL != hkeyQuery ) {
  3246. RegCloseKey ( hkeyQuery );
  3247. }
  3248. return pdhStatus;
  3249. }
  3250. /*****************************************************************************\
  3251. PdhPlaSetRunAs
  3252. Set the security for to run as when the log is active
  3253. Arguments:
  3254. LPTSTR strName
  3255. Log Name
  3256. LPTSTR strComputer
  3257. Computer to connect to
  3258. LPTSTR strUser
  3259. User to run as
  3260. LPTSTR strPassword
  3261. Users password
  3262. Return:
  3263. PDH_INVALID_ARGUMENT
  3264. The query does not exist
  3265. ERROR_SUCCESS
  3266. \*****************************************************************************/
  3267. BOOL
  3268. PlaiIsNetworkService( BOOL bLogon )
  3269. {
  3270. //
  3271. // If bLogon is TRUE this function will try to Impersonate the
  3272. // NetworkService if you is not already running that way.
  3273. // RevertToSelf() should be called after you are done being the
  3274. // NetworkService
  3275. //
  3276. DWORD dwStatus = ERROR_SUCCESS;
  3277. BOOL bResult;
  3278. HKEY hkeyQuery = NULL;
  3279. HANDLE hProcess;
  3280. PSID NetworkService = NULL;
  3281. SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
  3282. HANDLE hToken = NULL;
  3283. DWORD dwSize;
  3284. PTOKEN_OWNER pOwnerInfo = NULL;
  3285. bResult = OpenProcessToken( GetCurrentProcess(), TOKEN_QUERY, &hToken );
  3286. if( bResult ){
  3287. bResult = GetTokenInformation( hToken, TokenOwner, NULL, 0, &dwSize );
  3288. dwStatus = GetLastError();
  3289. if( ERROR_INSUFFICIENT_BUFFER == dwStatus ){
  3290. pOwnerInfo = (PTOKEN_OWNER)G_ALLOC(dwSize);
  3291. if( NULL == pOwnerInfo ) {
  3292. bResult = FALSE;
  3293. goto cleanup;
  3294. }
  3295. bResult = GetTokenInformation(
  3296. hToken,
  3297. TokenOwner,
  3298. pOwnerInfo,
  3299. dwSize,
  3300. &dwSize
  3301. );
  3302. if( bResult ) {
  3303. bResult = AllocateAndInitializeSid(
  3304. &NtAuthority,
  3305. 1,
  3306. SECURITY_NETWORK_SERVICE_RID,
  3307. 0,0,0,0,0,0,0,
  3308. &NetworkService
  3309. );
  3310. }
  3311. }else{
  3312. bResult = FALSE;
  3313. goto cleanup;
  3314. }
  3315. }
  3316. if( bResult ){
  3317. bResult = EqualSid( NetworkService, pOwnerInfo->Owner );
  3318. }
  3319. if( (!bResult) && bLogon ){
  3320. HANDLE hNetwork = NULL;
  3321. bResult= LogonUserW(
  3322. L"NetworkService",
  3323. L"NT AUTHORITY",
  3324. L"",
  3325. LOGON32_LOGON_SERVICE,
  3326. LOGON32_PROVIDER_WINNT50,
  3327. &hNetwork
  3328. );
  3329. if( bResult ){
  3330. bResult = ImpersonateLoggedOnUser( hNetwork );
  3331. }
  3332. if( INVALID_HANDLE_VALUE != hNetwork ){
  3333. CloseHandle( hNetwork );
  3334. }
  3335. }
  3336. cleanup:
  3337. G_FREE( pOwnerInfo );
  3338. if( INVALID_HANDLE_VALUE != hToken ){
  3339. CloseHandle( hToken );
  3340. }
  3341. if( NULL != NetworkService){
  3342. FreeSid(NetworkService);
  3343. }
  3344. return bResult;
  3345. }
  3346. PDH_FUNCTION
  3347. PlaiSetRunAs(
  3348. HKEY hkeyQuery,
  3349. LPWSTR strUser,
  3350. LPWSTR strPassword
  3351. )
  3352. {
  3353. PDH_STATUS pdhStatus = ERROR_SUCCESS;
  3354. BOOL bResult = FALSE;
  3355. WCHAR buffer[PLA_ACCOUNT_BUFFER];
  3356. if( LoadStringW( (HINSTANCE)ThisDLLHandle, IDS_DEFAULT_ACCOUNT, buffer, PLA_ACCOUNT_BUFFER ) ){
  3357. bResult = ( wcscmp( buffer, strUser ) == 0 );
  3358. }
  3359. if( strPassword == NULL || bResult ){
  3360. pdhStatus = PlaiWriteRegistryStringValue( hkeyQuery, szKey, REG_SZ, NULL, 0 );
  3361. if( bResult ){
  3362. pdhStatus = PlaiWriteRegistryStringValue( hkeyQuery, szRunAs, REG_SZ, NULL, 0 );
  3363. }
  3364. }else{
  3365. DATA_BLOB data;
  3366. DATA_BLOB crypt;
  3367. HANDLE hToken = NULL;
  3368. bResult = PlaiIsNetworkService(TRUE);
  3369. if( bResult != TRUE ){
  3370. pdhStatus = PlaiErrorToPdhStatus( GetLastError() );
  3371. }
  3372. if( ERROR_SUCCESS == pdhStatus ){
  3373. data.cbData = BYTE_SIZE( strPassword ) + (DWORD)sizeof(UNICODE_NULL);
  3374. data.pbData = (BYTE*)strPassword;
  3375. bResult = CryptProtectData(
  3376. &data,
  3377. NULL, NULL, NULL, 0,
  3378. CRYPTPROTECT_UI_FORBIDDEN,
  3379. &crypt
  3380. );
  3381. if( bResult == TRUE ){
  3382. DWORD dwStatus = RegSetValueEx( hkeyQuery, szKey, 0, REG_BINARY, crypt.pbData, crypt.cbData );
  3383. pdhStatus = PlaiErrorToPdhStatus( dwStatus );
  3384. if( crypt.pbData ){
  3385. LocalFree(crypt.pbData);
  3386. }
  3387. }else{
  3388. pdhStatus = PlaiErrorToPdhStatus( GetLastError() );
  3389. }
  3390. RevertToSelf();
  3391. }
  3392. }
  3393. if( ERROR_SUCCESS == pdhStatus ){
  3394. pdhStatus = PlaiWriteRegistryStringValue( hkeyQuery, szRunAs, REG_SZ, strUser, 0 );
  3395. }
  3396. return pdhStatus;
  3397. }
  3398. PDH_FUNCTION
  3399. PdhiPlaSetRunAs(
  3400. LPWSTR strName,
  3401. LPWSTR strComputer,
  3402. LPWSTR strUser,
  3403. LPWSTR strPassword
  3404. )
  3405. {
  3406. //
  3407. // Only make this call if you are sure you have no better chance
  3408. // of being logged on as the NetworkService account. If you are
  3409. // not the NetworkService and can not log on as the NetworkService
  3410. // this call will fail.
  3411. //
  3412. PDH_STATUS pdhStatus;
  3413. HKEY hkeyQuery = NULL;
  3414. VALIDATE_QUERY( strName );
  3415. LPWSTR szName = PlaiStringDuplicate( strName );
  3416. LPWSTR szComputer = PlaiStringDuplicate( strComputer );
  3417. CHECK_NAMES( szName, szComputer, strComputer );
  3418. LPWSTR szUser = PlaiStringDuplicate( strUser );
  3419. LPWSTR szPassword = PlaiStringDuplicate( strPassword );
  3420. pdhStatus = PlaiConnectAndLockQuery( szComputer, szName, hkeyQuery );
  3421. if( ERROR_SUCCESS == pdhStatus ){
  3422. pdhStatus = PlaiSetRunAs( hkeyQuery, szUser, szPassword );
  3423. RELEASE_MUTEX(hPdhPlaMutex);
  3424. }
  3425. if ( NULL != hkeyQuery ) {
  3426. RegCloseKey ( hkeyQuery );
  3427. }
  3428. if( NULL != szPassword ){
  3429. ZeroMemory( szPassword, wcslen(szPassword)*sizeof(WCHAR) );
  3430. }
  3431. G_FREE( szUser );
  3432. G_FREE( szPassword );
  3433. cleanup:
  3434. G_FREE( szName );
  3435. G_FREE( szComputer );
  3436. return pdhStatus;
  3437. }
  3438. PDH_FUNCTION
  3439. PdhPlaSetRunAsA(
  3440. LPSTR /*strName*/,
  3441. LPSTR /*strComputer*/,
  3442. LPSTR /*strUser*/,
  3443. LPSTR /*strPassword*/
  3444. )
  3445. {
  3446. return PDH_NOT_IMPLEMENTED;
  3447. }
  3448. PDH_FUNCTION
  3449. PdhPlaSetRunAsW(
  3450. LPWSTR strName,
  3451. LPWSTR strComputer,
  3452. LPWSTR strUser,
  3453. LPWSTR strPassword
  3454. )
  3455. {
  3456. PDH_STATUS pdhStatus = ERROR_SUCCESS;
  3457. BOOL bResult;
  3458. VALIDATE_QUERY( strName );
  3459. LPWSTR szName = PlaiStringDuplicate( strName );
  3460. LPWSTR szComputer = PlaiStringDuplicate( strComputer );
  3461. CHECK_NAMES( szName, szComputer, strComputer );
  3462. bResult = PlaiIsNetworkService(TRUE);
  3463. if( bResult ){
  3464. bResult = PlaiIsLocalComputer( szComputer );
  3465. }
  3466. if( bResult ){
  3467. pdhStatus = PdhiPlaSetRunAs( szName, szComputer, strUser, strPassword );
  3468. RevertToSelf();
  3469. }else{
  3470. pdhStatus = PdhPlaWbemSetRunAs( szName, szComputer, strUser, strPassword );
  3471. }
  3472. cleanup:
  3473. G_FREE( szName );
  3474. G_FREE( szComputer );
  3475. return pdhStatus;
  3476. }
  3477. /*****************************************************************************\
  3478. PdhPlaEnumCollections
  3479. Set the security for to run as when the log is active
  3480. Arguments:
  3481. LPTSTR strComputer
  3482. Computer to connect to
  3483. LPDWORD pcchBufferSize
  3484. [IN] Size of buffer in TCHAR's pointed to by mszCollections.
  3485. [OUT] Size required or number of characters written.
  3486. LPTSTR mszCollections
  3487. Multistring of the existing collections.
  3488. Return:
  3489. ERROR_SUCCESS
  3490. \*****************************************************************************/
  3491. PDH_FUNCTION
  3492. PdhPlaEnumCollectionsA(
  3493. LPSTR /*strComputer*/,
  3494. LPDWORD /*pcchBufferSize*/,
  3495. LPSTR /*mszCollections*/
  3496. )
  3497. {
  3498. return PDH_NOT_IMPLEMENTED;
  3499. }
  3500. PDH_FUNCTION
  3501. PdhPlaEnumCollectionsW(
  3502. LPWSTR strComputer,
  3503. LPDWORD pcchBufferSize, /* Character Count */
  3504. LPWSTR mszCollections
  3505. )
  3506. {
  3507. DWORD dwStatus;
  3508. PDH_STATUS pdhStatus = ERROR_SUCCESS;
  3509. HKEY hkeyQueries = NULL;
  3510. DWORD cchTotalLength = 0;
  3511. DWORD cchBufferLeft = 0;
  3512. DWORD nCollections = 0;
  3513. DWORD nMaxSubKeyLength = 0;
  3514. DWORD dwSize;
  3515. LPWSTR strCollection;
  3516. LPWSTR str;
  3517. __try{
  3518. if( mszCollections != NULL && pcchBufferSize > 0 ){
  3519. ZeroMemory( mszCollections, *pcchBufferSize * sizeof(WCHAR) );
  3520. str = mszCollections;
  3521. cchBufferLeft = *pcchBufferSize;
  3522. }
  3523. } __except (EXCEPTION_EXECUTE_HANDLER) {
  3524. pdhStatus = PDH_INVALID_ARGUMENT;
  3525. }
  3526. CHECK_STATUS( pdhStatus );
  3527. LPWSTR szComputer = PlaiStringDuplicate( strComputer );
  3528. if( NULL == szComputer && NULL != strComputer ){
  3529. pdhStatus = PDH_MEMORY_ALLOCATION_FAILURE;
  3530. goto cleanup;
  3531. }
  3532. dwStatus = WAIT_FOR_AND_LOCK_MUTEX( hPdhPlaMutex );
  3533. if( dwStatus != ERROR_SUCCESS && dwStatus != WAIT_ABANDONED ){
  3534. return PlaiErrorToPdhStatus( dwStatus );
  3535. }
  3536. pdhStatus = PlaiConnectToRegistry( szComputer, hkeyQueries, TRUE, FALSE );
  3537. CHECK_STATUS( pdhStatus );
  3538. dwStatus = RegQueryInfoKey(
  3539. hkeyQueries,
  3540. NULL,
  3541. NULL,
  3542. NULL,
  3543. &nCollections,
  3544. &nMaxSubKeyLength,
  3545. NULL,
  3546. NULL,
  3547. NULL,
  3548. NULL,
  3549. NULL,
  3550. NULL
  3551. );
  3552. CHECK_STATUS( dwStatus );
  3553. dwSize = (sizeof(WCHAR)*(nMaxSubKeyLength+1));
  3554. strCollection = (LPWSTR)G_ALLOC( dwSize );
  3555. if( strCollection ){
  3556. for( ULONG i = 0; i<nCollections && ERROR_SUCCESS == dwStatus; i++ ){
  3557. LPWSTR strQueryName = NULL;
  3558. DWORD dwQueryName = 0;
  3559. dwStatus = RegEnumKey( hkeyQueries, i, strCollection, dwSize );
  3560. if( ERROR_SUCCESS == dwStatus ){
  3561. HKEY hkeyQuery = NULL;
  3562. dwStatus = RegOpenKeyExW (
  3563. hkeyQueries,
  3564. strCollection,
  3565. 0,
  3566. KEY_READ,
  3567. &hkeyQuery
  3568. );
  3569. if( ERROR_SUCCESS == dwStatus ){
  3570. DWORD cchNameSize = 0;
  3571. LPWSTR szName = NULL;
  3572. pdhStatus = PlaiReadRegistryStringValue(
  3573. hkeyQuery,
  3574. szCollection,
  3575. READ_REG_MUI,
  3576. &strQueryName,
  3577. &dwQueryName
  3578. );
  3579. __try{
  3580. if( pdhStatus == ERROR_SUCCESS &&
  3581. strQueryName != NULL &&
  3582. dwQueryName > sizeof(WCHAR) ){
  3583. cchNameSize = wcslen( strQueryName ) + 1;
  3584. szName = strQueryName;
  3585. }else{
  3586. pdhStatus = ERROR_SUCCESS;
  3587. cchNameSize = wcslen( strCollection ) + 1;
  3588. szName = strCollection;
  3589. }
  3590. cchTotalLength += cchNameSize;
  3591. if( NULL != mszCollections && cchTotalLength < *pcchBufferSize ){
  3592. StringCchCopy( str, cchBufferLeft, szName );
  3593. cchBufferLeft -= cchNameSize;
  3594. str += ( wcslen(str) + 1 );
  3595. }
  3596. } __except (EXCEPTION_EXECUTE_HANDLER) {
  3597. pdhStatus = PDH_INVALID_ARGUMENT;
  3598. }
  3599. G_FREE( strQueryName );
  3600. }
  3601. if( NULL != hkeyQuery ){
  3602. RegCloseKey( hkeyQuery );
  3603. }
  3604. }
  3605. }
  3606. G_FREE( strCollection );
  3607. __try{
  3608. if( ERROR_SUCCESS == dwStatus ){
  3609. if( (cchTotalLength + 1) > *pcchBufferSize ){
  3610. pdhStatus = PDH_INSUFFICIENT_BUFFER;
  3611. }
  3612. *pcchBufferSize = cchTotalLength + 1;
  3613. }
  3614. } __except (EXCEPTION_EXECUTE_HANDLER) {
  3615. pdhStatus = PDH_INVALID_ARGUMENT;
  3616. }
  3617. }else{
  3618. dwStatus = ERROR_OUTOFMEMORY;
  3619. }
  3620. cleanup:
  3621. RELEASE_MUTEX( hPdhPlaMutex );
  3622. if ( NULL != hkeyQueries ) {
  3623. RegCloseKey ( hkeyQueries );
  3624. }
  3625. G_FREE( szComputer );
  3626. if( ERROR_SUCCESS == pdhStatus ){
  3627. return PlaiErrorToPdhStatus( dwStatus );
  3628. }else{
  3629. return pdhStatus;
  3630. }
  3631. }
  3632. /*****************************************************************************\
  3633. PlaTimeInfoToMilliSeconds
  3634. Converts the PLA_TIME_INFO structure to ms in a LONGLONG
  3635. Arguments:
  3636. PLA_TIME_INFO* pTimeInfo
  3637. LONGLONG* pllmsecs
  3638. Return:
  3639. PDH_INVALID_ARGUMENT
  3640. The pTimeInfo->wDataType is not PLA_TT_DTYPE_UNITS
  3641. ERROR_SUCCESS
  3642. \*****************************************************************************/
  3643. PDH_FUNCTION
  3644. PlaTimeInfoToMilliSeconds (
  3645. PLA_TIME_INFO* pTimeInfo,
  3646. LONGLONG* pllmsecs)
  3647. {
  3648. PDH_STATUS pdhStatus = ERROR_SUCCESS;
  3649. __try{
  3650. if( PLA_TT_DTYPE_UNITS != pTimeInfo->wDataType ){
  3651. pdhStatus = PDH_INVALID_ARGUMENT;
  3652. }else{
  3653. switch (pTimeInfo->dwUnitType) {
  3654. case PLA_TT_UTYPE_SECONDS:
  3655. *pllmsecs = pTimeInfo->dwValue;
  3656. break;
  3657. case PLA_TT_UTYPE_MINUTES:
  3658. *pllmsecs = pTimeInfo->dwValue * PLA_SECONDS_IN_MINUTE;
  3659. break;
  3660. case PLA_TT_UTYPE_HOURS:
  3661. *pllmsecs = pTimeInfo->dwValue * PLA_SECONDS_IN_HOUR;
  3662. break;
  3663. case PLA_TT_UTYPE_DAYS:
  3664. *pllmsecs = pTimeInfo->dwValue * PLA_SECONDS_IN_DAY;
  3665. break;
  3666. default:
  3667. *pllmsecs = 0;
  3668. }
  3669. *pllmsecs *= 1000;
  3670. }
  3671. } __except (EXCEPTION_EXECUTE_HANDLER) {
  3672. pdhStatus = PDH_INVALID_ARGUMENT;
  3673. }
  3674. return pdhStatus;
  3675. }
  3676. /*****************************************************************************\
  3677. PdhiPlaFormatBlanks
  3678. Replaces blanks with the character specified by:
  3679. HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SysmonLog\Replace Blanks
  3680. Arguments:
  3681. Return:
  3682. ERROR_SUCCESS
  3683. \*****************************************************************************/
  3684. PDH_FUNCTION
  3685. PdhiPlaFormatBlanksA( LPSTR strComputer, LPSTR strFormat )
  3686. {
  3687. return PDH_NOT_IMPLEMENTED;
  3688. }
  3689. PDH_FUNCTION
  3690. PdhiPlaFormatBlanksW( LPWSTR strComputer, LPWSTR strFormat )
  3691. {
  3692. HKEY hkey = NULL;
  3693. LPWSTR strScan = strFormat;
  3694. PDH_STATUS pdhStatus;
  3695. LPWSTR strBlank = NULL;
  3696. DWORD dwSize = 0;
  3697. if( PlaiIsStringEmpty( strFormat ) ){
  3698. return ERROR_SUCCESS;
  3699. }
  3700. pdhStatus = PlaiConnectToRegistry( strComputer, hkey, FALSE );
  3701. CHECK_STATUS( pdhStatus );
  3702. pdhStatus = PlaiReadRegistryStringValue(
  3703. hkey,
  3704. L"Replace Blanks",
  3705. READ_REG_MUI,
  3706. &strBlank,
  3707. &dwSize
  3708. );
  3709. if( ERROR_SUCCESS != pdhStatus || PlaiIsStringEmpty( strBlank ) ){
  3710. pdhStatus = ERROR_SUCCESS;
  3711. goto cleanup;
  3712. }
  3713. __try {
  3714. while( *strScan != L'\0' ){
  3715. if( *strScan == L' ' ){
  3716. *strScan = *strBlank;
  3717. }
  3718. strScan++;
  3719. }
  3720. } __except (EXCEPTION_EXECUTE_HANDLER) {
  3721. pdhStatus = PDH_INVALID_ARGUMENT;
  3722. }
  3723. cleanup:
  3724. G_FREE( strBlank );
  3725. if( hkey != NULL ){
  3726. RegCloseKey ( hkey );
  3727. }
  3728. return pdhStatus;
  3729. }
  3730. /*****************************************************************************\
  3731. PdhPlaGetLogFileName
  3732. Arguments:
  3733. Return:
  3734. PDH_PLA_ERROR_FILEPATH
  3735. Not all needed fields we set in the passed info block
  3736. ERROR_INVALID_NAME
  3737. The final path contains invalid characters
  3738. ERROR_SUCCESS
  3739. \*****************************************************************************/
  3740. PDH_FUNCTION
  3741. PlaiScanForInvalidChar( LPWSTR strScan )
  3742. {
  3743. LPWSTR strCheck = strScan;
  3744. if( PlaiIsStringEmpty( strScan ) ){
  3745. return PDH_INVALID_ARGUMENT;
  3746. }
  3747. if( PlaiIsCharWhitespace( *strCheck ) ){
  3748. return PDH_PLA_ERROR_FILEPATH;
  3749. }
  3750. if( PlaiIsCharWhitespace( strCheck[wcslen(strCheck)-1] ) ){
  3751. return PDH_PLA_ERROR_FILEPATH;
  3752. }
  3753. while( *strCheck != L'\0' ){
  3754. switch( *strCheck ){
  3755. case L'?':
  3756. case L'*':
  3757. case L'|':
  3758. case L'<':
  3759. case L'>':
  3760. case L'/':
  3761. case L'\"':
  3762. return PDH_PLA_ERROR_FILEPATH;
  3763. case L'\\':
  3764. if( strCheck > strScan ){
  3765. if( PlaiIsCharWhitespace( *((WCHAR*)strCheck-1)) ){
  3766. return PDH_PLA_ERROR_FILEPATH;
  3767. }
  3768. }
  3769. }
  3770. strCheck++;
  3771. }
  3772. return ERROR_SUCCESS;
  3773. }
  3774. long PlaiJulianDate( SYSTEMTIME st )
  3775. {
  3776. long day = 0;
  3777. BOOL bLeap = FALSE;
  3778. static int cDaysInMonth[] =
  3779. { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
  3780. for( int i = 0; i < st.wMonth - 1 && i<12; i++ ){
  3781. day += cDaysInMonth[i];
  3782. }
  3783. day += st.wDay;
  3784. if( st.wYear % 400 == 0){
  3785. bLeap = TRUE;
  3786. }else if( st.wYear % 100 == 0){
  3787. bLeap = FALSE;
  3788. }else if( st.wYear % 4 ){
  3789. bLeap = TRUE;
  3790. }
  3791. if( st.wMonth > 2 && bLeap ){
  3792. day++;
  3793. }
  3794. return day;
  3795. }
  3796. PDH_FUNCTION
  3797. PlaiGetLogFileName(
  3798. DWORD dwFlags,
  3799. PPDH_PLA_INFO_W pInfo,
  3800. LPDWORD pcchBufferSize,
  3801. LPWSTR strFileName
  3802. )
  3803. {
  3804. PDH_STATUS pdhStatus = ERROR_SUCCESS;
  3805. DWORD cchExpanded = 0;
  3806. WCHAR buffer[128];
  3807. LPWSTR strExpand;
  3808. DWORD cchSize;
  3809. DWORD dwSwitch;
  3810. SYSTEMTIME st;
  3811. GetLocalTime (&st);
  3812. LPWSTR strWhack = L"\\";
  3813. LPWSTR strUnder = L"_";
  3814. DWORD cchTotalSize = 0;
  3815. LPWSTR strLocalFileName = NULL;
  3816. LPWSTR strBaseFileName = NULL;
  3817. LPWSTR strDefaultDir = NULL;
  3818. LPWSTR strSQL = L"";
  3819. TCHAR strBuffer[MAX_PATH];
  3820. if( pInfo->dwMask & PLA_INFO_FLAG_FILENAME ){
  3821. strBaseFileName = pInfo->strBaseFileName;
  3822. }
  3823. if( pInfo->dwMask & PLA_INFO_FLAG_DEFAULTDIR ){
  3824. strDefaultDir = pInfo->strDefaultDir;
  3825. }
  3826. if( (pInfo->dwMask & PLA_INFO_FLAG_FORMAT) &&
  3827. pInfo->dwFileFormat == PLA_SQL_LOG ){
  3828. if( (pInfo->dwMask & PLA_INFO_FLAG_SQLNAME) &&
  3829. ! PlaiIsStringEmpty( pInfo->strSqlName ) ){
  3830. strDefaultDir = pInfo->strSqlName;
  3831. }else{
  3832. strDefaultDir = strBaseFileName;
  3833. }
  3834. strBaseFileName = L"";
  3835. if( ! PlaiIsStringEmpty( strDefaultDir ) ){
  3836. BOOL bBang = FALSE;
  3837. BOOL bLogSet = FALSE;
  3838. LPWSTR strLogSet = wcsstr( strDefaultDir, L"!" );
  3839. if( ! PlaiIsStringEmpty( strLogSet ) ){
  3840. bBang = TRUE;
  3841. if( wcslen( strLogSet ) > 1 ){
  3842. bLogSet = TRUE;
  3843. }
  3844. }
  3845. if( pInfo->dwAutoNameFormat != PLA_SLF_NAME_NONE ){
  3846. if( !bLogSet ){
  3847. strUnder = L"";
  3848. }
  3849. }else if( ! bLogSet ){
  3850. pdhStatus = PDH_INVALID_ARGUMENT;
  3851. goto cleanup;
  3852. }
  3853. if( ! bLogSet && ! bBang ){
  3854. strWhack = L"!";
  3855. }else{
  3856. strWhack = L"";
  3857. }
  3858. if( StrCmpNI( strDefaultDir, L"SQL:", 4 ) != 0 ){
  3859. strSQL = L"SQL:";
  3860. }
  3861. }else{
  3862. pdhStatus = PDH_INVALID_ARGUMENT;
  3863. goto cleanup;
  3864. }
  3865. }else{
  3866. WCHAR fname[_MAX_FNAME];
  3867. WCHAR ext[_MAX_EXT];
  3868. if( PlaiIsStringEmpty( strDefaultDir ) ){
  3869. strDefaultDir = L"%SystemDrive%\\PerfLogs";
  3870. }else if( strDefaultDir[wcslen(strDefaultDir)-1] == L'\\' ){
  3871. strWhack = L"";
  3872. }
  3873. if( PlaiIsStringEmpty( strBaseFileName ) ){
  3874. if( (pInfo->dwMask & PLA_INFO_FLAG_AUTOFORMAT) &&
  3875. PLA_SLF_NAME_NONE == pInfo->dwAutoNameFormat ){
  3876. pdhStatus = PDH_INVALID_ARGUMENT;
  3877. goto cleanup;
  3878. }else{
  3879. strBaseFileName = L"";
  3880. strUnder = L"";
  3881. }
  3882. }
  3883. _wsplitpath( strBaseFileName, NULL, NULL, fname, ext );
  3884. if( _wcsicmp( ext, L".etl" ) == 0 ||
  3885. _wcsicmp( ext, L".blg" ) == 0 ||
  3886. _wcsicmp( ext, L".csv" ) == 0 ||
  3887. _wcsicmp( ext, L".tsv" ) == 0 ){
  3888. if( wcslen( fname ) < _MAX_PATH ){
  3889. StringCchCopy( strBuffer, _MAX_PATH, fname );
  3890. strBaseFileName = strBuffer;
  3891. }
  3892. }
  3893. }
  3894. cchTotalSize = 32; // padding for cnf suffix and sql prefix
  3895. cchTotalSize += BYTE_SIZE( strBaseFileName ) / sizeof(WCHAR);
  3896. cchTotalSize += BYTE_SIZE( strDefaultDir ) / sizeof(WCHAR);
  3897. strLocalFileName = (LPWSTR)G_ALLOC( cchTotalSize * sizeof(WCHAR) );
  3898. if( NULL == strLocalFileName ){
  3899. pdhStatus = PDH_MEMORY_ALLOCATION_FAILURE;
  3900. goto cleanup;
  3901. }
  3902. if( pInfo->dwMask & PLA_INFO_FLAG_AUTOFORMAT ){
  3903. dwSwitch = pInfo->dwAutoNameFormat;
  3904. }else{
  3905. // default
  3906. dwSwitch = PLA_SLF_NAME_NONE;
  3907. }
  3908. switch( dwSwitch ){
  3909. case PLA_SLF_NAME_NONE:
  3910. StringCchPrintf( strLocalFileName, cchTotalSize,
  3911. L"%s%s%s%s",
  3912. strSQL, strDefaultDir, strWhack, strBaseFileName );
  3913. break;
  3914. case PLA_SLF_NAME_MMDDHH:
  3915. StringCchPrintf( strLocalFileName, cchTotalSize,
  3916. L"%s%s%s%s%s%02d%02d%02d",
  3917. strSQL, strDefaultDir, strWhack, strBaseFileName, strUnder, st.wMonth, st.wDay, st.wHour );
  3918. break;
  3919. case PLA_SLF_NAME_NNNNNN:
  3920. StringCchPrintf( strLocalFileName, cchTotalSize,
  3921. L"%s%s%s%s%s%06d",
  3922. strSQL, strDefaultDir, strWhack, strBaseFileName, strUnder, pInfo->dwLogFileSerialNumber );
  3923. break;
  3924. case PLA_SLF_NAME_YYYYDDD:
  3925. StringCchPrintf( strLocalFileName, cchTotalSize,
  3926. L"%s%s%s%s%s%04d%03d",
  3927. strSQL, strDefaultDir, strWhack, strBaseFileName, strUnder, st.wYear, PlaiJulianDate( st ) );
  3928. break;
  3929. case PLA_SLF_NAME_YYYYMM:
  3930. StringCchPrintf( strLocalFileName, cchTotalSize,
  3931. L"%s%s%s%s%s%04d%02d",
  3932. strSQL, strDefaultDir, strWhack, strBaseFileName, strUnder, st.wYear, st.wMonth );
  3933. break;
  3934. case PLA_SLF_NAME_YYYYMMDD:
  3935. StringCchPrintf( strLocalFileName, cchTotalSize,
  3936. L"%s%s%s%s%s%04d%02d%02d",
  3937. strSQL, strDefaultDir, strWhack, strBaseFileName, strUnder, st.wYear, st.wMonth, st.wDay );
  3938. break;
  3939. case PLA_SLF_NAME_YYYYMMDDHH:
  3940. StringCchPrintf( strLocalFileName, cchTotalSize,
  3941. L"%s%s%s%s%s%04d%02d%02d%02d",
  3942. strSQL, strDefaultDir, strWhack, strBaseFileName, strUnder, st.wYear, st.wMonth, st.wDay, st.wHour );
  3943. break;
  3944. case PLA_SLF_NAME_MMDDHHMM:
  3945. StringCchPrintf( strLocalFileName, cchTotalSize,
  3946. L"%s%s%s%s%s%02d%02d%02d%02d",
  3947. strSQL, strDefaultDir, strWhack, strBaseFileName, strUnder, st.wMonth, st.wDay, st.wHour, st.wMinute );
  3948. break;
  3949. }
  3950. if( (pInfo->dwMask & PLA_INFO_FLAG_CRTNEWFILE) &&
  3951. PLA_AUTO_MODE_NONE != pInfo->ptCreateNewFile.dwAutoMode ){
  3952. dwFlags |= PLA_FILENAME_USE_SUBEXT;
  3953. // default the CNF number.
  3954. if ( 0 == pInfo->dwReserved1 ) {
  3955. pInfo->dwReserved1 = 1;
  3956. }
  3957. }
  3958. if( dwFlags & PLA_FILENAME_USE_SUBEXT ){
  3959. if( dwFlags & PLA_FILENAME_GET_SUBFMT ){
  3960. StringCchCat( strLocalFileName, cchTotalSize, L"_%03d" );
  3961. }else if( dwFlags & PLA_FILENAME_GET_SUBXXX ){
  3962. StringCchCat( strLocalFileName, cchTotalSize, L"_xxx" );
  3963. }else{
  3964. StringCchPrintf( buffer, 128, L"_%03d", pInfo->dwReserved1 );
  3965. StringCchCat( strLocalFileName, cchTotalSize, buffer );
  3966. }
  3967. }
  3968. if( pInfo->dwMask & PLA_INFO_FLAG_FORMAT ){
  3969. dwSwitch = (pInfo->dwFileFormat & 0x0000FFFF);
  3970. }else{
  3971. dwSwitch = PLA_NUM_FILE_TYPES;
  3972. }
  3973. switch( dwSwitch ){
  3974. case PLA_CSV_FILE:
  3975. StringCchCat( strLocalFileName, cchTotalSize, L".csv" );
  3976. break;
  3977. case PLA_TSV_FILE:
  3978. StringCchCat( strLocalFileName, cchTotalSize, L".tsv" );
  3979. break;
  3980. case PLA_BIN_FILE:
  3981. case PLA_BIN_CIRC_FILE:
  3982. StringCchCat( strLocalFileName, cchTotalSize, L".blg" );
  3983. break;
  3984. case PLA_CIRC_TRACE_FILE:
  3985. case PLA_SEQ_TRACE_FILE:
  3986. StringCchCat( strLocalFileName, cchTotalSize, L".etl" );
  3987. break;
  3988. case PLA_SQL_LOG:
  3989. break;
  3990. }
  3991. if( !(dwFlags & PLA_FILENAME_NOEXPANDEV) ){
  3992. if( NULL == strFileName ){
  3993. strExpand = buffer;
  3994. cchSize = 128;
  3995. pdhStatus = PDH_INSUFFICIENT_BUFFER;
  3996. }else{
  3997. strExpand = strFileName;
  3998. cchSize = (*pcchBufferSize);
  3999. }
  4000. cchExpanded = ExpandEnvironmentStrings( strLocalFileName, strExpand, cchSize );
  4001. if( cchExpanded == 0 ){
  4002. DWORD dwStatus = GetLastError();
  4003. pdhStatus = PlaiErrorToPdhStatus( dwStatus );
  4004. }else{
  4005. cchTotalSize = cchExpanded;
  4006. if( NULL != strFileName && *pcchBufferSize < cchTotalSize ){
  4007. pdhStatus = PDH_INSUFFICIENT_BUFFER;
  4008. }
  4009. }
  4010. }else{
  4011. cchTotalSize = wcslen( strLocalFileName ) + 1;
  4012. if( NULL == strFileName ){
  4013. pdhStatus = PDH_INSUFFICIENT_BUFFER;
  4014. }else{
  4015. if( cchTotalSize <= *pcchBufferSize ){
  4016. StringCchCopy( strFileName, *pcchBufferSize, strLocalFileName );
  4017. strExpand = strFileName;
  4018. }else{
  4019. pdhStatus = PDH_INSUFFICIENT_BUFFER;
  4020. }
  4021. }
  4022. }
  4023. if( ERROR_SUCCESS == pdhStatus ){
  4024. pdhStatus = PlaiScanForInvalidChar( strExpand );
  4025. }
  4026. cleanup:
  4027. G_FREE( strLocalFileName );
  4028. *pcchBufferSize = cchTotalSize;
  4029. return pdhStatus;
  4030. }
  4031. PDH_FUNCTION
  4032. PdhPlaGetLogFileNameA(
  4033. LPSTR strName,
  4034. LPSTR strComputer,
  4035. PPDH_PLA_INFO_A pInfo,
  4036. DWORD dwFlags,
  4037. LPDWORD pcchBufferSize,
  4038. LPSTR strFileName
  4039. )
  4040. {
  4041. return PDH_NOT_IMPLEMENTED;
  4042. }
  4043. PDH_FUNCTION
  4044. PdhPlaGetLogFileNameW(
  4045. LPWSTR strName,
  4046. LPWSTR strComputer,
  4047. PPDH_PLA_INFO_W pInfo,
  4048. DWORD dwFlags,
  4049. LPDWORD pcchBufferSize,
  4050. LPWSTR strFileName
  4051. )
  4052. {
  4053. PDH_STATUS pdhStatus = ERROR_SUCCESS;
  4054. PPDH_PLA_INFO_W pLocalInfo = NULL;
  4055. LPWSTR strFolder = NULL;
  4056. LPWSTR strLocalFileName = NULL;
  4057. DWORD cbSize;
  4058. __try{
  4059. if( pInfo == NULL ){
  4060. DWORD dwInfoSize = 0;
  4061. pdhStatus = PdhPlaGetInfoW( strName, strComputer, &dwInfoSize, pLocalInfo );
  4062. CHECK_STATUS(pdhStatus);
  4063. pLocalInfo = (PPDH_PLA_INFO)G_ALLOC(dwInfoSize);
  4064. if( NULL != pLocalInfo ){
  4065. ZeroMemory( pLocalInfo, dwInfoSize );
  4066. pLocalInfo->dwMask = PLA_INFO_CREATE_FILENAME;
  4067. pdhStatus = PdhPlaGetInfoW( strName, strComputer, &dwInfoSize, pLocalInfo );
  4068. CHECK_STATUS(pdhStatus);
  4069. }else{
  4070. pdhStatus = PDH_MEMORY_ALLOCATION_FAILURE;
  4071. goto cleanup;
  4072. }
  4073. }else{
  4074. pLocalInfo = (PPDH_PLA_INFO)G_ALLOC(sizeof(PDH_PLA_INFO) );
  4075. if( NULL != pLocalInfo ){
  4076. memcpy( pLocalInfo, pInfo, sizeof(PDH_PLA_INFO) );
  4077. }else{
  4078. pdhStatus = PDH_MEMORY_ALLOCATION_FAILURE;
  4079. goto cleanup;
  4080. }
  4081. }
  4082. if( !(pLocalInfo->dwMask & PLA_INFO_FLAG_TYPE) || PLA_ALERT == pLocalInfo->dwType ){
  4083. if( *pcchBufferSize > 1 && strFileName != NULL ){
  4084. strFileName[0] = L'\0';
  4085. }
  4086. *pcchBufferSize = 1;
  4087. goto cleanup;
  4088. }
  4089. if( ((dwFlags & PLA_FILENAME_CURRENTLOG) ||
  4090. ((pLocalInfo->dwMask & PLA_INFO_FLAG_STATUS) &&
  4091. PLA_QUERY_RUNNING == pLocalInfo->dwStatus)) &&
  4092. !(dwFlags & PLA_FILENAME_CREATEONLY) ){
  4093. if( NULL != strName ){
  4094. HKEY hkeyQuery = NULL;
  4095. pdhStatus = PlaiConnectAndLockQuery ( strComputer, strName, hkeyQuery, FALSE );
  4096. if( ERROR_SUCCESS == pdhStatus ){
  4097. cbSize = 0;
  4098. pdhStatus = PlaiReadRegistryStringValue( hkeyQuery, szCurrentLogFile, 0, &strLocalFileName, &cbSize );
  4099. RELEASE_MUTEX(hPdhPlaMutex);
  4100. if( NULL != hkeyQuery ){
  4101. RegCloseKey( hkeyQuery );
  4102. }
  4103. if( pdhStatus == ERROR_SUCCESS ){
  4104. if( strFileName != NULL && *pcchBufferSize >= (cbSize/sizeof(WCHAR)) ){
  4105. StringCchCopy( strFileName, *pcchBufferSize, strLocalFileName );
  4106. }else{
  4107. if( NULL != strFileName ){
  4108. pdhStatus = PDH_INSUFFICIENT_BUFFER;
  4109. }
  4110. }
  4111. *pcchBufferSize = (cbSize/sizeof(WCHAR));
  4112. goto cleanup;
  4113. }
  4114. }
  4115. }
  4116. }
  4117. if( !(pLocalInfo->dwMask & PLA_INFO_FLAG_DEFAULTDIR) ||
  4118. PlaiIsStringEmpty( pLocalInfo->strDefaultDir ) ){
  4119. HKEY hkeyLogs = NULL;
  4120. pdhStatus = PlaiConnectToRegistry( strComputer, hkeyLogs, FALSE );
  4121. CHECK_STATUS( pdhStatus );
  4122. cbSize = 0;
  4123. pdhStatus = PlaiReadRegistryStringValue(
  4124. hkeyLogs,
  4125. L"DefaultLogFileFolder",
  4126. READ_REG_MUI,
  4127. &strFolder,
  4128. &cbSize
  4129. );
  4130. if( hkeyLogs != NULL ){
  4131. RegCloseKey ( hkeyLogs );
  4132. }
  4133. CHECK_STATUS(pdhStatus);
  4134. pLocalInfo->strDefaultDir = strFolder;
  4135. pLocalInfo->dwMask |= PLA_INFO_FLAG_DEFAULTDIR;
  4136. }
  4137. if( ! PlaiIsLocalComputer( strComputer ) ){
  4138. dwFlags |= PLA_FILENAME_NOEXPANDEV;
  4139. }
  4140. pdhStatus = PlaiGetLogFileName( dwFlags, pLocalInfo, pcchBufferSize, strFileName );
  4141. if(ERROR_SUCCESS == pdhStatus){
  4142. pdhStatus = PdhiPlaFormatBlanksW( strComputer, strFileName );
  4143. }
  4144. } __except (EXCEPTION_EXECUTE_HANDLER) {
  4145. pdhStatus = PDH_INVALID_ARGUMENT;
  4146. }
  4147. cleanup:
  4148. G_FREE( pLocalInfo );
  4149. G_FREE( strFolder );
  4150. G_FREE( strLocalFileName );
  4151. return pdhStatus;
  4152. }