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.

497 lines
17 KiB

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <memory.h>
  4. #include "windows.h"
  5. #define MSG_ERROR_VALUE_INCORRECT_SIZE "\tERROR: Value entry data has incorrect size \n\t\tValueName = %ls \n\t\tNameSize = %d \n\t\tValueType = %s \n\t\tValueSize = %d\n"
  6. #define MSG_ERROR_VALUE_NOT_NUL_TERMINATED "\tERROR: Value entry data is not NUL terminated \n\t\tValueName = %ls \n\t\tNameSize = %d \n\t\tValueType = %s\n"
  7. #define MSG_ERROR_VALUE_UNKNOWN_DATA "\tERROR: Value entry contains unknown data \n\t\tValueName = %ls \n\t\tNameSize = %d \n\t\tValueType = %#x \n\t\tValueSize = %d\n"
  8. #define MSG_ERROR_REG_ENUM_VALUE "\tERROR: RegEnumValue() failed, iValue = %d, Status = %d \n"
  9. #define MSG_ERROR_REG_OPEN_KEY_EX "\tERROR: RegOpenKeyEx() failed, Status = %d \n"
  10. #define MSG_ERROR_REG_QUERY_INFO_KEY "\tERROR: RegQueryInfoKey() failed, Status = %d \n"
  11. #define MSG_ERROR_REG_ENUM_KEY_EX "ERROR: RegEnumKeyEx() failed, \n\t Status = %d \n\t, SubKey = %d"
  12. #define MSG_ERROR_REG_CONNECT_REGISTRY "ERROR: Unable to connect to %s, Status = %d \n"
  13. #define MSG_COMPLETE_KEY_NAME "%ls\\%ls \n"
  14. VOID
  15. ExamineValueEntries( IN HKEY Key,
  16. IN LPCWSTR CompleteKeyName,
  17. IN DWORD cchMaxValueName,
  18. IN DWORD cbMaxValueData,
  19. IN DWORD cValues,
  20. IN LPCWSTR PredefinedKeyName )
  21. {
  22. LONG Status;
  23. DWORD iValue;
  24. LPWSTR lpszValue;
  25. DWORD cchValue;
  26. DWORD dwType;
  27. PBYTE lpbData;
  28. DWORD cbData;
  29. BOOLEAN KeyNameAlreadyPrinted;
  30. //
  31. // Allocate the buffers for the value name and value data
  32. //
  33. lpszValue = ( LPWSTR )malloc( (cchMaxValueName + 1)*sizeof( WCHAR ) );
  34. lpbData = ( LPBYTE )malloc( cbMaxValueData );
  35. if( ( lpszValue == NULL ) ||
  36. ( lpbData == NULL ) ) {
  37. printf( "ERROR: Unable to allocate memory, cchMaxValueName = %d, cbMaxValuedata = %d \n",
  38. cchMaxValueName, cbMaxValueData );
  39. if( lpszValue != NULL ) {
  40. free( lpszValue );
  41. }
  42. if( lpbData != NULL ) {
  43. free( lpbData );
  44. }
  45. return;
  46. }
  47. //
  48. // Examine all value entries
  49. //
  50. KeyNameAlreadyPrinted = FALSE;
  51. for( iValue = 0; iValue < cValues; iValue++ ) {
  52. cchValue = cchMaxValueName + 1;
  53. cbData = cbMaxValueData;
  54. Status = RegEnumValueW( Key,
  55. iValue,
  56. lpszValue,
  57. &cchValue,
  58. 0,
  59. &dwType,
  60. lpbData,
  61. &cbData );
  62. if( Status != ERROR_SUCCESS ) {
  63. if( !KeyNameAlreadyPrinted ) {
  64. KeyNameAlreadyPrinted = TRUE;
  65. printf( MSG_COMPLETE_KEY_NAME, PredefinedKeyName, CompleteKeyName );
  66. }
  67. printf( MSG_ERROR_REG_ENUM_VALUE, iValue, Status );
  68. continue;
  69. }
  70. //
  71. // For debugging only
  72. //
  73. // printf( "\tValueName = %ls \n", lpszValue );
  74. //
  75. switch( dwType ) {
  76. case REG_BINARY:
  77. if( cbData == 0 ) {
  78. if( !KeyNameAlreadyPrinted ) {
  79. KeyNameAlreadyPrinted = TRUE;
  80. printf( MSG_COMPLETE_KEY_NAME, PredefinedKeyName, CompleteKeyName );
  81. }
  82. printf( MSG_ERROR_VALUE_INCORRECT_SIZE,
  83. lpszValue, cchValue, "REG_BINARY", cbData );
  84. }
  85. break;
  86. case REG_DWORD:
  87. if( cbData != sizeof( DWORD ) ) {
  88. if( !KeyNameAlreadyPrinted ) {
  89. KeyNameAlreadyPrinted = TRUE;
  90. printf( MSG_COMPLETE_KEY_NAME, PredefinedKeyName, CompleteKeyName );
  91. }
  92. printf( MSG_ERROR_VALUE_INCORRECT_SIZE,
  93. lpszValue, cchValue, "REG_DWORD", cbData );
  94. }
  95. break;
  96. case REG_DWORD_BIG_ENDIAN:
  97. if( cbData != sizeof( DWORD ) ) {
  98. if( !KeyNameAlreadyPrinted ) {
  99. KeyNameAlreadyPrinted = TRUE;
  100. printf( MSG_COMPLETE_KEY_NAME, PredefinedKeyName, CompleteKeyName );
  101. }
  102. printf( MSG_ERROR_VALUE_INCORRECT_SIZE,
  103. lpszValue, cchValue, "REG_DWORD_BIG_ENDIAN", cbData );
  104. }
  105. break;
  106. case REG_EXPAND_SZ:
  107. if( ( cbData != 0 ) && ( ( cbData % sizeof( WCHAR ) ) == 0 )) {
  108. if( *( ( PWCHAR )( lpbData + cbData - sizeof( WCHAR ) ) ) != ( WCHAR )'\0' ) {
  109. if( !KeyNameAlreadyPrinted ) {
  110. KeyNameAlreadyPrinted = TRUE;
  111. printf( MSG_COMPLETE_KEY_NAME, PredefinedKeyName, CompleteKeyName );
  112. }
  113. printf( MSG_ERROR_VALUE_NOT_NUL_TERMINATED,
  114. lpszValue, cchValue, "REG_EXPAND_SZ" );
  115. }
  116. } else {
  117. if( !KeyNameAlreadyPrinted ) {
  118. KeyNameAlreadyPrinted = TRUE;
  119. printf( MSG_COMPLETE_KEY_NAME, PredefinedKeyName, CompleteKeyName );
  120. }
  121. printf( MSG_ERROR_VALUE_INCORRECT_SIZE,
  122. lpszValue, cchValue, "REG_EXPAND_SZ", cbData );
  123. }
  124. break;
  125. case REG_LINK:
  126. if( cbData == 0 ) {
  127. if( !KeyNameAlreadyPrinted ) {
  128. KeyNameAlreadyPrinted = TRUE;
  129. printf( MSG_COMPLETE_KEY_NAME, PredefinedKeyName, CompleteKeyName );
  130. }
  131. printf( MSG_ERROR_VALUE_INCORRECT_SIZE,
  132. lpszValue, cchValue, "REG_LINK", cbData );
  133. }
  134. break;
  135. case REG_MULTI_SZ:
  136. if( ( cbData != 0 ) && ( ( cbData % sizeof( WCHAR ) ) == 0 )) {
  137. if( *( ( PWCHAR )( lpbData + cbData - sizeof( WCHAR ) ) ) != ( WCHAR )'\0' ) {
  138. if( !KeyNameAlreadyPrinted ) {
  139. KeyNameAlreadyPrinted = TRUE;
  140. printf( MSG_COMPLETE_KEY_NAME, PredefinedKeyName, CompleteKeyName );
  141. }
  142. printf( MSG_ERROR_VALUE_NOT_NUL_TERMINATED,
  143. lpszValue, cchValue, "REG_MULTI_SZ" );
  144. }
  145. } else {
  146. if( !KeyNameAlreadyPrinted ) {
  147. KeyNameAlreadyPrinted = TRUE;
  148. printf( MSG_COMPLETE_KEY_NAME, PredefinedKeyName, CompleteKeyName );
  149. }
  150. printf( MSG_ERROR_VALUE_INCORRECT_SIZE,
  151. lpszValue, cchValue, "REG_MULTI_SZ", cbData );
  152. }
  153. break;
  154. case REG_NONE:
  155. if( cbData != 0 ) {
  156. if( !KeyNameAlreadyPrinted ) {
  157. KeyNameAlreadyPrinted = TRUE;
  158. printf( MSG_COMPLETE_KEY_NAME, PredefinedKeyName, CompleteKeyName );
  159. }
  160. printf( MSG_ERROR_VALUE_INCORRECT_SIZE,
  161. lpszValue, cchValue, "REG_NONE", cbData );
  162. }
  163. break;
  164. case REG_RESOURCE_LIST:
  165. if( cbData == 0 ) {
  166. if( !KeyNameAlreadyPrinted ) {
  167. KeyNameAlreadyPrinted = TRUE;
  168. printf( MSG_COMPLETE_KEY_NAME, PredefinedKeyName, CompleteKeyName );
  169. }
  170. printf( MSG_ERROR_VALUE_INCORRECT_SIZE,
  171. lpszValue, cchValue, "REG_RESOURCE_LIST", cbData );
  172. }
  173. break;
  174. case REG_SZ:
  175. if( ( cbData != 0 ) && ( ( cbData % sizeof( WCHAR ) ) == 0 ) ) {
  176. if( *( ( PWCHAR )( lpbData + cbData - sizeof( WCHAR ) ) ) != ( WCHAR )'\0' ) {
  177. if( !KeyNameAlreadyPrinted ) {
  178. KeyNameAlreadyPrinted = TRUE;
  179. printf( MSG_COMPLETE_KEY_NAME, PredefinedKeyName, CompleteKeyName );
  180. }
  181. printf( MSG_ERROR_VALUE_NOT_NUL_TERMINATED,
  182. lpszValue, cchValue, "REG_SZ" );
  183. }
  184. } else {
  185. if( !KeyNameAlreadyPrinted ) {
  186. KeyNameAlreadyPrinted = TRUE;
  187. printf( MSG_COMPLETE_KEY_NAME, PredefinedKeyName, CompleteKeyName );
  188. }
  189. printf( MSG_ERROR_VALUE_INCORRECT_SIZE,
  190. lpszValue, cchValue, "REG_SZ", cbData );
  191. }
  192. break;
  193. case REG_FULL_RESOURCE_DESCRIPTOR:
  194. if( cbData == 0 ) {
  195. if( !KeyNameAlreadyPrinted ) {
  196. KeyNameAlreadyPrinted = TRUE;
  197. printf( MSG_COMPLETE_KEY_NAME, PredefinedKeyName, CompleteKeyName );
  198. }
  199. printf( MSG_ERROR_VALUE_INCORRECT_SIZE,
  200. lpszValue, cchValue, "REG_FULL_RESOURCE_DESCRIPTOR", cbData );
  201. }
  202. break;
  203. default:
  204. if( !KeyNameAlreadyPrinted ) {
  205. KeyNameAlreadyPrinted = TRUE;
  206. printf( MSG_COMPLETE_KEY_NAME, PredefinedKeyName, CompleteKeyName );
  207. }
  208. printf( MSG_ERROR_VALUE_UNKNOWN_DATA,
  209. lpszValue, cchValue, dwType, cbData );
  210. break;
  211. }
  212. }
  213. //
  214. // Free buffers for value name and value data
  215. //
  216. free( lpszValue );
  217. free( lpbData );
  218. }
  219. VOID
  220. ExamineKey(
  221. IN HKEY PredefinedKey,
  222. IN LPCWSTR ParentName,
  223. IN LPCWSTR KeyName,
  224. IN LPCWSTR PredefinedKeyName
  225. )
  226. {
  227. LPWSTR CompleteKeyName;
  228. HKEY Key;
  229. LONG Status;
  230. WCHAR szClass[ MAX_PATH + 1 ];
  231. DWORD cchClass;
  232. DWORD cSubKeys;
  233. DWORD cchMaxSubKey;
  234. DWORD cchMaxClass;
  235. DWORD cValues;
  236. DWORD cchMaxValueName;
  237. DWORD cbMaxValueData;
  238. DWORD cbSecurityDescriptor;
  239. FILETIME ftLastWriteTime;
  240. WCHAR szSubKeyName[ MAX_PATH + 1 ];
  241. DWORD cchSubKeyNameLength;
  242. DWORD iSubKey;
  243. BOOLEAN KeyNameAlreadyPrinted;
  244. //
  245. // Build the complete key name
  246. //
  247. if( wcslen( ParentName ) == 0 ) {
  248. CompleteKeyName = wcsdup( KeyName );
  249. if( CompleteKeyName == NULL ) {
  250. printf( "ERROR: wcsdup( KeyName ) failed \n" );
  251. return;
  252. }
  253. } else {
  254. CompleteKeyName = wcsdup( ParentName );
  255. if( CompleteKeyName == NULL ) {
  256. printf( "ERROR: wcsdup( ParentName ) failed \n" );
  257. return;
  258. }
  259. if( wcslen( KeyName ) != 0 ) {
  260. CompleteKeyName = realloc( CompleteKeyName,
  261. ( wcslen( CompleteKeyName ) +
  262. wcslen( L"\\" ) +
  263. wcslen( KeyName ) + 1 )*sizeof( WCHAR ) );
  264. wcscat( CompleteKeyName, L"\\" );
  265. wcscat( CompleteKeyName, KeyName );
  266. }
  267. }
  268. //
  269. // For debugging only
  270. //
  271. // printf( "%ls\\%ls \n", PredefinedKeyName, CompleteKeyName );
  272. //
  273. //
  274. // Open the key
  275. //
  276. Status = RegOpenKeyExW( PredefinedKey,
  277. CompleteKeyName,
  278. 0,
  279. MAXIMUM_ALLOWED,
  280. &Key );
  281. if( Status != ERROR_SUCCESS ) {
  282. printf( MSG_COMPLETE_KEY_NAME, PredefinedKeyName, CompleteKeyName );
  283. printf( MSG_ERROR_REG_OPEN_KEY_EX, Status );
  284. free( CompleteKeyName );
  285. return;
  286. }
  287. //
  288. // Determine the number of value entries, the maximum length of a value
  289. // entry name, the maximum data size, and the number of subkeys
  290. //
  291. cchClass = sizeof( szClass ) / sizeof( WCHAR );
  292. Status = RegQueryInfoKeyW( Key,
  293. szClass,
  294. &cchClass,
  295. 0,
  296. &cSubKeys,
  297. &cchMaxSubKey,
  298. &cchMaxClass,
  299. &cValues,
  300. &cchMaxValueName,
  301. &cbMaxValueData,
  302. &cbSecurityDescriptor,
  303. &ftLastWriteTime );
  304. if( Status != ERROR_SUCCESS ) {
  305. printf( MSG_COMPLETE_KEY_NAME, PredefinedKeyName, CompleteKeyName );
  306. printf( MSG_ERROR_REG_QUERY_INFO_KEY, Status );
  307. free( CompleteKeyName );
  308. RegCloseKey( Key );
  309. return;
  310. }
  311. if( cValues != 0 ) {
  312. //
  313. // Examine the value entries
  314. //
  315. ExamineValueEntries( Key,
  316. CompleteKeyName,
  317. cchMaxValueName,
  318. cbMaxValueData,
  319. cValues,
  320. PredefinedKeyName );
  321. }
  322. //
  323. // Traverse each subkey
  324. //
  325. if( cSubKeys != 0 ) {
  326. KeyNameAlreadyPrinted = FALSE;
  327. for( iSubKey = 0; iSubKey < cSubKeys; iSubKey++ ) {
  328. cchSubKeyNameLength = sizeof( szSubKeyName )/sizeof( WCHAR );
  329. cchClass = sizeof( szClass ) / sizeof( WCHAR );
  330. Status = RegEnumKeyExW( Key,
  331. iSubKey,
  332. szSubKeyName,
  333. &cchSubKeyNameLength,
  334. 0,
  335. NULL,
  336. NULL,
  337. &ftLastWriteTime );
  338. if( Status != ERROR_SUCCESS ) {
  339. if( !KeyNameAlreadyPrinted ) {
  340. KeyNameAlreadyPrinted = TRUE;
  341. printf( MSG_COMPLETE_KEY_NAME, PredefinedKeyName, CompleteKeyName );
  342. }
  343. printf( MSG_ERROR_REG_ENUM_KEY_EX, Status, iSubKey );
  344. continue;
  345. }
  346. ExamineKey( PredefinedKey,
  347. CompleteKeyName,
  348. szSubKeyName,
  349. PredefinedKeyName );
  350. }
  351. }
  352. RegCloseKey( Key );
  353. free( CompleteKeyName );
  354. }
  355. main( int argc, char* argv[] )
  356. {
  357. DWORD i;
  358. HKEY RemoteUsers;
  359. HKEY RemoteLocalMachine;
  360. LONG Status;
  361. if( argc <= 1 ) {
  362. printf( "\n******* Examining HKEY_LOCAL_MACHINE on local machine\n\n" );
  363. ExamineKey( HKEY_LOCAL_MACHINE,
  364. L"",
  365. L"",
  366. L"HKEY_LOCAL_MACHINE" );
  367. printf( "\n******* Examining HKEY_USERS on local machine\n\n" );
  368. ExamineKey( HKEY_USERS,
  369. L"",
  370. L"",
  371. L"HKEY_USERS" );
  372. printf( "\n******* Examining HKEY_CLASSES_ROOT on local machine\n\n" );
  373. ExamineKey( HKEY_CLASSES_ROOT,
  374. L"",
  375. L"",
  376. L"HKEY_CLASSES_ROOT" );
  377. printf( "\n******* Examining HKEY_CURRENT_USER on local machine\n\n" );
  378. ExamineKey( HKEY_CURRENT_USER,
  379. L"",
  380. L"",
  381. L"HKEY_CURRENT_USER" );
  382. } else {
  383. for( i = 1; i < argc; i++ ) {
  384. //
  385. // printf( "Machine name = %s \n", argv[ i ] );
  386. //
  387. Status = RegConnectRegistry( argv[ i ],
  388. HKEY_LOCAL_MACHINE,
  389. &RemoteLocalMachine );
  390. if( Status != ERROR_SUCCESS ) {
  391. printf( MSG_ERROR_REG_CONNECT_REGISTRY, argv[i], Status );
  392. continue;
  393. }
  394. Status = RegConnectRegistry( argv[ i ],
  395. HKEY_USERS,
  396. &RemoteUsers );
  397. if( Status != ERROR_SUCCESS ) {
  398. RegCloseKey( RemoteLocalMachine );
  399. printf( MSG_ERROR_REG_CONNECT_REGISTRY, argv[i], Status );
  400. continue;
  401. }
  402. printf( "\n******* Examining HKEY_LOCAL_MACHINE on %s \n\n", argv[i] );
  403. ExamineKey( RemoteLocalMachine,
  404. L"",
  405. L"",
  406. L"HKEY_LOCAL_MACHINE" );
  407. printf( "\n******* Examining HKEY_USERS on %s \n\n", argv[i] );
  408. ExamineKey( RemoteUsers,
  409. L"",
  410. L"",
  411. L"HKEY_USERS" );
  412. RegCloseKey( RemoteLocalMachine );
  413. RegCloseKey( RemoteUsers );
  414. }
  415. }
  416. }