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.

209 lines
4.9 KiB

  1. //depot/Lab04_N/Base/screg/winreg/server/regdkey.c#5 - integrate change 12179 (text)
  2. /*++
  3. Copyright (c) 1991 Microsoft Corporation
  4. Module Name:
  5. Regdkey.c
  6. Abstract:
  7. This module contains the server side implementation for the Win32
  8. Registry API to delete a key. That is:
  9. - BaseRegDeleteKey
  10. Author:
  11. David J. Gilman (davegi) 15-Nov-1991
  12. Notes:
  13. See the Notes in Regkey.c.
  14. --*/
  15. #include <rpc.h>
  16. #include "regrpc.h"
  17. #include "localreg.h"
  18. #include "regclass.h"
  19. #include <malloc.h>
  20. #ifdef LOCAL
  21. #include "tsappcmp.h"
  22. #include <wow64reg.h>
  23. #endif
  24. error_status_t
  25. BaseRegDeleteKey(
  26. HKEY hKey,
  27. PUNICODE_STRING lpSubKey
  28. )
  29. /*++
  30. Routine Description:
  31. Delete a key.
  32. Arguments:
  33. hKey - Supplies a handle to an open key. The lpSubKey pathname
  34. parameter is relative to this key handle. Any of the predefined
  35. reserved handles or a previously opened key handle may be used for
  36. hKey.
  37. lpSubKey - Supplies the downward key path to the key to delete. May
  38. NOT be NULL.
  39. Return Value:
  40. Returns ERROR_SUCCESS (0) for success; error-code for failure.
  41. Notes:
  42. If successful, RegDeleteKey removes the key at the desired location
  43. from the registration database. The entire key, including all of its
  44. values, will be removed. The key to be deleted may NOT have children,
  45. otherwise the call will fail. There must not be any open handles that
  46. refer to the key to be deleted, otherwise the call will fail. DELETE
  47. access to the key being deleted is required.
  48. --*/
  49. {
  50. OBJECT_ATTRIBUTES Obja;
  51. NTSTATUS Status;
  52. NTSTATUS StatusCheck;
  53. HKEY KeyHandle;
  54. BOOL fSafeToDelete;
  55. #ifdef LOCAL
  56. UNICODE_STRING TmpStr = *lpSubKey; //used to keep original SubKey string
  57. #endif //LOCAL
  58. //
  59. // Check for malformed arguments from malicious clients
  60. //
  61. if( (lpSubKey == NULL) ||
  62. (lpSubKey->Length < sizeof(UNICODE_NULL)) ||
  63. (lpSubKey->Buffer == NULL) ||
  64. ((lpSubKey->Length % sizeof(WCHAR)) != 0) ||
  65. (lpSubKey->Buffer[lpSubKey->Length / sizeof(WCHAR) - 1] != L'\0') ) {
  66. return(ERROR_INVALID_PARAMETER);
  67. }
  68. ASSERT( IsPredefinedRegistryHandle( hKey ) == FALSE );
  69. //
  70. // Impersonate the client.
  71. //
  72. RPC_IMPERSONATE_CLIENT( NULL );
  73. //
  74. // Subtract the NULL from the string length. This was added
  75. // by the client so that RPC would transmit the whole thing.
  76. //
  77. lpSubKey->Length -= sizeof( UNICODE_NULL );
  78. #ifdef LOCAL
  79. //
  80. // see if this key is a special key in HKCR
  81. //
  82. if (REG_CLASS_IS_SPECIAL_KEY(hKey) ||
  83. ( (gdwRegistryExtensionFlags & TERMSRV_ENABLE_PER_USER_CLASSES_REDIRECTION)
  84. && ExtractClassKey(&hKey,lpSubKey) ) ) {
  85. //
  86. // if this is a class registration, we call a special routine
  87. // to open this key
  88. //
  89. Status = BaseRegOpenClassKey(
  90. hKey,
  91. lpSubKey,
  92. 0,
  93. MAXIMUM_ALLOWED,
  94. &KeyHandle);
  95. if (!NT_SUCCESS(Status)) {
  96. goto cleanup;
  97. }
  98. } else
  99. #endif // LOCAL
  100. {
  101. //
  102. // Initialize the OBJECT_ATTRIBUTES structure and open the sub key
  103. // so that it can then be deleted.
  104. //
  105. InitializeObjectAttributes(
  106. &Obja,
  107. lpSubKey,
  108. OBJ_CASE_INSENSITIVE,
  109. hKey,
  110. NULL
  111. );
  112. Status = NtOpenKey(
  113. &KeyHandle,
  114. DELETE,
  115. &Obja
  116. );
  117. }
  118. #ifdef LOCAL
  119. if (gpfnTermsrvDeleteKey) {
  120. //
  121. // Remove the key from the Terminal Server registry tracking database
  122. //
  123. gpfnTermsrvDeleteKey(KeyHandle);
  124. }
  125. #endif
  126. //
  127. // If for any reason the key could not be opened, return the error.
  128. //
  129. if( NT_SUCCESS( Status )) {
  130. //
  131. // Call the Nt APIs to delete and close the key.
  132. //
  133. #if defined(_WIN64) & defined ( LOCAL)
  134. HKEY hWowKey = Wow64OpenRemappedKeyOnReflection (KeyHandle);
  135. #endif //wow64 reflection case
  136. Status = NtDeleteKey( KeyHandle );
  137. StatusCheck = NtClose( KeyHandle );
  138. ASSERT( NT_SUCCESS( StatusCheck ));
  139. #if defined(_WIN64) & defined ( LOCAL)
  140. if ( (NT_SUCCESS( Status )) && (hWowKey != NULL))
  141. Wow64RegDeleteKey (hWowKey, NULL);
  142. if (hWowKey != NULL)
  143. NtClose (hWowKey);
  144. #endif //wow64 reflection case
  145. }
  146. #ifdef LOCAL
  147. cleanup:
  148. *lpSubKey = TmpStr;
  149. #endif
  150. RPC_REVERT_TO_SELF();
  151. //
  152. // Map the NTSTATUS code to a Win32 Registry error code and return.
  153. //
  154. return (error_status_t)RtlNtStatusToDosError( Status );
  155. }