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.

796 lines
18 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. NTSTATUS Status;
  168. #if DBG
  169. if ( BreakPointOnEntry ) {
  170. DbgBreakPoint();
  171. }
  172. #endif
  173. //
  174. // Limit the capabilities associated with HKEY_PERFORMANCE_DATA.
  175. //
  176. if( hKey == HKEY_PERFORMANCE_DATA ) {
  177. return ERROR_INVALID_HANDLE;
  178. }
  179. Handle = MapPredefinedHandle( hKey, &TempHandle );
  180. if ( Handle == NULL ) {
  181. Error = ERROR_INVALID_HANDLE;
  182. goto ExitCleanup;
  183. }
  184. //
  185. // Convert the subkey to a counted Unicode string.
  186. // This also acounts for the NULL we are adding at the end
  187. //
  188. Status = RtlInitUnicodeStringEx(&SubKey, lpSubKey);
  189. if( !NT_SUCCESS(Status) ) {
  190. Error = RtlNtStatusToDosError( Status );
  191. goto ExitCleanup;
  192. }
  193. //
  194. // Add the NULL to the length so that RPC will transmit the entire
  195. // thing
  196. //
  197. if ( SubKey.Length > 0 ) {
  198. SubKey.Length += sizeof( UNICODE_NULL );
  199. }
  200. Status = RtlInitUnicodeStringEx(&File, lpFile);
  201. if( !NT_SUCCESS(Status) ) {
  202. Error = RtlNtStatusToDosError( Status );
  203. goto ExitCleanup;
  204. }
  205. //
  206. // Add the NULL to the length so that RPC will transmit the entire
  207. // thing
  208. //
  209. if ( File.Length > 0 ) {
  210. File.Length += sizeof( UNICODE_NULL );
  211. }
  212. //
  213. // Call the server
  214. //
  215. if( IsLocalHandle( Handle )) {
  216. Error = (LONG)LocalBaseRegLoadKey(
  217. Handle,
  218. &SubKey,
  219. &File
  220. );
  221. } else {
  222. Error = (LONG)BaseRegLoadKey(
  223. DereferenceRemoteHandle( Handle ),
  224. &SubKey,
  225. &File
  226. );
  227. }
  228. ExitCleanup:
  229. CLOSE_LOCAL_HANDLE(TempHandle);
  230. return Error;
  231. }
  232. LONG
  233. APIENTRY
  234. RegUnLoadKeyA(
  235. HKEY hKey,
  236. LPCSTR lpSubKey
  237. )
  238. /*++
  239. Routine Description:
  240. Win32 Ansi API for unloading a key.
  241. --*/
  242. {
  243. HKEY Handle;
  244. UNICODE_STRING SubKey;
  245. NTSTATUS NtStatus;
  246. LONG Error;
  247. HKEY TempHandle = NULL;
  248. #if DBG
  249. if ( BreakPointOnEntry ) {
  250. DbgBreakPoint();
  251. }
  252. #endif
  253. //
  254. // Limit the capabilities associated with HKEY_PERFORMANCE_DATA.
  255. //
  256. if( hKey == HKEY_PERFORMANCE_DATA ) {
  257. return ERROR_INVALID_HANDLE;
  258. }
  259. Handle = MapPredefinedHandle( hKey,&TempHandle );
  260. if ( Handle == NULL ) {
  261. Error = ERROR_INVALID_HANDLE;
  262. goto ExitCleanup;
  263. }
  264. //
  265. // Convert the SubKey name to a counted Unicode
  266. //
  267. if( !RtlCreateUnicodeStringFromAsciiz(&SubKey,lpSubKey) ) {
  268. NtStatus = STATUS_NO_MEMORY;
  269. Error = RtlNtStatusToDosError( NtStatus );
  270. goto ExitCleanup;
  271. }
  272. //
  273. // Add the NULL to the length so that RPC will transmit the entire
  274. // thing
  275. //
  276. if ( SubKey.Length > 0 ) {
  277. SubKey.Length += sizeof( UNICODE_NULL );
  278. }
  279. if( IsLocalHandle( Handle )) {
  280. Error = (LONG)LocalBaseRegUnLoadKey(
  281. Handle,
  282. &SubKey
  283. );
  284. } else {
  285. Error = (LONG)BaseRegUnLoadKey(
  286. DereferenceRemoteHandle( Handle ),
  287. &SubKey
  288. );
  289. }
  290. // free the allocated unicode string
  291. RtlFreeUnicodeString( &SubKey );
  292. ExitCleanup:
  293. CLOSE_LOCAL_HANDLE(TempHandle);
  294. return Error;
  295. }
  296. LONG
  297. APIENTRY
  298. RegUnLoadKeyW(
  299. HKEY hKey,
  300. LPCWSTR lpSubKey
  301. )
  302. /*++
  303. Routine Description:
  304. Unload the specified tree (hive) from the Registry.
  305. Arguments:
  306. hKey - Supplies a handle to an open key. lpSubKey is relative to this
  307. handle.
  308. lpSubKey - Supplies a path name to the key that is to be unloaded.
  309. The combination of hKey and lpSubKey must refer to a hive in the
  310. Registry created with RegRestoreKey or RegLoadKey. This parameter may
  311. be NULL.
  312. Return Value:
  313. Returns ERROR_SUCCESS (0) for success; error-code for failure.
  314. RegUnLoadKey requires SeRestorePrivilege.
  315. --*/
  316. {
  317. HKEY Handle;
  318. UNICODE_STRING SubKey;
  319. LONG Error;
  320. HKEY TempHandle = NULL;
  321. NTSTATUS Status;
  322. #if DBG
  323. if ( BreakPointOnEntry ) {
  324. DbgBreakPoint();
  325. }
  326. #endif
  327. //
  328. // Limit the capabilities associated with HKEY_PERFORMANCE_DATA.
  329. //
  330. if( hKey == HKEY_PERFORMANCE_DATA ) {
  331. return ERROR_INVALID_HANDLE;
  332. }
  333. Handle = MapPredefinedHandle( hKey, &TempHandle );
  334. if ( Handle == NULL ) {
  335. Error = ERROR_INVALID_HANDLE;
  336. goto ExitCleanup;
  337. }
  338. Status = RtlInitUnicodeStringEx(&SubKey, lpSubKey);
  339. if( !NT_SUCCESS(Status) ) {
  340. Error = RtlNtStatusToDosError( Status );
  341. goto ExitCleanup;
  342. }
  343. //
  344. // Add the NULL to the length so that RPC will transmit the entire
  345. // thing
  346. //
  347. if ( SubKey.Length > 0 ) {
  348. SubKey.Length += sizeof( UNICODE_NULL );
  349. }
  350. //
  351. // Call the server
  352. //
  353. if( IsLocalHandle( Handle )) {
  354. Error = (LONG)LocalBaseRegUnLoadKey(
  355. Handle,
  356. &SubKey
  357. );
  358. } else {
  359. Error = (LONG)BaseRegUnLoadKey(
  360. DereferenceRemoteHandle( Handle ),
  361. &SubKey
  362. );
  363. }
  364. ExitCleanup:
  365. CLOSE_LOCAL_HANDLE(TempHandle);
  366. return Error;
  367. }
  368. LONG
  369. APIENTRY
  370. RegReplaceKeyA(
  371. HKEY hKey,
  372. LPCSTR lpSubKey,
  373. LPCSTR lpNewFile,
  374. LPCSTR lpOldFile
  375. )
  376. /*++
  377. Routine Description:
  378. Win32 Ansi API for replacing a key.
  379. --*/
  380. {
  381. HKEY Handle;
  382. UNICODE_STRING SubKey;
  383. UNICODE_STRING NewFile;
  384. UNICODE_STRING OldFile;
  385. WCHAR NewUnicodeBuffer[ MAX_PATH ];
  386. WCHAR OldUnicodeBuffer[ MAX_PATH ];
  387. ANSI_STRING AnsiFile;
  388. NTSTATUS NtStatus;
  389. LONG Error;
  390. HKEY TempHandle = NULL;
  391. #if DBG
  392. if ( BreakPointOnEntry ) {
  393. DbgBreakPoint();
  394. }
  395. #endif
  396. //
  397. // Limit the capabilities associated with HKEY_PERFORMANCE_DATA.
  398. //
  399. if( hKey == HKEY_PERFORMANCE_DATA ) {
  400. return ERROR_INVALID_HANDLE;
  401. }
  402. Handle = MapPredefinedHandle( hKey, &TempHandle );
  403. if ( Handle == NULL ) {
  404. Error = ERROR_INVALID_HANDLE;
  405. goto ExitCleanup;
  406. }
  407. //
  408. // Convert the SubKey name to a counted Unicode
  409. //
  410. if( !RtlCreateUnicodeStringFromAsciiz(&SubKey,lpSubKey) ) {
  411. NtStatus = STATUS_NO_MEMORY;
  412. Error = RtlNtStatusToDosError( NtStatus );
  413. goto ExitCleanup;
  414. }
  415. //
  416. // Convert the new file name to a counted Unicode string using the
  417. // Unicode string on the stack.
  418. //
  419. NewFile.Buffer = NewUnicodeBuffer;
  420. NewFile.MaximumLength = sizeof( NewUnicodeBuffer );
  421. RtlInitAnsiString( &AnsiFile, lpNewFile );
  422. NtStatus = RtlAnsiStringToUnicodeString(
  423. &NewFile,
  424. &AnsiFile,
  425. FALSE
  426. );
  427. //
  428. // If the file name could not be converted, map the results and return.
  429. //
  430. if( ! NT_SUCCESS( NtStatus )) {
  431. // free the allocated unicode string
  432. RtlFreeUnicodeString( &SubKey );
  433. Error = RtlNtStatusToDosError( NtStatus );
  434. goto ExitCleanup;
  435. }
  436. //
  437. // Convert the old file name to a counted Unicode string using the
  438. // Unicode string on the stack.
  439. //
  440. OldFile.Buffer = OldUnicodeBuffer;
  441. OldFile.MaximumLength = sizeof( OldUnicodeBuffer );
  442. RtlInitAnsiString( &AnsiFile, lpOldFile );
  443. NtStatus = RtlAnsiStringToUnicodeString(
  444. &OldFile,
  445. &AnsiFile,
  446. FALSE
  447. );
  448. //
  449. // If the file name could not be converted, map the results and return.
  450. //
  451. if( ! NT_SUCCESS( NtStatus )) {
  452. // free the allocated unicode string
  453. RtlFreeUnicodeString( &SubKey );
  454. Error = RtlNtStatusToDosError( NtStatus );
  455. goto ExitCleanup;
  456. }
  457. //
  458. // Add the NULL to the length so that RPC will transmit the entire
  459. // thing
  460. //
  461. if ( SubKey.Length > 0 ) {
  462. SubKey.Length += sizeof( UNICODE_NULL );
  463. }
  464. if ( NewFile.Length > 0 ) {
  465. NewFile.Length += sizeof( UNICODE_NULL );
  466. }
  467. if ( OldFile.Length > 0 ) {
  468. OldFile.Length += sizeof( UNICODE_NULL );
  469. }
  470. //
  471. // Call the server
  472. //
  473. if( IsLocalHandle( Handle )) {
  474. Error = (LONG)LocalBaseRegReplaceKey(
  475. Handle,
  476. &SubKey,
  477. &NewFile,
  478. &OldFile
  479. );
  480. } else {
  481. Error = (LONG)BaseRegReplaceKey(
  482. DereferenceRemoteHandle( Handle ),
  483. &SubKey,
  484. &NewFile,
  485. &OldFile
  486. );
  487. }
  488. // free the allocated unicode string
  489. RtlFreeUnicodeString( &SubKey );
  490. ExitCleanup:
  491. CLOSE_LOCAL_HANDLE(TempHandle);
  492. return Error;
  493. }
  494. LONG
  495. APIENTRY
  496. RegReplaceKeyW(
  497. HKEY hKey,
  498. LPCWSTR lpSubKey,
  499. LPCWSTR lpNewFile,
  500. LPCWSTR lpOldFile
  501. )
  502. /*++
  503. Routine Description:
  504. Replace an existing tree (hive) in the Registry. The new tree will
  505. take effect the next time the system is rebooted.
  506. Arguments:
  507. hKey - Supplies a handle to an open key. lpSubKey is relative to this
  508. handle.
  509. lpSubKey - Supplies a path name to the key that is to be replaced.
  510. The combination of hKey and lpSubKey must refer to a hive in the
  511. Registry. This parameter may be NULL.
  512. lpNewFile - Supplies a file name for the new hive file.
  513. lpOldFile - Supplies a backup file name for the old (existing) hive file.
  514. Return Value:
  515. Returns ERROR_SUCCESS (0) for success; error-code for failure.
  516. Notes:
  517. lpNewFile will remain open until after the system is rebooted.
  518. RegUnLoadKey requires SeRestorePrivilege.
  519. --*/
  520. {
  521. HKEY Handle;
  522. UNICODE_STRING SubKey;
  523. UNICODE_STRING NewFile;
  524. UNICODE_STRING OldFile;
  525. LONG Error;
  526. HKEY TempHandle = NULL;
  527. NTSTATUS Status;
  528. #if DBG
  529. if ( BreakPointOnEntry ) {
  530. DbgBreakPoint();
  531. }
  532. #endif
  533. //
  534. // Limit the capabilities associated with HKEY_PERFORMANCE_DATA.
  535. //
  536. if( hKey == HKEY_PERFORMANCE_DATA ) {
  537. return ERROR_INVALID_HANDLE;
  538. }
  539. Handle = MapPredefinedHandle( hKey, &TempHandle );
  540. if ( Handle == NULL ) {
  541. Error = ERROR_INVALID_HANDLE;
  542. goto ExitCleanup;
  543. }
  544. Status = RtlInitUnicodeStringEx(&SubKey,lpSubKey);
  545. if( !NT_SUCCESS(Status) ) {
  546. Error = RtlNtStatusToDosError( Status );
  547. goto ExitCleanup;
  548. }
  549. Status = RtlInitUnicodeStringEx(&NewFile,lpNewFile);
  550. if( !NT_SUCCESS(Status) ) {
  551. Error = RtlNtStatusToDosError( Status );
  552. goto ExitCleanup;
  553. }
  554. Status = RtlInitUnicodeStringEx(&OldFile,lpOldFile);
  555. if( !NT_SUCCESS(Status) ) {
  556. Error = RtlNtStatusToDosError( Status );
  557. goto ExitCleanup;
  558. }
  559. //
  560. // Add the NULL to the length so that RPC will transmit the entire
  561. // thing
  562. //
  563. if ( SubKey.Length > 0 ) {
  564. SubKey.Length += sizeof( UNICODE_NULL );
  565. }
  566. if ( NewFile.Length > 0 ) {
  567. NewFile.Length += sizeof( UNICODE_NULL );
  568. }
  569. if ( OldFile.Length > 0 ) {
  570. OldFile.Length += sizeof( UNICODE_NULL );
  571. }
  572. //
  573. // Call the server
  574. //
  575. if( IsLocalHandle( Handle )) {
  576. Error = (LONG)LocalBaseRegReplaceKey(
  577. Handle,
  578. &SubKey,
  579. &NewFile,
  580. &OldFile
  581. );
  582. } else {
  583. Error = (LONG)BaseRegReplaceKey(
  584. DereferenceRemoteHandle( Handle ),
  585. &SubKey,
  586. &NewFile,
  587. &OldFile
  588. );
  589. }
  590. ExitCleanup:
  591. CLOSE_LOCAL_HANDLE(TempHandle);
  592. return Error;
  593. }