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.

487 lines
13 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. RegWriter.h
  5. Abstract:
  6. Contains the registry writer abstraction
  7. implementation
  8. Author:
  9. Mike Cirello
  10. Vijay Jayaseelan (vijayj)
  11. Revision History:
  12. 03 March 2001 :
  13. Rewamp the whole source to make it more maintainable
  14. (particularly readable)
  15. --*/
  16. #include "RegWriter.h"
  17. #include "buildhive.h"
  18. #include "Data.h"
  19. #include <shlwapi.h>
  20. #include "msginc.h"
  21. #include <libmsg.h>
  22. #include "msg.h"
  23. //////////////////////////////////////////////////////////////////////
  24. // Construction/Destruction
  25. //////////////////////////////////////////////////////////////////////
  26. //
  27. // Macro definitions
  28. //
  29. #define AS(x) ( sizeof( (x) ) / sizeof( (x[0]) ) )
  30. //
  31. // static data initilization
  32. //
  33. int RegWriter::ctr = 0;
  34. TCHAR RegWriter::Namespace[64] = {0};
  35. //
  36. // Initializes a new subkey for this regwriter
  37. //
  38. // Arguments:
  39. // LUID is the name of the subkey, all LUID's must be unique
  40. // target is the name of the hive file to load into the key.
  41. // If it is null an empty key is created
  42. //
  43. DWORD RegWriter::Init(
  44. IN int LUID,
  45. PCTSTR target
  46. )
  47. {
  48. DWORD dwRet;
  49. TCHAR buf[10];
  50. //
  51. // initialize the namespace, if needed
  52. //
  53. if (0 == Namespace[0]) {
  54. GUID guid = {0};
  55. if (CoCreateGuid(&guid) != S_OK) {
  56. return ERROR_FUNCTION_FAILED;
  57. }
  58. swprintf(Namespace,
  59. L"bldhives.exe{%08X-%04X-%04X-%02X%02X%02X%02X%02X%02X%02X%02X}\\",
  60. guid.Data1,
  61. guid.Data2,
  62. guid.Data3,
  63. guid.Data4[0],
  64. guid.Data4[1],
  65. guid.Data4[2],
  66. guid.Data4[3],
  67. guid.Data4[4],
  68. guid.Data4[5],
  69. guid.Data4[6],
  70. guid.Data4[7]);
  71. }
  72. wcscpy(root, Namespace);
  73. luid = LUID;
  74. //
  75. // if this is the first time, load the root key
  76. //
  77. if (!ctr) {
  78. dwRet = RegLoadKey(HKEY_USERS, root, L".\\nothing");
  79. if (dwRet !=ERROR_SUCCESS) {
  80. _putws( GetFormattedMessage(ThisModule,
  81. FALSE,
  82. Message,
  83. sizeof(Message)/sizeof(Message[0]),
  84. MSG_ERROR_LOADING_EMPTY_KEY,
  85. dwRet) );
  86. }
  87. }
  88. //
  89. // create root key for this regwriter (subkey of dummy) if it is for a new file
  90. //
  91. if (!target) {
  92. wcscat(root, _itow(luid,buf,10));
  93. dwRet = RegCreateKeyEx(HKEY_USERS, root, 0, 0, 0, KEY_ALL_ACCESS, 0, &key, 0);
  94. if (dwRet !=ERROR_SUCCESS) {
  95. _putws( GetFormattedMessage(ThisModule,
  96. FALSE,
  97. Message,
  98. sizeof(Message)/sizeof(Message[0]),
  99. MSG_ERROR_LOADING_ROOT_KEY,
  100. dwRet) );
  101. }
  102. RegCloseKey(key);
  103. } else {
  104. //
  105. // otherwise load existing hive into subkey of dummy
  106. //
  107. wcscat(root, _itow(luid,buf,10));
  108. _putws( GetFormattedMessage(ThisModule,
  109. FALSE,
  110. Message,
  111. sizeof(Message)/sizeof(Message[0]),
  112. MSG_LOADING_HIVE,
  113. target) );
  114. dwRet = Load(L"", target);
  115. if (dwRet !=ERROR_SUCCESS) {
  116. _putws( GetFormattedMessage(ThisModule,
  117. FALSE,
  118. Message,
  119. sizeof(Message)/sizeof(Message[0]),
  120. MSG_ERROR_LOADING_ROOT_KEY,
  121. dwRet) );
  122. }
  123. }
  124. ctr++;
  125. return ERROR_SUCCESS;
  126. }
  127. RegWriter::~RegWriter()
  128. {
  129. DWORD dwRet;
  130. ctr--;
  131. if (!ctr) {
  132. //
  133. // unload everything from the registry
  134. //
  135. dwRet = RegUnLoadKey(HKEY_USERS, Namespace);
  136. if (dwRet !=ERROR_SUCCESS) {
  137. _putws( GetFormattedMessage(ThisModule,
  138. FALSE,
  139. Message,
  140. sizeof(Message)/sizeof(Message[0]),
  141. MSG_DECONSTRUCTOR_UNLOAD,
  142. dwRet) );
  143. }
  144. //
  145. // delete the files created when we made the empty root key
  146. //
  147. HANDLE Handle = CreateFile(L".\\nothing",
  148. DELETE,
  149. FILE_SHARE_DELETE,
  150. 0,
  151. OPEN_EXISTING,
  152. 0,
  153. 0);
  154. if (Handle !=INVALID_HANDLE_VALUE) {
  155. DeleteFile(L".\\nothing");
  156. CloseHandle(Handle);
  157. } else {
  158. _putws( GetFormattedMessage(ThisModule,
  159. FALSE,
  160. Message,
  161. sizeof(Message)/sizeof(Message[0]),
  162. MSG_EMPTY_HIVE_DELETE_FAILED) );
  163. }
  164. Handle = CreateFile(L".\\nothing.LOG",
  165. DELETE,
  166. FILE_SHARE_DELETE,
  167. 0,
  168. OPEN_EXISTING,
  169. 0,
  170. 0);
  171. if (Handle !=INVALID_HANDLE_VALUE) {
  172. DeleteFile(L".\\nothing.LOG");
  173. CloseHandle(Handle);
  174. } else {
  175. _putws( GetFormattedMessage(ThisModule,
  176. FALSE,
  177. Message,
  178. sizeof(Message)/sizeof(Message[0]),
  179. MSG_EMPTY_HIVE_LOG_DELETE_FAILED) );
  180. }
  181. }
  182. }
  183. //
  184. // Writes data to a subkey of this regwriter's root
  185. //
  186. // Arguments:
  187. // Root - ignored
  188. // Key - the subkey to store the data in
  189. // Value - the value to store the data in
  190. // flag - registry flag describing the data - REG_SZ, REG_DWORD, etc..
  191. // data - a data object containing the information to be written to the subkey
  192. //
  193. DWORD RegWriter::Write(
  194. IN PCTSTR Root,
  195. IN PCTSTR Key,
  196. IN PCTSTR Value,
  197. IN DWORD flag,
  198. IN Data* data)
  199. {
  200. HKEY key;
  201. DWORD dwRet;
  202. TCHAR full[1024] = {0};
  203. wcsncpy(full, root, AS(full) - 1);
  204. wcsncpy(full + wcslen(full), Key, AS(full) - wcslen(full) - 1);
  205. //
  206. // open a key and set its value
  207. //
  208. dwRet = RegCreateKeyEx(HKEY_USERS, full, 0, 0, 0, KEY_WRITE, 0, &key, 0);
  209. if (dwRet !=ERROR_SUCCESS) {
  210. _putws( GetFormattedMessage(ThisModule,
  211. FALSE,
  212. Message,
  213. sizeof(Message)/sizeof(Message[0]),
  214. MSG_CREATE_KEY,
  215. dwRet) );
  216. return dwRet;
  217. }
  218. if ((data) && (data->GetData())) {
  219. dwRet = RegSetValueEx(key, Value, 0, flag,data->GetData(), data->Sizeof());
  220. if (dwRet != ERROR_SUCCESS) {
  221. _putws( GetFormattedMessage(ThisModule,
  222. FALSE,
  223. Message,
  224. sizeof(Message)/sizeof(Message[0]),
  225. MSG_SET_KEY,
  226. dwRet) );
  227. RegCloseKey(key);
  228. return dwRet;
  229. }
  230. } else if (Value) {
  231. dwRet = RegSetValueEx(key, Value, 0, flag, 0, 0);
  232. if (dwRet !=ERROR_SUCCESS) {
  233. _putws( GetFormattedMessage(ThisModule,
  234. FALSE,
  235. Message,
  236. sizeof(Message)/sizeof(Message[0]),
  237. MSG_SET_KEY2,
  238. dwRet) );
  239. RegCloseKey(key);
  240. return dwRet;
  241. }
  242. }
  243. RegCloseKey(key);
  244. return ERROR_SUCCESS;
  245. }
  246. //
  247. // Saves a subkey to disk
  248. //
  249. // Arguments:
  250. // Key - the subkey to be saved
  251. // fileName - the file to save the information to.
  252. //
  253. DWORD RegWriter::Save(
  254. PCTSTR Key,
  255. PCTSTR fileName
  256. )
  257. {
  258. DWORD dwRet = 0;
  259. HKEY key;
  260. TCHAR full[1024] = {0};
  261. wcsncpy(full, root, AS(full) - 1);
  262. wcsncpy(full + wcslen(full), Key, AS(full) - wcslen(full) - 1);
  263. //
  264. // save a key to file
  265. //
  266. dwRet = RegCreateKeyEx(HKEY_USERS,full,0,0,0,KEY_READ,0,&key,0);
  267. if (dwRet != ERROR_SUCCESS) {
  268. _putws( GetFormattedMessage(ThisModule,
  269. FALSE,
  270. Message,
  271. sizeof(Message)/sizeof(Message[0]),
  272. MSG_CREATE_KEY,
  273. dwRet) );
  274. return dwRet;
  275. }
  276. dwRet = RegSaveKey(key,fileName,0);
  277. if (dwRet != ERROR_SUCCESS) {
  278. _putws( GetFormattedMessage(ThisModule,
  279. FALSE,
  280. Message,
  281. sizeof(Message)/sizeof(Message[0]),
  282. MSG_SAVE_KEY,
  283. dwRet) );
  284. RegCloseKey(key);
  285. return dwRet;
  286. }
  287. RegCloseKey(key);
  288. return dwRet;
  289. }
  290. //
  291. // Loads information from a hive file to a subkey.
  292. //
  293. // Arguments :
  294. // Key - subkey to write the information to
  295. // fileName - full path and file name of the hive file to be loaded.
  296. //
  297. DWORD RegWriter::Load(PCTSTR Key, PCTSTR fileName) {
  298. DWORD dwRet = 0;
  299. TCHAR full[1024] = {0};
  300. wcsncpy(full, root, AS(full) - 1);
  301. wcsncpy(full + wcslen(full), Key, AS(full) - wcslen(full) - 1);
  302. //
  303. // load data in from a hive
  304. //
  305. dwRet = RegCreateKeyEx(HKEY_USERS,full,0,0,0,KEY_ALL_ACCESS,0,&key,0);
  306. if (dwRet != ERROR_SUCCESS) {
  307. _putws( GetFormattedMessage(ThisModule,
  308. FALSE,
  309. Message,
  310. sizeof(Message)/sizeof(Message[0]),
  311. MSG_ERROR_CREATE_KEY,
  312. dwRet,
  313. root,
  314. full,
  315. fileName) );
  316. return dwRet;
  317. }
  318. dwRet = RegRestoreKey(key,fileName,0);
  319. if (dwRet != ERROR_SUCCESS) {
  320. _putws( GetFormattedMessage(ThisModule,
  321. FALSE,
  322. Message,
  323. sizeof(Message)/sizeof(Message[0]),
  324. MSG_ERROR_RESTORE_KEY,
  325. dwRet,
  326. root,
  327. full,
  328. fileName) );
  329. RegCloseKey(key);
  330. return dwRet;
  331. }
  332. dwRet = RegFlushKey(key);
  333. if (dwRet != ERROR_SUCCESS) {
  334. _putws( GetFormattedMessage(ThisModule,
  335. FALSE,
  336. Message,
  337. sizeof(Message)/sizeof(Message[0]),
  338. MSG_ERROR_FLUSH_KEY,
  339. dwRet,
  340. root,
  341. full,
  342. fileName) );
  343. RegCloseKey(key);
  344. return dwRet;
  345. }
  346. RegCloseKey(key);
  347. return dwRet;
  348. }
  349. DWORD
  350. RegWriter::Delete(
  351. PCTSTR CurrentRoot,
  352. PCTSTR Key,
  353. PCTSTR Value OPTIONAL
  354. )
  355. /*++
  356. Routine Description:
  357. Deletes the given key / value underneath the key
  358. Arguments:
  359. CurrentRoot - The Root key (ignored for the time being)
  360. Key - The key to delete or key containing the value to delete
  361. Value - The value to delete
  362. Return Value:
  363. Appropriate WIN32 error code
  364. --*/
  365. {
  366. DWORD Result = ERROR_INVALID_PARAMETER;
  367. if (CurrentRoot && Key) {
  368. DWORD BufferLength = (_tcslen(root) + _tcslen(Key) + _tcslen(root));
  369. PTSTR Buffer;
  370. if (Value) {
  371. BufferLength += _tcslen(Value);;
  372. }
  373. BufferLength += sizeof(TCHAR); // for null
  374. BufferLength = sizeof(TCHAR) * BufferLength;
  375. Buffer = new TCHAR[BufferLength];
  376. if (Buffer) {
  377. _tcscpy(Buffer, root);
  378. _tcscat(Buffer, Key);
  379. if (Value) {
  380. Result = SHDeleteValue(HKEY_USERS,
  381. Buffer,
  382. Value);
  383. } else {
  384. Result = SHDeleteKey(HKEY_USERS,
  385. Buffer);
  386. }
  387. delete []Buffer;
  388. } else {
  389. Result = ERROR_OUTOFMEMORY;
  390. }
  391. }
  392. return Result;
  393. }