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.

378 lines
9.1 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. regops.c
  5. Abstract:
  6. Routines that manage the merging of registry keys. Given a key
  7. and a value, these functions allow the user to perform the same
  8. types of actions as those specified in usermig.inf and wkstamig.inf
  9. (i.e.: Copying, Suppressing, and Forcing various registry keys to be
  10. merged into the NT registry.)
  11. Routines:
  12. Author:
  13. Marc R. Whitten (marcw) 01-Aug-1997
  14. Revision History:
  15. Jim Schmidt (jimschm) 25-Mar-1998 Updated to properly support
  16. tree notation, fixed value suppression
  17. bug.
  18. --*/
  19. #include "pch.h"
  20. #include "memdbp.h"
  21. #include "merge.h"
  22. #define DBG_REGOPS "RegOps"
  23. /*++
  24. Routine Description:
  25. IsRegObjectMarkedForOperation builds an encoded key, escaping multi-byte
  26. characters and syntax characters, and then performs a MemDb lookup to see
  27. if the object is marked with the bit specified by OperationMask. A set of
  28. macros are built on top of this routine in regops.h.
  29. Arguments:
  30. Key - Specifies the unencoded registry key, with abriviated roots
  31. (i.e., HKLM\Software\Foo)
  32. Value - Specifies the registry key value name
  33. TreeState - Specifies KEY_ONLY to query against the key and optional
  34. value, KEY_TREE to query against the key with a star at the
  35. end, or TREE_OPTIONAL to query both.
  36. OperationMask - Specifies an operation mask. See merge.h.
  37. Return Value:
  38. TRUE if the key is in MemDb, or FALSE if it is not.
  39. --*/
  40. BOOL
  41. IsRegObjectMarkedForOperationA (
  42. IN PCSTR Key,
  43. IN PCSTR Value, OPTIONAL
  44. IN TREE_STATE TreeState,
  45. IN DWORD OperationMask
  46. )
  47. {
  48. PCSTR regObject;
  49. BOOL rIsMarked = FALSE;
  50. DWORD value;
  51. MYASSERT (TreeState != KEY_TREE || !Value);
  52. if (TreeState == KEY_ONLY || TreeState == TREE_OPTIONAL) {
  53. regObject = CreateEncodedRegistryStringExA(Key,Value,FALSE);
  54. if (MemDbGetStoredEndPatternValueA(regObject,&value)) {
  55. rIsMarked = (value & OperationMask) == OperationMask;
  56. }
  57. FreeEncodedRegistryStringA(regObject);
  58. }
  59. if (!rIsMarked && TreeState == KEY_TREE || TreeState == TREE_OPTIONAL && !Value) {
  60. regObject = CreateEncodedRegistryStringExA(Key,Value,TRUE);
  61. if (MemDbGetStoredEndPatternValueA(regObject,&value)) {
  62. rIsMarked = (value & OperationMask) == OperationMask;
  63. }
  64. FreeEncodedRegistryStringA(regObject);
  65. }
  66. return rIsMarked;
  67. }
  68. BOOL
  69. IsRegObjectMarkedForOperationW (
  70. IN PCWSTR Key,
  71. IN PCWSTR Value, OPTIONAL
  72. IN TREE_STATE TreeState,
  73. IN DWORD OperationMask
  74. )
  75. {
  76. PCWSTR regObject;
  77. BOOL rIsMarked = FALSE;
  78. DWORD value;
  79. MYASSERT (TreeState != KEY_TREE || !Value);
  80. if (TreeState == KEY_ONLY || TreeState == TREE_OPTIONAL) {
  81. regObject = CreateEncodedRegistryStringExW(Key,Value,FALSE);
  82. if (MemDbGetStoredEndPatternValueW(regObject,&value)) {
  83. rIsMarked = (value & OperationMask) == OperationMask;
  84. }
  85. FreeEncodedRegistryStringW(regObject);
  86. }
  87. if (!rIsMarked && TreeState == KEY_TREE || TreeState == TREE_OPTIONAL && !Value) {
  88. regObject = CreateEncodedRegistryStringExW(Key,Value,TRUE);
  89. if (MemDbGetStoredEndPatternValueW(regObject,&value)) {
  90. rIsMarked = (value & OperationMask) == OperationMask;
  91. }
  92. FreeEncodedRegistryStringW(regObject);
  93. }
  94. return rIsMarked;
  95. }
  96. /*++
  97. Routine Description:
  98. MarkRegObjectForOperation creates an encoded string and sets the operation
  99. bit in memdb. This routine is used to suppress operations from occurring
  100. on a registry key, registry value, or registry key tree.
  101. Arguments:
  102. Key - Specifies an unencoded registry key, with abriviated root
  103. (i.e., HKLM\Software\Foo).
  104. Value - Specifies the registry key value name.
  105. Tree - Specifies TRUE if Key specifies an entire registry key tree
  106. (in which case Value must be NULL), or FALSE if Key
  107. specifies a key that has different behavior for its subkeys.
  108. OperationMask - Specifies the suppression operation. See merge.h.
  109. Return Value:
  110. TRUE if the set was successful.
  111. --*/
  112. BOOL
  113. MarkRegObjectForOperationA (
  114. IN PCSTR Key,
  115. IN PCSTR Value, OPTIONAL
  116. IN BOOL Tree,
  117. IN DWORD OperationMask
  118. )
  119. {
  120. PCSTR regObject;
  121. BOOL rSuccess = TRUE;
  122. if (Tree && Value) {
  123. Tree = FALSE;
  124. }
  125. regObject = CreateEncodedRegistryStringExA(Key,Value,Tree);
  126. rSuccess = MarkObjectForOperationA (regObject, OperationMask);
  127. FreeEncodedRegistryStringA(regObject);
  128. return rSuccess;
  129. }
  130. BOOL
  131. MarkRegObjectForOperationW (
  132. IN PCWSTR Key,
  133. IN PCWSTR Value, OPTIONAL
  134. IN BOOL Tree,
  135. IN DWORD OperationMask
  136. )
  137. {
  138. PCWSTR regObject;
  139. BOOL rSuccess = TRUE;
  140. if (Tree && Value) {
  141. Tree = FALSE;
  142. }
  143. regObject = CreateEncodedRegistryStringExW(Key,Value,Tree);
  144. rSuccess = MarkObjectForOperationW (regObject, OperationMask);
  145. FreeEncodedRegistryStringW(regObject);
  146. return rSuccess;
  147. }
  148. /*++
  149. Routine Description:
  150. MarkObjectForOperation sets operation bits on a specified registry object,
  151. unless operation bits have already been specified.
  152. Arguments:
  153. Object - Specifies the encoded registry object. See memdbdef.h for
  154. syntax (the HKLM or HKR categories).
  155. OperationMask - Specifies the suppression operation for the particular
  156. object.
  157. Return Value:
  158. TRUE if the set operation was successful, or FALSE if an operation was
  159. already specified.
  160. --*/
  161. BOOL
  162. MarkObjectForOperationA (
  163. IN PCSTR Object,
  164. IN DWORD OperationMask
  165. )
  166. {
  167. DWORD Value;
  168. if (MemDbGetValueA (Object, &Value)) {
  169. DEBUGMSG_IF ((
  170. Value == OperationMask,
  171. DBG_REGOPS,
  172. "%hs is already in memdb.",
  173. Object
  174. ));
  175. DEBUGMSG_IF ((
  176. Value != OperationMask,
  177. DBG_REGOPS,
  178. "%hs is already in memdb with different flags %u. New flags ignored: %u.",
  179. Object,
  180. Value,
  181. OperationMask
  182. ));
  183. return FALSE;
  184. }
  185. return MemDbSetValueA (Object, OperationMask);
  186. }
  187. BOOL
  188. MarkObjectForOperationW (
  189. IN PCWSTR Object,
  190. IN DWORD OperationMask
  191. )
  192. {
  193. DWORD Value;
  194. if (MemDbGetValueW (Object, &Value)) {
  195. DEBUGMSG_IF ((
  196. Value == OperationMask,
  197. DBG_REGOPS,
  198. "%ls is already in memdb.",
  199. Object
  200. ));
  201. DEBUGMSG_IF ((
  202. Value != OperationMask,
  203. DBG_REGOPS,
  204. "%ls is already in memdb with different flags %u. New flags ignored: %u.",
  205. Object,
  206. Value,
  207. OperationMask
  208. ));
  209. return FALSE;
  210. }
  211. return MemDbSetValueW (Object, OperationMask);
  212. }
  213. BOOL
  214. ForceWin9xSettingA (
  215. IN PCSTR SourceKey,
  216. IN PCSTR SourceValue,
  217. IN BOOL SourceTree,
  218. IN PCSTR DestinationKey,
  219. IN PCSTR DestinationValue,
  220. IN BOOL DestinationTree
  221. )
  222. {
  223. PCSTR regSource;
  224. CHAR keySource[MEMDB_MAX];
  225. PCSTR regDestination;
  226. CHAR keyDestination[MEMDB_MAX];
  227. DWORD offset = 0;
  228. BOOL rSuccess = TRUE;
  229. regSource = CreateEncodedRegistryStringExA (SourceKey, SourceValue, SourceTree);
  230. MemDbBuildKeyA (keySource, MEMDB_CATEGORY_FORCECOPYA, regSource, NULL, NULL);
  231. regDestination = CreateEncodedRegistryStringExA (DestinationKey, DestinationValue, DestinationTree);
  232. MemDbBuildKeyA (keyDestination, MEMDB_CATEGORY_FORCECOPYA, regDestination, NULL, NULL);
  233. rSuccess = MemDbSetValueExA (keyDestination, NULL, NULL, NULL, 0, &offset);
  234. if (rSuccess) {
  235. rSuccess = MemDbSetValueA (keySource, offset);
  236. }
  237. FreeEncodedRegistryStringA (regDestination);
  238. FreeEncodedRegistryStringA (regSource);
  239. return rSuccess;
  240. }
  241. BOOL
  242. ForceWin9xSettingW (
  243. IN PCWSTR SourceKey,
  244. IN PCWSTR SourceValue,
  245. IN BOOL SourceTree,
  246. IN PCWSTR DestinationKey,
  247. IN PCWSTR DestinationValue,
  248. IN BOOL DestinationTree
  249. )
  250. {
  251. PCWSTR regSource;
  252. WCHAR keySource[MEMDB_MAX];
  253. PCWSTR regDestination;
  254. WCHAR keyDestination[MEMDB_MAX];
  255. DWORD offset = 0;
  256. BOOL rSuccess = TRUE;
  257. regSource = CreateEncodedRegistryStringExW (SourceKey, SourceValue, SourceTree);
  258. MemDbBuildKeyW (keySource, MEMDB_CATEGORY_FORCECOPYW, regSource, NULL, NULL);
  259. regDestination = CreateEncodedRegistryStringExW (DestinationKey, DestinationValue, DestinationTree);
  260. MemDbBuildKeyW (keyDestination, MEMDB_CATEGORY_FORCECOPYW, regDestination, NULL, NULL);
  261. rSuccess = MemDbSetValueExW (keyDestination, NULL, NULL, NULL, 0, &offset);
  262. if (rSuccess) {
  263. rSuccess = MemDbSetValueW (keySource, offset);
  264. }
  265. FreeEncodedRegistryStringW (regDestination);
  266. FreeEncodedRegistryStringW (regSource);
  267. return rSuccess;
  268. }