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.

651 lines
17 KiB

  1. /*****************************************************************************\
  2. Copyright (c) Microsoft Corporation. All rights reserved.
  3. \*****************************************************************************/
  4. #include <assert.h>
  5. #include <windows.h>
  6. #include <string.h>
  7. #include <tchar.h>
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <pdh.h>
  11. #include <pdhp.h>
  12. #include <ntsecapi.h>
  13. #include <shlwapi.h>
  14. #include <shlwapip.h>
  15. #include "plogman.h"
  16. PDH_FUNCTION
  17. PlaiReadRegistryPlaTime (
  18. HKEY hKey,
  19. LPCWSTR cwszValueName,
  20. PPLA_TIME_INFO pstiData
  21. )
  22. {
  23. DWORD dwStatus = ERROR_SUCCESS;
  24. DWORD dwType = 0;
  25. DWORD dwBufferSize = 0;
  26. PLA_TIME_INFO slqLocal;
  27. memset (&slqLocal, 0, sizeof(PLA_TIME_INFO));
  28. dwStatus = RegQueryValueExW (
  29. hKey,
  30. cwszValueName,
  31. NULL,
  32. &dwType,
  33. NULL,
  34. &dwBufferSize );
  35. if ( ERROR_SUCCESS == dwStatus ) {
  36. if ( (dwBufferSize == sizeof(PLA_TIME_INFO)) && ( REG_BINARY == dwType ) ) {
  37. // then there's something to read
  38. dwType = 0;
  39. dwStatus = RegQueryValueExW (
  40. hKey,
  41. cwszValueName,
  42. NULL,
  43. &dwType,
  44. (LPBYTE)&slqLocal,
  45. &dwBufferSize);
  46. } else {
  47. // nothing to read
  48. dwStatus = ERROR_NO_DATA;
  49. }
  50. }
  51. if ( ERROR_SUCCESS == dwStatus ) {
  52. *pstiData = slqLocal;
  53. }
  54. return PlaiErrorToPdhStatus( dwStatus );
  55. }
  56. PDH_FUNCTION
  57. PlaiWriteRegistryPlaTime (
  58. HKEY hKey,
  59. LPCWSTR cwszValueName,
  60. PPLA_TIME_INFO pstiData
  61. )
  62. {
  63. DWORD dwStatus = ERROR_SUCCESS;
  64. DWORD dwValue = sizeof(PLA_TIME_INFO);
  65. dwStatus = RegSetValueExW (
  66. hKey,
  67. cwszValueName,
  68. 0L,
  69. REG_BINARY,
  70. (CONST BYTE *)pstiData,
  71. dwValue);
  72. return PlaiErrorToPdhStatus( dwStatus );
  73. }
  74. PDH_FUNCTION
  75. PlaiReadRegistryDwordValue (
  76. HKEY hKey,
  77. LPCWSTR cwszValueName,
  78. LPDWORD pdwValue
  79. )
  80. {
  81. DWORD dwStatus = ERROR_SUCCESS;
  82. DWORD dwValue = sizeof(DWORD);
  83. DWORD dwType = 0;
  84. DWORD dwBufferSize = 0;
  85. dwStatus = RegQueryValueExW (
  86. hKey,
  87. cwszValueName,
  88. NULL,
  89. &dwType,
  90. NULL,
  91. &dwBufferSize );
  92. if ( ERROR_SUCCESS == dwStatus ) {
  93. if ( ( dwBufferSize == sizeof(DWORD) )
  94. && ( ( REG_DWORD == dwType ) || ( REG_BINARY == dwType ) ) ) {
  95. // then there's something to read
  96. dwType = 0;
  97. dwStatus = RegQueryValueExW (
  98. hKey,
  99. cwszValueName,
  100. NULL,
  101. &dwType,
  102. (LPBYTE)&dwValue,
  103. &dwBufferSize);
  104. } else {
  105. // nothing to read
  106. dwStatus = ERROR_NO_DATA;
  107. }
  108. } // else hr has error.
  109. if ( ERROR_SUCCESS == dwStatus ) {
  110. *pdwValue = dwValue;
  111. }
  112. return PlaiErrorToPdhStatus( dwStatus );
  113. }
  114. PDH_FUNCTION
  115. PlaiWriteRegistryDwordValue (
  116. HKEY hKey,
  117. LPCWSTR cwszValueName,
  118. LPDWORD pdwValue
  119. )
  120. {
  121. DWORD dwType = REG_DWORD;
  122. DWORD dwStatus = ERROR_SUCCESS;
  123. DWORD dwValue = sizeof(DWORD);
  124. dwStatus = RegSetValueExW (
  125. hKey,
  126. cwszValueName,
  127. 0L,
  128. dwType,
  129. (CONST BYTE *)pdwValue,
  130. dwValue);
  131. return PlaiErrorToPdhStatus( dwStatus );
  132. }
  133. PDH_FUNCTION
  134. PlaiReadRegistryStringValue(
  135. HKEY hKey,
  136. LPCWSTR strKey,
  137. DWORD dwFlags,
  138. LPWSTR* pszBuffer,
  139. DWORD* dwBufLen
  140. )
  141. {
  142. DWORD dwStatus = ERROR_SUCCESS;
  143. DWORD dwDataType;
  144. DWORD dwDataSize = 0;
  145. LPWSTR pBuffer;
  146. dwStatus = RegQueryValueExW(
  147. hKey,
  148. strKey,
  149. NULL,
  150. &dwDataType,
  151. (LPBYTE)NULL,
  152. (LPDWORD)&dwDataSize
  153. );
  154. if( (dwFlags & READ_REG_MUI) ){
  155. if( dwDataSize < 1024 ){
  156. dwDataSize = 1024;
  157. }
  158. dwStatus = ERROR_SUCCESS;
  159. }
  160. if( ERROR_SUCCESS == dwStatus ){
  161. pBuffer = *pszBuffer;
  162. if( pBuffer == NULL || dwDataSize > G_SIZE(pBuffer) ){
  163. if( pBuffer != NULL ){
  164. pBuffer = (LPWSTR)G_REALLOC( pBuffer, dwDataSize );
  165. }else{
  166. pBuffer = (LPWSTR)G_ALLOC( dwDataSize );
  167. }
  168. if( pBuffer ){
  169. *pszBuffer = pBuffer;
  170. }else{
  171. G_FREE( (*pszBuffer) );
  172. return ERROR_OUTOFMEMORY;
  173. }
  174. }
  175. if( dwFlags & READ_REG_MUI ){
  176. WCHAR strKeyIndirect[1024];
  177. wsprintf( strKeyIndirect, L"%s Indirect", strKey );
  178. dwStatus = SHLoadRegUIStringW (
  179. hKey,
  180. strKeyIndirect,
  181. *pszBuffer,
  182. dwDataSize
  183. );
  184. if( ERROR_SUCCESS == dwStatus ){
  185. *dwBufLen = (DWORD)((char*)&(*pszBuffer)[wcslen(*pszBuffer)]
  186. - (char*)&(*pszBuffer)[0]);
  187. *dwBufLen += sizeof(WCHAR);
  188. }else{
  189. *dwBufLen = 0;
  190. }
  191. }
  192. if( !(dwFlags & READ_REG_MUI) ||
  193. ((dwFlags & READ_REG_MUI) && ERROR_SUCCESS != dwStatus) ){
  194. dwStatus = RegQueryValueExW(
  195. hKey,
  196. strKey,
  197. NULL,
  198. &dwDataType,
  199. (LPBYTE)*pszBuffer,
  200. (LPDWORD)&dwDataSize
  201. );
  202. if( dwStatus == ERROR_SUCCESS ){
  203. *dwBufLen = dwDataSize;
  204. }else{
  205. *dwBufLen = 0;
  206. }
  207. }
  208. }
  209. return PlaiErrorToPdhStatus( dwStatus );
  210. }
  211. PDH_FUNCTION
  212. PlaiWriteRegistryStringValue (
  213. HKEY hKey,
  214. LPCWSTR cwszValueName,
  215. DWORD dwType,
  216. LPCWSTR pszBuffer,
  217. DWORD cbBufferLength
  218. )
  219. {
  220. // writes the contents of pszBuffer to szValue under hKey
  221. DWORD dwStatus = ERROR_SUCCESS;
  222. CONST BYTE *pLclBuffer;
  223. if ( NULL == pszBuffer ) {
  224. // substitute an empty string
  225. pLclBuffer = (CONST BYTE *)L"\0";
  226. cbBufferLength = sizeof(WCHAR);
  227. } else {
  228. // use args passed in
  229. pLclBuffer = (CONST BYTE *)pszBuffer;
  230. if( cbBufferLength == 0 ){
  231. cbBufferLength = BYTE_SIZE( pszBuffer ) + (DWORD)sizeof(UNICODE_NULL);
  232. }
  233. }
  234. dwStatus = RegSetValueExW (hKey,
  235. cwszValueName,
  236. 0L,
  237. dwType,
  238. (CONST BYTE *)pLclBuffer,
  239. cbBufferLength );
  240. return PlaiErrorToPdhStatus( dwStatus );
  241. }
  242. PDH_FUNCTION
  243. PlaiWriteRegistryLastModified( HKEY hkeyQuery )
  244. {
  245. DWORD dwStatus = ERROR_SUCCESS;
  246. PLA_TIME_INFO plqLastModified;
  247. SYSTEMTIME stLocalTime;
  248. FILETIME ftModified;
  249. RegFlushKey( hkeyQuery );
  250. dwStatus = RegQueryInfoKey (
  251. hkeyQuery,
  252. NULL,
  253. NULL,
  254. NULL,
  255. NULL,
  256. NULL,
  257. NULL,
  258. NULL,
  259. NULL,
  260. NULL,
  261. NULL,
  262. &ftModified );
  263. if( ERROR_SUCCESS != dwStatus ) {
  264. GetLocalTime (&stLocalTime);
  265. SystemTimeToFileTime (&stLocalTime, &ftModified);
  266. }
  267. plqLastModified.wDataType = PLA_TT_DTYPE_DATETIME;
  268. plqLastModified.wTimeType = PLA_TT_TTYPE_LAST_MODIFIED;
  269. plqLastModified.dwAutoMode = PLA_AUTO_MODE_NONE;
  270. plqLastModified.llDateTime = *(LONGLONG *)&ftModified;
  271. if( ERROR_SUCCESS == dwStatus ){
  272. return PlaiWriteRegistryPlaTime (
  273. hkeyQuery,
  274. L"Last Modified",
  275. &plqLastModified
  276. );
  277. }
  278. return PlaiErrorToPdhStatus( dwStatus );
  279. }
  280. DWORD
  281. PlaiCreateQuery(
  282. HKEY hkeyMachine,
  283. HKEY& rhkeyLogQueries
  284. )
  285. {
  286. DWORD dwStatus = ERROR_SUCCESS;
  287. HKEY hkeySysmonLog;
  288. DWORD dwDisposition;
  289. rhkeyLogQueries = NULL;
  290. dwStatus = RegOpenKeyExW (
  291. hkeyMachine,
  292. L"System\\CurrentControlSet\\Services\\SysmonLog",
  293. 0,
  294. KEY_READ | KEY_WRITE,
  295. &hkeySysmonLog);
  296. if ( ERROR_SUCCESS == dwStatus ) {
  297. // Create registry subkey for Log Queries
  298. dwStatus = RegCreateKeyExW (
  299. hkeySysmonLog,
  300. L"Log Queries",
  301. 0,
  302. NULL,
  303. REG_OPTION_NON_VOLATILE,
  304. KEY_READ | KEY_WRITE,
  305. NULL,
  306. &rhkeyLogQueries,
  307. &dwDisposition);
  308. }
  309. return dwStatus;
  310. }
  311. PDH_FUNCTION
  312. PdhiPlaGetVersion(
  313. LPCWSTR strComputer,
  314. PPLA_VERSION pVersion )
  315. {
  316. DWORD dwStatus = ERROR_SUCCESS;
  317. HKEY hkeyMachine = HKEY_LOCAL_MACHINE;
  318. HKEY hkeyQuery = NULL;
  319. DWORD cbBufferSize = 0;
  320. DWORD dwType;
  321. WCHAR szRegValue[MAX_PATH];
  322. PLA_VERSION version;
  323. ZeroMemory( &version, sizeof(PLA_VERSION) );
  324. if ( NULL != strComputer ) {
  325. if ( wcslen( strComputer) ) {
  326. dwStatus = RegConnectRegistryW (
  327. strComputer,
  328. HKEY_LOCAL_MACHINE,
  329. &hkeyMachine
  330. );
  331. }
  332. }
  333. if ( ERROR_SUCCESS == dwStatus ) {
  334. dwStatus = RegOpenKeyExW (
  335. hkeyMachine,
  336. L"Software\\Microsoft\\Windows NT\\CurrentVersion",
  337. 0,
  338. KEY_READ,
  339. &hkeyQuery
  340. );
  341. if( ERROR_SUCCESS == dwStatus ){
  342. dwStatus = RegQueryValueExW (
  343. hkeyQuery,
  344. L"CurrentVersion",
  345. NULL,
  346. &dwType,
  347. NULL,
  348. &cbBufferSize
  349. );
  350. if( ERROR_SUCCESS == dwStatus ) {
  351. if( (MAX_PATH*sizeof(WCHAR) > cbBufferSize ) &&
  352. (sizeof(WCHAR) < cbBufferSize) &&
  353. (REG_SZ == dwType ) )
  354. {
  355. ZeroMemory ( szRegValue, MAX_PATH );
  356. dwStatus = RegQueryValueExW (
  357. hkeyQuery,
  358. L"CurrentVersion",
  359. NULL,
  360. &dwType,
  361. (LPBYTE)szRegValue,
  362. &cbBufferSize
  363. );
  364. if ( ERROR_SUCCESS == dwStatus ) {
  365. version.dwMajorVersion = _wtol ( szRegValue );
  366. }
  367. }
  368. }
  369. }
  370. if( ERROR_SUCCESS == dwStatus ){
  371. dwStatus = RegQueryValueExW (
  372. hkeyQuery,
  373. L"CurrentBuildNumber",
  374. NULL,
  375. &dwType,
  376. NULL,
  377. &cbBufferSize
  378. );
  379. if( ERROR_SUCCESS == dwStatus ) {
  380. if( (MAX_PATH*sizeof(WCHAR) > cbBufferSize ) &&
  381. (sizeof(WCHAR) < cbBufferSize) &&
  382. (REG_SZ == dwType ) )
  383. {
  384. ZeroMemory ( szRegValue, MAX_PATH );
  385. dwStatus = RegQueryValueExW (
  386. hkeyQuery,
  387. L"CurrentBuildNumber",
  388. NULL,
  389. &dwType,
  390. (LPBYTE)szRegValue,
  391. &cbBufferSize
  392. );
  393. if ( ERROR_SUCCESS == dwStatus ) {
  394. version.dwBuild = _wtol ( szRegValue );
  395. }
  396. }
  397. }
  398. }
  399. }
  400. memcpy( pVersion, &version, sizeof(PLA_VERSION) );
  401. if ( NULL != hkeyMachine ) {
  402. RegCloseKey ( hkeyMachine );
  403. }
  404. if( NULL != hkeyQuery ){
  405. RegCloseKey( hkeyQuery );
  406. }
  407. return PlaiErrorToPdhStatus( dwStatus );
  408. }
  409. PDH_FUNCTION
  410. PlaiConnectToRegistry(
  411. LPCWSTR strComputer,
  412. HKEY& rhkeyLogQueries,
  413. BOOL bQueries,
  414. BOOL bWrite)
  415. {
  416. DWORD dwStatus = ERROR_SUCCESS;
  417. HKEY hkeyMachine = HKEY_LOCAL_MACHINE;
  418. if ( NULL != strComputer ) {
  419. if( wcslen( strComputer ) ){
  420. dwStatus = RegConnectRegistryW (
  421. strComputer,
  422. HKEY_LOCAL_MACHINE,
  423. &hkeyMachine );
  424. }
  425. }
  426. if ( ERROR_SUCCESS == dwStatus ) {
  427. if( bQueries ){
  428. if ( bWrite ) {
  429. dwStatus = RegOpenKeyExW (
  430. hkeyMachine,
  431. L"System\\CurrentControlSet\\Services\\SysmonLog\\Log Queries",
  432. 0,
  433. KEY_READ | KEY_WRITE,
  434. &rhkeyLogQueries );
  435. }else{
  436. dwStatus = RegOpenKeyExW (
  437. hkeyMachine,
  438. L"System\\CurrentControlSet\\Services\\SysmonLog\\Log Queries",
  439. 0,
  440. KEY_READ,
  441. &rhkeyLogQueries );
  442. }
  443. }else{
  444. dwStatus = RegOpenKeyExW (
  445. hkeyMachine,
  446. L"System\\CurrentControlSet\\Services\\SysmonLog",
  447. 0,
  448. KEY_READ,
  449. &rhkeyLogQueries );
  450. }
  451. if ( ERROR_SUCCESS != dwStatus ) {
  452. dwStatus = PlaiCreateQuery( hkeyMachine, rhkeyLogQueries );
  453. }
  454. }
  455. if ( NULL != hkeyMachine ) {
  456. RegCloseKey ( hkeyMachine );
  457. }
  458. return PlaiErrorToPdhStatus( dwStatus );
  459. }
  460. PDH_FUNCTION
  461. PlaiConnectAndLockQuery (
  462. LPCWSTR strComputer,
  463. LPCWSTR strQuery,
  464. HKEY& rhkeyQuery,
  465. BOOL bWrite )
  466. {
  467. DWORD dwStatus = ERROR_SUCCESS;
  468. PDH_STATUS pdhStatus = ERROR_SUCCESS;
  469. HKEY hkeyQuery = NULL;
  470. HKEY hkeyLogQueries = NULL;
  471. rhkeyQuery = NULL;
  472. dwStatus = WAIT_FOR_AND_LOCK_MUTEX(hPdhPlaMutex);
  473. if( ERROR_SUCCESS == dwStatus || WAIT_ABANDONED == dwStatus ){
  474. pdhStatus = PlaiConnectToRegistry (
  475. strComputer,
  476. hkeyLogQueries,
  477. TRUE,
  478. bWrite
  479. );
  480. if( ERROR_SUCCESS == pdhStatus ){
  481. DWORD nCollections = 0;
  482. DWORD nMaxSubKeyLength = 0;
  483. dwStatus = RegQueryInfoKey(
  484. hkeyLogQueries,
  485. NULL,
  486. NULL,
  487. NULL,
  488. &nCollections,
  489. &nMaxSubKeyLength,
  490. NULL,
  491. NULL,
  492. NULL,
  493. NULL,
  494. NULL,
  495. NULL
  496. );
  497. if( ERROR_SUCCESS == dwStatus ){
  498. LPWSTR strCollection;
  499. LPWSTR strQueryName = NULL;
  500. DWORD dwQueryName = 0;
  501. DWORD dwSize = (sizeof(WCHAR)*(nMaxSubKeyLength+1));
  502. strCollection = (LPWSTR)G_ALLOC( dwSize );
  503. if( strCollection ){
  504. dwStatus = ERROR_FILE_NOT_FOUND;
  505. for( ULONG i = 0; i<nCollections; i++ ){
  506. dwStatus = RegEnumKey( hkeyLogQueries, i, strCollection, dwSize );
  507. if( ERROR_SUCCESS == dwStatus ) {
  508. dwStatus = RegOpenKeyExW (
  509. hkeyLogQueries,
  510. strCollection,
  511. 0,
  512. bWrite ? KEY_READ | KEY_WRITE : KEY_READ,
  513. &hkeyQuery
  514. );
  515. if( ERROR_SUCCESS == dwStatus ){
  516. if( !_wcsicmp( strCollection, strQuery ) ){
  517. break;
  518. }
  519. PlaiReadRegistryStringValue( hkeyQuery, szCollection, READ_REG_MUI, &strQueryName, &dwQueryName );
  520. if( strQueryName != NULL && !_wcsicmp( strQueryName, strQuery ) ){
  521. break;
  522. }
  523. dwStatus = ERROR_FILE_NOT_FOUND;
  524. if ( NULL != hkeyQuery ) {
  525. RegCloseKey ( hkeyQuery );
  526. }
  527. }
  528. }
  529. }
  530. G_FREE( strQueryName );
  531. G_FREE( strCollection );
  532. }else{
  533. dwStatus = ERROR_OUTOFMEMORY;
  534. }
  535. }
  536. }
  537. RegCloseKey ( hkeyLogQueries );
  538. if( ERROR_SUCCESS != dwStatus || ERROR_SUCCESS != pdhStatus){
  539. RELEASE_MUTEX( hPdhPlaMutex );
  540. }else{
  541. rhkeyQuery = hkeyQuery;
  542. }
  543. }
  544. if( ERROR_SUCCESS != pdhStatus ){
  545. return pdhStatus;
  546. }else{
  547. return PlaiErrorToPdhStatus( dwStatus );
  548. }
  549. }