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

668 lines
18 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. const int cBuffer = 512;
  177. WCHAR strKeyIndirect[cBuffer];
  178. LPWSTR szIndirect = L" Indirect";
  179. if( wcslen(strKey) + wcslen( szIndirect ) + sizeof(WCHAR ) > cBuffer ){
  180. dwStatus = ERROR_INVALID_DATA;
  181. }else{
  182. StringCchPrintfW( strKeyIndirect, cBuffer, L"%s%s", strKey, szIndirect );
  183. dwStatus = SHLoadRegUIStringW (
  184. hKey,
  185. strKeyIndirect,
  186. *pszBuffer,
  187. dwDataSize/sizeof(WCHAR)
  188. );
  189. if( ERROR_SUCCESS == dwStatus ){
  190. *dwBufLen = (DWORD)((char*)&(*pszBuffer)[wcslen(*pszBuffer)]
  191. - (char*)&(*pszBuffer)[0]);
  192. *dwBufLen += sizeof(WCHAR);
  193. }else{
  194. *dwBufLen = 0;
  195. }
  196. }
  197. }
  198. if( !(dwFlags & READ_REG_MUI) ||
  199. ((dwFlags & READ_REG_MUI) && ERROR_SUCCESS != dwStatus) ){
  200. dwStatus = RegQueryValueExW(
  201. hKey,
  202. strKey,
  203. NULL,
  204. &dwDataType,
  205. (LPBYTE)*pszBuffer,
  206. (LPDWORD)&dwDataSize
  207. );
  208. if( dwStatus == ERROR_SUCCESS ){
  209. *dwBufLen = dwDataSize;
  210. }else{
  211. *dwBufLen = 0;
  212. }
  213. }
  214. }
  215. if( ERROR_SUCCESS == dwStatus && !(dwFlags&READ_REG_BLOB) ){
  216. (*pszBuffer)[(*dwBufLen/sizeof(WCHAR))-1] = L'\0';
  217. }
  218. return PlaiErrorToPdhStatus( dwStatus );
  219. }
  220. PDH_FUNCTION
  221. PlaiWriteRegistryStringValue (
  222. HKEY hKey,
  223. LPCWSTR cwszValueName,
  224. DWORD dwType,
  225. LPCWSTR pszBuffer,
  226. DWORD cbBufferLength
  227. )
  228. {
  229. // writes the contents of pszBuffer to szValue under hKey
  230. DWORD dwStatus = ERROR_SUCCESS;
  231. CONST BYTE *pLclBuffer;
  232. if ( NULL == pszBuffer ) {
  233. // substitute an empty string
  234. pLclBuffer = (CONST BYTE *)L"\0";
  235. cbBufferLength = sizeof(WCHAR);
  236. } else {
  237. // use args passed in
  238. pLclBuffer = (CONST BYTE *)pszBuffer;
  239. if( cbBufferLength == 0 ){
  240. cbBufferLength = BYTE_SIZE( pszBuffer ) + (DWORD)sizeof(UNICODE_NULL);
  241. }
  242. }
  243. dwStatus = RegSetValueExW (hKey,
  244. cwszValueName,
  245. 0L,
  246. dwType,
  247. (CONST BYTE *)pLclBuffer,
  248. cbBufferLength );
  249. return PlaiErrorToPdhStatus( dwStatus );
  250. }
  251. PDH_FUNCTION
  252. PlaiWriteRegistryLastModified( HKEY hkeyQuery )
  253. {
  254. DWORD dwStatus = ERROR_SUCCESS;
  255. PLA_TIME_INFO plqLastModified;
  256. SYSTEMTIME stLocalTime;
  257. FILETIME ftModified;
  258. RegFlushKey( hkeyQuery );
  259. dwStatus = RegQueryInfoKey (
  260. hkeyQuery,
  261. NULL,
  262. NULL,
  263. NULL,
  264. NULL,
  265. NULL,
  266. NULL,
  267. NULL,
  268. NULL,
  269. NULL,
  270. NULL,
  271. &ftModified );
  272. if( ERROR_SUCCESS != dwStatus ) {
  273. GetLocalTime (&stLocalTime);
  274. SystemTimeToFileTime (&stLocalTime, &ftModified);
  275. }
  276. plqLastModified.wDataType = PLA_TT_DTYPE_DATETIME;
  277. plqLastModified.wTimeType = PLA_TT_TTYPE_LAST_MODIFIED;
  278. plqLastModified.dwAutoMode = PLA_AUTO_MODE_NONE;
  279. plqLastModified.llDateTime = *(LONGLONG *)&ftModified;
  280. if( ERROR_SUCCESS == dwStatus ){
  281. return PlaiWriteRegistryPlaTime (
  282. hkeyQuery,
  283. L"Last Modified",
  284. &plqLastModified
  285. );
  286. }
  287. return PlaiErrorToPdhStatus( dwStatus );
  288. }
  289. DWORD
  290. PlaiCreateQuery(
  291. HKEY hkeyMachine,
  292. HKEY& rhkeyLogQueries
  293. )
  294. {
  295. DWORD dwStatus = ERROR_SUCCESS;
  296. HKEY hkeySysmonLog;
  297. DWORD dwDisposition;
  298. rhkeyLogQueries = NULL;
  299. dwStatus = RegOpenKeyExW (
  300. hkeyMachine,
  301. L"System\\CurrentControlSet\\Services\\SysmonLog",
  302. 0,
  303. KEY_READ | KEY_WRITE,
  304. &hkeySysmonLog);
  305. if ( ERROR_SUCCESS == dwStatus ) {
  306. // Create registry subkey for Log Queries
  307. dwStatus = RegCreateKeyExW (
  308. hkeySysmonLog,
  309. L"Log Queries",
  310. 0,
  311. NULL,
  312. REG_OPTION_NON_VOLATILE,
  313. KEY_READ | KEY_WRITE,
  314. NULL,
  315. &rhkeyLogQueries,
  316. &dwDisposition);
  317. RegCloseKey( hkeySysmonLog );
  318. }
  319. return dwStatus;
  320. }
  321. PDH_FUNCTION
  322. PdhiPlaGetVersion(
  323. LPCWSTR strComputer,
  324. PPLA_VERSION pVersion )
  325. {
  326. DWORD dwStatus = ERROR_SUCCESS;
  327. HKEY hkeyMachine = HKEY_LOCAL_MACHINE;
  328. HKEY hkeyQuery = NULL;
  329. DWORD cbBufferSize = 0;
  330. DWORD dwType;
  331. WCHAR szRegValue[MAX_PATH];
  332. PLA_VERSION version;
  333. ZeroMemory( &version, sizeof(PLA_VERSION) );
  334. if ( NULL != strComputer ) {
  335. if ( wcslen( strComputer) ) {
  336. dwStatus = RegConnectRegistryW (
  337. strComputer,
  338. HKEY_LOCAL_MACHINE,
  339. &hkeyMachine
  340. );
  341. }
  342. }
  343. if ( ERROR_SUCCESS == dwStatus ) {
  344. dwStatus = RegOpenKeyExW (
  345. hkeyMachine,
  346. L"Software\\Microsoft\\Windows NT\\CurrentVersion",
  347. 0,
  348. KEY_READ,
  349. &hkeyQuery
  350. );
  351. if( ERROR_SUCCESS == dwStatus ){
  352. dwStatus = RegQueryValueExW (
  353. hkeyQuery,
  354. L"CurrentVersion",
  355. NULL,
  356. &dwType,
  357. NULL,
  358. &cbBufferSize
  359. );
  360. if( ERROR_SUCCESS == dwStatus ) {
  361. if( (MAX_PATH*sizeof(WCHAR) > cbBufferSize ) &&
  362. (sizeof(WCHAR) < cbBufferSize) &&
  363. (REG_SZ == dwType ) )
  364. {
  365. ZeroMemory ( szRegValue, MAX_PATH );
  366. dwStatus = RegQueryValueExW (
  367. hkeyQuery,
  368. L"CurrentVersion",
  369. NULL,
  370. &dwType,
  371. (LPBYTE)szRegValue,
  372. &cbBufferSize
  373. );
  374. if ( ERROR_SUCCESS == dwStatus ) {
  375. version.dwMajorVersion = _wtol ( szRegValue );
  376. }
  377. }
  378. }
  379. }
  380. if( ERROR_SUCCESS == dwStatus ){
  381. dwStatus = RegQueryValueExW (
  382. hkeyQuery,
  383. L"CurrentBuildNumber",
  384. NULL,
  385. &dwType,
  386. NULL,
  387. &cbBufferSize
  388. );
  389. if( ERROR_SUCCESS == dwStatus ) {
  390. if( (MAX_PATH*sizeof(WCHAR) > cbBufferSize ) &&
  391. (sizeof(WCHAR) < cbBufferSize) &&
  392. (REG_SZ == dwType ) )
  393. {
  394. ZeroMemory ( szRegValue, MAX_PATH );
  395. dwStatus = RegQueryValueExW (
  396. hkeyQuery,
  397. L"CurrentBuildNumber",
  398. NULL,
  399. &dwType,
  400. (LPBYTE)szRegValue,
  401. &cbBufferSize
  402. );
  403. if ( ERROR_SUCCESS == dwStatus ) {
  404. version.dwBuild = _wtol ( szRegValue );
  405. }
  406. }
  407. }
  408. }
  409. }
  410. memcpy( pVersion, &version, sizeof(PLA_VERSION) );
  411. if ( NULL != hkeyMachine && HKEY_LOCAL_MACHINE != hkeyMachine ) {
  412. RegCloseKey ( hkeyMachine );
  413. }
  414. if( NULL != hkeyQuery ){
  415. RegCloseKey( hkeyQuery );
  416. }
  417. return PlaiErrorToPdhStatus( dwStatus );
  418. }
  419. PDH_FUNCTION
  420. PlaiConnectToRegistry(
  421. LPCWSTR strComputer,
  422. HKEY& rhkeyLogQueries,
  423. BOOL bQueries,
  424. BOOL bWrite )
  425. {
  426. DWORD dwStatus = ERROR_SUCCESS;
  427. HKEY hkeyMachine = HKEY_LOCAL_MACHINE;
  428. if ( NULL != strComputer ) {
  429. if( wcslen( strComputer ) ){
  430. dwStatus = RegConnectRegistryW (
  431. strComputer,
  432. HKEY_LOCAL_MACHINE,
  433. &hkeyMachine );
  434. }
  435. }
  436. if ( ERROR_SUCCESS == dwStatus ) {
  437. if( bQueries ){
  438. if ( bWrite ) {
  439. dwStatus = RegOpenKeyExW (
  440. hkeyMachine,
  441. L"System\\CurrentControlSet\\Services\\SysmonLog\\Log Queries",
  442. 0,
  443. KEY_READ|KEY_WRITE,
  444. &rhkeyLogQueries );
  445. }else{
  446. dwStatus = RegOpenKeyExW (
  447. hkeyMachine,
  448. L"System\\CurrentControlSet\\Services\\SysmonLog\\Log Queries",
  449. 0,
  450. KEY_READ,
  451. &rhkeyLogQueries );
  452. }
  453. }else{
  454. dwStatus = RegOpenKeyExW (
  455. hkeyMachine,
  456. L"System\\CurrentControlSet\\Services\\SysmonLog",
  457. 0,
  458. KEY_READ,
  459. &rhkeyLogQueries );
  460. }
  461. if ( ERROR_SUCCESS != dwStatus ) {
  462. dwStatus = PlaiCreateQuery( hkeyMachine, rhkeyLogQueries );
  463. }
  464. }
  465. if ( NULL != hkeyMachine && HKEY_LOCAL_MACHINE != hkeyMachine ) {
  466. RegCloseKey ( hkeyMachine );
  467. }
  468. return PlaiErrorToPdhStatus( dwStatus );
  469. }
  470. PDH_FUNCTION
  471. PlaiConnectAndLockQuery (
  472. LPCWSTR strComputer,
  473. LPCWSTR strQuery,
  474. HKEY& rhkeyQuery,
  475. BOOL bWrite )
  476. {
  477. DWORD dwStatus = ERROR_SUCCESS;
  478. PDH_STATUS pdhStatus = ERROR_SUCCESS;
  479. HKEY hkeyQuery = NULL;
  480. HKEY hkeyLogQueries = NULL;
  481. rhkeyQuery = NULL;
  482. dwStatus = WAIT_FOR_AND_LOCK_MUTEX(hPdhPlaMutex);
  483. if( ERROR_SUCCESS == dwStatus || WAIT_ABANDONED == dwStatus ){
  484. pdhStatus = PlaiConnectToRegistry (
  485. strComputer,
  486. hkeyLogQueries,
  487. TRUE,
  488. bWrite
  489. );
  490. if( ERROR_SUCCESS == pdhStatus ){
  491. DWORD nCollections = 0;
  492. DWORD nMaxSubKeyLength = 0;
  493. dwStatus = RegQueryInfoKey(
  494. hkeyLogQueries,
  495. NULL,
  496. NULL,
  497. NULL,
  498. &nCollections,
  499. &nMaxSubKeyLength,
  500. NULL,
  501. NULL,
  502. NULL,
  503. NULL,
  504. NULL,
  505. NULL
  506. );
  507. if( ERROR_SUCCESS == dwStatus ){
  508. LPWSTR strCollection;
  509. LPWSTR strQueryName = NULL;
  510. DWORD dwQueryName = 0;
  511. DWORD dwSize = (sizeof(WCHAR)*(nMaxSubKeyLength+1));
  512. strCollection = (LPWSTR)G_ALLOC( dwSize );
  513. if( strCollection ){
  514. dwStatus = ERROR_FILE_NOT_FOUND;
  515. for( ULONG i = 0; i<nCollections; i++ ){
  516. dwStatus = RegEnumKey( hkeyLogQueries, i, strCollection, dwSize );
  517. if( ERROR_SUCCESS == dwStatus ) {
  518. dwStatus = RegOpenKeyExW (
  519. hkeyLogQueries,
  520. strCollection,
  521. 0,
  522. bWrite ? KEY_READ | KEY_WRITE : KEY_READ,
  523. &hkeyQuery
  524. );
  525. if( ERROR_SUCCESS == dwStatus ){
  526. if( !_wcsicmp( strCollection, strQuery ) ){
  527. break;
  528. }
  529. PlaiReadRegistryStringValue( hkeyQuery, szCollection, READ_REG_MUI, &strQueryName, &dwQueryName );
  530. if( strQueryName != NULL && !_wcsicmp( strQueryName, strQuery ) ){
  531. break;
  532. }
  533. dwStatus = ERROR_FILE_NOT_FOUND;
  534. if ( NULL != hkeyQuery ) {
  535. RegCloseKey ( hkeyQuery );
  536. }
  537. }
  538. }
  539. }
  540. G_FREE( strQueryName );
  541. G_FREE( strCollection );
  542. }else{
  543. dwStatus = ERROR_OUTOFMEMORY;
  544. }
  545. }
  546. }
  547. if( NULL != hkeyLogQueries ){
  548. RegCloseKey ( hkeyLogQueries );
  549. }
  550. if( ERROR_SUCCESS != dwStatus || ERROR_SUCCESS != pdhStatus){
  551. RELEASE_MUTEX( hPdhPlaMutex );
  552. }else{
  553. rhkeyQuery = hkeyQuery;
  554. }
  555. }
  556. if( ERROR_SUCCESS != pdhStatus ){
  557. return pdhStatus;
  558. }else{
  559. return PlaiErrorToPdhStatus( dwStatus );
  560. }
  561. }