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.

785 lines
16 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. Reglukey.c
  5. Abstract:
  6. This module contains the client side wrappers for the Win32 Registry
  7. APIs to load, unload and replace keys. That is:
  8. - RegLoadKeyA
  9. - RegLoadKeyW
  10. - RegUnLoadKeyA
  11. - RegUnLoadKeyW
  12. - RegReplaceKeyA
  13. - RegReplaceKeyW
  14. Author:
  15. Ramon J. San Andres (ramonsa) 16-Apr-1992
  16. --*/
  17. #include <rpc.h>
  18. #include "regrpc.h"
  19. #include "client.h"
  20. LONG
  21. APIENTRY
  22. RegLoadKeyA(
  23. HKEY hKey,
  24. LPCSTR lpSubKey,
  25. LPCSTR lpFile
  26. )
  27. /*++
  28. Routine Description:
  29. Win32 Ansi API for loading a key.
  30. --*/
  31. {
  32. HKEY Handle;
  33. UNICODE_STRING SubKey;
  34. UNICODE_STRING File;
  35. WCHAR UnicodeBuffer[ MAX_PATH ];
  36. ANSI_STRING AnsiFile;
  37. NTSTATUS NtStatus;
  38. LONG Error;
  39. HKEY TempHandle = NULL;
  40. #if DBG
  41. // OutputDebugString( "Winreg: Entering RegLoadKeyA\n" );
  42. if ( BreakPointOnEntry ) {
  43. DbgBreakPoint();
  44. }
  45. #endif
  46. //
  47. // Limit the capabilities associated with HKEY_PERFORMANCE_DATA.
  48. //
  49. if( hKey == HKEY_PERFORMANCE_DATA ) {
  50. return ERROR_INVALID_HANDLE;
  51. }
  52. Handle = MapPredefinedHandle( hKey, &TempHandle );
  53. if ( Handle == NULL ) {
  54. Error = ERROR_INVALID_HANDLE;
  55. goto ExitCleanup;
  56. }
  57. //
  58. // Convert the SubKey name to a counted Unicode
  59. //
  60. if( !RtlCreateUnicodeStringFromAsciiz(&SubKey,lpSubKey) ) {
  61. NtStatus = STATUS_NO_MEMORY;
  62. Error = RtlNtStatusToDosError( NtStatus );
  63. goto ExitCleanup;
  64. }
  65. //
  66. // Add the NULL to the length so that RPC will transmit the entire
  67. // thing
  68. //
  69. if ( SubKey.Length > 0 ) {
  70. SubKey.Length += sizeof( UNICODE_NULL );
  71. }
  72. //
  73. // Convert the file name to a counted Unicode string using the
  74. // Unicode string on the stack.
  75. //
  76. File.Buffer = UnicodeBuffer;
  77. File.MaximumLength = sizeof( UnicodeBuffer );
  78. RtlInitAnsiString( &AnsiFile, lpFile );
  79. NtStatus = RtlAnsiStringToUnicodeString(
  80. &File,
  81. &AnsiFile,
  82. FALSE
  83. );
  84. //
  85. // If the file name could not be converted, map the results and return.
  86. //
  87. if( ! NT_SUCCESS( NtStatus )) {
  88. // free the allocated unicode string
  89. RtlFreeUnicodeString( &SubKey );
  90. Error = RtlNtStatusToDosError( NtStatus );
  91. goto ExitCleanup;
  92. }
  93. //
  94. // Add the NULL to the length so that RPC will transmit the entire
  95. // thing
  96. //
  97. if ( File.Length > 0 ) {
  98. File.Length += sizeof( UNICODE_NULL );
  99. }
  100. //
  101. // Call the server
  102. //
  103. if( IsLocalHandle( Handle )) {
  104. Error = (LONG)LocalBaseRegLoadKey(
  105. Handle,
  106. &SubKey,
  107. &File
  108. );
  109. } else {
  110. Error = (LONG)BaseRegLoadKey(
  111. DereferenceRemoteHandle( Handle ),
  112. &SubKey,
  113. &File
  114. );
  115. }
  116. // free the allocated unicode string
  117. RtlFreeUnicodeString( &SubKey );
  118. ExitCleanup:
  119. CLOSE_LOCAL_HANDLE(TempHandle);
  120. return Error;
  121. }
  122. LONG
  123. APIENTRY
  124. RegLoadKeyW(
  125. HKEY hKey,
  126. LPCWSTR lpSubKey,
  127. LPCWSTR lpFile
  128. )
  129. /*++
  130. Routine Description:
  131. Load the tree in the supplied file into the key referenced by the
  132. supplied key handle and sub-key. The loaded tree will overwrite all
  133. of the contents of the supplied sub-key except for its name.
  134. Pictorially, if the file contains:
  135. A
  136. / \
  137. / \
  138. B C
  139. and the supplied key refers to a key name X, the resultant tree would
  140. look like:
  141. X
  142. / \
  143. / \
  144. B C
  145. Arguments:
  146. hKey - Supplies the predefined handle HKEY_USERS or HKEY_LOCAL_MACHINE.
  147. lpSubKey is relative to this handle.
  148. lpSubKey - Supplies a path name to a new (i.e. non-existant) key
  149. where the supplied file will be loaded.
  150. lpFile - Supplies a pointer to an existing file name whose contents was
  151. created with RegSaveKey. The file name may not have an extension.
  152. Return Value:
  153. Returns ERROR_SUCCESS (0) for success; error-code for failure.
  154. Notes:
  155. The difference between RegRestoreKey and RegLoadKey is that in the
  156. latter case the supplied file is used as the actual backing store
  157. whereas in the former case the information in the file is copied into
  158. the Registry.
  159. RegLoadKey requires SeRestorePrivilege.
  160. --*/
  161. {
  162. HKEY Handle;
  163. UNICODE_STRING SubKey;
  164. UNICODE_STRING File;
  165. LONG Error;
  166. HKEY TempHandle = NULL;
  167. #if DBG
  168. if ( BreakPointOnEntry ) {
  169. DbgBreakPoint();
  170. }
  171. #endif
  172. //
  173. // Limit the capabilities associated with HKEY_PERFORMANCE_DATA.
  174. //
  175. if( hKey == HKEY_PERFORMANCE_DATA ) {
  176. return ERROR_INVALID_HANDLE;
  177. }
  178. Handle = MapPredefinedHandle( hKey, &TempHandle );
  179. if ( Handle == NULL ) {
  180. Error = ERROR_INVALID_HANDLE;
  181. goto ExitCleanup;
  182. }
  183. RtlInitUnicodeString(
  184. &SubKey,
  185. lpSubKey
  186. );
  187. //
  188. // Add the NULL to the length so that RPC will transmit the entire
  189. // thing
  190. //
  191. if ( SubKey.Length > 0 ) {
  192. SubKey.Length += sizeof( UNICODE_NULL );
  193. }
  194. RtlInitUnicodeString(
  195. &File,
  196. lpFile
  197. );
  198. //
  199. // Add the NULL to the length so that RPC will transmit the entire
  200. // thing
  201. //
  202. if ( File.Length > 0 ) {
  203. File.Length += sizeof( UNICODE_NULL );
  204. }
  205. //
  206. // Call the server
  207. //
  208. if( IsLocalHandle( Handle )) {
  209. Error = (LONG)LocalBaseRegLoadKey(
  210. Handle,
  211. &SubKey,
  212. &File
  213. );
  214. } else {
  215. Error = (LONG)BaseRegLoadKey(
  216. DereferenceRemoteHandle( Handle ),
  217. &SubKey,
  218. &File
  219. );
  220. }
  221. ExitCleanup:
  222. CLOSE_LOCAL_HANDLE(TempHandle);
  223. return Error;
  224. }
  225. LONG
  226. APIENTRY
  227. RegUnLoadKeyA(
  228. HKEY hKey,
  229. LPCSTR lpSubKey
  230. )
  231. /*++
  232. Routine Description:
  233. Win32 Ansi API for unloading a key.
  234. --*/
  235. {
  236. HKEY Handle;
  237. UNICODE_STRING SubKey;
  238. NTSTATUS NtStatus;
  239. LONG Error;
  240. HKEY TempHandle = NULL;
  241. #if DBG
  242. if ( BreakPointOnEntry ) {
  243. DbgBreakPoint();
  244. }
  245. #endif
  246. //
  247. // Limit the capabilities associated with HKEY_PERFORMANCE_DATA.
  248. //
  249. if( hKey == HKEY_PERFORMANCE_DATA ) {
  250. return ERROR_INVALID_HANDLE;
  251. }
  252. Handle = MapPredefinedHandle( hKey,&TempHandle );
  253. if ( Handle == NULL ) {
  254. Error = ERROR_INVALID_HANDLE;
  255. goto ExitCleanup;
  256. }
  257. //
  258. // Convert the SubKey name to a counted Unicode
  259. //
  260. if( !RtlCreateUnicodeStringFromAsciiz(&SubKey,lpSubKey) ) {
  261. NtStatus = STATUS_NO_MEMORY;
  262. Error = RtlNtStatusToDosError( NtStatus );
  263. goto ExitCleanup;
  264. }
  265. //
  266. // Add the NULL to the length so that RPC will transmit the entire
  267. // thing
  268. //
  269. if ( SubKey.Length > 0 ) {
  270. SubKey.Length += sizeof( UNICODE_NULL );
  271. }
  272. if( IsLocalHandle( Handle )) {
  273. Error = (LONG)LocalBaseRegUnLoadKey(
  274. Handle,
  275. &SubKey
  276. );
  277. } else {
  278. Error = (LONG)BaseRegUnLoadKey(
  279. DereferenceRemoteHandle( Handle ),
  280. &SubKey
  281. );
  282. }
  283. // free the allocated unicode string
  284. RtlFreeUnicodeString( &SubKey );
  285. ExitCleanup:
  286. CLOSE_LOCAL_HANDLE(TempHandle);
  287. return Error;
  288. }
  289. LONG
  290. APIENTRY
  291. RegUnLoadKeyW(
  292. HKEY hKey,
  293. LPCWSTR lpSubKey
  294. )
  295. /*++
  296. Routine Description:
  297. Unload the specified tree (hive) from the Registry.
  298. Arguments:
  299. hKey - Supplies a handle to an open key. lpSubKey is relative to this
  300. handle.
  301. lpSubKey - Supplies a path name to the key that is to be unloaded.
  302. The combination of hKey and lpSubKey must refer to a hive in the
  303. Registry created with RegRestoreKey or RegLoadKey. This parameter may
  304. be NULL.
  305. Return Value:
  306. Returns ERROR_SUCCESS (0) for success; error-code for failure.
  307. RegUnLoadKey requires SeRestorePrivilege.
  308. --*/
  309. {
  310. HKEY Handle;
  311. UNICODE_STRING SubKey;
  312. LONG Error;
  313. HKEY TempHandle = NULL;
  314. #if DBG
  315. if ( BreakPointOnEntry ) {
  316. DbgBreakPoint();
  317. }
  318. #endif
  319. //
  320. // Limit the capabilities associated with HKEY_PERFORMANCE_DATA.
  321. //
  322. if( hKey == HKEY_PERFORMANCE_DATA ) {
  323. return ERROR_INVALID_HANDLE;
  324. }
  325. Handle = MapPredefinedHandle( hKey, &TempHandle );
  326. if ( Handle == NULL ) {
  327. Error = ERROR_INVALID_HANDLE;
  328. goto ExitCleanup;
  329. }
  330. RtlInitUnicodeString(
  331. &SubKey,
  332. lpSubKey
  333. );
  334. //
  335. // Add the NULL to the length so that RPC will transmit the entire
  336. // thing
  337. //
  338. if ( SubKey.Length > 0 ) {
  339. SubKey.Length += sizeof( UNICODE_NULL );
  340. }
  341. //
  342. // Call the server
  343. //
  344. if( IsLocalHandle( Handle )) {
  345. Error = (LONG)LocalBaseRegUnLoadKey(
  346. Handle,
  347. &SubKey
  348. );
  349. } else {
  350. Error = (LONG)BaseRegUnLoadKey(
  351. DereferenceRemoteHandle( Handle ),
  352. &SubKey
  353. );
  354. }
  355. ExitCleanup:
  356. CLOSE_LOCAL_HANDLE(TempHandle);
  357. return Error;
  358. }
  359. LONG
  360. APIENTRY
  361. RegReplaceKeyA(
  362. HKEY hKey,
  363. LPCSTR lpSubKey,
  364. LPCSTR lpNewFile,
  365. LPCSTR lpOldFile
  366. )
  367. /*++
  368. Routine Description:
  369. Win32 Ansi API for replacing a key.
  370. --*/
  371. {
  372. HKEY Handle;
  373. UNICODE_STRING SubKey;
  374. UNICODE_STRING NewFile;
  375. UNICODE_STRING OldFile;
  376. WCHAR NewUnicodeBuffer[ MAX_PATH ];
  377. WCHAR OldUnicodeBuffer[ MAX_PATH ];
  378. ANSI_STRING AnsiFile;
  379. NTSTATUS NtStatus;
  380. LONG Error;
  381. HKEY TempHandle = NULL;
  382. #if DBG
  383. if ( BreakPointOnEntry ) {
  384. DbgBreakPoint();
  385. }
  386. #endif
  387. //
  388. // Limit the capabilities associated with HKEY_PERFORMANCE_DATA.
  389. //
  390. if( hKey == HKEY_PERFORMANCE_DATA ) {
  391. return ERROR_INVALID_HANDLE;
  392. }
  393. Handle = MapPredefinedHandle( hKey, &TempHandle );
  394. if ( Handle == NULL ) {
  395. Error = ERROR_INVALID_HANDLE;
  396. goto ExitCleanup;
  397. }
  398. //
  399. // Convert the SubKey name to a counted Unicode
  400. //
  401. if( !RtlCreateUnicodeStringFromAsciiz(&SubKey,lpSubKey) ) {
  402. NtStatus = STATUS_NO_MEMORY;
  403. Error = RtlNtStatusToDosError( NtStatus );
  404. goto ExitCleanup;
  405. }
  406. //
  407. // Convert the new file name to a counted Unicode string using the
  408. // Unicode string on the stack.
  409. //
  410. NewFile.Buffer = NewUnicodeBuffer;
  411. NewFile.MaximumLength = sizeof( NewUnicodeBuffer );
  412. RtlInitAnsiString( &AnsiFile, lpNewFile );
  413. NtStatus = RtlAnsiStringToUnicodeString(
  414. &NewFile,
  415. &AnsiFile,
  416. FALSE
  417. );
  418. //
  419. // If the file name could not be converted, map the results and return.
  420. //
  421. if( ! NT_SUCCESS( NtStatus )) {
  422. // free the allocated unicode string
  423. RtlFreeUnicodeString( &SubKey );
  424. Error = RtlNtStatusToDosError( NtStatus );
  425. goto ExitCleanup;
  426. }
  427. //
  428. // Convert the old file name to a counted Unicode string using the
  429. // Unicode string on the stack.
  430. //
  431. OldFile.Buffer = OldUnicodeBuffer;
  432. OldFile.MaximumLength = sizeof( OldUnicodeBuffer );
  433. RtlInitAnsiString( &AnsiFile, lpOldFile );
  434. NtStatus = RtlAnsiStringToUnicodeString(
  435. &OldFile,
  436. &AnsiFile,
  437. FALSE
  438. );
  439. //
  440. // If the file name could not be converted, map the results and return.
  441. //
  442. if( ! NT_SUCCESS( NtStatus )) {
  443. // free the allocated unicode string
  444. RtlFreeUnicodeString( &SubKey );
  445. Error = RtlNtStatusToDosError( NtStatus );
  446. goto ExitCleanup;
  447. }
  448. //
  449. // Add the NULL to the length so that RPC will transmit the entire
  450. // thing
  451. //
  452. if ( SubKey.Length > 0 ) {
  453. SubKey.Length += sizeof( UNICODE_NULL );
  454. }
  455. if ( NewFile.Length > 0 ) {
  456. NewFile.Length += sizeof( UNICODE_NULL );
  457. }
  458. if ( OldFile.Length > 0 ) {
  459. OldFile.Length += sizeof( UNICODE_NULL );
  460. }
  461. //
  462. // Call the server
  463. //
  464. if( IsLocalHandle( Handle )) {
  465. Error = (LONG)LocalBaseRegReplaceKey(
  466. Handle,
  467. &SubKey,
  468. &NewFile,
  469. &OldFile
  470. );
  471. } else {
  472. Error = (LONG)BaseRegReplaceKey(
  473. DereferenceRemoteHandle( Handle ),
  474. &SubKey,
  475. &NewFile,
  476. &OldFile
  477. );
  478. }
  479. // free the allocated unicode string
  480. RtlFreeUnicodeString( &SubKey );
  481. ExitCleanup:
  482. CLOSE_LOCAL_HANDLE(TempHandle);
  483. return Error;
  484. }
  485. LONG
  486. APIENTRY
  487. RegReplaceKeyW(
  488. HKEY hKey,
  489. LPCWSTR lpSubKey,
  490. LPCWSTR lpNewFile,
  491. LPCWSTR lpOldFile
  492. )
  493. /*++
  494. Routine Description:
  495. Replace an existing tree (hive) in the Registry. The new tree will
  496. take effect the next time the system is rebooted.
  497. Arguments:
  498. hKey - Supplies a handle to an open key. lpSubKey is relative to this
  499. handle.
  500. lpSubKey - Supplies a path name to the key that is to be replaced.
  501. The combination of hKey and lpSubKey must refer to a hive in the
  502. Registry. This parameter may be NULL.
  503. lpNewFile - Supplies a file name for the new hive file.
  504. lpOldFile - Supplies a backup file name for the old (existing) hive file.
  505. Return Value:
  506. Returns ERROR_SUCCESS (0) for success; error-code for failure.
  507. Notes:
  508. lpNewFile will remain open until after the system is rebooted.
  509. RegUnLoadKey requires SeRestorePrivilege.
  510. --*/
  511. {
  512. HKEY Handle;
  513. UNICODE_STRING SubKey;
  514. UNICODE_STRING NewFile;
  515. UNICODE_STRING OldFile;
  516. LONG Error;
  517. HKEY TempHandle = NULL;
  518. #if DBG
  519. if ( BreakPointOnEntry ) {
  520. DbgBreakPoint();
  521. }
  522. #endif
  523. //
  524. // Limit the capabilities associated with HKEY_PERFORMANCE_DATA.
  525. //
  526. if( hKey == HKEY_PERFORMANCE_DATA ) {
  527. return ERROR_INVALID_HANDLE;
  528. }
  529. Handle = MapPredefinedHandle( hKey, &TempHandle );
  530. if ( Handle == NULL ) {
  531. Error = ERROR_INVALID_HANDLE;
  532. goto ExitCleanup;
  533. }
  534. RtlInitUnicodeString(
  535. &SubKey,
  536. lpSubKey
  537. );
  538. RtlInitUnicodeString(
  539. &NewFile,
  540. lpNewFile
  541. );
  542. RtlInitUnicodeString(
  543. &OldFile,
  544. lpOldFile
  545. );
  546. //
  547. // Add the NULL to the length so that RPC will transmit the entire
  548. // thing
  549. //
  550. if ( SubKey.Length > 0 ) {
  551. SubKey.Length += sizeof( UNICODE_NULL );
  552. }
  553. if ( NewFile.Length > 0 ) {
  554. NewFile.Length += sizeof( UNICODE_NULL );
  555. }
  556. if ( OldFile.Length > 0 ) {
  557. OldFile.Length += sizeof( UNICODE_NULL );
  558. }
  559. //
  560. // Call the server
  561. //
  562. if( IsLocalHandle( Handle )) {
  563. Error = (LONG)LocalBaseRegReplaceKey(
  564. Handle,
  565. &SubKey,
  566. &NewFile,
  567. &OldFile
  568. );
  569. } else {
  570. Error = (LONG)BaseRegReplaceKey(
  571. DereferenceRemoteHandle( Handle ),
  572. &SubKey,
  573. &NewFile,
  574. &OldFile
  575. );
  576. }
  577. ExitCleanup:
  578. CLOSE_LOCAL_HANDLE(TempHandle);
  579. return Error;
  580. }