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.

844 lines
19 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. Regsrkey.c
  5. Abstract:
  6. This module contains the client side wrappers for the Win32 Registry
  7. save/restore key APIs, that is:
  8. - RegRestoreKeyA
  9. - RegRestoreKeyW
  10. - RegSaveKeyA
  11. - RegSaveKeyW
  12. Author:
  13. David J. Gilman (davegi) 23-Jan-1992
  14. Notes:
  15. The RegSaveKey and RegRestoreKey APIs involve up to 3 machines:
  16. 1.- CLIENT: The machine where the API is invoked.
  17. 2.- SERVER: The machine where the Registry resides.
  18. 3.- TARGET: The machine of the specified file.
  19. Note that both the client and the server will be running Windows NT,
  20. but that the target machine might not.
  21. Even though the target might be accessible from the client, it might
  22. not be accessible from the server (e.g. the share is protected).
  23. Revision History:
  24. 25-Mar-1992 Ramon J. San Andres (ramonsa)
  25. Changed to use RPC.
  26. --*/
  27. #include <rpc.h>
  28. #include "regrpc.h"
  29. #include "client.h"
  30. LONG
  31. APIENTRY
  32. RegRestoreKeyA (
  33. HKEY hKey,
  34. LPCSTR lpFile,
  35. DWORD dwFlags
  36. )
  37. /*++
  38. Routine Description:
  39. Win32 Ansi API for restoring a key.
  40. --*/
  41. {
  42. PUNICODE_STRING FileName;
  43. ANSI_STRING AnsiString;
  44. NTSTATUS Status;
  45. LONG Error;
  46. HKEY TempHandle = NULL;
  47. #if DBG
  48. if ( BreakPointOnEntry ) {
  49. DbgBreakPoint();
  50. }
  51. #endif
  52. ASSERT( lpFile != NULL );
  53. //
  54. // Limit the capabilities associated with HKEY_PERFORMANCE_DATA.
  55. //
  56. if( hKey == HKEY_PERFORMANCE_DATA ) {
  57. return ERROR_INVALID_HANDLE;
  58. }
  59. hKey = MapPredefinedHandle( hKey, &TempHandle );
  60. if( hKey == NULL ) {
  61. Error = ERROR_INVALID_HANDLE;
  62. goto ExitCleanup;
  63. }
  64. //
  65. // Convert the file name to a counted Unicode string using the static
  66. // Unicode string in the TEB.
  67. //
  68. FileName = &NtCurrentTeb( )->StaticUnicodeString;
  69. ASSERT( FileName != NULL );
  70. RtlInitAnsiString( &AnsiString, lpFile );
  71. Status = RtlAnsiStringToUnicodeString(
  72. FileName,
  73. &AnsiString,
  74. FALSE
  75. );
  76. //
  77. // If the file name could not be converted, map the results and return.
  78. //
  79. if( ! NT_SUCCESS( Status )) {
  80. Error = RtlNtStatusToDosError( Status );
  81. goto ExitCleanup;
  82. }
  83. //
  84. // Add the NULL to the length so that RPC will transmit the entire
  85. // thing
  86. //
  87. if ( FileName->Length > 0 ) {
  88. FileName->Length += sizeof( UNICODE_NULL );
  89. }
  90. if( IsLocalHandle( hKey )) {
  91. Error = (LONG)LocalBaseRegRestoreKey(
  92. hKey,
  93. FileName,
  94. dwFlags
  95. );
  96. } else {
  97. Error = (LONG)BaseRegRestoreKey(
  98. DereferenceRemoteHandle( hKey ),
  99. FileName,
  100. dwFlags
  101. );
  102. }
  103. ExitCleanup:
  104. CLOSE_LOCAL_HANDLE(TempHandle);
  105. return Error;
  106. }
  107. LONG
  108. APIENTRY
  109. RegRestoreKeyW (
  110. HKEY hKey,
  111. LPCWSTR lpFile,
  112. DWORD dwFlags
  113. )
  114. /*++
  115. Routine Description:
  116. Restore the tree in the supplied file onto the key referenced by the
  117. supplied key handle. The restored tree will overwrite all of the
  118. contents of the supplied hKey except for its name. Pictorially, if
  119. the file contains:
  120. A
  121. / \
  122. / \
  123. B C
  124. and the supplied key refers to a key name X, the resultant tree would
  125. look like:
  126. X
  127. / \
  128. / \
  129. B C
  130. Arguments:
  131. hKey - Supplies a handle to the key where the file is to be restored.
  132. lpFile - Supplies a pointer to an existing file name whose contents was
  133. created with RegSaveKey.
  134. dwFlags - Supplies an optional flag argument which can be:
  135. - REG_WHOLE_HIVE_VOLATILE
  136. If specified this flag causes a new, volatile
  137. (i.e. memory only) hive to be created. In this case
  138. the hKey can only refer to a child of HKEY_USERS or
  139. HKEY_LOCAL_MACHINE.
  140. If not specified, hKey can refer to any key in the
  141. Registry.
  142. Return Value:
  143. Returns ERROR_SUCCESS (0) for success; error-code for failure.
  144. --*/
  145. {
  146. UNICODE_STRING FileName;
  147. LONG Error;
  148. HKEY TempHandle = NULL;
  149. #if DBG
  150. if ( BreakPointOnEntry ) {
  151. DbgBreakPoint();
  152. }
  153. #endif
  154. ASSERT( lpFile != NULL );
  155. //
  156. // Limit the capabilities associated with HKEY_PERFORMANCE_DATA.
  157. //
  158. if( hKey == HKEY_PERFORMANCE_DATA ) {
  159. return ERROR_INVALID_HANDLE;
  160. }
  161. hKey = MapPredefinedHandle( hKey, &TempHandle );
  162. if( hKey == NULL ) {
  163. Error = ERROR_INVALID_HANDLE;
  164. goto ExitCleanup;
  165. }
  166. RtlInitUnicodeString( &FileName, lpFile );
  167. //
  168. // Add the NULL to the length so that RPC will transmit the entire
  169. // thing
  170. //
  171. if ( FileName.Length > 0 ) {
  172. FileName.Length += sizeof( UNICODE_NULL );
  173. }
  174. if( IsLocalHandle( hKey )) {
  175. Error = (LONG)LocalBaseRegRestoreKey(
  176. hKey,
  177. &FileName,
  178. dwFlags
  179. );
  180. } else {
  181. Error = (LONG)BaseRegRestoreKey(
  182. DereferenceRemoteHandle( hKey ),
  183. &FileName,
  184. dwFlags
  185. );
  186. }
  187. ExitCleanup:
  188. CLOSE_LOCAL_HANDLE(TempHandle);
  189. return Error;
  190. }
  191. LONG
  192. APIENTRY
  193. RegSaveKeyA (
  194. HKEY hKey,
  195. LPCSTR lpFile,
  196. LPSECURITY_ATTRIBUTES lpSecurityAttributes
  197. )
  198. /*++
  199. Routine Description:
  200. Win32 ANSI wrapper to RegSaveKeyW.
  201. Save the key (and all of its decsendants) to the non-existant file
  202. named by the supplied string.
  203. Arguments:
  204. hKey - Supplies a handle to the key where the save operation is to
  205. begin.
  206. lpFile - Supplies a pointer to a non-existant file name where the tree
  207. rooted at the supplied key handle will be saved.
  208. lpSecurityAttributes - Supplies an optional pointer to a
  209. SECURITY_ATTRIBUTES structure for the newly created file.
  210. Return Value:
  211. Returns ERROR_SUCCESS (0) for success; error-code for failure.
  212. --*/
  213. {
  214. PUNICODE_STRING FileName;
  215. ANSI_STRING AnsiString;
  216. NTSTATUS Status;
  217. PRPC_SECURITY_ATTRIBUTES pRpcSA;
  218. RPC_SECURITY_ATTRIBUTES RpcSA;
  219. LONG Error;
  220. HKEY TempHandle = NULL;
  221. #if DBG
  222. if ( BreakPointOnEntry ) {
  223. DbgBreakPoint();
  224. }
  225. #endif
  226. ASSERT( lpFile != NULL );
  227. //
  228. // Limit the capabilities associated with HKEY_PERFORMANCE_DATA.
  229. //
  230. if( hKey == HKEY_PERFORMANCE_DATA ) {
  231. return ERROR_INVALID_HANDLE;
  232. }
  233. //
  234. // Note that we must map the handle here even though RegSaveKeyW
  235. // will map it again. This is so that the second map will not
  236. // overwrite the static Unicode string in the TEB that will
  237. // contain the file name.
  238. //
  239. hKey = MapPredefinedHandle( hKey, &TempHandle );
  240. if( hKey == NULL ) {
  241. Error = ERROR_INVALID_HANDLE;
  242. goto ExitCleanup;
  243. }
  244. //
  245. // Convert the file name to a counted Unicode string using the static
  246. // Unicode string in the TEB.
  247. //
  248. FileName = &NtCurrentTeb( )->StaticUnicodeString;
  249. ASSERT( FileName != NULL );
  250. RtlInitAnsiString( &AnsiString, lpFile );
  251. Status = RtlAnsiStringToUnicodeString(
  252. FileName,
  253. &AnsiString,
  254. FALSE
  255. );
  256. //
  257. // If the file name could not be converted, map the results and return.
  258. //
  259. if( ! NT_SUCCESS( Status )) {
  260. Error = RtlNtStatusToDosError( Status );
  261. goto ExitCleanup;
  262. }
  263. //
  264. // Add the NULL to the length so that RPC will transmit the entire
  265. // thing
  266. //
  267. if ( FileName->Length > 0 ) {
  268. FileName->Length += sizeof( UNICODE_NULL );
  269. }
  270. //
  271. // If the caller supplied a LPSECURITY_ATTRIBUTES argument, map
  272. // it to the RPCable version.
  273. //
  274. if( ARGUMENT_PRESENT( lpSecurityAttributes )) {
  275. pRpcSA = &RpcSA;
  276. Error = MapSAToRpcSA( lpSecurityAttributes, pRpcSA );
  277. if( Error != ERROR_SUCCESS ) {
  278. goto ExitCleanup;
  279. }
  280. } else {
  281. //
  282. // No PSECURITY_ATTRIBUTES argument, therefore no mapping was done.
  283. //
  284. pRpcSA = NULL;
  285. }
  286. if( IsLocalHandle( hKey )) {
  287. Error = (LONG)LocalBaseRegSaveKey(
  288. hKey,
  289. FileName,
  290. pRpcSA
  291. );
  292. } else {
  293. Error = (LONG)BaseRegSaveKey(
  294. DereferenceRemoteHandle( hKey ),
  295. FileName,
  296. pRpcSA
  297. );
  298. }
  299. ExitCleanup:
  300. CLOSE_LOCAL_HANDLE(TempHandle);
  301. return Error;
  302. }
  303. LONG
  304. APIENTRY
  305. RegSaveKeyW (
  306. HKEY hKey,
  307. LPCWSTR lpFile,
  308. LPSECURITY_ATTRIBUTES lpSecurityAttributes
  309. )
  310. /*++
  311. Routine Description:
  312. Save the key (and all of its decsendants) to the non-existant file
  313. named by the supplied string.
  314. Arguments:
  315. hKey - Supplies a handle to the key where the save operation is to
  316. begin.
  317. lpFile - Supplies a pointer to a non-existant file name where the tree
  318. rooted at the supplied key handle will be saved.
  319. lpSecurityAttributes - Supplies an optional pointer to a
  320. SECURITY_ATTRIBUTES structure for the newly created file.
  321. Return Value:
  322. Returns ERROR_SUCCESS (0) for success; error-code for failure.
  323. --*/
  324. {
  325. UNICODE_STRING FileName;
  326. PRPC_SECURITY_ATTRIBUTES pRpcSA;
  327. RPC_SECURITY_ATTRIBUTES RpcSA;
  328. LONG Error;
  329. HKEY TempHandle = NULL;
  330. #if DBG
  331. if ( BreakPointOnEntry ) {
  332. DbgBreakPoint();
  333. }
  334. #endif
  335. ASSERT( lpFile != NULL );
  336. //
  337. // Limit the capabilities associated with HKEY_PERFORMANCE_DATA.
  338. //
  339. if( hKey == HKEY_PERFORMANCE_DATA ) {
  340. return ERROR_INVALID_HANDLE;
  341. }
  342. //
  343. // Note that we must map the handle here even though RegSaveKeyW
  344. // will map it again. This is so that the second map will not
  345. // overwrite the static Unicode string in the TEB that will
  346. // contain the file name.
  347. //
  348. hKey = MapPredefinedHandle( hKey, &TempHandle );
  349. if( hKey == NULL ) {
  350. Error = ERROR_INVALID_HANDLE;
  351. goto ExitCleanup;
  352. }
  353. RtlInitUnicodeString( &FileName, lpFile );
  354. //
  355. // Add the NULL to the length so that RPC will transmit the entire
  356. // thing
  357. //
  358. if ( FileName.Length > 0 ) {
  359. FileName.Length += sizeof( UNICODE_NULL );
  360. }
  361. //
  362. // If the caller supplied a LPSECURITY_ATTRIBUTES argument, map
  363. // it to the RPCable version.
  364. //
  365. if( ARGUMENT_PRESENT( lpSecurityAttributes )) {
  366. pRpcSA = &RpcSA;
  367. Error = MapSAToRpcSA( lpSecurityAttributes, pRpcSA );
  368. if( Error != ERROR_SUCCESS ) {
  369. goto ExitCleanup;
  370. }
  371. } else {
  372. //
  373. // No PSECURITY_ATTRIBUTES argument, therefore no mapping was done.
  374. //
  375. pRpcSA = NULL;
  376. }
  377. if( IsLocalHandle( hKey )) {
  378. Error = (LONG)LocalBaseRegSaveKey(
  379. hKey,
  380. &FileName,
  381. pRpcSA
  382. );
  383. } else {
  384. Error = (LONG)BaseRegSaveKey(
  385. DereferenceRemoteHandle( hKey ),
  386. &FileName,
  387. pRpcSA
  388. );
  389. }
  390. ExitCleanup:
  391. CLOSE_LOCAL_HANDLE(TempHandle);
  392. return Error;
  393. }
  394. LONG
  395. APIENTRY
  396. RegSaveKeyExA (
  397. HKEY hKey,
  398. LPCSTR lpFile,
  399. LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  400. DWORD Flags
  401. )
  402. /*++
  403. Routine Description:
  404. Win32 ANSI wrapper to RegSaveKeyExW.
  405. Save the key (and all of its decsendants) to the non-existant file
  406. named by the supplied string.
  407. Arguments:
  408. hKey - Supplies a handle to the key where the save operation is to
  409. begin.
  410. lpFile - Supplies a pointer to a non-existant file name where the tree
  411. rooted at the supplied key handle will be saved.
  412. lpSecurityAttributes - Supplies an optional pointer to a
  413. SECURITY_ATTRIBUTES structure for the newly created file.
  414. Return Value:
  415. Returns ERROR_SUCCESS (0) for success; error-code for failure.
  416. --*/
  417. {
  418. PUNICODE_STRING FileName;
  419. ANSI_STRING AnsiString;
  420. NTSTATUS Status;
  421. PRPC_SECURITY_ATTRIBUTES pRpcSA;
  422. RPC_SECURITY_ATTRIBUTES RpcSA;
  423. LONG Error;
  424. HKEY TempHandle = NULL;
  425. #if DBG
  426. if ( BreakPointOnEntry ) {
  427. DbgBreakPoint();
  428. }
  429. #endif
  430. ASSERT( lpFile != NULL );
  431. //
  432. // Limit the capabilities associated with HKEY_PERFORMANCE_DATA.
  433. //
  434. if( hKey == HKEY_PERFORMANCE_DATA ) {
  435. return ERROR_INVALID_HANDLE;
  436. }
  437. //
  438. // Note that we must map the handle here even though RegSaveKeyW
  439. // will map it again. This is so that the second map will not
  440. // overwrite the static Unicode string in the TEB that will
  441. // contain the file name.
  442. //
  443. hKey = MapPredefinedHandle( hKey, &TempHandle );
  444. if( hKey == NULL ) {
  445. Error = ERROR_INVALID_HANDLE;
  446. goto ExitCleanup;
  447. }
  448. //
  449. // Convert the file name to a counted Unicode string using the static
  450. // Unicode string in the TEB.
  451. //
  452. FileName = &NtCurrentTeb( )->StaticUnicodeString;
  453. ASSERT( FileName != NULL );
  454. RtlInitAnsiString( &AnsiString, lpFile );
  455. Status = RtlAnsiStringToUnicodeString(
  456. FileName,
  457. &AnsiString,
  458. FALSE
  459. );
  460. //
  461. // If the file name could not be converted, map the results and return.
  462. //
  463. if( ! NT_SUCCESS( Status )) {
  464. Error = RtlNtStatusToDosError( Status );
  465. goto ExitCleanup;
  466. }
  467. //
  468. // Add the NULL to the length so that RPC will transmit the entire
  469. // thing
  470. //
  471. if ( FileName->Length > 0 ) {
  472. FileName->Length += sizeof( UNICODE_NULL );
  473. }
  474. //
  475. // If the caller supplied a LPSECURITY_ATTRIBUTES argument, map
  476. // it to the RPCable version.
  477. //
  478. if( ARGUMENT_PRESENT( lpSecurityAttributes )) {
  479. pRpcSA = &RpcSA;
  480. Error = MapSAToRpcSA( lpSecurityAttributes, pRpcSA );
  481. if( Error != ERROR_SUCCESS ) {
  482. goto ExitCleanup;
  483. }
  484. } else {
  485. //
  486. // No PSECURITY_ATTRIBUTES argument, therefore no mapping was done.
  487. //
  488. pRpcSA = NULL;
  489. }
  490. if( IsLocalHandle( hKey )) {
  491. Error = (LONG)LocalBaseRegSaveKeyEx(
  492. hKey,
  493. FileName,
  494. pRpcSA,
  495. Flags
  496. );
  497. } else {
  498. Error = (LONG)BaseRegSaveKeyEx(
  499. DereferenceRemoteHandle( hKey ),
  500. FileName,
  501. pRpcSA,
  502. Flags
  503. );
  504. }
  505. ExitCleanup:
  506. CLOSE_LOCAL_HANDLE(TempHandle);
  507. return Error;
  508. }
  509. LONG
  510. APIENTRY
  511. RegSaveKeyExW (
  512. HKEY hKey,
  513. LPCWSTR lpFile,
  514. LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  515. DWORD Flags
  516. )
  517. /*++
  518. Routine Description:
  519. Save the key (and all of its decsendants) to the non-existant file
  520. named by the supplied string.
  521. This variant is used by setup in order to create a hive in the latest
  522. format. Helps creating hives in %systemroot%\system32\config in the
  523. latest (presumably the best) format, and allows RegSaveKey to use the
  524. standard format (bacward compatible) for roaming profiles and tools
  525. using registry hives on downlevel OSes.
  526. Arguments:
  527. hKey - Supplies a handle to the key where the save operation is to
  528. begin.
  529. lpFile - Supplies a pointer to a non-existant file name where the tree
  530. rooted at the supplied key handle will be saved.
  531. lpSecurityAttributes - Supplies an optional pointer to a
  532. SECURITY_ATTRIBUTES structure for the newly created file.
  533. Flags - [REG_STANDARD_FORMAT] - roaming format
  534. [REG_LATEST_FORMAT] - latest format
  535. [REG_NO_COMPRESSION] - no hive compression : faster
  536. Return Value:
  537. Returns ERROR_SUCCESS (0) for success; error-code for failure.
  538. --*/
  539. {
  540. UNICODE_STRING FileName;
  541. PRPC_SECURITY_ATTRIBUTES pRpcSA;
  542. RPC_SECURITY_ATTRIBUTES RpcSA;
  543. LONG Error;
  544. HKEY TempHandle = NULL;
  545. #if DBG
  546. if ( BreakPointOnEntry ) {
  547. DbgBreakPoint();
  548. }
  549. #endif
  550. ASSERT( lpFile != NULL );
  551. //
  552. // Limit the capabilities associated with HKEY_PERFORMANCE_DATA.
  553. //
  554. if( hKey == HKEY_PERFORMANCE_DATA ) {
  555. return ERROR_INVALID_HANDLE;
  556. }
  557. //
  558. // Note that we must map the handle here even though RegSaveKeyW
  559. // will map it again. This is so that the second map will not
  560. // overwrite the static Unicode string in the TEB that will
  561. // contain the file name.
  562. //
  563. hKey = MapPredefinedHandle( hKey, &TempHandle );
  564. if( hKey == NULL ) {
  565. Error = ERROR_INVALID_HANDLE;
  566. goto ExitCleanup;
  567. }
  568. RtlInitUnicodeString( &FileName, lpFile );
  569. //
  570. // Add the NULL to the length so that RPC will transmit the entire
  571. // thing
  572. //
  573. if ( FileName.Length > 0 ) {
  574. FileName.Length += sizeof( UNICODE_NULL );
  575. }
  576. //
  577. // If the caller supplied a LPSECURITY_ATTRIBUTES argument, map
  578. // it to the RPCable version.
  579. //
  580. if( ARGUMENT_PRESENT( lpSecurityAttributes )) {
  581. pRpcSA = &RpcSA;
  582. Error = MapSAToRpcSA( lpSecurityAttributes, pRpcSA );
  583. if( Error != ERROR_SUCCESS ) {
  584. goto ExitCleanup;
  585. }
  586. } else {
  587. //
  588. // No PSECURITY_ATTRIBUTES argument, therefore no mapping was done.
  589. //
  590. pRpcSA = NULL;
  591. }
  592. if( IsLocalHandle( hKey )) {
  593. Error = (LONG)LocalBaseRegSaveKeyEx(
  594. hKey,
  595. &FileName,
  596. pRpcSA,
  597. Flags
  598. );
  599. } else {
  600. Error = (LONG)BaseRegSaveKeyEx(
  601. DereferenceRemoteHandle( hKey ),
  602. &FileName,
  603. pRpcSA,
  604. Flags
  605. );
  606. }
  607. ExitCleanup:
  608. CLOSE_LOCAL_HANDLE(TempHandle);
  609. return Error;
  610. }