Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

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