Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

885 lines
21 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. NTSTATUS Status;
  150. #if DBG
  151. if ( BreakPointOnEntry ) {
  152. DbgBreakPoint();
  153. }
  154. #endif
  155. ASSERT( lpFile != NULL );
  156. //
  157. // Limit the capabilities associated with HKEY_PERFORMANCE_DATA.
  158. //
  159. if( hKey == HKEY_PERFORMANCE_DATA ) {
  160. return ERROR_INVALID_HANDLE;
  161. }
  162. hKey = MapPredefinedHandle( hKey, &TempHandle );
  163. if( hKey == NULL ) {
  164. Error = ERROR_INVALID_HANDLE;
  165. goto ExitCleanup;
  166. }
  167. Status = RtlInitUnicodeStringEx(&FileName, lpFile);
  168. if( !NT_SUCCESS(Status) ) {
  169. Error = RtlNtStatusToDosError( Status );
  170. goto ExitCleanup;
  171. }
  172. //
  173. // Add the NULL to the length so that RPC will transmit the entire
  174. // thing
  175. //
  176. if ( FileName.Length > 0 ) {
  177. FileName.Length += sizeof( UNICODE_NULL );
  178. }
  179. if( IsLocalHandle( hKey )) {
  180. Error = (LONG)LocalBaseRegRestoreKey(
  181. hKey,
  182. &FileName,
  183. dwFlags
  184. );
  185. } else {
  186. Error = (LONG)BaseRegRestoreKey(
  187. DereferenceRemoteHandle( hKey ),
  188. &FileName,
  189. dwFlags
  190. );
  191. }
  192. ExitCleanup:
  193. CLOSE_LOCAL_HANDLE(TempHandle);
  194. return Error;
  195. }
  196. LONG
  197. APIENTRY
  198. RegSaveKeyA (
  199. HKEY hKey,
  200. LPCSTR lpFile,
  201. LPSECURITY_ATTRIBUTES lpSecurityAttributes
  202. )
  203. /*++
  204. Routine Description:
  205. Win32 ANSI wrapper to RegSaveKeyW.
  206. Save the key (and all of its decsendants) to the non-existant file
  207. named by the supplied string.
  208. Arguments:
  209. hKey - Supplies a handle to the key where the save operation is to
  210. begin.
  211. lpFile - Supplies a pointer to a non-existant file name where the tree
  212. rooted at the supplied key handle will be saved.
  213. lpSecurityAttributes - Supplies an optional pointer to a
  214. SECURITY_ATTRIBUTES structure for the newly created file.
  215. Return Value:
  216. Returns ERROR_SUCCESS (0) for success; error-code for failure.
  217. --*/
  218. {
  219. PUNICODE_STRING FileName;
  220. ANSI_STRING AnsiString;
  221. NTSTATUS Status;
  222. PRPC_SECURITY_ATTRIBUTES pRpcSA;
  223. RPC_SECURITY_ATTRIBUTES RpcSA;
  224. LONG Error;
  225. HKEY TempHandle = NULL;
  226. #if DBG
  227. if ( BreakPointOnEntry ) {
  228. DbgBreakPoint();
  229. }
  230. #endif
  231. ASSERT( lpFile != NULL );
  232. //
  233. // Limit the capabilities associated with HKEY_PERFORMANCE_DATA.
  234. //
  235. if( hKey == HKEY_PERFORMANCE_DATA ) {
  236. return ERROR_INVALID_HANDLE;
  237. }
  238. //
  239. // Note that we must map the handle here even though RegSaveKeyW
  240. // will map it again. This is so that the second map will not
  241. // overwrite the static Unicode string in the TEB that will
  242. // contain the file name.
  243. //
  244. hKey = MapPredefinedHandle( hKey, &TempHandle );
  245. if( hKey == NULL ) {
  246. Error = ERROR_INVALID_HANDLE;
  247. goto ExitCleanup;
  248. }
  249. //
  250. // Convert the file name to a counted Unicode string using the static
  251. // Unicode string in the TEB.
  252. //
  253. FileName = &NtCurrentTeb( )->StaticUnicodeString;
  254. ASSERT( FileName != NULL );
  255. RtlInitAnsiString( &AnsiString, lpFile );
  256. Status = RtlAnsiStringToUnicodeString(
  257. FileName,
  258. &AnsiString,
  259. FALSE
  260. );
  261. //
  262. // If the file name could not be converted, map the results and return.
  263. //
  264. if( ! NT_SUCCESS( Status )) {
  265. Error = RtlNtStatusToDosError( Status );
  266. goto ExitCleanup;
  267. }
  268. //
  269. // Add the NULL to the length so that RPC will transmit the entire
  270. // thing
  271. //
  272. if ( FileName->Length > 0 ) {
  273. FileName->Length += sizeof( UNICODE_NULL );
  274. }
  275. //
  276. // If the caller supplied a LPSECURITY_ATTRIBUTES argument, map
  277. // it to the RPCable version.
  278. //
  279. if( ARGUMENT_PRESENT( lpSecurityAttributes )) {
  280. pRpcSA = &RpcSA;
  281. Error = MapSAToRpcSA( lpSecurityAttributes, pRpcSA );
  282. if( Error != ERROR_SUCCESS ) {
  283. goto ExitCleanup;
  284. }
  285. } else {
  286. //
  287. // No PSECURITY_ATTRIBUTES argument, therefore no mapping was done.
  288. //
  289. pRpcSA = NULL;
  290. }
  291. if( IsLocalHandle( hKey )) {
  292. Error = (LONG)LocalBaseRegSaveKey(
  293. hKey,
  294. FileName,
  295. pRpcSA
  296. );
  297. } else {
  298. Error = (LONG)BaseRegSaveKey(
  299. DereferenceRemoteHandle( hKey ),
  300. FileName,
  301. pRpcSA
  302. );
  303. }
  304. //
  305. // Free the RPC_SECURITY_DESCRIPTOR buffer and return the
  306. //
  307. if( pRpcSA != NULL ) {
  308. RtlFreeHeap(
  309. RtlProcessHeap( ), 0,
  310. pRpcSA->RpcSecurityDescriptor.lpSecurityDescriptor
  311. );
  312. }
  313. ExitCleanup:
  314. CLOSE_LOCAL_HANDLE(TempHandle);
  315. return Error;
  316. }
  317. LONG
  318. APIENTRY
  319. RegSaveKeyW (
  320. HKEY hKey,
  321. LPCWSTR lpFile,
  322. LPSECURITY_ATTRIBUTES lpSecurityAttributes
  323. )
  324. /*++
  325. Routine Description:
  326. Save the key (and all of its decsendants) to the non-existant file
  327. named by the supplied string.
  328. Arguments:
  329. hKey - Supplies a handle to the key where the save operation is to
  330. begin.
  331. lpFile - Supplies a pointer to a non-existant file name where the tree
  332. rooted at the supplied key handle will be saved.
  333. lpSecurityAttributes - Supplies an optional pointer to a
  334. SECURITY_ATTRIBUTES structure for the newly created file.
  335. Return Value:
  336. Returns ERROR_SUCCESS (0) for success; error-code for failure.
  337. --*/
  338. {
  339. UNICODE_STRING FileName;
  340. PRPC_SECURITY_ATTRIBUTES pRpcSA;
  341. RPC_SECURITY_ATTRIBUTES RpcSA;
  342. LONG Error;
  343. HKEY TempHandle = NULL;
  344. NTSTATUS Status;
  345. #if DBG
  346. if ( BreakPointOnEntry ) {
  347. DbgBreakPoint();
  348. }
  349. #endif
  350. ASSERT( lpFile != NULL );
  351. //
  352. // Limit the capabilities associated with HKEY_PERFORMANCE_DATA.
  353. //
  354. if( hKey == HKEY_PERFORMANCE_DATA ) {
  355. return ERROR_INVALID_HANDLE;
  356. }
  357. //
  358. // Note that we must map the handle here even though RegSaveKeyW
  359. // will map it again. This is so that the second map will not
  360. // overwrite the static Unicode string in the TEB that will
  361. // contain the file name.
  362. //
  363. hKey = MapPredefinedHandle( hKey, &TempHandle );
  364. if( hKey == NULL ) {
  365. Error = ERROR_INVALID_HANDLE;
  366. goto ExitCleanup;
  367. }
  368. Status = RtlInitUnicodeStringEx(&FileName, lpFile);
  369. if( !NT_SUCCESS(Status) ) {
  370. Error = RtlNtStatusToDosError( Status );
  371. goto ExitCleanup;
  372. }
  373. //
  374. // Add the NULL to the length so that RPC will transmit the entire
  375. // thing
  376. //
  377. if ( FileName.Length > 0 ) {
  378. FileName.Length += sizeof( UNICODE_NULL );
  379. }
  380. //
  381. // If the caller supplied a LPSECURITY_ATTRIBUTES argument, map
  382. // it to the RPCable version.
  383. //
  384. if( ARGUMENT_PRESENT( lpSecurityAttributes )) {
  385. pRpcSA = &RpcSA;
  386. Error = MapSAToRpcSA( lpSecurityAttributes, pRpcSA );
  387. if( Error != ERROR_SUCCESS ) {
  388. goto ExitCleanup;
  389. }
  390. } else {
  391. //
  392. // No PSECURITY_ATTRIBUTES argument, therefore no mapping was done.
  393. //
  394. pRpcSA = NULL;
  395. }
  396. if( IsLocalHandle( hKey )) {
  397. Error = (LONG)LocalBaseRegSaveKey(
  398. hKey,
  399. &FileName,
  400. pRpcSA
  401. );
  402. } else {
  403. Error = (LONG)BaseRegSaveKey(
  404. DereferenceRemoteHandle( hKey ),
  405. &FileName,
  406. pRpcSA
  407. );
  408. }
  409. //
  410. // Free the RPC_SECURITY_DESCRIPTOR buffer and return the
  411. //
  412. if( pRpcSA != NULL ) {
  413. RtlFreeHeap(
  414. RtlProcessHeap( ), 0,
  415. pRpcSA->RpcSecurityDescriptor.lpSecurityDescriptor
  416. );
  417. }
  418. ExitCleanup:
  419. CLOSE_LOCAL_HANDLE(TempHandle);
  420. return Error;
  421. }
  422. LONG
  423. APIENTRY
  424. RegSaveKeyExA (
  425. HKEY hKey,
  426. LPCSTR lpFile,
  427. LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  428. DWORD Flags
  429. )
  430. /*++
  431. Routine Description:
  432. Win32 ANSI wrapper to RegSaveKeyExW.
  433. Save the key (and all of its decsendants) to the non-existant file
  434. named by the supplied string.
  435. Arguments:
  436. hKey - Supplies a handle to the key where the save operation is to
  437. begin.
  438. lpFile - Supplies a pointer to a non-existant file name where the tree
  439. rooted at the supplied key handle will be saved.
  440. lpSecurityAttributes - Supplies an optional pointer to a
  441. SECURITY_ATTRIBUTES structure for the newly created file.
  442. Return Value:
  443. Returns ERROR_SUCCESS (0) for success; error-code for failure.
  444. --*/
  445. {
  446. PUNICODE_STRING FileName;
  447. ANSI_STRING AnsiString;
  448. NTSTATUS Status;
  449. PRPC_SECURITY_ATTRIBUTES pRpcSA;
  450. RPC_SECURITY_ATTRIBUTES RpcSA;
  451. LONG Error;
  452. HKEY TempHandle = NULL;
  453. #if DBG
  454. if ( BreakPointOnEntry ) {
  455. DbgBreakPoint();
  456. }
  457. #endif
  458. ASSERT( lpFile != NULL );
  459. //
  460. // Limit the capabilities associated with HKEY_PERFORMANCE_DATA.
  461. //
  462. if( hKey == HKEY_PERFORMANCE_DATA ) {
  463. return ERROR_INVALID_HANDLE;
  464. }
  465. //
  466. // Note that we must map the handle here even though RegSaveKeyW
  467. // will map it again. This is so that the second map will not
  468. // overwrite the static Unicode string in the TEB that will
  469. // contain the file name.
  470. //
  471. hKey = MapPredefinedHandle( hKey, &TempHandle );
  472. if( hKey == NULL ) {
  473. Error = ERROR_INVALID_HANDLE;
  474. goto ExitCleanup;
  475. }
  476. //
  477. // Convert the file name to a counted Unicode string using the static
  478. // Unicode string in the TEB.
  479. //
  480. FileName = &NtCurrentTeb( )->StaticUnicodeString;
  481. ASSERT( FileName != NULL );
  482. RtlInitAnsiString( &AnsiString, lpFile );
  483. Status = RtlAnsiStringToUnicodeString(
  484. FileName,
  485. &AnsiString,
  486. FALSE
  487. );
  488. //
  489. // If the file name could not be converted, map the results and return.
  490. //
  491. if( ! NT_SUCCESS( Status )) {
  492. Error = RtlNtStatusToDosError( Status );
  493. goto ExitCleanup;
  494. }
  495. //
  496. // Add the NULL to the length so that RPC will transmit the entire
  497. // thing
  498. //
  499. if ( FileName->Length > 0 ) {
  500. FileName->Length += sizeof( UNICODE_NULL );
  501. }
  502. //
  503. // If the caller supplied a LPSECURITY_ATTRIBUTES argument, map
  504. // it to the RPCable version.
  505. //
  506. if( ARGUMENT_PRESENT( lpSecurityAttributes )) {
  507. pRpcSA = &RpcSA;
  508. Error = MapSAToRpcSA( lpSecurityAttributes, pRpcSA );
  509. if( Error != ERROR_SUCCESS ) {
  510. goto ExitCleanup;
  511. }
  512. } else {
  513. //
  514. // No PSECURITY_ATTRIBUTES argument, therefore no mapping was done.
  515. //
  516. pRpcSA = NULL;
  517. }
  518. if( IsLocalHandle( hKey )) {
  519. Error = (LONG)LocalBaseRegSaveKeyEx(
  520. hKey,
  521. FileName,
  522. pRpcSA,
  523. Flags
  524. );
  525. } else {
  526. Error = (LONG)BaseRegSaveKeyEx(
  527. DereferenceRemoteHandle( hKey ),
  528. FileName,
  529. pRpcSA,
  530. Flags
  531. );
  532. }
  533. //
  534. // Free the RPC_SECURITY_DESCRIPTOR buffer and return the
  535. //
  536. if( pRpcSA != NULL ) {
  537. RtlFreeHeap(
  538. RtlProcessHeap( ), 0,
  539. pRpcSA->RpcSecurityDescriptor.lpSecurityDescriptor
  540. );
  541. }
  542. ExitCleanup:
  543. CLOSE_LOCAL_HANDLE(TempHandle);
  544. return Error;
  545. }
  546. LONG
  547. APIENTRY
  548. RegSaveKeyExW (
  549. HKEY hKey,
  550. LPCWSTR lpFile,
  551. LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  552. DWORD Flags
  553. )
  554. /*++
  555. Routine Description:
  556. Save the key (and all of its decsendants) to the non-existant file
  557. named by the supplied string.
  558. This variant is used by setup in order to create a hive in the latest
  559. format. Helps creating hives in %systemroot%\system32\config in the
  560. latest (presumably the best) format, and allows RegSaveKey to use the
  561. standard format (bacward compatible) for roaming profiles and tools
  562. using registry hives on downlevel OSes.
  563. Arguments:
  564. hKey - Supplies a handle to the key where the save operation is to
  565. begin.
  566. lpFile - Supplies a pointer to a non-existant file name where the tree
  567. rooted at the supplied key handle will be saved.
  568. lpSecurityAttributes - Supplies an optional pointer to a
  569. SECURITY_ATTRIBUTES structure for the newly created file.
  570. Flags - [REG_STANDARD_FORMAT] - roaming format
  571. [REG_LATEST_FORMAT] - latest format
  572. [REG_NO_COMPRESSION] - no hive compression : faster
  573. Return Value:
  574. Returns ERROR_SUCCESS (0) for success; error-code for failure.
  575. --*/
  576. {
  577. UNICODE_STRING FileName;
  578. PRPC_SECURITY_ATTRIBUTES pRpcSA;
  579. RPC_SECURITY_ATTRIBUTES RpcSA;
  580. LONG Error;
  581. HKEY TempHandle = NULL;
  582. NTSTATUS Status;
  583. #if DBG
  584. if ( BreakPointOnEntry ) {
  585. DbgBreakPoint();
  586. }
  587. #endif
  588. ASSERT( lpFile != NULL );
  589. //
  590. // Limit the capabilities associated with HKEY_PERFORMANCE_DATA.
  591. //
  592. if( hKey == HKEY_PERFORMANCE_DATA ) {
  593. return ERROR_INVALID_HANDLE;
  594. }
  595. //
  596. // Note that we must map the handle here even though RegSaveKeyW
  597. // will map it again. This is so that the second map will not
  598. // overwrite the static Unicode string in the TEB that will
  599. // contain the file name.
  600. //
  601. hKey = MapPredefinedHandle( hKey, &TempHandle );
  602. if( hKey == NULL ) {
  603. Error = ERROR_INVALID_HANDLE;
  604. goto ExitCleanup;
  605. }
  606. Status = RtlInitUnicodeStringEx(&FileName, lpFile);
  607. if( !NT_SUCCESS(Status) ) {
  608. Error = RtlNtStatusToDosError( Status );
  609. goto ExitCleanup;
  610. }
  611. //
  612. // Add the NULL to the length so that RPC will transmit the entire
  613. // thing
  614. //
  615. if ( FileName.Length > 0 ) {
  616. FileName.Length += sizeof( UNICODE_NULL );
  617. }
  618. //
  619. // If the caller supplied a LPSECURITY_ATTRIBUTES argument, map
  620. // it to the RPCable version.
  621. //
  622. if( ARGUMENT_PRESENT( lpSecurityAttributes )) {
  623. pRpcSA = &RpcSA;
  624. Error = MapSAToRpcSA( lpSecurityAttributes, pRpcSA );
  625. if( Error != ERROR_SUCCESS ) {
  626. goto ExitCleanup;
  627. }
  628. } else {
  629. //
  630. // No PSECURITY_ATTRIBUTES argument, therefore no mapping was done.
  631. //
  632. pRpcSA = NULL;
  633. }
  634. if( IsLocalHandle( hKey )) {
  635. Error = (LONG)LocalBaseRegSaveKeyEx(
  636. hKey,
  637. &FileName,
  638. pRpcSA,
  639. Flags
  640. );
  641. } else {
  642. Error = (LONG)BaseRegSaveKeyEx(
  643. DereferenceRemoteHandle( hKey ),
  644. &FileName,
  645. pRpcSA,
  646. Flags
  647. );
  648. }
  649. //
  650. // Free the RPC_SECURITY_DESCRIPTOR buffer and return the
  651. //
  652. if( pRpcSA != NULL ) {
  653. RtlFreeHeap(
  654. RtlProcessHeap( ), 0,
  655. pRpcSA->RpcSecurityDescriptor.lpSecurityDescriptor
  656. );
  657. }
  658. ExitCleanup:
  659. CLOSE_LOCAL_HANDLE(TempHandle);
  660. return Error;
  661. }