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.

3734 lines
139 KiB

  1. /*++
  2. Copyright (c) 1997-1999 Microsoft Corporation
  3. Module Name:
  4. config.c
  5. Abstract:
  6. GetConfigParam reads a configuration keyword from the registry.
  7. Author:
  8. David Orbits - June-1999 Complete Rewrite to make table driven.
  9. Environment:
  10. Revision History:
  11. --*/
  12. #include <ntreppch.h>
  13. #pragma hdrstop
  14. #include <ctype.h>
  15. #include <frs.h>
  16. #include <ntfrsapi.h>
  17. #define FULL_KEY_BUFF_SIZE 8192
  18. VOID
  19. FrsRegPostEventLog(
  20. IN PFRS_REGISTRY_KEY KeyCtx,
  21. IN PWCHAR KeyArg1,
  22. IN ULONG Flags,
  23. IN LONG IDScode
  24. );
  25. //
  26. // Possible errors are:
  27. // required key not present
  28. // required value not present
  29. // value out of range
  30. //
  31. // **** NOTE: Also use this for FRS tuning parameters to select between
  32. // workstation and server operation modes. Create a table with a list of the
  33. // parameter codes and override values for the min, max and defaults.
  34. // Apply during startup to reduce server footprint.
  35. //
  36. typedef struct _FRS_REG_KEY_REVISIONS {
  37. LONG FrsKeyCode; // Frs code name for this key.
  38. DWORD ValueMin; // Minimum data value, or string len
  39. DWORD ValueMax; // Maximum Data value, or string len
  40. DWORD ValueDefault; // Default data value if not present.
  41. } FRS_REG_KEY_REVISIONS, *PFRS_REG_KEY_REVISIONS;
  42. FRS_REG_KEY_REVISIONS FrsRegKeyRevisionTable[] = {
  43. {FKC_DEBUG_LOG_FILES , 0 , 8, 2 },
  44. {FKC_DEBUG_LOG_SEVERITY , 0 , 5, 0 },
  45. {FKC_DEBUG_MAX_LOG , 0 , MAXULONG, 10000 },
  46. {FKC_MAX_REPLICA_THREADS , 2 , 10, 2 },
  47. {FKC_MAX_RPC_SERVER_THREADS , 2 , 10, 2 },
  48. {FKC_MAX_INSTALLCS_THREADS , 2 , 10, 2 },
  49. {FKC_MAX_STAGE_GENCS_THREADS, 2 , 10, 2 },
  50. {FKC_MAX_STAGE_FETCHCS_THREADS, 2 , 10, 2 },
  51. {FKC_MAX_INITSYNCCS_THREADS, 2 , 10, 2 },
  52. {FKC_SNDCS_MAXTHREADS_PAR , 2 , 10, 2 },
  53. {FKC_STAGING_LIMIT , 2*1024, 64*1024, 16*1024 },
  54. {FKC_NTFS_JRNL_SIZE , 1 , 128, 8 },
  55. {FKC_MAX_NUMBER_REPLICA_SETS, 1 , 30, 5 },
  56. {FKC_MAX_NUMBER_JET_SESSIONS, 1 , 50, 50 },
  57. {FKC_END_OF_TABLE, 0, 0, 0 }
  58. };
  59. //
  60. // See sdk\inc\ntconfig.h if more registry data types are added.
  61. //
  62. #define NUMBER_OF_REG_DATATYPES 12
  63. PWCHAR RegDataTypeNames[NUMBER_OF_REG_DATATYPES] = {
  64. L"REG_NONE" , // ( 0 ) No value type
  65. L"REG_SZ" , // ( 1 ) Unicode nul terminated string
  66. L"REG_EXPAND_SZ" , // ( 2 ) Unicode nul terminated string (with environment variable references)
  67. L"REG_BINARY" , // ( 3 ) Free form binary
  68. L"REG_DWORD" , // ( 4 ) 32-bit number
  69. L"REG_DWORD_BIG_ENDIAN" , // ( 5 ) 32-bit number
  70. L"REG_LINK" , // ( 6 ) Symbolic Link (unicode)
  71. L"REG_MULTI_SZ" , // ( 7 ) Multiple Unicode strings
  72. L"REG_RESOURCE_LIST" , // ( 8 ) Resource list in the resource map
  73. L"REG_FULL_RESOURCE_DESCRIPTOR" , // ( 9 ) Resource list in the hardware description
  74. L"REG_RESOURCE_REQUIREMENTS_LIST" , // ( 10 )
  75. L"REG_QWORD" // ( 11 ) 64-bit number
  76. };
  77. #define REG_DT_NAME(_code_) \
  78. (((_code_) < NUMBER_OF_REG_DATATYPES) ? \
  79. RegDataTypeNames[(_code_)] : RegDataTypeNames[0])
  80. //
  81. //
  82. // If a range check fails the event EVENT_FRS_PARAM_OUT_OF_RANGE is logged if
  83. // FRS_RKF_LOG_EVENT is set.
  84. //
  85. // If a syntax check fails the event EVENT_FRS_PARAM_INVALID_SYNTAX is logged if
  86. // FRS_RKF_LOG_EVENT is set.
  87. //
  88. // If a required parameter is missing the event EVENT_FRS_PARAM_MISSING is logged
  89. // if FRS_RKF_LOG_EVENT is set.
  90. //
  91. BOOL Win2kPro;
  92. FLAG_NAME_TABLE RkfFlagNameTable[] = {
  93. {FRS_RKF_KEY_PRESENT , "KeyPresent " },
  94. {FRS_RKF_VALUE_PRESENT , "ValuePresent " },
  95. {FRS_RKF_DISPLAY_ERROR , "ShowErrorMsg " },
  96. {FRS_RKF_LOG_EVENT , "ShowEventMsg " },
  97. {FRS_RKF_READ_AT_START , "ReadAtStart " },
  98. {FRS_RKF_READ_AT_POLL , "ReadAtPoll " },
  99. {FRS_RKF_RANGE_CHECK , "RangeCheck " },
  100. {FRS_RKF_SYNTAX_CHECK , "SyntaxCheck " },
  101. {FRS_RKF_KEY_MUST_BE_PRESENT , "KeyMustBePresent " },
  102. {FRS_RKF_VALUE_MUST_BE_PRESENT , "ValueMustBePresent " },
  103. {FRS_RKF_OK_TO_USE_DEFAULT , "DefaultOK " },
  104. {FRS_RKF_FORCE_DEFAULT_VALUE , "ForceDefault " },
  105. {FRS_RKF_DEBUG_MODE_ONLY , "DebugMode " },
  106. {FRS_RKF_TEST_MODE_ONLY , "TestMode " },
  107. {FRS_RKF_API_ACCESS_CHECK_KEY , "DoAPIAccessChk " },
  108. {FRS_RKF_CREATE_KEY , "CreateKey " },
  109. {FRS_RKF_KEEP_EXISTING_VALUE , "KeepExistingValue " },
  110. {FRS_RKF_KEY_ACCCHK_READ , "DoReadAccessChk " },
  111. {FRS_RKF_KEY_ACCCHK_WRITE , "DoWriteAccessChk " },
  112. {FRS_RKF_RANGE_SATURATE , "RangeSaturate " },
  113. {FRS_RKF_DEBUG_PARAM , "DisplayAsDebugPar " },
  114. {0, NULL}
  115. };
  116. //
  117. // The following describes the registry keys used by FRS.
  118. // KeyName ValueName DataUnits
  119. // RegValueType DataValueType Min Max Default EventCode
  120. // FrsKeyCode Flags
  121. //
  122. //
  123. // Notation for keyName field. Multiple key components separated by commas.
  124. // Break on commas. Open leading key then create/open each successive component.
  125. // ARG1 means substitute the Arg1 PWSTR parameter passed to the function for this
  126. // key component. Most often this is a stringized guid. The string FRS_RKEY_SET_N
  127. // below will end up opening/creating the following key:
  128. //
  129. // "System\\CurrentControlSet\\Services\\NtFrs\\Parameters\\Replica Sets\\27d6d1c4-d6b8-480b-9f18b5ea390a0178"
  130. // assuming the argument passed in was "27d6d1c4-d6b8-480b-9f18b5ea390a0178"
  131. //
  132. // see FrsRegOpenKey() for details.
  133. //
  134. FRS_REGISTRY_KEY FrsRegistryKeyTable[] = {
  135. /******************************************************************************
  136. *******************************************************************************
  137. ** **
  138. ** S e r v i c e D e b u g K e y s **
  139. ** **
  140. ** **
  141. *******************************************************************************
  142. ******************************************************************************/
  143. // Number of assert files
  144. {FRS_CONFIG_SECTION, L"Debug Assert Files", UNITS_NONE,
  145. REG_DWORD, DT_ULONG, 0, 1000, 5, EVENT_FRS_BAD_REG_DATA, NULL,
  146. FKC_DEBUG_ASSERT_FILES, FRS_RKF_READ_AT_START |
  147. FRS_RKF_LOG_EVENT |
  148. FRS_RKF_RANGE_CHECK |
  149. FRS_RKF_DEBUG_PARAM |
  150. FRS_RKF_OK_TO_USE_DEFAULT},
  151. // Force an assert after N seconds (0 == don't assert)
  152. {FRS_CONFIG_SECTION, L"Debug Force Assert in N Seconds", UNITS_SECONDS,
  153. REG_DWORD, DT_ULONG, 0, 1000, 0, EVENT_FRS_BAD_REG_DATA, NULL,
  154. FKC_DEBUG_ASSERT_SECONDS, FRS_RKF_READ_AT_START |
  155. FRS_RKF_LOG_EVENT |
  156. FRS_RKF_RANGE_CHECK |
  157. FRS_RKF_DEBUG_PARAM |
  158. FRS_RKF_OK_TO_USE_DEFAULT |
  159. FRS_RKF_TEST_MODE_ONLY},
  160. // Share for copying log/assert files
  161. {FRS_CONFIG_SECTION, L"Debug Share for Assert Files", UNITS_NONE,
  162. REG_SZ, DT_UNICODE, 0, 0, 0, EVENT_FRS_NONE, NULL,
  163. FKC_DEBUG_ASSERT_SHARE, FRS_RKF_READ_AT_START |
  164. FRS_RKF_DEBUG_PARAM},
  165. // If TRUE, Break into the debugger, if present
  166. {FRS_CONFIG_SECTION, L"Debug Break", UNITS_NONE,
  167. REG_DWORD, DT_BOOL, FALSE, TRUE, FALSE, EVENT_FRS_NONE, NULL,
  168. FKC_DEBUG_BREAK, FRS_RKF_READ_AT_START |
  169. FRS_RKF_READ_AT_POLL |
  170. FRS_RKF_RANGE_CHECK |
  171. FRS_RKF_TEST_MODE_ONLY |
  172. FRS_RKF_DEBUG_PARAM |
  173. FRS_RKF_OK_TO_USE_DEFAULT},
  174. // If TRUE, copy log files into assert share
  175. {FRS_CONFIG_SECTION, L"Debug Copy Log Files into Assert Share", UNITS_NONE,
  176. REG_DWORD, DT_BOOL, FALSE, TRUE, FALSE, EVENT_FRS_BAD_REG_DATA, NULL,
  177. FKC_DEBUG_COPY_LOG_FILES, FRS_RKF_READ_AT_START |
  178. FRS_RKF_LOG_EVENT |
  179. FRS_RKF_READ_AT_POLL |
  180. FRS_RKF_RANGE_CHECK |
  181. FRS_RKF_DEBUG_PARAM |
  182. FRS_RKF_OK_TO_USE_DEFAULT},
  183. // Force real out of disk space errors on database operations
  184. {FRS_CONFIG_SECTION, L"Debug Dbs Out Of Space", UNITS_NONE,
  185. REG_DWORD, DT_ULONG, 0, DBG_DBS_OUT_OF_SPACE_OP_MAX, 0, EVENT_FRS_BAD_REG_DATA, NULL,
  186. FKC_DEBUG_DBS_OUT_OF_SPACE, FRS_RKF_READ_AT_START |
  187. FRS_RKF_LOG_EVENT |
  188. FRS_RKF_READ_AT_POLL |
  189. FRS_RKF_TEST_MODE_ONLY |
  190. FRS_RKF_RANGE_CHECK |
  191. FRS_RKF_DEBUG_PARAM |
  192. FRS_RKF_OK_TO_USE_DEFAULT},
  193. // Force Jet Err simulated out of disk space errors on database operations
  194. {FRS_CONFIG_SECTION, L"Debug Dbs Out Of Space Trigger", UNITS_NONE,
  195. REG_DWORD, DT_ULONG, 0, MAXULONG, 0, EVENT_FRS_BAD_REG_DATA, NULL,
  196. FKC_DEBUG_DBS_OUT_OF_SPACE_TRIGGER, FRS_RKF_READ_AT_START |
  197. FRS_RKF_LOG_EVENT |
  198. FRS_RKF_READ_AT_POLL |
  199. FRS_RKF_TEST_MODE_ONLY |
  200. FRS_RKF_DEBUG_PARAM |
  201. FRS_RKF_OK_TO_USE_DEFAULT},
  202. // If TRUE, debug log file generation (DPRINTS and CO Trace output) is off.
  203. {FRS_CONFIG_SECTION, L"Debug Disable", UNITS_NONE,
  204. REG_DWORD, DT_BOOL, FALSE, TRUE, FALSE, EVENT_FRS_NONE, NULL,
  205. FKC_DEBUG_DISABLE, FRS_RKF_READ_AT_START |
  206. FRS_RKF_READ_AT_POLL |
  207. FRS_RKF_RANGE_CHECK |
  208. FRS_RKF_DEBUG_PARAM |
  209. FRS_RKF_OK_TO_USE_DEFAULT},
  210. // The directory path for the FRS debug logs.
  211. {FRS_CONFIG_SECTION, L"Debug Log File", UNITS_NONE,
  212. REG_EXPAND_SZ, DT_UNICODE, 0, 0, 0, EVENT_FRS_BAD_REG_DATA,
  213. L"%SystemRoot%\\debug",
  214. FKC_DEBUG_LOG_FILE, FRS_RKF_READ_AT_START |
  215. FRS_RKF_LOG_EVENT |
  216. FRS_RKF_DEBUG_PARAM |
  217. FRS_RKF_SYNTAX_CHECK |
  218. FRS_RKF_OK_TO_USE_DEFAULT},
  219. // Number of debug log files to keep as history
  220. {FRS_CONFIG_SECTION, L"Debug Log Files", UNITS_NONE,
  221. REG_DWORD, DT_ULONG, 0, 300, 5, EVENT_FRS_BAD_REG_DATA, NULL,
  222. FKC_DEBUG_LOG_FILES, FRS_RKF_READ_AT_START |
  223. FRS_RKF_LOG_EVENT |
  224. FRS_RKF_RANGE_CHECK |
  225. FRS_RKF_DEBUG_PARAM |
  226. FRS_RKF_OK_TO_USE_DEFAULT},
  227. // Number of debug log records written between file flushes.
  228. // btw: Severity 0 log records always force a log file flush.
  229. {FRS_CONFIG_SECTION, L"Debug Log Flush Interval", UNITS_NONE,
  230. REG_DWORD, DT_LONG, 1, MAXLONG, 20000, EVENT_FRS_BAD_REG_DATA, NULL,
  231. FKC_DEBUG_LOG_FLUSH_INTERVAL, FRS_RKF_READ_AT_START |
  232. FRS_RKF_LOG_EVENT |
  233. FRS_RKF_RANGE_CHECK |
  234. FRS_RKF_DEBUG_PARAM |
  235. FRS_RKF_OK_TO_USE_DEFAULT},
  236. // Print debug msgs with severity level LE DEBUG_LOG_SEVERITY to debug log.
  237. // 0 - Most severe, eg. fatal inconsistency, mem alloc fail. Least noisey.
  238. // 1 - Important info, eg. Key config parameters, unexpected conditions
  239. // 2 - File tracking records.
  240. // 3 - Change Order Process trace records.
  241. // 4 - Status results, e.g. table lookup failures, new entry inserted
  242. // 5 - Information level messages to show flow. Noisest level. Maybe in a loop
  243. // see also DEBUG_SEVERITY.
  244. {FRS_CONFIG_SECTION, L"Debug Log Severity", UNITS_NONE,
  245. REG_DWORD, DT_ULONG, 0, 5, 2, EVENT_FRS_BAD_REG_DATA, NULL,
  246. FKC_DEBUG_LOG_SEVERITY, FRS_RKF_READ_AT_START |
  247. FRS_RKF_LOG_EVENT |
  248. FRS_RKF_READ_AT_POLL |
  249. FRS_RKF_RANGE_CHECK |
  250. FRS_RKF_DEBUG_PARAM |
  251. FRS_RKF_OK_TO_USE_DEFAULT},
  252. // Max number of debug log messages output before opening a new log file.
  253. {FRS_CONFIG_SECTION, L"Debug Maximum Log Messages", UNITS_NONE,
  254. REG_DWORD, DT_ULONG, 0, MAXULONG, 20000, EVENT_FRS_BAD_REG_DATA, NULL,
  255. FKC_DEBUG_MAX_LOG, FRS_RKF_READ_AT_START |
  256. FRS_RKF_LOG_EVENT |
  257. FRS_RKF_READ_AT_POLL |
  258. FRS_RKF_DEBUG_PARAM |
  259. FRS_RKF_OK_TO_USE_DEFAULT},
  260. // If >0, then track and check all mem alloc / dealloc. (slow)
  261. // 1 - checks allocs and frees and prints stack of unalloced mem at exit
  262. // 2 - checks for mem alloc region overwrite on each alloc/free - very slow.
  263. //
  264. {FRS_CONFIG_SECTION, L"Debug Mem", UNITS_NONE,
  265. REG_DWORD, DT_ULONG, 0, 4, 0, EVENT_FRS_NONE, NULL,
  266. FKC_DEBUG_MEM, FRS_RKF_READ_AT_START |
  267. FRS_RKF_RANGE_CHECK |
  268. FRS_RKF_TEST_MODE_ONLY |
  269. FRS_RKF_DEBUG_PARAM |
  270. FRS_RKF_OK_TO_USE_DEFAULT},
  271. // If TRUE, then call HeapCompact(GetProcessHeap(), 0) on mem dealloc. (slower)
  272. {FRS_CONFIG_SECTION, L"Debug Mem Compact", UNITS_NONE,
  273. REG_DWORD, DT_BOOL, FALSE, TRUE, FALSE, EVENT_FRS_NONE, NULL,
  274. FKC_DEBUG_MEM_COMPACT, FRS_RKF_READ_AT_START |
  275. FRS_RKF_READ_AT_POLL |
  276. FRS_RKF_RANGE_CHECK |
  277. FRS_RKF_TEST_MODE_ONLY |
  278. FRS_RKF_DEBUG_PARAM |
  279. FRS_RKF_OK_TO_USE_DEFAULT},
  280. // Mail profile for sending mail notifications. (future)
  281. {FRS_CONFIG_SECTION, L"Debug Profile", UNITS_NONE,
  282. REG_SZ, DT_UNICODE, 0, 0, 0, EVENT_FRS_NONE, NULL,
  283. FKC_DEBUG_PROFILE, FRS_RKF_READ_AT_START |
  284. FRS_RKF_DEBUG_PARAM |
  285. FRS_RKF_READ_AT_POLL},
  286. // If TRUE, then check consistency of command queues on each queue op. (slow)
  287. {FRS_CONFIG_SECTION, L"Debug Queues", UNITS_NONE,
  288. REG_DWORD, DT_BOOL, FALSE, TRUE, FALSE, EVENT_FRS_NONE, NULL,
  289. FKC_DEBUG_QUEUES, FRS_RKF_READ_AT_START |
  290. FRS_RKF_READ_AT_POLL |
  291. FRS_RKF_RANGE_CHECK |
  292. FRS_RKF_TEST_MODE_ONLY |
  293. FRS_RKF_DEBUG_PARAM |
  294. FRS_RKF_OK_TO_USE_DEFAULT},
  295. // Mail recipients for sending mail notifications. (future)
  296. {FRS_CONFIG_SECTION, L"Debug Recipients", UNITS_NONE,
  297. REG_EXPAND_SZ, DT_UNICODE, 0, 0, 0, EVENT_FRS_NONE, NULL,
  298. FKC_DEBUG_RECIPIENTS, FRS_RKF_READ_AT_START |
  299. FRS_RKF_DEBUG_PARAM |
  300. FRS_RKF_READ_AT_POLL},
  301. // Restart the service after an assertion failure iff the service was able
  302. // to run for at least DEBUG_RESTART_SECONDS before the assert hit.
  303. {FRS_CONFIG_SECTION, L"Debug Restart if Assert after N Seconds", UNITS_SECONDS,
  304. REG_DWORD, DT_ULONG, 0, MAXULONG, 600, EVENT_FRS_BAD_REG_DATA, NULL,
  305. FKC_DEBUG_RESTART_SECONDS, FRS_RKF_READ_AT_START |
  306. FRS_RKF_READ_AT_POLL |
  307. FRS_RKF_LOG_EVENT |
  308. FRS_RKF_DEBUG_PARAM |
  309. FRS_RKF_OK_TO_USE_DEFAULT},
  310. // Print debug msgs with severity level LE DEBUG_SEVERITY to
  311. // stdout if running as -notservice.
  312. // see also DEBUG_LOG_SEVERITY.
  313. {FRS_CONFIG_SECTION, L"Debug Severity", UNITS_NONE,
  314. REG_DWORD, DT_ULONG, 0, 5, 0, EVENT_FRS_BAD_REG_DATA, NULL,
  315. FKC_DEBUG_SEVERITY, FRS_RKF_READ_AT_START |
  316. FRS_RKF_READ_AT_POLL |
  317. FRS_RKF_LOG_EVENT |
  318. FRS_RKF_RANGE_CHECK |
  319. FRS_RKF_DEBUG_PARAM |
  320. FRS_RKF_OK_TO_USE_DEFAULT},
  321. // If FALSE, Print debug msgs with severity level LE DEBUG_SEVERITY to
  322. // an attached debugger. (slow)
  323. // see also DEBUG_LOG_SEVERITY.
  324. {FRS_CONFIG_SECTION, L"Debug Suppress", UNITS_NONE,
  325. REG_DWORD, DT_BOOL, FALSE, TRUE, TRUE, EVENT_FRS_NONE, NULL,
  326. FKC_DEBUG_SUPPRESS, FRS_RKF_READ_AT_START |
  327. FRS_RKF_READ_AT_POLL |
  328. FRS_RKF_RANGE_CHECK |
  329. FRS_RKF_DEBUG_PARAM |
  330. FRS_RKF_OK_TO_USE_DEFAULT},
  331. // Suppress debug prints from components in the DEBUG_SYSTEMS list.
  332. // default is all components print.
  333. {FRS_CONFIG_SECTION, L"Debug Systems", UNITS_NONE,
  334. REG_EXPAND_SZ, DT_UNICODE, 0, 0, 0, EVENT_FRS_NONE, NULL,
  335. FKC_DEBUG_SYSTEMS, FRS_RKF_READ_AT_START |
  336. FRS_RKF_DEBUG_PARAM |
  337. FRS_RKF_READ_AT_POLL},
  338. // hklm\software\microsoft\windows nt\current version\buildlab
  339. {FRS_CURRENT_VER_SECTION, L"buildlab", UNITS_NONE,
  340. REG_SZ, DT_UNICODE, 0, 0, 0, EVENT_FRS_NONE, NULL,
  341. FKC_DEBUG_BUILDLAB, FRS_RKF_READ_AT_START |
  342. FRS_RKF_DEBUG_PARAM},
  343. /******************************************************************************
  344. *******************************************************************************
  345. ** **
  346. ** S e r v i c e C o n f i g K e y s **
  347. ** **
  348. ** **
  349. *******************************************************************************
  350. ******************************************************************************/
  351. #define FRS_MUTUAL_AUTHENTICATION_IS \
  352. L"Mutual authentication is [" FRS_IS_ENABLED L" or " FRS_IS_DISABLED L"]"
  353. // Comm Timeout In Milliseconds
  354. // Unjoin the cxtion if the partner doesn't respond soon enough
  355. {FRS_CONFIG_SECTION, L"Comm Timeout In Milliseconds", UNITS_MILLISEC,
  356. REG_DWORD, DT_ULONG, 0, MAXULONG, (5 * 60 * 1000), EVENT_FRS_BAD_REG_DATA, NULL,
  357. FKC_COMM_TIMEOUT, FRS_RKF_READ_AT_START |
  358. FRS_RKF_LOG_EVENT |
  359. FRS_RKF_OK_TO_USE_DEFAULT},
  360. // The directory filter exclusion list. Default: None
  361. // Don't supply a default here. See FRS_DS_COMPOSE_FILTER_LIST for why.
  362. {FRS_CONFIG_SECTION, L"Directory Exclusion Filter List", UNITS_NONE,
  363. REG_SZ, DT_FILE_LIST, 0, 0, 0, EVENT_FRS_BAD_REG_DATA, NULL,
  364. FKC_DIR_EXCL_FILTER_LIST, FRS_RKF_READ_AT_START |
  365. FRS_RKF_LOG_EVENT |
  366. FRS_RKF_SYNTAX_CHECK |
  367. FRS_RKF_READ_AT_POLL},
  368. // The directory filter inclusion list. Default: None
  369. {FRS_CONFIG_SECTION, L"Directory Inclusion Filter List", UNITS_NONE,
  370. REG_SZ, DT_FILE_LIST, 0, 0, 0, EVENT_FRS_BAD_REG_DATA, NULL,
  371. FKC_DIR_INCL_FILTER_LIST, FRS_RKF_READ_AT_START |
  372. FRS_RKF_LOG_EVENT |
  373. FRS_RKF_SYNTAX_CHECK |
  374. FRS_RKF_CREATE_KEY |
  375. FRS_RKF_OK_TO_USE_DEFAULT |
  376. FRS_RKF_READ_AT_POLL},
  377. // Minutes between polls of the DS when data does not appear to be changing.
  378. {FRS_CONFIG_SECTION, L"DS Polling Long Interval in Minutes", UNITS_MINUTES,
  379. REG_DWORD, DT_ULONG, NTFRSAPI_MIN_INTERVAL, NTFRSAPI_MAX_INTERVAL,
  380. NTFRSAPI_DEFAULT_LONG_INTERVAL, EVENT_FRS_BAD_REG_DATA, NULL,
  381. FKC_DS_POLLING_LONG_INTERVAL, FRS_RKF_READ_AT_START |
  382. FRS_RKF_READ_AT_POLL |
  383. FRS_RKF_LOG_EVENT |
  384. FRS_RKF_RANGE_CHECK |
  385. FRS_RKF_OK_TO_USE_DEFAULT},
  386. // Minutes between polls of the DS when data does appear to be changing.
  387. // If no data in the DS has changed after 8 (DS_POLLING_MAX_SHORTS) short
  388. // polling intervals then we fall back to DS_POLLING_LONG_INTERVAL.
  389. // Note: if FRS is running on a DC always use the short interval.
  390. {FRS_CONFIG_SECTION, L"DS Polling Short Interval in Minutes", UNITS_MINUTES,
  391. REG_DWORD, DT_ULONG, NTFRSAPI_MIN_INTERVAL, NTFRSAPI_MAX_INTERVAL,
  392. NTFRSAPI_DEFAULT_SHORT_INTERVAL, EVENT_FRS_BAD_REG_DATA, NULL,
  393. FKC_DS_POLLING_SHORT_INTERVAL, FRS_RKF_READ_AT_START |
  394. FRS_RKF_READ_AT_POLL |
  395. FRS_RKF_LOG_EVENT |
  396. FRS_RKF_RANGE_CHECK |
  397. FRS_RKF_OK_TO_USE_DEFAULT},
  398. // Enumerate Directory Buffer Size in Bytes (WHY DO WE NEED THIS???)
  399. {FRS_CONFIG_SECTION, L"Enumerate Directory Buffer Size in Bytes", UNITS_BYTES,
  400. REG_DWORD, DT_ULONG, MINIMUM_ENUMERATE_DIRECTORY_SIZE, 1024*1024, 4*1024, EVENT_FRS_BAD_REG_DATA, NULL,
  401. FKC_ENUMERATE_DIRECTORY_SIZE, FRS_RKF_READ_AT_START |
  402. FRS_RKF_READ_AT_POLL |
  403. FRS_RKF_LOG_EVENT |
  404. FRS_RKF_RANGE_CHECK |
  405. FRS_RKF_OK_TO_USE_DEFAULT},
  406. // The file filter exclusion list.
  407. // Don't supply a default here. See FRS_DS_COMPOSE_FILTER_LIST for why.
  408. {FRS_CONFIG_SECTION, L"File Exclusion Filter List", UNITS_NONE,
  409. REG_SZ, DT_FILE_LIST, 0, 0, 0, EVENT_FRS_BAD_REG_DATA, NULL,
  410. FKC_FILE_EXCL_FILTER_LIST, FRS_RKF_READ_AT_START |
  411. FRS_RKF_LOG_EVENT |
  412. FRS_RKF_READ_AT_POLL},
  413. // The file filter inclusion list. Default: L""
  414. {FRS_CONFIG_SECTION, L"File Inclusion Filter List", UNITS_NONE,
  415. REG_SZ, DT_FILE_LIST, 0, 0, 0, EVENT_FRS_BAD_REG_DATA, L"",
  416. FKC_FILE_INCL_FILTER_LIST, FRS_RKF_READ_AT_START |
  417. FRS_RKF_LOG_EVENT |
  418. FRS_RKF_SYNTAX_CHECK |
  419. FRS_RKF_CREATE_KEY |
  420. FRS_RKF_OK_TO_USE_DEFAULT |
  421. FRS_RKF_READ_AT_POLL},
  422. // The name of the FRS eventlog message file.
  423. // Default value: "%SystemRoot%\system32\ntfrsres.dll"
  424. // WHY DO WE NEED TO BE ABLE TO CHANGE THIS???
  425. {FRS_CONFIG_SECTION, L"Message File Path", UNITS_NONE,
  426. REG_EXPAND_SZ, DT_UNICODE, 2, 0, 0, EVENT_FRS_NONE,
  427. DEFAULT_MESSAGE_FILE_PATH,
  428. FKC_FRS_MESSAGE_FILE_PATH, FRS_RKF_READ_AT_START |
  429. FRS_RKF_OK_TO_USE_DEFAULT},
  430. // Mutual authentication is [Enabled or Disabled]
  431. {FRS_CONFIG_SECTION, FRS_MUTUAL_AUTHENTICATION_IS, UNITS_NONE,
  432. REG_SZ, DT_UNICODE, 2, 200, 0, EVENT_FRS_NONE,
  433. FRS_IS_DEFAULT_ENABLED,
  434. FKC_FRS_MUTUAL_AUTHENTICATION_IS, FRS_RKF_READ_AT_START |
  435. FRS_RKF_RANGE_CHECK |
  436. FRS_RKF_VALUE_MUST_BE_PRESENT},
  437. // Maximum Join Retry time In MilliSeconds Default: 1 hr.
  438. {FRS_CONFIG_SECTION, L"Maximum Join Retry In MilliSeconds", UNITS_MILLISEC,
  439. REG_DWORD, DT_ULONG, 30*1000, 10*3600*1000, (60 * 60 * 1000), EVENT_FRS_NONE, NULL,
  440. FKC_MAX_JOIN_RETRY, FRS_RKF_READ_AT_START |
  441. FRS_RKF_READ_AT_POLL |
  442. FRS_RKF_RANGE_CHECK |
  443. FRS_RKF_OK_TO_USE_DEFAULT},
  444. // Maximum Replica Command Server Threads Default: 16
  445. // The replica command server services commands for configuration changes
  446. // and replication.
  447. {FRS_CONFIG_SECTION, L"Maximum Replica Command Server Threads", UNITS_NONE,
  448. REG_DWORD, DT_ULONG, 2, 200, (16), EVENT_FRS_NONE, NULL,
  449. FKC_MAX_REPLICA_THREADS, FRS_RKF_READ_AT_START |
  450. FRS_RKF_READ_AT_POLL |
  451. FRS_RKF_RANGE_CHECK |
  452. FRS_RKF_OK_TO_USE_DEFAULT},
  453. // Max Rpc Server Threads Default: 16
  454. // Maximum number of concurrent RPC calls
  455. {FRS_CONFIG_SECTION, L"Max Rpc Server Threads", UNITS_NONE,
  456. REG_DWORD, DT_ULONG, 2, 200, (16), EVENT_FRS_NONE, NULL,
  457. FKC_MAX_RPC_SERVER_THREADS, FRS_RKF_READ_AT_START |
  458. FRS_RKF_READ_AT_POLL |
  459. FRS_RKF_RANGE_CHECK |
  460. FRS_RKF_OK_TO_USE_DEFAULT},
  461. // Maximum Install Command Server Threads Default: 4
  462. {FRS_CONFIG_SECTION, L"Maximum Install Command Server Threads", UNITS_NONE,
  463. REG_DWORD, DT_ULONG, 2, 200, (4), EVENT_FRS_NONE, NULL,
  464. FKC_MAX_INSTALLCS_THREADS, FRS_RKF_READ_AT_START |
  465. FRS_RKF_READ_AT_POLL |
  466. FRS_RKF_RANGE_CHECK |
  467. FRS_RKF_OK_TO_USE_DEFAULT},
  468. // Maximum Stage Gen Command Server Threads Default: 4
  469. {FRS_CONFIG_SECTION, L"Maximum Stage Gen Command Server Threads", UNITS_NONE,
  470. REG_DWORD, DT_ULONG, 2, 200, (4), EVENT_FRS_NONE, NULL,
  471. FKC_MAX_STAGE_GENCS_THREADS, FRS_RKF_READ_AT_START |
  472. FRS_RKF_READ_AT_POLL |
  473. FRS_RKF_RANGE_CHECK |
  474. FRS_RKF_OK_TO_USE_DEFAULT},
  475. // Maximum Stage Fetch Command Server Threads Default: 4
  476. {FRS_CONFIG_SECTION, L"Maximum Stage Fetch Command Server Threads", UNITS_NONE,
  477. REG_DWORD, DT_ULONG, 2, 200, (4), EVENT_FRS_NONE, NULL,
  478. FKC_MAX_STAGE_FETCHCS_THREADS, FRS_RKF_READ_AT_START |
  479. FRS_RKF_READ_AT_POLL |
  480. FRS_RKF_RANGE_CHECK |
  481. FRS_RKF_OK_TO_USE_DEFAULT},
  482. // Maximum Initial SYnc Command Server Threads Default: 4
  483. {FRS_CONFIG_SECTION, L"Maximum Initial Sync Command Server Threads", UNITS_NONE,
  484. REG_DWORD, DT_ULONG, 2, 200, (4), EVENT_FRS_NONE, NULL,
  485. FKC_MAX_INITSYNCCS_THREADS, FRS_RKF_READ_AT_START |
  486. FRS_RKF_READ_AT_POLL |
  487. FRS_RKF_RANGE_CHECK |
  488. FRS_RKF_OK_TO_USE_DEFAULT},
  489. // Minimum Join Retry time In MilliSeconds Default: 10 sec.
  490. // Retry a join every MinJoinRetry milliseconds, doubling the interval
  491. // every retry. Stop retrying when the interval is greater than MaxJoinRetry.
  492. {FRS_CONFIG_SECTION, L"Minimum Join Retry In MilliSeconds", UNITS_MILLISEC,
  493. REG_DWORD, DT_ULONG, 500, 10*3600*1000, (10 * 1000), EVENT_FRS_NONE, NULL,
  494. FKC_MIN_JOIN_RETRY, FRS_RKF_READ_AT_START |
  495. FRS_RKF_READ_AT_POLL |
  496. FRS_RKF_RANGE_CHECK |
  497. FRS_RKF_OK_TO_USE_DEFAULT},
  498. // Partner Clock Skew In Minutes Default: 30 min.
  499. // Partners are not allowed to join if their clocks are out-of-sync
  500. {FRS_CONFIG_SECTION, L"Partner Clock Skew In Minutes", UNITS_MINUTES,
  501. REG_DWORD, DT_ULONG, 1, 10*60, 30, EVENT_FRS_NONE, NULL,
  502. FKC_PARTNER_CLOCK_SKEW, FRS_RKF_READ_AT_START |
  503. FRS_RKF_READ_AT_POLL |
  504. FRS_RKF_RANGE_CHECK |
  505. FRS_RKF_OK_TO_USE_DEFAULT},
  506. // ChangeOrder Reconcile Event Time Window In Minutes Default: 30 min.
  507. {FRS_CONFIG_SECTION, L"Reconcile Time Window In Minutes", UNITS_MINUTES,
  508. REG_DWORD, DT_ULONG, 1, 120, 30, EVENT_FRS_NONE, NULL,
  509. FKC_RECONCILE_WINDOW, FRS_RKF_READ_AT_START |
  510. FRS_RKF_READ_AT_POLL |
  511. FRS_RKF_RANGE_CHECK |
  512. FRS_RKF_OK_TO_USE_DEFAULT},
  513. // ChangeOrder Inlog retry interval in seconds Default: 60 sec.
  514. {FRS_CONFIG_SECTION, L"Inlog Retry Time In Seconds", UNITS_SECONDS,
  515. REG_DWORD, DT_ULONG, 1, 24*3600, 60, EVENT_FRS_NONE, NULL,
  516. FKC_INLOG_RETRY_TIME, FRS_RKF_READ_AT_START |
  517. FRS_RKF_READ_AT_POLL |
  518. FRS_RKF_RANGE_CHECK |
  519. FRS_RKF_OK_TO_USE_DEFAULT},
  520. // ChangeOrder Aging Delay in seconds Default: 3 sec.
  521. // Should be a min of 3 sec to allow file system tunnel cache info to propagate.
  522. {FRS_CONFIG_SECTION, L"Changeorder Aging Delay In Seconds", UNITS_SECONDS,
  523. REG_DWORD, DT_ULONG, 3, 30*60, 3, EVENT_FRS_NONE, NULL,
  524. FKC_CO_AGING_DELAY, FRS_RKF_READ_AT_START |
  525. FRS_RKF_READ_AT_POLL |
  526. FRS_RKF_RANGE_CHECK |
  527. FRS_RKF_OK_TO_USE_DEFAULT},
  528. // Outlog File Repeat Interval In Seconds Default: 30 sec.
  529. // A CO update for a given file will not be sent out more frequently than this.
  530. // Set to zero to disable the Outlog dominant file update optimization.
  531. {FRS_CONFIG_SECTION, L"Outlog File Repeat Interval In Seconds", UNITS_SECONDS,
  532. REG_DWORD, DT_ULONG, 0, 24*3600, 30, EVENT_FRS_NONE, NULL,
  533. FKC_OUTLOG_REPEAT_INTERVAL, FRS_RKF_READ_AT_START |
  534. FRS_RKF_READ_AT_POLL |
  535. FRS_RKF_RANGE_CHECK |
  536. FRS_RKF_OK_TO_USE_DEFAULT},
  537. // Sysvol Promotion Timeout In Milliseconds Default: 10 min.
  538. {FRS_CONFIG_SECTION, L"Sysvol Promotion Timeout In Milliseconds", UNITS_MILLISEC,
  539. REG_DWORD, DT_ULONG, 0, 3600*1000, (10 * 60 * 1000), EVENT_FRS_NONE, NULL,
  540. FKC_PROMOTION_TIMEOUT, FRS_RKF_READ_AT_START |
  541. FRS_RKF_READ_AT_POLL |
  542. FRS_RKF_RANGE_CHECK |
  543. FRS_RKF_OK_TO_USE_DEFAULT},
  544. // Replica Start Timeout In MilliSeconds Default: 0 means can't start without DS.
  545. // Start replication even if the DS could not be accessed
  546. // 0: no DS == no start replicas
  547. // N: start replicas in N milliseconds
  548. {FRS_CONFIG_SECTION, L"Replica Start Timeout In MilliSeconds", UNITS_MILLISEC,
  549. REG_DWORD, DT_ULONG, 0, 3600*1000, (0), EVENT_FRS_NONE, NULL,
  550. FKC_REPLICA_START_TIMEOUT, FRS_RKF_READ_AT_START |
  551. FRS_RKF_READ_AT_POLL |
  552. FRS_RKF_RANGE_CHECK |
  553. FRS_RKF_OK_TO_USE_DEFAULT},
  554. // Replica Tombstone in Days Default: 32
  555. // The length of time we will hold onto the database state for a replica
  556. // set after we see our membership in the DS has been deleted. Since
  557. // delete is not explicit (except for DC Demote) it may just be that the
  558. // DC is missing our objects or an admin erroneously deleted our subscriber
  559. // or member object. Once this time has lapsed we will delete the tables
  560. // from the database.
  561. {FRS_CONFIG_SECTION, L"Replica Tombstone in Days", UNITS_DAYS,
  562. REG_DWORD, DT_ULONG, 3, MAXULONG, (32), EVENT_FRS_NONE, NULL,
  563. FKC_REPLICA_TOMBSTONE, FRS_RKF_READ_AT_START |
  564. FRS_RKF_READ_AT_POLL |
  565. FRS_RKF_RANGE_CHECK |
  566. FRS_RKF_OK_TO_USE_DEFAULT},
  567. // Shutdown Timeout in Seconds Default: 90 sec.
  568. // The max time FRS main will wait for all threads to exit during shutdown.
  569. {FRS_CONFIG_SECTION, L"Shutdown Timeout in Seconds", UNITS_SECONDS,
  570. REG_DWORD, DT_ULONG, 30, 24*60*60, DEFAULT_SHUTDOWN_TIMEOUT, EVENT_FRS_NONE, NULL,
  571. FKC_SHUTDOWN_TIMEOUT, FRS_RKF_READ_AT_START |
  572. FRS_RKF_READ_AT_POLL |
  573. FRS_RKF_RANGE_CHECK |
  574. FRS_RKF_OK_TO_USE_DEFAULT},
  575. // Maximum Send Command Server Threads Default: 16
  576. {FRS_CONFIG_SECTION, L"Maximum Send Command Server Threads", UNITS_NONE,
  577. REG_DWORD, DT_ULONG, 2, 200, (16), EVENT_FRS_NONE, NULL,
  578. FKC_SNDCS_MAXTHREADS_PAR, FRS_RKF_READ_AT_START |
  579. FRS_RKF_READ_AT_POLL |
  580. FRS_RKF_RANGE_CHECK |
  581. FRS_RKF_OK_TO_USE_DEFAULT},
  582. // Staging Space Limit in KB Default: 660 MB
  583. {FRS_CONFIG_SECTION, L"Staging Space Limit in KB", UNITS_KBYTES,
  584. REG_DWORD, DT_ULONG, 10*1024, MAXULONG, (660 * 1024), EVENT_FRS_BAD_REG_DATA, NULL,
  585. FKC_STAGING_LIMIT, FRS_RKF_READ_AT_START |
  586. FRS_RKF_RANGE_CHECK |
  587. FRS_RKF_OK_TO_USE_DEFAULT |
  588. FRS_RKF_LOG_EVENT},
  589. // VvJoin Limit in Change Orders Default: 16 ChangeOrders
  590. // Max number of VVJoin gened COs to prevent flooding.
  591. {FRS_CONFIG_SECTION, L"VvJoin Limit in Change Orders", UNITS_NONE,
  592. REG_DWORD, DT_ULONG, 2, 128, (16), EVENT_FRS_NONE, NULL,
  593. FKC_VVJOIN_LIMIT, FRS_RKF_READ_AT_START |
  594. FRS_RKF_READ_AT_POLL |
  595. FRS_RKF_RANGE_CHECK |
  596. FRS_RKF_OK_TO_USE_DEFAULT},
  597. // VVJoin Outbound Log Throttle Timeout Default: 1 sec.
  598. // The time FRS VVJoin thread waits after generating VVJOIN_LIMIT COs.
  599. {FRS_CONFIG_SECTION, L"VvJoin Timeout in Milliseconds", UNITS_MILLISEC,
  600. REG_DWORD, DT_ULONG, 100, 10*60*1000, (1000), EVENT_FRS_NONE, NULL,
  601. FKC_VVJOIN_TIMEOUT, FRS_RKF_READ_AT_START |
  602. FRS_RKF_READ_AT_POLL |
  603. FRS_RKF_RANGE_CHECK |
  604. FRS_RKF_OK_TO_USE_DEFAULT},
  605. // The FRS working dir is where the Jet (ESENT) database is created.
  606. // If this dir does not exist or can't be created FRS will fail to startup.
  607. {FRS_CONFIG_SECTION, L"Working Directory", UNITS_NONE,
  608. REG_SZ, DT_DIR_PATH, 4, 10*(MAX_PATH+1), 4, EVENT_FRS_BAD_REG_DATA, NULL,
  609. FKC_WORKING_DIRECTORY, FRS_RKF_READ_AT_START |
  610. FRS_RKF_RANGE_CHECK |
  611. FRS_RKF_VALUE_MUST_BE_PRESENT |
  612. FRS_RKF_SYNTAX_CHECK |
  613. FRS_RKF_LOG_EVENT },
  614. // The FRS Log File Directory allows the Jet Logs to created on a different volume.
  615. // By default they are placed in a Log subdir under the "Working Directory".
  616. // If this dir does not exist or can't be created FRS will fail to startup.
  617. {FRS_CONFIG_SECTION, L"DB Log File Directory", UNITS_NONE,
  618. REG_SZ, DT_DIR_PATH, 4, 10*(MAX_PATH+1), 4, EVENT_FRS_BAD_REG_DATA, NULL,
  619. FKC_DBLOG_DIRECTORY, FRS_RKF_READ_AT_START |
  620. FRS_RKF_RANGE_CHECK |
  621. FRS_RKF_SYNTAX_CHECK |
  622. FRS_RKF_LOG_EVENT },
  623. // Ntfs Journal size in MB Default: 32 Meg
  624. {FRS_CONFIG_SECTION, L"Ntfs Journal size in MB", UNITS_MBYTES,
  625. REG_DWORD, DT_ULONG, 4, 128, (32), EVENT_FRS_BAD_REG_DATA, NULL,
  626. FKC_NTFS_JRNL_SIZE, FRS_RKF_READ_AT_START |
  627. FRS_RKF_LOG_EVENT |
  628. FRS_RKF_RANGE_CHECK |
  629. FRS_RKF_OK_TO_USE_DEFAULT},
  630. // Maximum Number of Replica Sets Default: 200.
  631. {FRS_CONFIG_SECTION, L"Maximum Number of Replica Sets", UNITS_NONE,
  632. REG_DWORD, DT_ULONG, 1, 5000, (200), EVENT_FRS_BAD_REG_DATA, NULL,
  633. FKC_MAX_NUMBER_REPLICA_SETS, FRS_RKF_READ_AT_START |
  634. FRS_RKF_LOG_EVENT |
  635. FRS_RKF_RANGE_CHECK |
  636. FRS_RKF_OK_TO_USE_DEFAULT},
  637. // Maximum Number of Jet Sessions Default: 128.
  638. {FRS_CONFIG_SECTION, L"Maximum Number of Jet Sessions", UNITS_NONE,
  639. REG_DWORD, DT_ULONG, 1, 5000, (128), EVENT_FRS_BAD_REG_DATA, NULL,
  640. FKC_MAX_NUMBER_JET_SESSIONS, FRS_RKF_READ_AT_START |
  641. FRS_RKF_LOG_EVENT |
  642. FRS_RKF_RANGE_CHECK |
  643. FRS_RKF_OK_TO_USE_DEFAULT},
  644. // Maximum Number of outstanding CO's per outbound connection. Default: 8.
  645. {FRS_CONFIG_SECTION, L"Max Num Outbound COs Per Connection", UNITS_NONE,
  646. REG_DWORD, DT_ULONG, 1, 100, (8), EVENT_FRS_BAD_REG_DATA, NULL,
  647. FKC_OUT_LOG_CO_QUOTA, FRS_RKF_READ_AT_START |
  648. FRS_RKF_LOG_EVENT |
  649. FRS_RKF_RANGE_CHECK |
  650. FRS_RKF_OK_TO_USE_DEFAULT},
  651. // If TRUE, Preserve OIDs on files whenever possible Default: False
  652. // -- See Bug 352250 for why this is a risky thing to do.
  653. {FRS_CONFIG_SECTION, L"Preserve File OID", UNITS_NONE,
  654. REG_DWORD, DT_BOOL, FALSE, TRUE, (FALSE), EVENT_FRS_NONE, NULL,
  655. FKC_PRESERVE_FILE_OID, FRS_RKF_READ_AT_START |
  656. FRS_RKF_READ_AT_POLL |
  657. FRS_RKF_RANGE_CHECK |
  658. FRS_RKF_OK_TO_USE_DEFAULT},
  659. //
  660. // Disable compression support. Need a non-auth restore to
  661. // make sure we don't have any old compressed staging files
  662. // when this key is turned on.
  663. //
  664. {FRS_CONFIG_SECTION, L"Debug Disable Compression", UNITS_NONE,
  665. REG_DWORD, DT_BOOL, FALSE, TRUE, (FALSE), EVENT_FRS_NONE, NULL,
  666. FKC_DEBUG_DISABLE_COMPRESSION, FRS_RKF_READ_AT_START |
  667. FRS_RKF_RANGE_CHECK |
  668. FRS_RKF_OK_TO_USE_DEFAULT},
  669. //
  670. // Compress staging files for local changes. Set to FALSE to disable.
  671. // This member will continue to install and propagate compressed files.
  672. // This is useful if the customer has content that originates on this member
  673. // which is either already compressed or doesn't compress well.
  674. //
  675. {FRS_CONFIG_SECTION, L"Compress Staging Files", UNITS_NONE,
  676. REG_DWORD, DT_BOOL, FALSE, TRUE, (TRUE), EVENT_FRS_NONE, NULL,
  677. FKC_COMPRESS_STAGING_FILES, FRS_RKF_READ_AT_START |
  678. FRS_RKF_RANGE_CHECK |
  679. FRS_RKF_OK_TO_USE_DEFAULT},
  680. //
  681. // Disable compression of staging files for local changes.
  682. // This member will continue to install and send compressed files
  683. // unless compression support it explicilt turned off by the
  684. // Debug Disable Compression key.
  685. // OBSOLETE -- WILL BE REMOVED.
  686. //
  687. {FRS_CONFIG_SECTION, L"Disable Compression of Staging Files", UNITS_NONE,
  688. REG_DWORD, DT_BOOL, FALSE, TRUE, (FALSE), EVENT_FRS_NONE, NULL,
  689. FKC_DISABLE_COMPRESSION_STAGING_FILE, FRS_RKF_READ_AT_START |
  690. FRS_RKF_RANGE_CHECK |
  691. FRS_RKF_OK_TO_USE_DEFAULT},
  692. //
  693. // Client side ldap search timeout value. Default is 10 minutes.
  694. //
  695. {FRS_CONFIG_SECTION, L"Ldap Search Timeout In Minutes", UNITS_NONE,
  696. REG_DWORD, DT_ULONG, 1, 120, (10), EVENT_FRS_BAD_REG_DATA, NULL,
  697. FKC_LDAP_SEARCH_TIMEOUT_IN_MINUTES, FRS_RKF_READ_AT_START |
  698. FRS_RKF_LOG_EVENT |
  699. FRS_RKF_RANGE_CHECK |
  700. FRS_RKF_OK_TO_USE_DEFAULT},
  701. //
  702. // Client side ldap_connect timeout value. Default is 30 seconds.
  703. //
  704. {FRS_CONFIG_SECTION, L"Ldap Bind Timeout In Seconds", UNITS_NONE,
  705. REG_DWORD, DT_ULONG, 2, MAXULONG, (30), EVENT_FRS_BAD_REG_DATA, NULL,
  706. FKC_LDAP_BIND_TIMEOUT_IN_SECONDS, FRS_RKF_READ_AT_START |
  707. FRS_RKF_LOG_EVENT |
  708. FRS_RKF_RANGE_CHECK |
  709. FRS_RKF_OK_TO_USE_DEFAULT},
  710. // add ReplDirLevelLimit as a reg key
  711. // add code support for the following
  712. //FKC_SET_N_DIR_EXCL_FILTER_LIST,
  713. //FKC_SET_N_DIR_INCL_FILTER_LIST,
  714. //FKC_SET_N_FILE_EXCL_FILTER_LIST,
  715. //FKC_SET_N_FILE_INCL_FILTER_LIST,
  716. //FKC_SET_N_SYSVOL_DIR_EXCL_FILTER_LIST,
  717. //FKC_SET_N_SYSVOL_DIR_INCL_FILTER_LIST,
  718. //FKC_SET_N_SYSVOL_FILE_EXCL_FILTER_LIST,
  719. //FKC_SET_N_SYSVOL_FILE_INCL_FILTER_LIST,
  720. /******************************************************************************
  721. *******************************************************************************
  722. ** **
  723. ** P e r - R e p l i c a S e t K e y s **
  724. ** **
  725. ** **
  726. *******************************************************************************
  727. ******************************************************************************/
  728. #define FRS_RKEY_SETS_SECTION FRS_CONFIG_SECTION L",Replica Sets"
  729. #define FRS_RKEY_SET_N FRS_CONFIG_SECTION L",Replica Sets,ARG1"
  730. #define FRS_RKEY_CUM_SET_N FRS_CONFIG_SECTION L",Cumulative Replica Sets,ARG1"
  731. #define FRS_RKEY_CUM_SET_SECTION FRS_CONFIG_SECTION L",Cumulative Replica Sets"
  732. //
  733. // FRS Sets parameter data. Lives in
  734. // "System\\CurrentControlSet\\Services\\NtFrs\\Parameters\\Replica Sets\\[RS-guid]"
  735. // Used for sysvols currently.
  736. //
  737. // No event log messages are generated for these keys since currently
  738. // they are only created by the service or NTFRSAPI so if they get
  739. // fouled up there is nothing the USER can do to correct the problem.
  740. //
  741. // The FRS working dir is where the Jet (ESENT) database is created.
  742. // Replica Sets\Database Directory
  743. {FRS_RKEY_SETS_SECTION, JET_PATH, UNITS_NONE,
  744. REG_SZ, DT_DIR_PATH, 4, 10*1024, 4, EVENT_FRS_NONE, NULL,
  745. FKC_SETS_JET_PATH, FRS_RKF_READ_AT_START |
  746. FRS_RKF_RANGE_CHECK |
  747. FRS_RKF_VALUE_MUST_BE_PRESENT |
  748. FRS_RKF_SYNTAX_CHECK},
  749. // Replica Sets\Guid\Replica Set Name
  750. {FRS_RKEY_SET_N, REPLICA_SET_NAME, UNITS_NONE,
  751. REG_SZ, DT_UNICODE, 4, 512, 0, EVENT_FRS_NONE, NULL,
  752. FKC_SET_N_REPLICA_SET_NAME, FRS_RKF_READ_AT_START |
  753. FRS_RKF_RANGE_CHECK |
  754. FRS_RKF_VALUE_MUST_BE_PRESENT},
  755. // The root of the replica tree.
  756. // Replica Sets\Guid\Replica Set Root
  757. {FRS_RKEY_SET_N, REPLICA_SET_ROOT, UNITS_NONE,
  758. REG_SZ, DT_DIR_PATH, 4, 10*1024, 4, EVENT_FRS_NONE, NULL,
  759. FKC_SET_N_REPLICA_SET_ROOT, FRS_RKF_READ_AT_START |
  760. FRS_RKF_RANGE_CHECK |
  761. FRS_RKF_VALUE_MUST_BE_PRESENT |
  762. FRS_RKF_SYNTAX_CHECK},
  763. // The staging area for this replica set.
  764. // Replica Sets\Guid\Replica Set Stage
  765. {FRS_RKEY_SET_N, REPLICA_SET_STAGE, UNITS_NONE,
  766. REG_SZ, DT_DIR_PATH, 4, 10*1024, 4, EVENT_FRS_NONE, NULL,
  767. FKC_SET_N_REPLICA_SET_STAGE, FRS_RKF_READ_AT_START |
  768. FRS_RKF_RANGE_CHECK |
  769. FRS_RKF_VALUE_MUST_BE_PRESENT |
  770. FRS_RKF_SYNTAX_CHECK},
  771. // The replica set type code. ( SYSVOL, DFS, ...)
  772. // Replica Sets\Guid\Replica Set Type
  773. {FRS_RKEY_SET_N, REPLICA_SET_TYPE, UNITS_NONE,
  774. REG_SZ, DT_UNICODE, 2, 1024, 0, EVENT_FRS_NONE, NULL,
  775. FKC_SET_N_REPLICA_SET_TYPE, FRS_RKF_READ_AT_START |
  776. FRS_RKF_RANGE_CHECK |
  777. FRS_RKF_VALUE_MUST_BE_PRESENT},
  778. // The directory filter exclusion list. Default: None
  779. // Don't supply a default here. See FRS_DS_COMPOSE_FILTER_LIST for why.
  780. {FRS_RKEY_SET_N, L"Directory Exclusion Filter List", UNITS_NONE,
  781. REG_SZ, DT_FILE_LIST, 0, 0, 0, EVENT_FRS_BAD_REG_DATA, NULL,
  782. FKC_SET_N_DIR_EXCL_FILTER_LIST, FRS_RKF_READ_AT_START |
  783. FRS_RKF_LOG_EVENT |
  784. FRS_RKF_SYNTAX_CHECK |
  785. FRS_RKF_READ_AT_POLL},
  786. // The directory filter inclusion list. Default: None
  787. {FRS_RKEY_SET_N, L"Directory Inclusion Filter List", UNITS_NONE,
  788. REG_SZ, DT_FILE_LIST, 0, 0, 0, EVENT_FRS_BAD_REG_DATA, NULL,
  789. FKC_SET_N_DIR_INCL_FILTER_LIST, FRS_RKF_READ_AT_START |
  790. FRS_RKF_LOG_EVENT |
  791. FRS_RKF_SYNTAX_CHECK |
  792. FRS_RKF_CREATE_KEY |
  793. FRS_RKF_OK_TO_USE_DEFAULT |
  794. FRS_RKF_READ_AT_POLL},
  795. // The file filter exclusion list.
  796. // Don't supply a default here. See FRS_DS_COMPOSE_FILTER_LIST for why.
  797. {FRS_RKEY_SET_N, L"File Exclusion Filter List", UNITS_NONE,
  798. REG_SZ, DT_FILE_LIST, 0, 0, 0, EVENT_FRS_BAD_REG_DATA, NULL,
  799. FKC_SET_N_FILE_EXCL_FILTER_LIST, FRS_RKF_READ_AT_START |
  800. FRS_RKF_LOG_EVENT |
  801. FRS_RKF_READ_AT_POLL},
  802. // The file filter inclusion list. Default: ~clbcatq.*
  803. {FRS_RKEY_SET_N, L"File Inclusion Filter List", UNITS_NONE,
  804. REG_SZ, DT_FILE_LIST, 0, 0, 0, EVENT_FRS_BAD_REG_DATA,
  805. L"~clbcatq.*",
  806. FKC_SET_N_FILE_INCL_FILTER_LIST, FRS_RKF_READ_AT_START |
  807. FRS_RKF_LOG_EVENT |
  808. FRS_RKF_SYNTAX_CHECK |
  809. FRS_RKF_CREATE_KEY |
  810. FRS_RKF_OK_TO_USE_DEFAULT |
  811. FRS_RKF_READ_AT_POLL},
  812. // The tombstone state of this replica set.
  813. // Replica Sets\Guid\Replica Set Tombstoned
  814. {FRS_RKEY_SET_N, REPLICA_SET_TOMBSTONED, UNITS_NONE,
  815. REG_DWORD, DT_BOOL, 0, 1, 0, EVENT_FRS_NONE, NULL,
  816. FKC_SET_N_REPLICA_SET_TOMBSTONED, FRS_RKF_READ_AT_START |
  817. FRS_RKF_RANGE_CHECK |
  818. FRS_RKF_VALUE_MUST_BE_PRESENT},
  819. // The operation to perform on the replica set.
  820. // Replica Sets\Guid\Replica Set Command
  821. {FRS_RKEY_SET_N, REPLICA_SET_COMMAND, UNITS_NONE,
  822. REG_SZ, DT_UNICODE, 2, 1024, 0, EVENT_FRS_NONE, NULL,
  823. FKC_SET_N_REPLICA_SET_COMMAND, FRS_RKF_READ_AT_START |
  824. FRS_RKF_RANGE_CHECK |
  825. FRS_RKF_VALUE_MUST_BE_PRESENT},
  826. // If TRUE this is the first member of a replica set and we init the DB
  827. // with the contents of the replica tree.
  828. // Replica Sets\Guid\Replica Set Primary
  829. {FRS_RKEY_SET_N, REPLICA_SET_PRIMARY, UNITS_NONE,
  830. REG_DWORD, DT_BOOL, 0, 1, 0, EVENT_FRS_NONE, NULL,
  831. FKC_SET_N_REPLICA_SET_PRIMARY, FRS_RKF_READ_AT_START |
  832. FRS_RKF_RANGE_CHECK |
  833. FRS_RKF_VALUE_MUST_BE_PRESENT},
  834. // LDAP error Status return if we have a problem creating sysvol.
  835. // Replica Sets\Guid\Replica Set Status
  836. {FRS_RKEY_SET_N, REPLICA_SET_STATUS, UNITS_NONE,
  837. REG_DWORD, DT_ULONG, 0, MAXULONG, 0, EVENT_FRS_NONE, NULL,
  838. FKC_SET_N_REPLICA_SET_STATUS, FRS_RKF_READ_AT_START},
  839. // Cumulative Replica Sets *NOTE* This is a key def only.
  840. {FRS_RKEY_CUM_SET_SECTION, L"*KeyOnly*", UNITS_NONE,
  841. REG_SZ, DT_UNICODE, 0, MAXULONG, 0, EVENT_FRS_NONE, NULL,
  842. FKC_CUMSET_SECTION_KEY, 0},
  843. // Number of inbound and outbound partners for this replica set.
  844. // Cumulative Replica Sets\Guid\Number Of Partners
  845. {FRS_RKEY_CUM_SET_N, L"Number Of Partners", UNITS_NONE,
  846. REG_DWORD, DT_ULONG, 0, MAXULONG, 0, EVENT_FRS_NONE, NULL,
  847. FKC_CUMSET_N_NUMBER_OF_PARTNERS, FRS_RKF_READ_AT_START},
  848. // Backup / Restore flags for this replica set.
  849. // Cumulative Replica Sets\Guid\BurFlags
  850. {FRS_RKEY_CUM_SET_N, FRS_VALUE_BURFLAGS, UNITS_NONE,
  851. REG_DWORD, DT_ULONG, 0, MAXULONG, 0, EVENT_FRS_NONE, NULL,
  852. FKC_CUMSET_N_BURFLAGS, FRS_RKF_READ_AT_START},
  853. /******************************************************************************
  854. *******************************************************************************
  855. ** **
  856. ** S y s t e m V o l u m e R e l a t e d K e y s **
  857. ** **
  858. ** **
  859. *******************************************************************************
  860. ******************************************************************************/
  861. #define FRS_RKEY_SYSVOL_SET_N FRS_CONFIG_SECTION L",SysVol,ARG1"
  862. #define FRS_RKEY_SYSVOL_SEED_N FRS_CONFIG_SECTION L",SysVol Seeding,ARG1"
  863. #define FRS_RKEY_SYSVOL_SEEDING_SECTION FRS_CONFIG_SECTION L",SysVol Seeding"
  864. //
  865. // No event log messages are generated for these keys since currently
  866. // they are only created by the service or NTFRSAPI so if they get
  867. // fouled up there is nothing the USER can do to correct the problem.
  868. //
  869. // TRUE if sysvol is ready. Notifies NetLogon to publish computer as a DC.
  870. // Netlogon\\Parameters\SysvolReady
  871. {NETLOGON_SECTION, SYSVOL_READY, UNITS_NONE,
  872. REG_DWORD, DT_BOOL, 0, 1, 0, EVENT_FRS_NONE, NULL,
  873. FKC_SYSVOL_READY, FRS_RKF_READ_AT_START},
  874. // SysVol Section *NOTE* THis is a key only. It has no value.
  875. {FRS_SYSVOL_SECTION, L"*KeyOnly*", UNITS_NONE,
  876. REG_SZ, DT_UNICODE, 2, 10*1024, 0, EVENT_FRS_NONE, NULL,
  877. FKC_SYSVOL_SECTION_KEY, 0},
  878. // TRUE if sysvol data is all present in registry.
  879. // Tells us that DCPromo completed.
  880. // Netlogon\\Parameters\SysVol Information is Committed
  881. {FRS_SYSVOL_SECTION, SYSVOL_INFO_IS_COMMITTED, UNITS_NONE,
  882. REG_DWORD, DT_BOOL, 0, 1, 0, EVENT_FRS_NONE, NULL,
  883. FKC_SYSVOL_INFO_COMMITTED, FRS_RKF_READ_AT_START |
  884. FRS_RKF_RANGE_CHECK |
  885. FRS_RKF_VALUE_MUST_BE_PRESENT},
  886. //
  887. // Note that the following keys are a repeat of those in the "Per-Replica
  888. // set" section above except the Key location in the registry is
  889. // FRS_CONFIG_SECTION\SysVol instead of FRS_CONFIG_SECTION\Replica Sets
  890. // unfortunate but something more to clean up later perhaps with a
  891. // second parameter (ARG2).
  892. //
  893. // SysVol\<Guid>\Replica Set Name
  894. {FRS_RKEY_SYSVOL_SET_N, REPLICA_SET_NAME, UNITS_NONE,
  895. REG_SZ, DT_UNICODE, 4, 512, 0, EVENT_FRS_NONE, NULL,
  896. FKC_SET_N_SYSVOL_NAME, FRS_RKF_READ_AT_START |
  897. FRS_RKF_RANGE_CHECK |
  898. FRS_RKF_VALUE_MUST_BE_PRESENT},
  899. // The root of the replica tree.
  900. // SysVol\<Guid>\Replica Set Root
  901. {FRS_RKEY_SYSVOL_SET_N, REPLICA_SET_ROOT, UNITS_NONE,
  902. REG_SZ, DT_DIR_PATH, 4, 10*1024, 4, EVENT_FRS_NONE, NULL,
  903. FKC_SET_N_SYSVOL_ROOT, FRS_RKF_READ_AT_START |
  904. FRS_RKF_RANGE_CHECK |
  905. FRS_RKF_VALUE_MUST_BE_PRESENT |
  906. FRS_RKF_SYNTAX_CHECK},
  907. // The staging area for this replica set.
  908. // SysVol\<Guid>\Replica Set Stage
  909. {FRS_RKEY_SYSVOL_SET_N, REPLICA_SET_STAGE, UNITS_NONE,
  910. REG_SZ, DT_DIR_PATH, 4, 10*1024, 4, EVENT_FRS_NONE, NULL,
  911. FKC_SET_N_SYSVOL_STAGE, FRS_RKF_READ_AT_START |
  912. FRS_RKF_RANGE_CHECK |
  913. FRS_RKF_VALUE_MUST_BE_PRESENT |
  914. FRS_RKF_SYNTAX_CHECK},
  915. // The replica set type code. ( SYSVOL, DFS, ...)
  916. // SysVol\<Guid>\Replica Set Type
  917. {FRS_RKEY_SYSVOL_SET_N, REPLICA_SET_TYPE, UNITS_NONE,
  918. REG_SZ, DT_UNICODE, 2, 1024, 0, EVENT_FRS_NONE, NULL,
  919. FKC_SET_N_SYSVOL_TYPE, FRS_RKF_READ_AT_START |
  920. FRS_RKF_RANGE_CHECK |
  921. FRS_RKF_VALUE_MUST_BE_PRESENT},
  922. // The directory filter exclusion list. Default: None
  923. // Don't supply a default here. See FRS_DS_COMPOSE_FILTER_LIST for why.
  924. {FRS_RKEY_SYSVOL_SET_N, L"Directory Exclusion Filter List", UNITS_NONE,
  925. REG_SZ, DT_FILE_LIST, 0, 0, 0, EVENT_FRS_BAD_REG_DATA, NULL,
  926. FKC_SET_N_SYSVOL_DIR_EXCL_FILTER_LIST, FRS_RKF_READ_AT_START |
  927. FRS_RKF_LOG_EVENT |
  928. FRS_RKF_SYNTAX_CHECK |
  929. FRS_RKF_READ_AT_POLL},
  930. // The directory filter inclusion list. Default: None
  931. {FRS_RKEY_SYSVOL_SET_N, L"Directory Inclusion Filter List", UNITS_NONE,
  932. REG_SZ, DT_FILE_LIST, 0, 0, 0, EVENT_FRS_BAD_REG_DATA, NULL,
  933. FKC_SET_N_SYSVOL_DIR_INCL_FILTER_LIST, FRS_RKF_READ_AT_START |
  934. FRS_RKF_LOG_EVENT |
  935. FRS_RKF_SYNTAX_CHECK |
  936. FRS_RKF_CREATE_KEY |
  937. FRS_RKF_OK_TO_USE_DEFAULT |
  938. FRS_RKF_READ_AT_POLL},
  939. // The file filter exclusion list.
  940. // Don't supply a default here. See FRS_DS_COMPOSE_FILTER_LIST for why.
  941. {FRS_RKEY_SYSVOL_SET_N, L"File Exclusion Filter List", UNITS_NONE,
  942. REG_SZ, DT_FILE_LIST, 0, 0, 0, EVENT_FRS_BAD_REG_DATA, NULL,
  943. FKC_SET_N_SYSVOL_FILE_EXCL_FILTER_LIST, FRS_RKF_READ_AT_START |
  944. FRS_RKF_LOG_EVENT |
  945. FRS_RKF_READ_AT_POLL},
  946. // The file filter inclusion list. Default: ~clbcatq.*
  947. {FRS_RKEY_SYSVOL_SET_N, L"File Inclusion Filter List", UNITS_NONE,
  948. REG_SZ, DT_FILE_LIST, 0, 0, 0, EVENT_FRS_BAD_REG_DATA,
  949. L"~clbcatq.*",
  950. FKC_SET_N_SYSVOL_FILE_INCL_FILTER_LIST, FRS_RKF_READ_AT_START |
  951. FRS_RKF_LOG_EVENT |
  952. FRS_RKF_SYNTAX_CHECK |
  953. FRS_RKF_CREATE_KEY |
  954. FRS_RKF_OK_TO_USE_DEFAULT |
  955. FRS_RKF_READ_AT_POLL},
  956. // The operation to perform on the replica set.
  957. // SysVol\<Guid>\Replica Set Command
  958. {FRS_RKEY_SYSVOL_SET_N, REPLICA_SET_COMMAND, UNITS_NONE,
  959. REG_SZ, DT_UNICODE, 2, 1024, 0, EVENT_FRS_NONE, NULL,
  960. FKC_SET_N_SYSVOL_COMMAND, FRS_RKF_READ_AT_START |
  961. FRS_RKF_RANGE_CHECK |
  962. FRS_RKF_VALUE_MUST_BE_PRESENT},
  963. // The RPC binding string for the parent computer to seed from.
  964. // SysVol\<Guid>\Replica Set Parent
  965. {FRS_RKEY_SYSVOL_SET_N, REPLICA_SET_PARENT, UNITS_NONE,
  966. REG_SZ, DT_UNICODE, 2, 10*1024, 0, EVENT_FRS_NONE, NULL,
  967. FKC_SET_N_SYSVOL_PARENT, FRS_RKF_READ_AT_START |
  968. FRS_RKF_RANGE_CHECK |
  969. FRS_RKF_VALUE_MUST_BE_PRESENT},
  970. // If TRUE this is the first member of a replica set and we init the DB
  971. // with the contents of the replica tree.
  972. // SysVol\<Guid>\Replica Set Primary
  973. {FRS_RKEY_SYSVOL_SET_N, REPLICA_SET_PRIMARY, UNITS_NONE,
  974. REG_DWORD, DT_BOOL, 0, 1, 0, EVENT_FRS_NONE, NULL,
  975. FKC_SET_N_SYSVOL_PRIMARY, FRS_RKF_READ_AT_START |
  976. FRS_RKF_RANGE_CHECK |
  977. FRS_RKF_VALUE_MUST_BE_PRESENT},
  978. // LDAP error Status return if we have a problem creating sysvol.
  979. // SysVol\<Guid>\Replica Set Status
  980. {FRS_RKEY_SYSVOL_SET_N, REPLICA_SET_STATUS, UNITS_NONE,
  981. REG_DWORD, DT_ULONG, 0, MAXULONG, 0, EVENT_FRS_NONE, NULL,
  982. FKC_SET_N_SYSVOL_STATUS, FRS_RKF_READ_AT_START},
  983. // The RPC binding string for the parent computer to seed from.
  984. // SysVol Seeding\ReplicaSetName(ARG1)\Replica Set Parent
  985. {FRS_RKEY_SYSVOL_SEED_N, REPLICA_SET_PARENT, UNITS_NONE,
  986. REG_SZ, DT_UNICODE, 2, 10*1024, 0, EVENT_FRS_NONE, NULL,
  987. FKC_SYSVOL_SEEDING_N_PARENT, FRS_RKF_READ_AT_START |
  988. FRS_RKF_RANGE_CHECK |
  989. FRS_RKF_VALUE_MUST_BE_PRESENT},
  990. // SysVol Seeding\ReplicaSetName(ARG1)\Replica Set Name
  991. {FRS_RKEY_SYSVOL_SEED_N, REPLICA_SET_NAME, UNITS_NONE,
  992. REG_SZ, DT_UNICODE, 2, 10*1024, 0, EVENT_FRS_NONE, NULL,
  993. FKC_SYSVOL_SEEDING_N_RSNAME, FRS_RKF_READ_AT_START |
  994. FRS_RKF_RANGE_CHECK |
  995. FRS_RKF_VALUE_MUST_BE_PRESENT},
  996. // SysVol Seeding *NOTE* THis is a key only. It has no value.
  997. {FRS_RKEY_SYSVOL_SEEDING_SECTION, L"*KeyOnly*", UNITS_NONE,
  998. REG_SZ, DT_UNICODE, 2, 10*1024, 0, EVENT_FRS_NONE, NULL,
  999. FKC_SYSVOL_SEEDING_SECTION_KEY, 0},
  1000. /******************************************************************************
  1001. *******************************************************************************
  1002. ** **
  1003. ** E v e n t L o g g i n g C o n f i g K e y s **
  1004. ** **
  1005. ** **
  1006. *******************************************************************************
  1007. ******************************************************************************/
  1008. #define FRS_RKEY_EVENTLOG EVENTLOG_ROOT L",ARG1"
  1009. #define FRS_RKEY_EVENTLOG_SOURCE EVENTLOG_ROOT L"," SERVICE_LONG_NAME L",ARG1"
  1010. // EventLog\File Replication Service\File
  1011. {FRS_RKEY_EVENTLOG, L"File", UNITS_NONE,
  1012. REG_EXPAND_SZ, DT_FILENAME, 4, 0, 0, EVENT_FRS_NONE,
  1013. L"%SystemRoot%\\system32\\config\\NtFrs.Evt",
  1014. FKC_EVENTLOG_FILE, FRS_RKF_READ_AT_START |
  1015. FRS_RKF_CREATE_KEY |
  1016. FRS_RKF_SYNTAX_CHECK |
  1017. FRS_RKF_OK_TO_USE_DEFAULT},
  1018. // EventLog\File Replication Service\DisplayNameFile
  1019. {FRS_RKEY_EVENTLOG, L"DisplayNameFile", UNITS_NONE,
  1020. REG_EXPAND_SZ, DT_FILENAME, 4, 0, 0, EVENT_FRS_NONE,
  1021. L"%SystemRoot%\\system32\\els.dll",
  1022. FKC_EVENTLOG_DISPLAY_FILENAME,FRS_RKF_READ_AT_START |
  1023. FRS_RKF_CREATE_KEY |
  1024. FRS_RKF_SYNTAX_CHECK |
  1025. FRS_RKF_OK_TO_USE_DEFAULT},
  1026. // EventLog\File Replication Service\EventMessageFile
  1027. // EventLog\NTFRS\EventMessageFile
  1028. // Default value: "%SystemRoot%\system32\ntfrsres.dll"
  1029. {FRS_RKEY_EVENTLOG_SOURCE, L"EventMessageFile", UNITS_NONE,
  1030. REG_EXPAND_SZ, DT_FILENAME, 4, 0, 0, EVENT_FRS_NONE,
  1031. DEFAULT_MESSAGE_FILE_PATH,
  1032. FKC_EVENTLOG_EVENT_MSG_FILE, FRS_RKF_READ_AT_START |
  1033. FRS_RKF_CREATE_KEY |
  1034. FRS_RKF_SYNTAX_CHECK |
  1035. FRS_RKF_OK_TO_USE_DEFAULT},
  1036. // EventLog\File Replication Service\Sources
  1037. {FRS_RKEY_EVENTLOG, L"Sources", UNITS_NONE,
  1038. REG_MULTI_SZ, DT_UNICODE, 4, 0, 0, EVENT_FRS_NONE,
  1039. (SERVICE_NAME L"\0" SERVICE_LONG_NAME L"\0"),
  1040. FKC_EVENTLOG_SOURCES, FRS_RKF_READ_AT_START |
  1041. FRS_RKF_CREATE_KEY |
  1042. FRS_RKF_OK_TO_USE_DEFAULT},
  1043. // EventLog\File Replication Service\Retention
  1044. {FRS_RKEY_EVENTLOG, L"Retention", UNITS_NONE,
  1045. REG_DWORD, DT_ULONG, 0, MAXULONG, 0, EVENT_FRS_BAD_REG_DATA, NULL,
  1046. FKC_EVENTLOG_RETENTION, FRS_RKF_READ_AT_START |
  1047. FRS_RKF_LOG_EVENT |
  1048. FRS_RKF_CREATE_KEY |
  1049. FRS_RKF_OK_TO_USE_DEFAULT},
  1050. // EventLog\File Replication Service\MaxSize
  1051. {FRS_RKEY_EVENTLOG, L"MaxSize", UNITS_NONE,
  1052. REG_DWORD, DT_ULONG, 0, MAXULONG, 0x80000, EVENT_FRS_BAD_REG_DATA, NULL,
  1053. FKC_EVENTLOG_MAXSIZE, FRS_RKF_READ_AT_START |
  1054. FRS_RKF_LOG_EVENT |
  1055. FRS_RKF_CREATE_KEY |
  1056. FRS_RKF_OK_TO_USE_DEFAULT},
  1057. // EventLog\File Replication Service\DisplayNameID
  1058. {FRS_RKEY_EVENTLOG, L"DisplayNameID", UNITS_NONE,
  1059. REG_DWORD, DT_ULONG, 0, MAXULONG, 259, EVENT_FRS_NONE, NULL,
  1060. FKC_EVENTLOG_DISPLAY_NAMEID, FRS_RKF_READ_AT_START |
  1061. FRS_RKF_CREATE_KEY |
  1062. FRS_RKF_OK_TO_USE_DEFAULT},
  1063. // EventLog\File Replication Service\TypesSupported
  1064. {FRS_RKEY_EVENTLOG_SOURCE, L"TypesSupported", UNITS_NONE,
  1065. REG_DWORD, DT_ULONG, 0, MAXULONG, FRS_EVENT_TYPES, EVENT_FRS_NONE, NULL,
  1066. FKC_EVENTLOG_TYPES_SUPPORTED, FRS_RKF_READ_AT_START |
  1067. FRS_RKF_CREATE_KEY |
  1068. FRS_RKF_OK_TO_USE_DEFAULT},
  1069. /******************************************************************************
  1070. *******************************************************************************
  1071. ** **
  1072. ** F R S A P I A c c e s s C h e c k K e y s **
  1073. ** **
  1074. ** **
  1075. *******************************************************************************
  1076. ******************************************************************************/
  1077. #define FRS_RKEY_ACCCHK_PERFMON \
  1078. FRS_CONFIG_SECTION L",Access Checks," ACK_COLLECT_PERFMON_DATA
  1079. // Access Checks\Get Perfmon Data\Access checks are [Enabled or Disabled]
  1080. {FRS_RKEY_ACCCHK_PERFMON, ACCESS_CHECKS_ARE, UNITS_NONE,
  1081. REG_SZ, DT_ACCESS_CHK, 2, 200, 0, EVENT_FRS_BAD_REG_DATA,
  1082. ACCESS_CHECKS_ARE_DEFAULT_ENABLED,
  1083. FKC_ACCCHK_PERFMON_ENABLE, FRS_RKF_READ_AT_START |
  1084. FRS_RKF_LOG_EVENT |
  1085. FRS_RKF_CREATE_KEY |
  1086. FRS_RKF_SYNTAX_CHECK |
  1087. FRS_RKF_RANGE_CHECK},
  1088. // Access Checks\Get Perfmon Data\Access checks require [Full Control or Read]
  1089. {FRS_RKEY_ACCCHK_PERFMON, ACCESS_CHECKS_REQUIRE, UNITS_NONE,
  1090. REG_SZ, DT_ACCESS_CHK, 2, 200, 0, EVENT_FRS_BAD_REG_DATA,
  1091. ACCESS_CHECKS_REQUIRE_DEFAULT_READ,
  1092. FKC_ACCCHK_PERFMON_RIGHTS, FRS_RKF_READ_AT_START |
  1093. FRS_RKF_LOG_EVENT |
  1094. FRS_RKF_CREATE_KEY |
  1095. FRS_RKF_SYNTAX_CHECK |
  1096. FRS_RKF_RANGE_CHECK},
  1097. #define FRS_RKEY_ACCCHK_GETDS_POLL \
  1098. FRS_CONFIG_SECTION L",Access Checks," ACK_GET_DS_POLL
  1099. // Access Checks\Get Ds Polling Interval\Access checks are [Enabled or Disabled]
  1100. {FRS_RKEY_ACCCHK_GETDS_POLL, ACCESS_CHECKS_ARE, UNITS_NONE,
  1101. REG_SZ, DT_ACCESS_CHK, 2, 200, 0, EVENT_FRS_BAD_REG_DATA,
  1102. ACCESS_CHECKS_ARE_DEFAULT_ENABLED,
  1103. FKC_ACCCHK_GETDS_POLL_ENABLE, FRS_RKF_READ_AT_START |
  1104. FRS_RKF_LOG_EVENT |
  1105. FRS_RKF_CREATE_KEY |
  1106. FRS_RKF_SYNTAX_CHECK |
  1107. FRS_RKF_RANGE_CHECK},
  1108. // Access Checks\Get Ds Polling Interval\Access checks require [Full Control or Read]
  1109. {FRS_RKEY_ACCCHK_GETDS_POLL, ACCESS_CHECKS_REQUIRE, UNITS_NONE,
  1110. REG_SZ, DT_ACCESS_CHK, 2, 200, 0, EVENT_FRS_BAD_REG_DATA,
  1111. ACCESS_CHECKS_REQUIRE_DEFAULT_READ,
  1112. FKC_ACCCHK_GETDS_POLL_RIGHTS, FRS_RKF_READ_AT_START |
  1113. FRS_RKF_LOG_EVENT |
  1114. FRS_RKF_CREATE_KEY |
  1115. FRS_RKF_SYNTAX_CHECK |
  1116. FRS_RKF_RANGE_CHECK},
  1117. #define FRS_RKEY_ACCCHK_GET_INFO \
  1118. FRS_CONFIG_SECTION L",Access Checks," ACK_INTERNAL_INFO
  1119. // Access Checks\Get Internal Information\Access checks are [Enabled or Disabled]
  1120. {FRS_RKEY_ACCCHK_GET_INFO, ACCESS_CHECKS_ARE, UNITS_NONE,
  1121. REG_SZ, DT_ACCESS_CHK, 2, 200, 0, EVENT_FRS_BAD_REG_DATA,
  1122. ACCESS_CHECKS_ARE_DEFAULT_ENABLED,
  1123. FKC_ACCCHK_GET_INFO_ENABLE, FRS_RKF_READ_AT_START |
  1124. FRS_RKF_LOG_EVENT |
  1125. FRS_RKF_CREATE_KEY |
  1126. FRS_RKF_SYNTAX_CHECK |
  1127. FRS_RKF_RANGE_CHECK},
  1128. // Access Checks\Get Internal Information\Access checks require [Full Control or Read]
  1129. {FRS_RKEY_ACCCHK_GET_INFO, ACCESS_CHECKS_REQUIRE, UNITS_NONE,
  1130. REG_SZ, DT_ACCESS_CHK, 2, 200, 0, EVENT_FRS_BAD_REG_DATA,
  1131. ACCESS_CHECKS_REQUIRE_DEFAULT_WRITE,
  1132. FKC_ACCCHK_GET_INFO_RIGHTS, FRS_RKF_READ_AT_START |
  1133. FRS_RKF_LOG_EVENT |
  1134. FRS_RKF_CREATE_KEY |
  1135. FRS_RKF_SYNTAX_CHECK |
  1136. FRS_RKF_RANGE_CHECK},
  1137. #define FRS_RKEY_ACCCHK_SETDS_POLL \
  1138. FRS_CONFIG_SECTION L",Access Checks," ACK_SET_DS_POLL
  1139. // Access Checks\set Ds Polling Interval\Access checks are [Enabled or Disabled]
  1140. {FRS_RKEY_ACCCHK_SETDS_POLL, ACCESS_CHECKS_ARE, UNITS_NONE,
  1141. REG_SZ, DT_ACCESS_CHK, 2, 200, 0, EVENT_FRS_BAD_REG_DATA,
  1142. ACCESS_CHECKS_ARE_DEFAULT_ENABLED,
  1143. FKC_ACCCHK_SETDS_POLL_ENABLE, FRS_RKF_READ_AT_START |
  1144. FRS_RKF_LOG_EVENT |
  1145. FRS_RKF_CREATE_KEY |
  1146. FRS_RKF_SYNTAX_CHECK |
  1147. FRS_RKF_RANGE_CHECK},
  1148. // Access Checks\Set Ds Polling Interval\Access checks require [Full Control or Read]
  1149. {FRS_RKEY_ACCCHK_SETDS_POLL, ACCESS_CHECKS_REQUIRE, UNITS_NONE,
  1150. REG_SZ, DT_ACCESS_CHK, 2, 200, 0, EVENT_FRS_BAD_REG_DATA,
  1151. ACCESS_CHECKS_REQUIRE_DEFAULT_WRITE,
  1152. FKC_ACCCHK_SETDS_POLL_RIGHTS, FRS_RKF_READ_AT_START |
  1153. FRS_RKF_LOG_EVENT |
  1154. FRS_RKF_CREATE_KEY |
  1155. FRS_RKF_SYNTAX_CHECK |
  1156. FRS_RKF_RANGE_CHECK},
  1157. #define FRS_RKEY_ACCCHK_STARTDS_POLL \
  1158. FRS_CONFIG_SECTION L",Access Checks," ACK_START_DS_POLL
  1159. // Access Checks\Start Ds Polling\Access checks are [Enabled or Disabled]
  1160. {FRS_RKEY_ACCCHK_STARTDS_POLL, ACCESS_CHECKS_ARE, UNITS_NONE,
  1161. REG_SZ, DT_ACCESS_CHK, 2, 200, 0, EVENT_FRS_BAD_REG_DATA,
  1162. ACCESS_CHECKS_ARE_DEFAULT_ENABLED,
  1163. FKC_ACCCHK_STARTDS_POLL_ENABLE, FRS_RKF_READ_AT_START |
  1164. FRS_RKF_LOG_EVENT |
  1165. FRS_RKF_CREATE_KEY |
  1166. FRS_RKF_SYNTAX_CHECK |
  1167. FRS_RKF_RANGE_CHECK},
  1168. // Access Checks\Start Ds Polling\Access checks require [Full Control or Read]
  1169. {FRS_RKEY_ACCCHK_STARTDS_POLL, ACCESS_CHECKS_REQUIRE, UNITS_NONE,
  1170. REG_SZ, DT_ACCESS_CHK, 2, 200, 0, EVENT_FRS_BAD_REG_DATA,
  1171. ACCESS_CHECKS_REQUIRE_DEFAULT_READ,
  1172. FKC_ACCCHK_STARTDS_POLL_RIGHTS, FRS_RKF_READ_AT_START |
  1173. FRS_RKF_LOG_EVENT |
  1174. FRS_RKF_CREATE_KEY |
  1175. FRS_RKF_SYNTAX_CHECK |
  1176. FRS_RKF_RANGE_CHECK},
  1177. #define FRS_RKEY_ACCCHK_DCPROMO \
  1178. FRS_CONFIG_SECTION L",Access Checks," ACK_DCPROMO
  1179. // Access Checks\dcpromo\Access checks are [Enabled or Disabled]
  1180. {FRS_RKEY_ACCCHK_DCPROMO, ACCESS_CHECKS_ARE, UNITS_NONE,
  1181. REG_SZ, DT_ACCESS_CHK, 2, 200, 0, EVENT_FRS_BAD_REG_DATA,
  1182. ACCESS_CHECKS_ARE_DEFAULT_ENABLED,
  1183. FKC_ACCESS_CHK_DCPROMO_ENABLE, FRS_RKF_READ_AT_START |
  1184. FRS_RKF_LOG_EVENT |
  1185. FRS_RKF_CREATE_KEY |
  1186. FRS_RKF_SYNTAX_CHECK |
  1187. FRS_RKF_RANGE_CHECK},
  1188. // Access Checks\dcpromo\Access checks require [Full Control or Read]
  1189. {FRS_RKEY_ACCCHK_DCPROMO, ACCESS_CHECKS_REQUIRE, UNITS_NONE,
  1190. REG_SZ, DT_ACCESS_CHK, 2, 200, 0, EVENT_FRS_BAD_REG_DATA,
  1191. ACCESS_CHECKS_REQUIRE_DEFAULT_WRITE,
  1192. FKC_ACCESS_CHK_DCPROMO_RIGHTS, FRS_RKF_READ_AT_START |
  1193. FRS_RKF_LOG_EVENT |
  1194. FRS_RKF_CREATE_KEY |
  1195. FRS_RKF_SYNTAX_CHECK |
  1196. FRS_RKF_RANGE_CHECK},
  1197. /******************************************************************************
  1198. *******************************************************************************
  1199. ** **
  1200. ** F R S B a c k u p / R e s t o r e R e l a t e d K e y s **
  1201. ** **
  1202. ** **
  1203. *******************************************************************************
  1204. ******************************************************************************/
  1205. //
  1206. // No event log messages are generated for these keys since currently
  1207. // they are only created by the service or NTFRSAPI so if they get
  1208. // fouled up there is nothing the USER can do to correct the problem.
  1209. //
  1210. #define FRS_RKEY_BACKUP_STARTUP_SET_N_SECTION FRS_BACKUP_RESTORE_MV_SETS_SECTION L",ARG1"
  1211. /*
  1212. Used in NtfrsApi.c to pass to backup/restore.
  1213. #define FRS_NEW_FILES_NOT_TO_BACKUP L"SYSTEM\\CurrentControlSet\\Control\\BackupRestore\\FilesNotToBackup"
  1214. FRS_NEW_FILES_NOT_TO_BACKUP REG_MULTI_SZ key
  1215. #define FRS_OLD_FILES_NOT_TO_BACKUP L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\FilesNotToBackup"
  1216. FRS_OLD_FILES_NOT_TO_BACKUP REG_MULTI_SZ key
  1217. */
  1218. // Backup/Restore
  1219. // *NOTE* THis is a key only. It has no value.
  1220. {FRS_BACKUP_RESTORE_SECTION, L"*KeyOnly*", UNITS_NONE,
  1221. REG_SZ, DT_UNICODE, 2, 10*1024, 0, EVENT_FRS_NONE, NULL,
  1222. FKC_BKUP_SECTION_KEY, 0},
  1223. // Backup/Restore\\Stop NtFrs from Starting
  1224. // *NOTE* THis is a key only. It has no value.
  1225. {FRS_BACKUP_RESTORE_STOP_SECTION, L"*KeyOnly*", UNITS_NONE,
  1226. REG_SZ, DT_UNICODE, 2, 10*1024, 0, EVENT_FRS_NONE, NULL,
  1227. FKC_BKUP_STOP_SECTION_KEY, 0},
  1228. // Backup/Restore\Process at Startup\Replica Sets
  1229. // *NOTE* THis is a key only. It has no value.
  1230. {FRS_BACKUP_RESTORE_MV_SETS_SECTION, L"*KeyOnly*", UNITS_NONE,
  1231. REG_SZ, DT_UNICODE, 2, 10*1024, 0, EVENT_FRS_NONE, NULL,
  1232. FKC_BKUP_MV_SETS_SECTION_KEY, 0},
  1233. // Backup/Restore\Process at Startup\Cumulative Replica Sets
  1234. // *NOTE* THis is a key only. It has no value.
  1235. {FRS_BACKUP_RESTORE_MV_CUMULATIVE_SETS_SECTION, L"*KeyOnly*", UNITS_NONE,
  1236. REG_SZ, DT_UNICODE, 2, 10*1024, 0, EVENT_FRS_NONE, NULL,
  1237. FKC_BKUP_MV_CUMSETS_SECTION_KEY, 0},
  1238. // Global Backup / Restore flags.
  1239. // backup/restore\Process at Startup\BurFlags
  1240. {FRS_BACKUP_RESTORE_MV_SECTION, FRS_VALUE_BURFLAGS, UNITS_NONE,
  1241. REG_DWORD, DT_ULONG, 0, MAXULONG, NTFRSAPI_BUR_FLAGS_NONE, EVENT_FRS_NONE, NULL,
  1242. FKC_BKUP_STARTUP_GLOBAL_BURFLAGS, FRS_RKF_READ_AT_START |
  1243. FRS_RKF_OK_TO_USE_DEFAULT},
  1244. // Backup / Restore flags for this replica set in "Process at Startup"
  1245. // backup/restore\Process at Startup\Replica Sets\<guid>\BurFlags
  1246. {FRS_RKEY_BACKUP_STARTUP_SET_N_SECTION, FRS_VALUE_BURFLAGS, UNITS_NONE,
  1247. REG_DWORD, DT_ULONG, 0, MAXULONG, 0, EVENT_FRS_NONE, NULL,
  1248. FKC_BKUP_STARTUP_SET_N_BURFLAGS, FRS_RKF_READ_AT_START},
  1249. /******************************************************************************
  1250. *******************************************************************************
  1251. ** **
  1252. ** F R S P E R F M O N R e l a t e d K e y s **
  1253. ** **
  1254. ** **
  1255. *******************************************************************************
  1256. ******************************************************************************/
  1257. //
  1258. // No event log messages are generated for these keys since currently
  1259. // they are only created by the service so if they get
  1260. // fouled up there is nothing the USER can do to correct the problem.
  1261. //
  1262. //
  1263. // Note: We can't really use thes yet since some of them are in the DLL
  1264. // which doesn't link with this module. Also some are MULTI_SZ which
  1265. // needs more work in CfgRegReadString and writestring.
  1266. #define FRS_RKEY_REPLICA_SET_PERFMON \
  1267. L"SYSTEM\\CurrentControlSet\\Services\\FileReplicaSet\\Performance"
  1268. #define FRS_RKEY_REPLICA_SET_PERF_LINKAGE \
  1269. L"SYSTEM\\CurrentControlSet\\Services\\FileReplicaSet\\Linkage"
  1270. #define FRS_RKEY_CXTION_PERFMON \
  1271. L"SYSTEM\\CurrentControlSet\\Services\\FileReplicaConn\\Performance"
  1272. #define FRS_RKEY_CXTION_PERF_LINKAGE \
  1273. L"SYSTEM\\CurrentControlSet\\Services\\FileReplicaConn\\Linkage"
  1274. // FileReplicaSet\\Performance\First Counter
  1275. {FRS_RKEY_REPLICA_SET_PERFMON, L"First Counter", UNITS_NONE,
  1276. REG_DWORD, DT_ULONG, 0, MAXULONG, 0, EVENT_FRS_NONE, NULL,
  1277. FKC_REPLICA_SET_FIRST_CTR, FRS_RKF_READ_AT_START},
  1278. // FileReplicaSet\\Performance\First Help
  1279. {FRS_RKEY_REPLICA_SET_PERFMON, L"First Help", UNITS_NONE,
  1280. REG_DWORD, DT_ULONG, 0, MAXULONG, 0, EVENT_FRS_NONE, NULL,
  1281. FKC_REPLICA_SET_FIRST_HELP, FRS_RKF_READ_AT_START},
  1282. // FileReplicaSet\\Linkage\Export
  1283. {FRS_RKEY_REPLICA_SET_PERF_LINKAGE, L"Export", UNITS_NONE,
  1284. REG_MULTI_SZ, DT_UNICODE, 0, MAXULONG, 0, EVENT_FRS_NONE, NULL,
  1285. FKC_REPLICA_SET_LINKAGE_EXPORT, FRS_RKF_READ_AT_START},
  1286. // FileReplicaConn\\Performance\First Counter
  1287. {FRS_RKEY_CXTION_PERFMON, L"First Counter", UNITS_NONE,
  1288. REG_DWORD, DT_ULONG, 0, MAXULONG, 0, EVENT_FRS_NONE, NULL,
  1289. FKC_REPLICA_CXTION_FIRST_CTR, FRS_RKF_READ_AT_START},
  1290. // FileReplicaConn\\Performance\First Help
  1291. {FRS_RKEY_CXTION_PERFMON, L"First Help", UNITS_NONE,
  1292. REG_DWORD, DT_ULONG, 0, MAXULONG, 0, EVENT_FRS_NONE, NULL,
  1293. FKC_REPLICA_CXTION_FIRST_HELP, FRS_RKF_READ_AT_START},
  1294. // FileReplicaConn\\Linkage\Export
  1295. {FRS_RKEY_CXTION_PERF_LINKAGE, L"Export", UNITS_NONE,
  1296. REG_MULTI_SZ, DT_UNICODE, 0, MAXULONG, 0, EVENT_FRS_NONE, NULL,
  1297. FKC_REPLICA_CXTION_LINKAGE_EXPORT, FRS_RKF_READ_AT_START},
  1298. {L"End of table", NULL, UNITS_NONE,
  1299. REG_SZ, DT_UNSPECIFIED, 0, 0, 0, EVENT_FRS_NONE, NULL,
  1300. FKC_END_OF_TABLE, 0}
  1301. }; // End of FrsRegistryKeyTable
  1302. PFRS_REGISTRY_KEY
  1303. FrsRegFindKeyContext(
  1304. IN FRS_REG_KEY_CODE KeyIndex
  1305. )
  1306. {
  1307. /*++
  1308. Routine Description:
  1309. This function takes an FRS Registry Key code and returns a pointer to
  1310. the associated key context data.
  1311. Arguments:
  1312. KeyIndex - An entry from the FRS_REG_KEY_CODE enum
  1313. Return Value:
  1314. Ptr to the matching Key context entry or NULL if not found.
  1315. --*/
  1316. #undef DEBSUB
  1317. #define DEBSUB "FrsRegFindKeyContext:"
  1318. PFRS_REGISTRY_KEY KeyCtx;
  1319. //DPRINT(0, "function entry\n");
  1320. FRS_ASSERT((KeyIndex > 0) && (KeyIndex < FRS_REG_KEY_CODE_MAX));
  1321. if (KeyIndex >= FRS_REG_KEY_CODE_MAX) {
  1322. return NULL;
  1323. }
  1324. KeyCtx = FrsRegistryKeyTable;
  1325. while (KeyCtx->FrsKeyCode > FKC_END_OF_TABLE) {
  1326. if (KeyIndex == KeyCtx->FrsKeyCode) {
  1327. //
  1328. // Found it.
  1329. //
  1330. return KeyCtx;
  1331. }
  1332. KeyCtx += 1;
  1333. }
  1334. //
  1335. // Not found.
  1336. //
  1337. return NULL;
  1338. }
  1339. PWCHAR
  1340. CfgRegGetValueName(
  1341. IN FRS_REG_KEY_CODE KeyIndex
  1342. )
  1343. {
  1344. /*++
  1345. Routine Description:
  1346. This function returns a ptr to the value name string in the key context.
  1347. This is NOT a ptr to an allocated string so it should NOT be freed.
  1348. Arguments:
  1349. KeyIndex - An entry from the FRS_REG_KEY_CODE enum
  1350. Return Value:
  1351. Ptr to value name string. NULL if KeyIndex lookup fails.
  1352. --*/
  1353. #undef DEBSUB
  1354. #define DEBSUB "CfgRegGetValueName:"
  1355. PFRS_REGISTRY_KEY KeyCtx;
  1356. //
  1357. // Find the key context assoicated with the supplied index.
  1358. //
  1359. KeyCtx = FrsRegFindKeyContext(KeyIndex);
  1360. if (KeyCtx == NULL) {
  1361. DPRINT1(0, ":FK: ERROR - Key contxt not found for key code number %d\n", KeyIndex);
  1362. return L"<null>";
  1363. }
  1364. return KeyCtx->ValueName;
  1365. }
  1366. DWORD
  1367. FrsRegExpandKeyStr(
  1368. IN PFRS_REGISTRY_KEY Kc,
  1369. IN PWCHAR KeyArg1,
  1370. IN ULONG Flags,
  1371. OUT PWCHAR *FullKeyStr
  1372. )
  1373. {
  1374. /*++
  1375. Routine Description:
  1376. This function only expands a key field in the given KeyContext and
  1377. returns the result in FullKeyStr. This is used primarily for error
  1378. messages but is also used to open registry access check keys.
  1379. The syntax for the the key field in the KeyContext consists of multiple
  1380. key components separated by commas. This function splits the key field on
  1381. the commas. It then opens the leading key followed by either a create or
  1382. open of each successive component. If a component matches the string
  1383. L"ARG1" then we substitute the KeyArg1 parameter passed to this function
  1384. for this key component. Most often this is a stringized guid. For
  1385. example, the string FRS_RKEY_SET_N is defined as:
  1386. FRS_CONFIG_SECTION L",Replica Sets,ARG1"
  1387. This will end up opening/creating the following key:
  1388. "System\\CurrentControlSet\\Services\\NtFrs\\Parameters\\
  1389. Replica Sets\\
  1390. 27d6d1c4-d6b8-480b-9f18b5ea390a0178"
  1391. assuming the argument passed in was "27d6d1c4-d6b8-480b-9f18b5ea390a0178".
  1392. Arguments:
  1393. Kc - A ptr to the key context struct for the desired reg key.
  1394. KeyArg1 - An optional caller supplied key component. NULL if not provided.
  1395. Flags - Modifer flags
  1396. FullKeyStr - ptr to return buffer for expanded key string.
  1397. NOTE: The buffer is allocated here. Caller must free it.
  1398. Return Value:
  1399. Win32 status of the result of the operation.
  1400. FullKeyStr is returned NULL if operation fails.
  1401. --*/
  1402. #undef DEBSUB
  1403. #define DEBSUB "FrsRegExpandKeyStr:"
  1404. UNICODE_STRING TempUStr, FirstArg;
  1405. PWCHAR FullKey = NULL;
  1406. ULONG Len, FullKeyLen;
  1407. WCHAR KeyStr[MAX_PATH];
  1408. //DPRINT(0, "function entry\n");
  1409. *FullKeyStr = NULL;
  1410. FullKey = FrsAlloc(FULL_KEY_BUFF_SIZE*sizeof(WCHAR));
  1411. FullKey[0] = UNICODE_NULL;
  1412. FullKeyLen = 1;
  1413. //
  1414. // If there are any commas in this key then we need to do a nested
  1415. // key open (perhaps creating nested keys as we go). If the key
  1416. // component matches the string L"ARG1" then we use KeyArg1 supplied by
  1417. // the caller.
  1418. //
  1419. RtlInitUnicodeString(&TempUStr, Kc->KeyName);
  1420. //
  1421. // Parse the comma list.
  1422. //
  1423. while (FrsDissectCommaList(TempUStr, &FirstArg, &TempUStr)) {
  1424. if ((FirstArg.Length == 0) || (FirstArg.Length >= sizeof(KeyStr))) {
  1425. DPRINT1(0, ":FK: ERROR - Bad keyName in Key contxt %ws\n", Kc->KeyName);
  1426. goto ERROR_RETURN;
  1427. }
  1428. //
  1429. // null terminate the key component string.
  1430. //
  1431. CopyMemory(KeyStr, FirstArg.Buffer, FirstArg.Length);
  1432. KeyStr[FirstArg.Length/sizeof(WCHAR)] = UNICODE_NULL;
  1433. //
  1434. // Check the Key Component for a match on ARG1 and substitute.
  1435. //
  1436. if (wcscmp(KeyStr, L"ARG1") == 0) {
  1437. if (wcslen(KeyArg1)*sizeof(WCHAR) > sizeof(KeyStr)) {
  1438. DPRINT1(0, ":FK: ERROR - ARG1 too big %ws\n", KeyArg1);
  1439. goto ERROR_RETURN;
  1440. }
  1441. wcscpy(KeyStr, KeyArg1);
  1442. }
  1443. Len = wcslen(KeyStr);
  1444. if (FullKeyLen + Len + 1 > FULL_KEY_BUFF_SIZE) {
  1445. goto ERROR_RETURN;
  1446. }
  1447. if (FullKeyLen > 1) {
  1448. wcscat(FullKey, L"\\");
  1449. FullKeyLen += 1;
  1450. }
  1451. wcscat(FullKey, KeyStr);
  1452. FullKeyLen += Len;
  1453. } // end while()
  1454. if (FullKeyLen <= 1) {
  1455. goto ERROR_RETURN;
  1456. }
  1457. DPRINT1(4, ":FK: Expanded key name is \"%ws\"\n", FullKey);
  1458. //
  1459. // Return the expanded key to the caller.
  1460. //
  1461. *FullKeyStr = FullKey;
  1462. return ERROR_SUCCESS;
  1463. ERROR_RETURN:
  1464. DPRINT1(0, ":FK: ERROR - FrsRegExpandKeyStr Failed on %ws", Kc->KeyName);
  1465. FrsFree(FullKey);
  1466. return ERROR_INVALID_PARAMETER;
  1467. }
  1468. DWORD
  1469. FrsRegOpenKey(
  1470. IN PFRS_REGISTRY_KEY Kc,
  1471. IN PWCHAR KeyArg1,
  1472. IN ULONG Flags,
  1473. OUT PHKEY hKeyRet
  1474. )
  1475. {
  1476. /*++
  1477. Routine Description:
  1478. This function opens a registry key and returns a handle.
  1479. See FrsRegExpandKeyStr() for a description of the key field syntax.
  1480. Arguments:
  1481. Kc - A ptr to the key context struct for the desired reg key.
  1482. KeyArg1 - An optional caller supplied key component. NULL if not provided.
  1483. Flags - Modifer flags
  1484. FRS_RKF_KEY_ACCCHK_READ means only do a read access check on the key.
  1485. FRS_RKF_KEY_ACCCHK_WRITE means only do a KEY_ALL_ACCESS access check on the key.
  1486. if FRS_RKF_CREATE_KEY is set and FRS_RKF_KEY_MUST_BE_PRESENT is clear
  1487. and the given key component is not found, this function creates it.
  1488. hKeyRet - ptr to HKEY for returned key handle.
  1489. Return Value:
  1490. Win32 status of the result of the registry operation.
  1491. hKeyRet is returned only on a success.
  1492. --*/
  1493. #undef DEBSUB
  1494. #define DEBSUB "FrsRegOpenKey:"
  1495. UNICODE_STRING TempUStr, FirstArg;
  1496. ULONG WStatus;
  1497. PWCHAR FullKey = NULL;
  1498. HKEY hKey = HKEY_LOCAL_MACHINE;
  1499. HKEY hKeyParent = INVALID_HANDLE_VALUE;
  1500. ULONG AccessRights;
  1501. PCHAR AccessName;
  1502. WCHAR KeyStr[MAX_PATH];
  1503. FrsFlagsToStr(Flags, RkfFlagNameTable, sizeof(KeyStr), (PCHAR)KeyStr);
  1504. DPRINT2(4, ":FK: %ws Caller Flags [%s]\n", Kc->ValueName, (PCHAR)KeyStr);
  1505. FrsFlagsToStr(Kc->Flags, RkfFlagNameTable, sizeof(KeyStr), (PCHAR)KeyStr);
  1506. DPRINT2(4, ":FK: %ws KeyCtx Flags [%s]\n", Kc->ValueName, (PCHAR)KeyStr);
  1507. //DPRINT(0, "function entry\n");
  1508. //
  1509. // If this is a call to make a read or write access check then we must
  1510. // first build the entire key string and then try the open. The
  1511. // caller has done an impersonation.
  1512. //
  1513. if (BooleanFlagOn(Flags | Kc->Flags, FRS_RKF_KEY_ACCCHK_READ |
  1514. FRS_RKF_KEY_ACCCHK_WRITE)) {
  1515. AccessRights = KEY_READ;
  1516. AccessName = "KEY_READ";
  1517. if (BooleanFlagOn(Flags | Kc->Flags, FRS_RKF_KEY_ACCCHK_WRITE)) {
  1518. AccessRights = KEY_ALL_ACCESS;
  1519. AccessName = "KEY_ALL_ACCESS";
  1520. }
  1521. //
  1522. // Expand the key string.
  1523. //
  1524. FrsRegExpandKeyStr(Kc, KeyArg1, Flags, &FullKey);
  1525. if (FullKey == NULL) {
  1526. return ERROR_INVALID_PARAMETER;
  1527. }
  1528. DPRINT2(4, ":FK: Doing Access Check (%s) on key \"%ws\"\n",
  1529. AccessName, FullKey);
  1530. WStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE, FullKey, 0, AccessRights, &hKey);
  1531. if (!WIN_SUCCESS(WStatus)) {
  1532. DPRINT1_WS(0, ":FK: ERROR - Access Check failed on %ws;", FullKey, WStatus);
  1533. FrsFree(FullKey);
  1534. return WStatus;
  1535. }
  1536. //
  1537. // Return the key handle to the caller.
  1538. //
  1539. *hKeyRet = hKey;
  1540. FrsFree(FullKey);
  1541. return ERROR_SUCCESS;
  1542. }
  1543. //
  1544. // Not a key access check. Do normal key open processing.
  1545. //
  1546. //
  1547. // If there are any commas in this key then we need to do a nested
  1548. // key open (perhaps creating nested keys as we go). If the key
  1549. // component matches the string L"ARG1" then we use KeyArg1 supplied by
  1550. // the caller.
  1551. //
  1552. RtlInitUnicodeString(&TempUStr, Kc->KeyName);
  1553. //
  1554. // Parse the comma list.
  1555. //
  1556. while (FrsDissectCommaList(TempUStr, &FirstArg, &TempUStr)) {
  1557. if ((FirstArg.Length == 0) || (FirstArg.Length >= sizeof(KeyStr))) {
  1558. DPRINT1(0, ":FK: ERROR - Bad keyName in Key contxt %ws\n", Kc->KeyName);
  1559. WStatus = ERROR_INVALID_PARAMETER;
  1560. goto RETURN;
  1561. }
  1562. //
  1563. // null terminate the key component string.
  1564. //
  1565. CopyMemory(KeyStr, FirstArg.Buffer, FirstArg.Length);
  1566. KeyStr[FirstArg.Length/sizeof(WCHAR)] = UNICODE_NULL;
  1567. hKeyParent = hKey;
  1568. hKey = INVALID_HANDLE_VALUE;
  1569. //
  1570. // Check the Key Component for a match on ARG1 and substitute.
  1571. //
  1572. if (wcscmp(KeyStr, L"ARG1") == 0) {
  1573. if (wcslen(KeyArg1)*sizeof(WCHAR) > sizeof(KeyStr)) {
  1574. DPRINT1(0, ":FK: ERROR - ARG1 too big %ws\n", KeyArg1);
  1575. WStatus = ERROR_INVALID_PARAMETER;
  1576. goto RETURN;
  1577. }
  1578. wcscpy(KeyStr, KeyArg1);
  1579. }
  1580. //
  1581. // Open the next key component.
  1582. //
  1583. DPRINT1(5, ":FK: Opening next key component [%ws]\n", KeyStr);
  1584. WStatus = RegOpenKeyEx(hKeyParent, KeyStr, 0, KEY_ALL_ACCESS, &hKey);
  1585. if (!WIN_SUCCESS(WStatus)) {
  1586. //
  1587. // If the key is supposed to be there then return error to caller.
  1588. //
  1589. if (BooleanFlagOn(Flags | Kc->Flags, FRS_RKF_KEY_MUST_BE_PRESENT)) {
  1590. DPRINT1_WS(0, ":FK: Could not open key component [%ws].", KeyStr, WStatus);
  1591. FrsRegPostEventLog(Kc, KeyArg1, Flags, IDS_REG_KEY_NOT_FOUND);
  1592. goto RETURN;
  1593. }
  1594. if (BooleanFlagOn(Flags | Kc->Flags, FRS_RKF_CREATE_KEY)) {
  1595. //
  1596. // Try to create the key.
  1597. //
  1598. DPRINT1(4, ":FK: Creating key component [%ws]\n", KeyStr);
  1599. WStatus = RegCreateKeyW(hKeyParent, KeyStr, &hKey);
  1600. CLEANUP1_WS(0, ":FK: Could not create key component [%ws].",
  1601. KeyStr, WStatus, RETURN);
  1602. } else {
  1603. //
  1604. // Key not there and not supposed to create it. Let caller know.
  1605. //
  1606. goto RETURN;
  1607. }
  1608. }
  1609. if (hKeyParent != HKEY_LOCAL_MACHINE) {
  1610. RegCloseKey(hKeyParent);
  1611. hKeyParent = INVALID_HANDLE_VALUE;
  1612. }
  1613. } // end while()
  1614. //
  1615. // Return the key handle to the caller.
  1616. //
  1617. *hKeyRet = hKey;
  1618. WStatus = ERROR_SUCCESS;
  1619. RETURN:
  1620. if ((hKeyParent != HKEY_LOCAL_MACHINE) && HANDLE_IS_VALID(hKeyParent)) {
  1621. RegCloseKey(hKeyParent);
  1622. }
  1623. if (!WIN_SUCCESS(WStatus)) {
  1624. DPRINT_WS(5, "ERROR - FrsRegOpenKey Failed.", WStatus);
  1625. if ((hKey != HKEY_LOCAL_MACHINE) && HANDLE_IS_VALID(hKey)) {
  1626. RegCloseKey(hKey);
  1627. }
  1628. }
  1629. return WStatus;
  1630. }
  1631. DWORD
  1632. CfgRegReadDWord(
  1633. IN FRS_REG_KEY_CODE KeyIndex,
  1634. IN PWCHAR KeyArg1,
  1635. IN ULONG Flags,
  1636. OUT PULONG DataRet
  1637. )
  1638. {
  1639. /*++
  1640. Routine Description:
  1641. This function reads a keyword value from the registry.
  1642. Arguments:
  1643. KeyIndex - An entry from the FRS_REG_KEY_CODE enum
  1644. KeyArg1 - An optional caller supplied key component. NULL if not provided.
  1645. Flags - Modifer flags
  1646. DataRet - ptr to DWORD for returned result.
  1647. Return Value:
  1648. Win32 status of the result of the registry operation.
  1649. Data is returned only on a success.
  1650. --*/
  1651. #undef DEBSUB
  1652. #define DEBSUB "CfgRegReadDWord:"
  1653. DWORD WStatus;
  1654. HKEY hKey = INVALID_HANDLE_VALUE;
  1655. DWORD Type;
  1656. DWORD Len;
  1657. DWORD Data;
  1658. BOOL DefaultValueUseOk;
  1659. PFRS_REGISTRY_KEY KeyCtx;
  1660. //DPRINT(0, "function entry\n");
  1661. //
  1662. // Find the key context assoicated with the supplied index.
  1663. //
  1664. KeyCtx = FrsRegFindKeyContext(KeyIndex);
  1665. if (KeyCtx == NULL) {
  1666. DPRINT1(0, ":FK: ERROR - Key contxt not found for key code number %d\n", KeyIndex);
  1667. return ERROR_INVALID_PARAMETER;
  1668. }
  1669. DefaultValueUseOk = BooleanFlagOn(Flags | KeyCtx->Flags,
  1670. FRS_RKF_OK_TO_USE_DEFAULT);
  1671. FRS_ASSERT(KeyCtx->ValueName != NULL);
  1672. DPRINT2(4, ":FK: Reading parameter [%ws] \"%ws\" \n",
  1673. KeyCtx->KeyName, KeyCtx->ValueName);
  1674. //
  1675. // Table entry better be REG_DWORD.
  1676. //
  1677. if (KeyCtx->RegValueType != REG_DWORD) {
  1678. DPRINT3(4, ":FK: Mismatch on KeyCtx->RegValueType for [%ws] \"%ws\". Expected REG_DWORD, Found type: %d\n",
  1679. KeyCtx->KeyName, KeyCtx->ValueName, KeyCtx->RegValueType);
  1680. FRS_ASSERT(!"Mismatch on KeyCtx->RegValueType, Expected REG_DWORD");
  1681. return ERROR_INVALID_PARAMETER;
  1682. }
  1683. //
  1684. // Open the key.
  1685. //
  1686. WStatus = FrsRegOpenKey(KeyCtx, KeyArg1, Flags, &hKey);
  1687. if (!WIN_SUCCESS(WStatus)) {
  1688. goto RETURN;
  1689. }
  1690. //
  1691. // Read the value
  1692. //
  1693. Len = sizeof(Data);
  1694. Type = REG_DWORD;
  1695. WStatus = RegQueryValueEx(hKey, KeyCtx->ValueName, NULL, &Type, (PUCHAR)&Data, &Len);
  1696. if (!WIN_SUCCESS(WStatus)) {
  1697. DPRINT_WS(5, "ERROR - RegQueryValueEx Failed.", WStatus);
  1698. if (WStatus == ERROR_FILE_NOT_FOUND) {
  1699. //
  1700. // If the value is supposed to be there then return error to caller.
  1701. //
  1702. if (BooleanFlagOn(Flags | KeyCtx->Flags, FRS_RKF_VALUE_MUST_BE_PRESENT)) {
  1703. DPRINT2_WS(0, ":FK: Value not found [%ws] \"%ws\".",
  1704. KeyCtx->KeyName, KeyCtx->ValueName, WStatus);
  1705. FrsRegPostEventLog(KeyCtx, KeyArg1, Flags, IDS_REG_VALUE_NOT_FOUND);
  1706. goto RETURN;
  1707. }
  1708. } else {
  1709. //
  1710. // Check for expected registry datatype if we found a value.
  1711. // Check for buffer size OK. 4 bytes for DWORDs.
  1712. //
  1713. if (WIN_BUF_TOO_SMALL(WStatus) || (Type != REG_DWORD)) {
  1714. DPRINT4(0, ":FK: Invalid registry data type for [%ws] \"%ws\". Found Type %d, Expecting Type %d\n",
  1715. KeyCtx->KeyName, KeyCtx->ValueName, Type, REG_DWORD);
  1716. FrsRegPostEventLog(KeyCtx, KeyArg1, Flags, IDS_REG_VALUE_WRONG_TYPE);
  1717. }
  1718. }
  1719. WStatus = ERROR_INVALID_PARAMETER;
  1720. } else {
  1721. //
  1722. // Found a value, Check type. If wrong, use default.
  1723. //
  1724. if (Type != REG_DWORD) {
  1725. DPRINT4(0, ":FK: Invalid registry data type for [%ws] \"%ws\". Found Type %d, Expecting Type %d\n",
  1726. KeyCtx->KeyName, KeyCtx->ValueName, Type, REG_DWORD);
  1727. FrsRegPostEventLog(KeyCtx, KeyArg1, Flags, IDS_REG_VALUE_WRONG_TYPE);
  1728. WStatus = ERROR_INVALID_PARAMETER;
  1729. }
  1730. }
  1731. if (!WIN_SUCCESS(WStatus) && DefaultValueUseOk) {
  1732. //
  1733. // Not found or wrong type but Ok to use the default value from key context.
  1734. //
  1735. Type = KeyCtx->RegValueType;
  1736. Data = KeyCtx->ValueDefault;
  1737. WStatus = ERROR_SUCCESS;
  1738. DPRINT2(4, ":FK: Using internal default value for [%ws] \"%ws\".\n",
  1739. KeyCtx->KeyName, KeyCtx->ValueName);
  1740. //
  1741. // Only use it once though.
  1742. //
  1743. DefaultValueUseOk = FALSE;
  1744. }
  1745. if (WIN_SUCCESS(WStatus)) {
  1746. //
  1747. // Perform syntax check based on data type in KeyCtx->DataValueType?
  1748. //
  1749. if (BooleanFlagOn(Flags | KeyCtx->Flags, FRS_RKF_SYNTAX_CHECK)) {
  1750. NOTHING;
  1751. }
  1752. //
  1753. // Perform Range check? (Applies to default value too)
  1754. //
  1755. if (BooleanFlagOn(Flags | KeyCtx->Flags, FRS_RKF_RANGE_CHECK)) {
  1756. if ((Data < KeyCtx->ValueMin) || ( Data > KeyCtx->ValueMax)) {
  1757. DPRINT5(0, ":FK: Value out of range for [%ws] \"%ws\". Found %d, must be between %d and %d\n",
  1758. KeyCtx->KeyName, KeyCtx->ValueName, Data,
  1759. KeyCtx->ValueMin, KeyCtx->ValueMax);
  1760. FrsRegPostEventLog(KeyCtx, KeyArg1, Flags, IDS_REG_VALUE_RANGE_ERROR);
  1761. if (DefaultValueUseOk) {
  1762. //
  1763. // out of range but Ok to use the default value from key context.
  1764. //
  1765. DPRINT2(4, ":FK: Using internal default value for [%ws] \"%ws\".\n",
  1766. KeyCtx->KeyName, KeyCtx->ValueName);
  1767. Type = KeyCtx->RegValueType;
  1768. Data = KeyCtx->ValueDefault;
  1769. WStatus = ERROR_SUCCESS;
  1770. //
  1771. // Recheck the range.
  1772. //
  1773. if ((Data < KeyCtx->ValueMin) || ( Data > KeyCtx->ValueMax)) {
  1774. DPRINT5(0, ":FK: Default Value out of range for [%ws] \"%ws\". Found %d, must be between %d and %d\n",
  1775. KeyCtx->KeyName, KeyCtx->ValueName, Data,
  1776. KeyCtx->ValueMin, KeyCtx->ValueMax);
  1777. WStatus = ERROR_INVALID_PARAMETER;
  1778. goto RETURN;
  1779. }
  1780. } else {
  1781. WStatus = ERROR_INVALID_PARAMETER;
  1782. goto RETURN;
  1783. }
  1784. }
  1785. }
  1786. //
  1787. // Data valid and in range. Return it and save it.
  1788. //
  1789. *DataRet = Data;
  1790. DPRINT3(3, ":FK: [%ws] \"%ws\" = %d\n",
  1791. KeyCtx->KeyName, KeyCtx->ValueName, Data);
  1792. }
  1793. RETURN:
  1794. if ((hKey != HKEY_LOCAL_MACHINE) && HANDLE_IS_VALID(hKey)) {
  1795. RegCloseKey(hKey);
  1796. }
  1797. return WStatus;
  1798. }
  1799. DWORD
  1800. CfgRegReadString(
  1801. IN FRS_REG_KEY_CODE KeyIndex,
  1802. IN PWCHAR KeyArg1,
  1803. IN ULONG Flags,
  1804. OUT PWSTR *pStrRet
  1805. )
  1806. {
  1807. /*++
  1808. Routine Description:
  1809. This function reads a keyword string value from the registry. The return
  1810. buffer is allocated here with FrsAlloc(). Caller must free.
  1811. Arguments:
  1812. KeyIndex - An entry from the FRS_REG_KEY_CODE enum
  1813. KeyArg1 - An optional caller supplied key component. NULL if not provided.
  1814. Flags - Modifer flags
  1815. pStrRet - ptr to address of string buffer for returned result else NULL.
  1816. NOTE: The return buffer is allocated here, caller must free it.
  1817. Return Value:
  1818. Win32 status of the result of the registry operation.
  1819. Data is returned only on a success.
  1820. --*/
  1821. #undef DEBSUB
  1822. #define DEBSUB "CfgRegReadString:"
  1823. DWORD WStatus;
  1824. HKEY hKey = INVALID_HANDLE_VALUE;
  1825. DWORD Type;
  1826. DWORD Len, NewLen;
  1827. PWCHAR Data, NewData;
  1828. BOOL DefaultValueUseOk;
  1829. PFRS_REGISTRY_KEY KeyCtx;
  1830. WCHAR TStr[4];
  1831. // add support or new func for REG_MULTI_SZ?
  1832. //DPRINT(0, "function entry\n");
  1833. Data = NULL;
  1834. //
  1835. // Find the key context assoicated with the supplied index.
  1836. //
  1837. KeyCtx = FrsRegFindKeyContext(KeyIndex);
  1838. if (KeyCtx == NULL) {
  1839. DPRINT1(0, ":FK: ERROR - Key contxt not found for key code number %d\n", KeyIndex);
  1840. *pStrRet = NULL;
  1841. return ERROR_INVALID_PARAMETER;
  1842. }
  1843. DefaultValueUseOk = BooleanFlagOn(Flags | KeyCtx->Flags,
  1844. FRS_RKF_OK_TO_USE_DEFAULT);
  1845. FRS_ASSERT(KeyCtx->ValueName != NULL);
  1846. DPRINT2(4, ":FK: Reading parameter [%ws] \"%ws\" \n",
  1847. KeyCtx->KeyName, KeyCtx->ValueName);
  1848. //
  1849. // Table entry better be some kind of string.
  1850. //
  1851. if ((KeyCtx->RegValueType != REG_SZ) &&
  1852. (KeyCtx->RegValueType != REG_EXPAND_SZ)) {
  1853. DPRINT3(0, ":FK: Mismatch on KeyCtx->RegValueType for [%ws] \"%ws\". Expected REG_SZ or REG_EXPAND_SZ, Found type: %d\n",
  1854. KeyCtx->KeyName, KeyCtx->ValueName, KeyCtx->RegValueType);
  1855. // don't return a null ptr since calling parameter may be wrong size.
  1856. FRS_ASSERT(!"Mismatch on KeyCtx->RegValueType, Expected REG_SZ or REG_EXPAND_SZ");
  1857. return ERROR_INVALID_PARAMETER;
  1858. }
  1859. *pStrRet = NULL;
  1860. //
  1861. // Open the key.
  1862. //
  1863. WStatus = FrsRegOpenKey(KeyCtx, KeyArg1, Flags, &hKey);
  1864. if (!WIN_SUCCESS(WStatus)) {
  1865. goto RETURN;
  1866. }
  1867. //
  1868. // Get the size and type for the value.
  1869. //
  1870. WStatus = RegQueryValueEx(hKey, KeyCtx->ValueName, NULL, &Type, NULL, &Len);
  1871. if (!WIN_SUCCESS(WStatus)) {
  1872. DPRINT1_WS(5, ":FK: RegQueryValueEx(%ws);", KeyCtx->ValueName, WStatus);
  1873. Len = 0;
  1874. }
  1875. //
  1876. // If the value is supposed to be there then return error to caller.
  1877. //
  1878. if ((Len == 0) &&
  1879. BooleanFlagOn(Flags | KeyCtx->Flags, FRS_RKF_VALUE_MUST_BE_PRESENT)) {
  1880. DPRINT2_WS(0, ":FK: Value not found [%ws] \"%ws\".",
  1881. KeyCtx->KeyName, KeyCtx->ValueName, WStatus);
  1882. FrsRegPostEventLog(KeyCtx, KeyArg1, Flags, IDS_REG_VALUE_NOT_FOUND);
  1883. goto RETURN;
  1884. }
  1885. if (WIN_SUCCESS(WStatus)) {
  1886. //
  1887. // Should be a string.
  1888. //
  1889. if ((Type != REG_SZ) && (Type != REG_EXPAND_SZ)) {
  1890. DPRINT4(0, ":FK: Invalid registry data type for [%ws] \"%ws\". Found Type %d, Expecting Type %d\n",
  1891. KeyCtx->KeyName, KeyCtx->ValueName, Type, KeyCtx->RegValueType);
  1892. WStatus = ERROR_INVALID_PARAMETER;
  1893. FrsRegPostEventLog(KeyCtx, KeyArg1, Flags, IDS_REG_VALUE_WRONG_TYPE);
  1894. goto CHECK_DEFAULT;
  1895. }
  1896. //
  1897. // If the string is too long or too short then complain and use default.
  1898. // If KeyCtx->ValueMax is zero then no maximum length check.
  1899. //
  1900. if (BooleanFlagOn(Flags | KeyCtx->Flags, FRS_RKF_RANGE_CHECK) &&
  1901. (Len < KeyCtx->ValueMin*sizeof(WCHAR)) ||
  1902. ((KeyCtx->ValueMax != 0) && (Len > KeyCtx->ValueMax*sizeof(WCHAR)))) {
  1903. DPRINT4(0, ":FK: String size out of range for [%ws] \"%ws\". Min: %d Max: %d\n",
  1904. KeyCtx->KeyName, KeyCtx->ValueName, KeyCtx->ValueMin, KeyCtx->ValueMax);
  1905. WStatus = ERROR_INVALID_PARAMETER;
  1906. FrsRegPostEventLog(KeyCtx, KeyArg1, Flags, IDS_REG_VALUE_RANGE_ERROR);
  1907. goto CHECK_DEFAULT;
  1908. }
  1909. //
  1910. // Alloc the return buffer and read the data.
  1911. //
  1912. Data = (PWCHAR) FrsAlloc ((Len+1) * sizeof(WCHAR));
  1913. WStatus = RegQueryValueEx(hKey, KeyCtx->ValueName, NULL, &Type, (PUCHAR)Data, &Len);
  1914. if (!WIN_SUCCESS(WStatus)) {
  1915. DPRINT2(0, ":FK: RegQueryValueEx(%ws); WStatus %s\n", KeyCtx->ValueName, ErrLabelW32(WStatus));
  1916. Data = (PWCHAR) FrsFree(Data);
  1917. goto RETURN;
  1918. }
  1919. }
  1920. CHECK_DEFAULT:
  1921. if (!WIN_SUCCESS(WStatus) && DefaultValueUseOk) {
  1922. //
  1923. // Not found or wrong type but Ok to use the default value from key context.
  1924. //
  1925. Data = (PWCHAR) FrsFree(Data);
  1926. if (KeyCtx->StringDefault == NULL) {
  1927. DPRINT2(4, ":FK: Using internal default value for [%ws] \"%ws\" = NULL\n",
  1928. KeyCtx->KeyName, KeyCtx->ValueName);
  1929. goto RETURN;
  1930. }
  1931. Type = KeyCtx->RegValueType;
  1932. Data = FrsWcsDup(KeyCtx->StringDefault);
  1933. WStatus = ERROR_SUCCESS;
  1934. DPRINT3(4, ":FK: Using internal default value for [%ws] \"%ws\" = %ws\n",
  1935. KeyCtx->KeyName, KeyCtx->ValueName, Data);
  1936. }
  1937. if (WIN_SUCCESS(WStatus) && (Data != NULL)) {
  1938. //
  1939. // Perform syntax check based on data type in KeyCtx->DataValueType?
  1940. //
  1941. if (BooleanFlagOn(Flags | KeyCtx->Flags, FRS_RKF_SYNTAX_CHECK)) {
  1942. NOTHING;
  1943. }
  1944. DPRINT3(4, ":FK: [%ws] \"%ws\" = \"%ws\"\n",
  1945. KeyCtx->KeyName, KeyCtx->ValueName, Data);
  1946. //
  1947. // Expand system strings if needed
  1948. //
  1949. if (Type == REG_EXPAND_SZ) {
  1950. NewLen = ExpandEnvironmentStrings(Data, TStr, 0);
  1951. while (TRUE) {
  1952. NewData = (PWCHAR) FrsAlloc ((NewLen+1) * sizeof(WCHAR));
  1953. Len = ExpandEnvironmentStrings(Data, NewData, NewLen);
  1954. if (Len == 0) {
  1955. WStatus = GetLastError();
  1956. DPRINT2_WS(5, ":FK: [%ws] \"%ws\" Param not expanded.",
  1957. KeyCtx->KeyName, KeyCtx->ValueName, WStatus);
  1958. Data = FrsFree(Data);
  1959. NewData = FrsFree(NewData);
  1960. break;
  1961. }
  1962. if (Len <= NewLen) {
  1963. //
  1964. // Free the original buffer and set to return expanded string.
  1965. //
  1966. FrsFree(Data);
  1967. Data = NewData;
  1968. Len = NewLen;
  1969. WStatus = ERROR_SUCCESS;
  1970. break;
  1971. }
  1972. //
  1973. // Get a bigger buffer.
  1974. //
  1975. NewData = (PWCHAR) FrsFree(NewData);
  1976. NewLen = Len;
  1977. }
  1978. }
  1979. //
  1980. // Return ptr to buffer and save a copy for debug printouts.
  1981. //
  1982. *pStrRet = Data;
  1983. DPRINT3(3, ":FK: [%ws] \"%ws\" = \"%ws\"\n",
  1984. KeyCtx->KeyName, KeyCtx->ValueName,
  1985. (Data != NULL) ? Data : L"<null>");
  1986. }
  1987. //
  1988. // Close the handle if one was opened.
  1989. //
  1990. RETURN:
  1991. if ((hKey != HKEY_LOCAL_MACHINE) && HANDLE_IS_VALID(hKey)) {
  1992. RegCloseKey(hKey);
  1993. }
  1994. return WStatus;
  1995. }
  1996. #if 0
  1997. // multisz example)
  1998. void
  1999. RegQueryMULTISZ(
  2000. HKEY hkey,
  2001. LPSTR szSubKey,
  2002. LPSTR szValue
  2003. )
  2004. /*++
  2005. Routine Description:
  2006. This function queries MULTISZ value in the registry using the
  2007. hkey and szSubKey as the registry key info. If the value is not
  2008. found in the registry, it is added with a zero value.
  2009. Arguments:
  2010. hkey - handle to a registry key
  2011. szSubKey - pointer to a subkey string
  2012. Return Value:
  2013. registry value
  2014. --*/
  2015. {
  2016. DWORD rc;
  2017. DWORD len;
  2018. DWORD dwType;
  2019. char buf[1024];
  2020. len = sizeof(buf);
  2021. rc = RegQueryValueEx( hkey, szSubKey, 0, &dwType, (LPBYTE)buf, &len );
  2022. if (!WIN_SUCCESS(rc)) {
  2023. if (rc == ERROR_FILE_NOT_FOUND) {
  2024. buf[0] = 0;
  2025. buf[1] = 0;
  2026. len = 2;
  2027. RegSetMULTISZ( hkey, szSubKey, buf );
  2028. }
  2029. }
  2030. CopyMemory( szValue, buf, len );
  2031. }
  2032. #endif
  2033. DWORD
  2034. CfgRegWriteDWord(
  2035. IN FRS_REG_KEY_CODE KeyIndex,
  2036. IN PWCHAR KeyArg1,
  2037. IN ULONG Flags,
  2038. IN ULONG NewData
  2039. )
  2040. {
  2041. /*++
  2042. Routine Description:
  2043. This function reads a keyword value from the registry.
  2044. Arguments:
  2045. KeyIndex - An entry from the FRS_REG_KEY_CODE enum
  2046. KeyArg1 - An optional caller supplied key component. NULL if not provided.
  2047. Flags - Modifer flags
  2048. FRS_RKF_FORCE_DEFAULT_VALUE - if set then ignore NewData and write the
  2049. default key value from the keyCtx into the registry.
  2050. NewData - DWORD to write to registry.
  2051. Return Value:
  2052. Win32 status of the result of the registry operation.
  2053. --*/
  2054. #undef DEBSUB
  2055. #define DEBSUB "CfgRegWriteDWord:"
  2056. DWORD WStatus;
  2057. HKEY hKey = INVALID_HANDLE_VALUE;
  2058. DWORD Len;
  2059. PFRS_REGISTRY_KEY KeyCtx;
  2060. //DPRINT(0, "function entry\n");
  2061. //
  2062. // Find the key context assoicated with the supplied index.
  2063. //
  2064. KeyCtx = FrsRegFindKeyContext(KeyIndex);
  2065. if (KeyCtx == NULL) {
  2066. DPRINT1(0, ":FK: ERROR - Key contxt not found for key code number %d\n", KeyIndex);
  2067. return ERROR_INVALID_PARAMETER;
  2068. }
  2069. FRS_ASSERT(KeyCtx->ValueName != NULL);
  2070. //
  2071. // Table entry better be REG_DWORD.
  2072. //
  2073. if (KeyCtx->RegValueType != REG_DWORD) {
  2074. DPRINT3(0, ":FK: Mismatch on KeyCtx->RegValueType for [%ws] \"%ws\". Expected REG_DWORD, Found type: %d\n",
  2075. KeyCtx->KeyName, KeyCtx->ValueName, KeyCtx->RegValueType);
  2076. FRS_ASSERT(!"Mismatch on KeyCtx->RegValueType, Expected REG_DWORD");
  2077. return ERROR_INVALID_PARAMETER;
  2078. }
  2079. //
  2080. // Open the key.
  2081. //
  2082. WStatus = FrsRegOpenKey(KeyCtx, KeyArg1, Flags, &hKey);
  2083. if (!WIN_SUCCESS(WStatus)) {
  2084. goto RETURN;
  2085. }
  2086. //
  2087. // Keep existing value if caller says so.
  2088. //
  2089. if (BooleanFlagOn(Flags, FRS_RKF_KEEP_EXISTING_VALUE)) {
  2090. WStatus = RegQueryValueEx(hKey, KeyCtx->ValueName, NULL, NULL, NULL, NULL);
  2091. if (WIN_SUCCESS(WStatus)) {
  2092. DPRINT2(4, ":FK: Retaining existing value for parameter [%ws] \"%ws\"\n",
  2093. KeyCtx->KeyName, KeyCtx->ValueName);
  2094. goto RETURN;
  2095. }
  2096. }
  2097. //
  2098. // Check if we are writing the default value to the registry.
  2099. //
  2100. if (BooleanFlagOn(Flags, FRS_RKF_FORCE_DEFAULT_VALUE)) {
  2101. NewData = KeyCtx->ValueDefault;
  2102. DPRINT1(4, ":FK: Using internal default value = %d\n", NewData);
  2103. }
  2104. //
  2105. // Perform Range check? (Applies to default value too)
  2106. //
  2107. if (BooleanFlagOn(Flags | KeyCtx->Flags,
  2108. FRS_RKF_RANGE_CHECK | FRS_RKF_RANGE_SATURATE)) {
  2109. if ((NewData < KeyCtx->ValueMin) || ( NewData > KeyCtx->ValueMax)) {
  2110. DPRINT5(0, ":FK: Value out of range for [%ws] \"%ws\". Found %d, must be between %d and %d\n",
  2111. KeyCtx->KeyName, KeyCtx->ValueName, NewData,
  2112. KeyCtx->ValueMin, KeyCtx->ValueMax);
  2113. if (!BooleanFlagOn(Flags | KeyCtx->Flags, FRS_RKF_RANGE_SATURATE)) {
  2114. WStatus = ERROR_INVALID_PARAMETER;
  2115. FrsRegPostEventLog(KeyCtx, KeyArg1, Flags, IDS_REG_VALUE_RANGE_ERROR);
  2116. goto RETURN;
  2117. }
  2118. //
  2119. // Set the value to either the min or max of the allowed range.
  2120. // WARNING: The only current use of this flag is in setting the
  2121. // DS polling interval. This flag should be used with caution
  2122. // since if a user miss-specifies a parameter and we jam
  2123. // it to the min or max value the resulting effect could be
  2124. // VERY UNDESIREABLE.
  2125. //
  2126. if (NewData < KeyCtx->ValueMin) {
  2127. DPRINT2(4, ":FK: Value (%d) below of range. Using Min value (%d)\n",
  2128. NewData, KeyCtx->ValueMin);
  2129. NewData = KeyCtx->ValueMin;
  2130. } else
  2131. if (NewData > KeyCtx->ValueMax) {
  2132. DPRINT2(4, ":FK: Value (%d) above of range. Using Max value (%d)\n",
  2133. NewData, KeyCtx->ValueMax);
  2134. NewData = KeyCtx->ValueMax;
  2135. }
  2136. }
  2137. }
  2138. //
  2139. // Write the value and save it.
  2140. //
  2141. Len = sizeof(NewData);
  2142. WStatus = RegSetValueEx(hKey, KeyCtx->ValueName, 0, REG_DWORD, (PCHAR)&NewData, Len);
  2143. if (!WIN_SUCCESS(WStatus)) {
  2144. DPRINT_WS(0, ":FK: ERROR - RegSetValueEx Failed.", WStatus);
  2145. } else {
  2146. DPRINT3(3, ":FK: [%ws] \"%ws\" = %d\n",
  2147. KeyCtx->KeyName, KeyCtx->ValueName, NewData);
  2148. }
  2149. RETURN:
  2150. if ((hKey != HKEY_LOCAL_MACHINE) && HANDLE_IS_VALID(hKey)) {
  2151. RegCloseKey(hKey);
  2152. }
  2153. return WStatus;
  2154. }
  2155. DWORD
  2156. CfgRegWriteString(
  2157. IN FRS_REG_KEY_CODE KeyIndex,
  2158. IN PWCHAR KeyArg1,
  2159. IN ULONG Flags,
  2160. IN PWSTR NewStr
  2161. )
  2162. {
  2163. /*++
  2164. Routine Description:
  2165. This function reads a keyword string value from the registry. The return
  2166. buffer is allocated here with FrsAlloc(). Caller must free.
  2167. Arguments:
  2168. KeyIndex - An entry from the FRS_REG_KEY_CODE enum
  2169. KeyArg1 - An optional caller supplied key component. NULL if not provided.
  2170. Flags - Modifer flags
  2171. FRS_RKF_FORCE_DEFAULT_VALUE - if set then ignore NewStr and write the
  2172. default key value from the keyCtx into the registry.
  2173. NewStr - ptr to buffer for new string data.
  2174. Return Value:
  2175. Win32 status of the result of the registry operation.
  2176. --*/
  2177. #undef DEBSUB
  2178. #define DEBSUB "CfgRegWriteString:"
  2179. DWORD WStatus;
  2180. HKEY hKey = INVALID_HANDLE_VALUE;
  2181. DWORD Type;
  2182. DWORD Len, NewLen;
  2183. PFRS_REGISTRY_KEY KeyCtx;
  2184. // add support or new func for REG_MULTI_SZ
  2185. //DPRINT(0, "function entry\n");
  2186. //
  2187. // Find the key context assoicated with the supplied index.
  2188. //
  2189. KeyCtx = FrsRegFindKeyContext(KeyIndex);
  2190. if (KeyCtx == NULL) {
  2191. DPRINT1(0, ":FK: ERROR - Key contxt not found for key code number %d\n", KeyIndex);
  2192. return ERROR_INVALID_PARAMETER;
  2193. }
  2194. //
  2195. // Table entry better be some kind of string.
  2196. //
  2197. if ((KeyCtx->RegValueType != REG_SZ) &&
  2198. // (KeyCtx->RegValueType != REG_MULTI_SZ) &&
  2199. (KeyCtx->RegValueType != REG_EXPAND_SZ)) {
  2200. DPRINT3(0, ":FK: Mismatch on KeyCtx->RegValueType for [%ws] \"%ws\". Expected REG_SZ or REG_EXPAND_SZ, Found type: %d\n",
  2201. KeyCtx->KeyName, KeyCtx->ValueName, KeyCtx->RegValueType);
  2202. FRS_ASSERT(!"Mismatch on KeyCtx->RegValueType, Expected REG_SZ or REG_EXPAND_SZ");
  2203. return ERROR_INVALID_PARAMETER;
  2204. }
  2205. //
  2206. // Open the key.
  2207. //
  2208. WStatus = FrsRegOpenKey(KeyCtx, KeyArg1, Flags, &hKey);
  2209. if (!WIN_SUCCESS(WStatus)) {
  2210. goto RETURN;
  2211. }
  2212. FRS_ASSERT(KeyCtx->ValueName != NULL);
  2213. //
  2214. // Keep existing value if caller says so.
  2215. //
  2216. if (BooleanFlagOn(Flags, FRS_RKF_KEEP_EXISTING_VALUE)) {
  2217. WStatus = RegQueryValueEx(hKey, KeyCtx->ValueName, NULL, NULL, NULL, NULL);
  2218. if (WIN_SUCCESS(WStatus)) {
  2219. DPRINT2(4, ":FK: Retaining existing value for parameter [%ws] \"%ws\"\n",
  2220. KeyCtx->KeyName, KeyCtx->ValueName);
  2221. goto RETURN;
  2222. }
  2223. }
  2224. //
  2225. // Check if we are writing the default value to the registry.
  2226. //
  2227. if (BooleanFlagOn(Flags, FRS_RKF_FORCE_DEFAULT_VALUE)) {
  2228. if (KeyCtx->StringDefault == NULL) {
  2229. DPRINT2(0, ":FK: ERROR - Key contxt has no default value for [%ws] \"%ws\" \n",
  2230. KeyCtx->KeyName, KeyCtx->ValueName);
  2231. WStatus = ERROR_INVALID_PARAMETER;
  2232. FRS_ASSERT(!"Key contxt has no default value");
  2233. goto RETURN;
  2234. }
  2235. NewStr = KeyCtx->StringDefault;
  2236. DPRINT1(4, ":FK: Using internal default value = \"%ws\" \n", NewStr);
  2237. }
  2238. //
  2239. // Perform Range check? (Applies to default value too)
  2240. // If the string is too long or too short then complain and use default.
  2241. // If KeyCtx->ValueMax is zero then no maximum length check.
  2242. //
  2243. // Note: for REG_MULTI_SZ we need to look for double null at end of str
  2244. // or use a unique symbol for the string separator and cvt to \0 before write.
  2245. Len = (wcslen(NewStr) + 1) * sizeof(WCHAR);
  2246. if (BooleanFlagOn(Flags | KeyCtx->Flags, FRS_RKF_RANGE_CHECK) &&
  2247. (Len < KeyCtx->ValueMin*sizeof(WCHAR)) ||
  2248. ((KeyCtx->ValueMax != 0) && (Len > KeyCtx->ValueMax*sizeof(WCHAR)))) {
  2249. DPRINT4(0, ":FK: String size out of range for [%ws] \"%ws\". Min: %d Max: %d\n",
  2250. KeyCtx->KeyName, KeyCtx->ValueName, KeyCtx->ValueMin, KeyCtx->ValueMax);
  2251. WStatus = ERROR_INVALID_PARAMETER;
  2252. FrsRegPostEventLog(KeyCtx, KeyArg1, Flags, IDS_REG_VALUE_RANGE_ERROR);
  2253. goto RETURN;
  2254. }
  2255. WStatus = RegSetValueEx(hKey,
  2256. KeyCtx->ValueName,
  2257. 0,
  2258. KeyCtx->RegValueType,
  2259. (PCHAR)NewStr,
  2260. Len);
  2261. if (!WIN_SUCCESS(WStatus)) {
  2262. DPRINT_WS(0, ":FK: ERROR - RegSetValueEx Failed.", WStatus);
  2263. } else {
  2264. // note: won't work for MULTI_SZ
  2265. DPRINT3(3, ":FK: [%ws] \"%ws\" = %ws\n",
  2266. KeyCtx->KeyName, KeyCtx->ValueName,
  2267. (NewStr != NULL) ? NewStr : L"<null>");
  2268. }
  2269. #if 0
  2270. // Multi_Sz example
  2271. //
  2272. // Event Message File
  2273. //
  2274. // WStatus = RegSetValueEx(FrsEventLogKey,
  2275. // L"Sources",
  2276. // 0,
  2277. // REG_MULTI_SZ,
  2278. // (PCHAR)(SERVICE_NAME L"\0"
  2279. // SERVICE_LONG_NAME L"\0"),
  2280. // (wcslen(SERVICE_NAME) +
  2281. // wcslen(SERVICE_LONG_NAME) +
  2282. // 3) * sizeof(WCHAR));
  2283. //
  2284. // Another example
  2285. //
  2286. void
  2287. RegSetMULTISZ(
  2288. HKEY hkey,
  2289. LPSTR szSubKey,
  2290. LPSTR szValue
  2291. )
  2292. /*++
  2293. Routine Description:
  2294. This function changes a Multi_SZ value in the registry using the
  2295. hkey and szSubKey as the registry key info.
  2296. Arguments:
  2297. hkey - handle to a registry key
  2298. szSubKey - pointer to a subkey string
  2299. szValue - new registry value
  2300. Return Value:
  2301. None.
  2302. --*/
  2303. {
  2304. ULONG i = 1;
  2305. ULONG j = 0;
  2306. LPSTR p = szValue;
  2307. while( TRUE ) {
  2308. j = strlen( p ) + 1;
  2309. i += j;
  2310. p += j;
  2311. if (!*p) {
  2312. break;
  2313. }
  2314. }
  2315. RegSetValueEx( hkey, szSubKey, 0, REG_MULTI_SZ, (PUCHAR)szValue, i );
  2316. }
  2317. #endif
  2318. //
  2319. // Close the handle if one was opened.
  2320. //
  2321. RETURN:
  2322. if ((hKey != HKEY_LOCAL_MACHINE) && HANDLE_IS_VALID(hKey)) {
  2323. RegCloseKey(hKey);
  2324. }
  2325. return WStatus;
  2326. }
  2327. DWORD
  2328. CfgRegDeleteValue(
  2329. IN FRS_REG_KEY_CODE KeyIndex,
  2330. IN PWCHAR KeyArg1,
  2331. IN ULONG Flags
  2332. )
  2333. {
  2334. /*++
  2335. Routine Description:
  2336. This function deletes a keyword value from the registry.
  2337. Arguments:
  2338. KeyIndex - An entry from the FRS_REG_KEY_CODE enum
  2339. KeyArg1 - An optional caller supplied key component. NULL if not provided.
  2340. Flags - Modifer flags
  2341. Return Value:
  2342. Win32 status of the result of the registry operation.
  2343. --*/
  2344. #undef DEBSUB
  2345. #define DEBSUB "CfgRegDeleteValue:"
  2346. DWORD WStatus;
  2347. HKEY hKey = INVALID_HANDLE_VALUE;
  2348. PFRS_REGISTRY_KEY KeyCtx;
  2349. //DPRINT(0, "function entry\n");
  2350. //
  2351. // Find the key context assoicated with the supplied index.
  2352. //
  2353. KeyCtx = FrsRegFindKeyContext(KeyIndex);
  2354. if (KeyCtx == NULL) {
  2355. DPRINT1(0, ":FK: ERROR - Key contxt not found for key code number %d\n", KeyIndex);
  2356. return ERROR_INVALID_PARAMETER;
  2357. }
  2358. FRS_ASSERT(KeyCtx->ValueName != NULL);
  2359. //
  2360. // Open the key.
  2361. //
  2362. WStatus = FrsRegOpenKey(KeyCtx, KeyArg1, Flags, &hKey);
  2363. if (!WIN_SUCCESS(WStatus)) {
  2364. goto RETURN;
  2365. }
  2366. DPRINT2(3, ":FK: Deleting parameter [%ws] \"%ws\" \n",
  2367. KeyCtx->KeyName, KeyCtx->ValueName);
  2368. //
  2369. // Delete the value.
  2370. //
  2371. WStatus = RegDeleteValue(hKey, KeyCtx->ValueName);
  2372. DPRINT2_WS(0, ":FK: WARN - Cannot delete key for [%ws] \"%ws\";",
  2373. KeyCtx->KeyName, KeyCtx->ValueName, WStatus);
  2374. RETURN:
  2375. if ((hKey != HKEY_LOCAL_MACHINE) && HANDLE_IS_VALID(hKey)) {
  2376. RegCloseKey(hKey);
  2377. }
  2378. return WStatus;
  2379. }
  2380. DWORD
  2381. CfgRegOpenKey(
  2382. IN FRS_REG_KEY_CODE KeyIndex,
  2383. IN PWCHAR KeyArg1,
  2384. IN ULONG Flags,
  2385. OUT HKEY *RethKey
  2386. )
  2387. {
  2388. /*++
  2389. Routine Description:
  2390. This function Opens the key associated with the entry from the FRS registry
  2391. key context table. It performs the normal substitution, key component
  2392. creation, etc.
  2393. Arguments:
  2394. KeyIndex - An entry from the FRS_REG_KEY_CODE enum
  2395. KeyArg1 - An optional caller supplied key component. NULL if not provided.
  2396. Flags - Modifer flags
  2397. RethKey -- ptr to HKEY to return the key handle. Caller must close the
  2398. key with RegCloseKey().
  2399. Return Value:
  2400. Win32 status of the result of the registry operation.
  2401. --*/
  2402. #undef DEBSUB
  2403. #define DEBSUB "CfgRegOpenKey:"
  2404. DWORD WStatus;
  2405. HKEY hKey = INVALID_HANDLE_VALUE;
  2406. PFRS_REGISTRY_KEY KeyCtx;
  2407. //DPRINT(0, "function entry\n");
  2408. FRS_ASSERT(RethKey != NULL);
  2409. *RethKey = INVALID_HANDLE_VALUE;
  2410. //
  2411. // Find the key context assoicated with the supplied index.
  2412. //
  2413. KeyCtx = FrsRegFindKeyContext(KeyIndex);
  2414. if (KeyCtx == NULL) {
  2415. DPRINT1(0, ":FK: ERROR - Key contxt not found for key code number %d\n", KeyIndex);
  2416. return ERROR_INVALID_PARAMETER;
  2417. }
  2418. //
  2419. // Open the key.
  2420. //
  2421. WStatus = FrsRegOpenKey(KeyCtx, KeyArg1, Flags, &hKey);
  2422. if (!WIN_SUCCESS(WStatus)) {
  2423. return WStatus;
  2424. }
  2425. DPRINT1(4, ":FK: Registry key opened [%ws]\n", KeyCtx->KeyName);
  2426. *RethKey = hKey;
  2427. return ERROR_SUCCESS;
  2428. }
  2429. DWORD
  2430. CfgRegCheckEnable(
  2431. IN FRS_REG_KEY_CODE KeyIndex,
  2432. IN PWCHAR KeyArg1,
  2433. IN ULONG Flags,
  2434. OUT PBOOL Enabled
  2435. )
  2436. /*++
  2437. Routine Description:
  2438. This function Opens the key associated with the entry from the FRS registry
  2439. key context table. It performs the normal substitution, key component
  2440. creation, etc. It then checks to see if the data value is "Enabled"
  2441. or "Disabled" and returns the boolean result.
  2442. Arguments:
  2443. KeyIndex - An entry from the FRS_REG_KEY_CODE enum
  2444. KeyArg1 - An optional caller supplied key component. NULL if not provided.
  2445. Flags - Modifer flags
  2446. Enabled -- ptr to BOOL to return the Enable / Disable state of the key.
  2447. Return Value:
  2448. Win32 status of the result of the registry operation.
  2449. --*/
  2450. #undef DEBSUB
  2451. #define DEBSUB "CfgRegCheckEnable:"
  2452. {
  2453. ULONG WStatus;
  2454. PWCHAR WStr = NULL;
  2455. //DPRINT(0, "function entry\n");
  2456. WStatus = CfgRegReadString(KeyIndex, KeyArg1, Flags, &WStr);
  2457. if ((WStr == NULL) ||
  2458. WSTR_EQ(WStr, FRS_IS_DEFAULT_DISABLED)||
  2459. WSTR_EQ(WStr, FRS_IS_DEFAULT_ENABLED)) {
  2460. //
  2461. // The key is in the default state so we can clobber it with a
  2462. // new default.
  2463. //
  2464. WStatus = CfgRegWriteString(KeyIndex,
  2465. KeyArg1,
  2466. FRS_RKF_FORCE_DEFAULT_VALUE,
  2467. NULL);
  2468. DPRINT1_WS(0, ":FK: WARN - Cannot create Enable key [%ws];",
  2469. CfgRegGetValueName(KeyIndex), WStatus);
  2470. //
  2471. // Now reread the key for the new default.
  2472. //
  2473. WStr = FrsFree(WStr);
  2474. WStatus = CfgRegReadString(KeyIndex, KeyArg1, Flags, &WStr);
  2475. }
  2476. if ((WStr != NULL) &&
  2477. (WSTR_EQ(WStr, FRS_IS_ENABLED) ||
  2478. WSTR_EQ(WStr, FRS_IS_DEFAULT_ENABLED))) {
  2479. *Enabled = TRUE;
  2480. DPRINT1(4, ":FK: %ws is enabled\n", CfgRegGetValueName(KeyIndex));
  2481. } else {
  2482. *Enabled = FALSE;
  2483. DPRINT1_WS(0, ":FK: WARN - %ws is not enabled.",
  2484. CfgRegGetValueName(KeyIndex), WStatus);
  2485. }
  2486. WStr = FrsFree(WStr);
  2487. return WStatus;
  2488. }
  2489. BOOL
  2490. IsWin2KPro (
  2491. VOID
  2492. )
  2493. /*++
  2494. Routine Description:
  2495. Check OS version for Win 2000 Professional (aka NT Workstation).
  2496. Arguments:
  2497. None.
  2498. Return Value:
  2499. True if running on win 2K professional.
  2500. --*/
  2501. #undef DEBSUB
  2502. #define DEBSUB "IsWin2KPro:"
  2503. {
  2504. OSVERSIONINFOEX Osvi;
  2505. DWORDLONG ConditionMask = 0;
  2506. //
  2507. // Initialize the OSVERSIONINFOEX structure.
  2508. //
  2509. ZeroMemory(&Osvi, sizeof(OSVERSIONINFOEX));
  2510. Osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
  2511. Osvi.dwMajorVersion = 5;
  2512. Osvi.wProductType = VER_NT_WORKSTATION;
  2513. //
  2514. // Initialize the condition mask.
  2515. //
  2516. VER_SET_CONDITION( ConditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL );
  2517. VER_SET_CONDITION( ConditionMask, VER_PRODUCT_TYPE, VER_EQUAL );
  2518. //
  2519. // Perform the test.
  2520. //
  2521. return VerifyVersionInfo(&Osvi, VER_MAJORVERSION | VER_PRODUCT_TYPE, ConditionMask);
  2522. }
  2523. VOID
  2524. CfgRegAdjustTuningDefaults(
  2525. VOID
  2526. )
  2527. /*++
  2528. Routine Description:
  2529. This function walks thru the FrsRegKeyRevisionTable and applies new
  2530. min, max and default values to the specified keys. The objective is
  2531. to reduce the footprint of FRS on the workstation.
  2532. Arguments:
  2533. None.
  2534. Return Value:
  2535. None.
  2536. --*/
  2537. #undef DEBSUB
  2538. #define DEBSUB "CfgRegAdjustTuningDefaults:"
  2539. {
  2540. PFRS_REG_KEY_REVISIONS Rev;
  2541. PFRS_REGISTRY_KEY KeyCtx;
  2542. Win2kPro = IsWin2KPro();
  2543. if (!Win2kPro) {
  2544. //
  2545. // Only adjust tunables on a workstation.
  2546. //
  2547. return;
  2548. }
  2549. Rev = FrsRegKeyRevisionTable;
  2550. while (Rev->FrsKeyCode != FKC_END_OF_TABLE) {
  2551. KeyCtx = FrsRegFindKeyContext(Rev->FrsKeyCode);
  2552. if (KeyCtx == NULL) {
  2553. DPRINT1(0, ":FK: ERROR - Key contxt not found for key code number %d\n",
  2554. Rev->FrsKeyCode);
  2555. continue;
  2556. }
  2557. //
  2558. // Table entry better be REG_DWORD.
  2559. //
  2560. if (KeyCtx->RegValueType != REG_DWORD) {
  2561. DPRINT3(0, ":FK: Mismatch on KeyCtx->RegValueType for [%ws] \"%ws\". Expected REG_DWORD, Found type: %d\n",
  2562. KeyCtx->KeyName, KeyCtx->ValueName, KeyCtx->RegValueType);
  2563. continue;
  2564. }
  2565. //
  2566. // Apply the new range and default values from the table.
  2567. //
  2568. KeyCtx->ValueMin = Rev->ValueMin;
  2569. KeyCtx->ValueMax = Rev->ValueMax;
  2570. KeyCtx->ValueDefault = Rev->ValueDefault;
  2571. Rev += 1;
  2572. }
  2573. }
  2574. #define BACKUP_STAR L"*"
  2575. #define BACKUP_APPEND L"\\* /s"
  2576. VOID
  2577. CfgFilesNotToBackup(
  2578. IN PGEN_TABLE Replicas
  2579. )
  2580. /*++
  2581. Routine Description:
  2582. Set the backup registry key to prevent backing up the jet
  2583. database, staging directories, preinstall directories, ...
  2584. Set the restore registry key KeysNotToRestore so that
  2585. NtBackup will retain the ntfrs restore keys by moving
  2586. them into the final restored registry.
  2587. Arguments:
  2588. Table of replicas
  2589. Return Value:
  2590. None.
  2591. --*/
  2592. {
  2593. #undef DEBSUB
  2594. #define DEBSUB "CfgFilesNotToBackup:"
  2595. DWORD WStatus;
  2596. PVOID Key;
  2597. PREPLICA Replica;
  2598. PWCHAR MStr = NULL;
  2599. DWORD Size = 0;
  2600. DWORD Idx = 0;
  2601. HKEY HOldBackupKey = 0;
  2602. HKEY HNewBackupKey = 0;
  2603. HKEY HKeysNotToRestore = 0;
  2604. //DPRINT(0, "function entry\n");
  2605. //
  2606. // "<Jetpath>\* /s"
  2607. //
  2608. FrsAddToMultiString(JetPath, &Size, &Idx, &MStr);
  2609. FrsCatToMultiString(BACKUP_APPEND, &Size, &Idx, &MStr);
  2610. //
  2611. // "<DebugInfo.LogFile>\NtFrs*" Default: "%SystemRoot%\debug\NtFrs*"
  2612. //
  2613. FrsAddToMultiString(DebugInfo.LogFile, &Size, &Idx, &MStr);
  2614. FrsCatToMultiString(NTFRS_DBG_LOG_FILE, &Size, &Idx, &MStr);
  2615. FrsCatToMultiString(BACKUP_STAR, &Size, &Idx, &MStr);
  2616. GTabLockTable(Replicas);
  2617. Key = NULL;
  2618. while (Replica = GTabNextDatumNoLock(Replicas, &Key)) {
  2619. //
  2620. // Ignore tombstoned sets
  2621. //
  2622. if (!IS_TIME_ZERO(Replica->MembershipExpires)) {
  2623. continue;
  2624. }
  2625. //
  2626. // Preinstall directories
  2627. //
  2628. if (Replica->Root) {
  2629. FrsAddToMultiString(Replica->Root, &Size, &Idx, &MStr);
  2630. FrsCatToMultiString(L"\\", &Size, &Idx, &MStr);
  2631. FrsCatToMultiString(NTFRS_PREINSTALL_DIRECTORY, &Size, &Idx, &MStr);
  2632. FrsCatToMultiString(BACKUP_APPEND, &Size, &Idx, &MStr);
  2633. }
  2634. //
  2635. // Preexisting directories
  2636. //
  2637. if (Replica->Root) {
  2638. FrsAddToMultiString(Replica->Root, &Size, &Idx, &MStr);
  2639. FrsCatToMultiString(L"\\", &Size, &Idx, &MStr);
  2640. FrsCatToMultiString(NTFRS_PREEXISTING_DIRECTORY, &Size, &Idx, &MStr);
  2641. FrsCatToMultiString(BACKUP_APPEND, &Size, &Idx, &MStr);
  2642. }
  2643. //
  2644. // Staging directories
  2645. //
  2646. if (Replica->Stage) {
  2647. FrsAddToMultiString(Replica->Stage, &Size, &Idx, &MStr);
  2648. FrsCatToMultiString(L"\\", &Size, &Idx, &MStr);
  2649. FrsCatToMultiString(GENERIC_PREFIX, &Size, &Idx, &MStr);
  2650. FrsCatToMultiString(BACKUP_STAR, &Size, &Idx, &MStr);
  2651. }
  2652. }
  2653. GTabUnLockTable(Replicas);
  2654. // Note: remove old_files_not_to_backup once existance of new key
  2655. // has been verified.
  2656. //
  2657. // FilesNotToBackup
  2658. // "SOFTWARE\Microsoft\Windows NT\CurrentVersion\FilesNotToBackup"
  2659. //
  2660. WStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  2661. FRS_OLD_FILES_NOT_TO_BACKUP,
  2662. 0,
  2663. KEY_SET_VALUE,
  2664. &HOldBackupKey);
  2665. CLEANUP1_WS(4, ":FK: WARN - RegOpenKeyEx(%ws);",
  2666. FRS_OLD_FILES_NOT_TO_BACKUP, WStatus, NEW_FILES_NOT_TO_BACKUP);
  2667. //
  2668. // Set the ntfrs multistring value
  2669. //
  2670. WStatus = RegSetValueEx(HOldBackupKey,
  2671. SERVICE_NAME,
  2672. 0,
  2673. REG_MULTI_SZ,
  2674. (PCHAR)MStr,
  2675. (Idx + 1) * sizeof(WCHAR));
  2676. CLEANUP2_WS(4, ":FK: ERROR - RegSetValueEx(%ws\\%ws);",
  2677. FRS_OLD_FILES_NOT_TO_BACKUP, SERVICE_NAME, WStatus, NEW_FILES_NOT_TO_BACKUP);
  2678. NEW_FILES_NOT_TO_BACKUP:
  2679. //
  2680. // FilesNotToBackup
  2681. // "SYSTEM\CurrentControlSet\Control\BackupRestore\FilesNotToBackup"
  2682. //
  2683. WStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  2684. FRS_NEW_FILES_NOT_TO_BACKUP,
  2685. 0,
  2686. KEY_SET_VALUE,
  2687. &HNewBackupKey);
  2688. CLEANUP1_WS(4, ":FK: WARN - RegOpenKeyEx(%ws);",
  2689. FRS_NEW_FILES_NOT_TO_BACKUP, WStatus, CLEANUP);
  2690. //
  2691. // Set the ntfrs multistring value
  2692. //
  2693. WStatus = RegSetValueEx(HNewBackupKey,
  2694. SERVICE_NAME,
  2695. 0,
  2696. REG_MULTI_SZ,
  2697. (PCHAR)MStr,
  2698. (Idx + 1) * sizeof(WCHAR));
  2699. CLEANUP2_WS(4, ":FK: ERROR - RegSetValueEx(%ws\\%ws);",
  2700. FRS_NEW_FILES_NOT_TO_BACKUP, SERVICE_NAME, WStatus, CLEANUP);
  2701. //
  2702. // KeysNotToRestore
  2703. //
  2704. // Set the restore registry key KeysNotToRestore so that NtBackup will
  2705. // retain the ntfrs restore keys by moving them into the final restored
  2706. // registry.
  2707. //
  2708. // CurrentControlSet\Services\<SERVICE_NAME>\Parameters\Backup/Restore\Process at Startup\"
  2709. //
  2710. MStr = FrsFree(MStr);
  2711. Size = 0;
  2712. Idx = 0;
  2713. FrsAddToMultiString(FRS_VALUE_FOR_KEYS_NOT_TO_RESTORE, &Size, &Idx, &MStr);
  2714. //
  2715. // KeysNotToRestore
  2716. // "SYSTEM\CurrentControlSet\Control\BackupRestore\KeysNotToRestore"
  2717. //
  2718. WStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  2719. FRS_KEYS_NOT_TO_RESTORE,
  2720. 0,
  2721. KEY_SET_VALUE,
  2722. &HKeysNotToRestore);
  2723. CLEANUP1_WS(4, ":FK: WARN - RegOpenKeyEx(%ws);",
  2724. FRS_KEYS_NOT_TO_RESTORE, WStatus, CLEANUP);
  2725. //
  2726. // Set the ntfrs multistring value
  2727. //
  2728. WStatus = RegSetValueEx(HKeysNotToRestore,
  2729. SERVICE_NAME,
  2730. 0,
  2731. REG_MULTI_SZ,
  2732. (PCHAR)MStr,
  2733. (Idx + 1) * sizeof(WCHAR));
  2734. CLEANUP2_WS(4, ":FK: ERROR - RegSetValueEx(%ws\\%ws);",
  2735. FRS_KEYS_NOT_TO_RESTORE, SERVICE_NAME, WStatus, CLEANUP);
  2736. //
  2737. // DONE
  2738. //
  2739. WStatus = ERROR_SUCCESS;
  2740. CLEANUP:
  2741. if (HOldBackupKey) {
  2742. RegCloseKey(HOldBackupKey);
  2743. }
  2744. if (HNewBackupKey) {
  2745. RegCloseKey(HNewBackupKey);
  2746. }
  2747. if (HKeysNotToRestore) {
  2748. RegCloseKey(HKeysNotToRestore);
  2749. }
  2750. FrsFree(MStr);
  2751. }
  2752. VOID
  2753. FrsRegPostEventLog(
  2754. IN PFRS_REGISTRY_KEY KeyCtx,
  2755. IN PWCHAR KeyArg1,
  2756. IN ULONG Flags,
  2757. IN LONG IDScode
  2758. )
  2759. /*++
  2760. Routine Description:
  2761. This Posts an event log message for a problem with a registry key.
  2762. Arguments:
  2763. KeyCtx - Ptr to the Key Context struct for this key.
  2764. KeyArg1 - An optional caller supplied key component. NULL if not provided.
  2765. Flags - Modifer flags
  2766. IDSCode - the error message code for a resource string to put in the message.
  2767. Return Value:
  2768. None.
  2769. --*/
  2770. #undef DEBSUB
  2771. #define DEBSUB "FrsRegPostEventLog:"
  2772. {
  2773. #define LEN_DEFAULT_VALUE 48
  2774. #define LEN_RANGE_STR 256
  2775. PWCHAR ErrorStr, UnitsStr, RangeStrFmt, ValStr, FullKeyStr;
  2776. WCHAR RangeStr[LEN_RANGE_STR];
  2777. //DPRINT(0, "function entry\n");
  2778. //
  2779. // Are we posting an event log message for this key?
  2780. //
  2781. if (!BooleanFlagOn(Flags | KeyCtx->Flags, FRS_RKF_LOG_EVENT) ||
  2782. (KeyCtx->EventCode == EVENT_FRS_NONE)) {
  2783. return;
  2784. }
  2785. //
  2786. // Post Eventlog message. Include KeyString, ValueName,
  2787. // MustBePresent, Expected Type, TypeMismatch or not,
  2788. // Value out of range (with range allowed), Default Value Used,
  2789. // regedit instrs to fix the problem,
  2790. //
  2791. UnitsStr = FrsGetResourceStr(XLATE_IDS_UNITS(KeyCtx->Units));
  2792. ErrorStr = FrsGetResourceStr(IDScode);
  2793. if (KeyCtx->RegValueType == REG_DWORD) {
  2794. //
  2795. // Get the range format string from the string resource.
  2796. //
  2797. RangeStrFmt = FrsGetResourceStr(IDS_RANGE_DWORD);
  2798. //
  2799. // Show default value used if default is ok.
  2800. //
  2801. if (BooleanFlagOn(Flags | KeyCtx->Flags, FRS_RKF_OK_TO_USE_DEFAULT)) {
  2802. ValStr = FrsAlloc(LEN_DEFAULT_VALUE * sizeof(WCHAR));
  2803. _snwprintf(ValStr, LEN_DEFAULT_VALUE, L"%d", KeyCtx->ValueDefault);
  2804. } else {
  2805. ValStr = FrsGetResourceStr(IDS_NO_DEFAULT);
  2806. }
  2807. } else {
  2808. //
  2809. // No default allowed.
  2810. //
  2811. RangeStrFmt = FrsGetResourceStr(IDS_RANGE_STRING);
  2812. ValStr = FrsGetResourceStr(IDS_NO_DEFAULT);
  2813. }
  2814. //
  2815. // Build the range string.
  2816. //
  2817. _snwprintf(RangeStr, LEN_RANGE_STR, RangeStrFmt, KeyCtx->ValueMin, KeyCtx->ValueMax);
  2818. RangeStr[LEN_RANGE_STR-1] = UNICODE_NULL;
  2819. //
  2820. // Expand the key string.
  2821. //
  2822. FrsRegExpandKeyStr(KeyCtx, KeyArg1, Flags, &FullKeyStr);
  2823. if (FullKeyStr == NULL) {
  2824. FullKeyStr = FrsWcsDup(KeyCtx->KeyName);
  2825. }
  2826. //
  2827. // Post the event log message using the keycode in the KeyContext and cleanup.
  2828. //
  2829. if (KeyCtx->EventCode == EVENT_FRS_BAD_REG_DATA) {
  2830. EPRINT9(KeyCtx->EventCode,
  2831. ErrorStr, // %1
  2832. FullKeyStr, // %2
  2833. KeyCtx->ValueName, // %3
  2834. REG_DT_NAME(KeyCtx->RegValueType), // %4
  2835. RangeStr, // %5
  2836. UnitsStr, // %6
  2837. ValStr, // %7
  2838. FullKeyStr, // %8
  2839. KeyCtx->ValueName); // %9
  2840. } else {
  2841. //
  2842. // Don't know this event code but put out something.
  2843. //
  2844. DPRINT1(0, ":FK: ERROR - Unexpected EventCode number (%d). Cannot post message.\n",
  2845. KeyCtx->EventCode);
  2846. }
  2847. DPRINT1(0, ":FK: EventCode number : %d\n" , (KeyCtx->EventCode & 0xFFFF));
  2848. DPRINT1(0, ":FK: Error String : %ws\n", ErrorStr);
  2849. DPRINT1(0, ":FK: Key String : %ws\n", FullKeyStr);
  2850. DPRINT1(0, ":FK: Value Name : %ws\n", KeyCtx->ValueName);
  2851. DPRINT1(0, ":FK: Expected Reg Type : %ws\n", REG_DT_NAME(KeyCtx->RegValueType));
  2852. DPRINT1(0, ":FK: Parameter Range : %ws\n", RangeStr);
  2853. DPRINT1(0, ":FK: Parameter units : %ws\n", UnitsStr);
  2854. FrsFree(ErrorStr);
  2855. FrsFree(RangeStrFmt);
  2856. FrsFree(UnitsStr);
  2857. FrsFree(ValStr);
  2858. FrsFree(FullKeyStr);
  2859. }