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.

130 lines
3.1 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. cmquery.c
  5. Abstract:
  6. This module contains the object name query method for the registry.
  7. Author:
  8. Bryan M. Willman (bryanwi) 8-Apr-1992
  9. Revision History:
  10. --*/
  11. #include "cmp.h"
  12. #ifdef ALLOC_PRAGMA
  13. #pragma alloc_text(PAGE,CmpQueryKeyName)
  14. #endif
  15. NTSTATUS
  16. CmpQueryKeyName(
  17. IN PVOID Object,
  18. IN BOOLEAN HasObjectName,
  19. OUT POBJECT_NAME_INFORMATION ObjectNameInfo,
  20. IN ULONG Length,
  21. OUT PULONG ReturnLength
  22. )
  23. /*++
  24. Routine Description:
  25. This routine interfaces to the NT Object Manager. It is invoked when
  26. the object system wishes to discover the name of an object that
  27. belongs to the registry.
  28. Arguments:
  29. Object - pointer to a Key, thus -> KEY_BODY.
  30. HasObjectName - indicates whether the object manager knows about a name
  31. for this object
  32. ObjectNameInfo - place where we report the name
  33. Length - maximum length they can deal with
  34. ReturnLength - supplies variable to receive actual length
  35. Return Value:
  36. STATUS_SUCCESS
  37. STATUS_INFO_LENGTH_MISMATCH
  38. --*/
  39. {
  40. PUNICODE_STRING Name;
  41. PWCHAR t;
  42. PWCHAR s;
  43. ULONG l;
  44. NTSTATUS status;
  45. UNREFERENCED_PARAMETER(HasObjectName);
  46. CmKdPrintEx((DPFLTR_CONFIG_ID,CML_PARSE,"CmpQueryKeyName:\n"));
  47. CmpLockRegistry();
  48. if ( ((PCM_KEY_BODY)Object)->KeyControlBlock->Delete) {
  49. CmpUnlockRegistry();
  50. return STATUS_KEY_DELETED;
  51. }
  52. Name = CmpConstructName(((PCM_KEY_BODY)Object)->KeyControlBlock);
  53. if (Name == NULL) {
  54. status = STATUS_INSUFFICIENT_RESOURCES;
  55. CmpUnlockRegistry();
  56. return status;
  57. }
  58. if (Length <= sizeof(OBJECT_NAME_INFORMATION)) {
  59. *ReturnLength = Name->Length + sizeof(WCHAR) + sizeof(OBJECT_NAME_INFORMATION);
  60. ExFreePoolWithTag(Name, CM_NAME_TAG | PROTECTED_POOL);
  61. CmpUnlockRegistry();
  62. return STATUS_INFO_LENGTH_MISMATCH; // they can't even handle null
  63. }
  64. t = (PWCHAR)(ObjectNameInfo + 1);
  65. s = Name->Buffer;
  66. l = Name->Length;
  67. l += sizeof(WCHAR); // account for null
  68. *ReturnLength = l + sizeof(OBJECT_NAME_INFORMATION);
  69. if (l > Length - sizeof(OBJECT_NAME_INFORMATION)) {
  70. l = Length - sizeof(OBJECT_NAME_INFORMATION);
  71. status = STATUS_INFO_LENGTH_MISMATCH;
  72. } else {
  73. status = STATUS_SUCCESS;
  74. }
  75. l -= sizeof(WCHAR);
  76. //
  77. // The ObjectNameInfo buffer is a usermode buffer, so make sure we have an
  78. // exception handler in case a malicious app changes the protection out from
  79. // under us.
  80. //
  81. // Note the object manager is responsible for probing the buffer and ensuring
  82. // that a top-level exception handler returns the correct error code. We just
  83. // need to make sure we drop our lock.
  84. //
  85. try {
  86. RtlCopyMemory(t, s, l);
  87. t[l/sizeof(WCHAR)] = UNICODE_NULL;
  88. ObjectNameInfo->Name.Length = (USHORT)l;
  89. ObjectNameInfo->Name.MaximumLength = ObjectNameInfo->Name.Length;
  90. ObjectNameInfo->Name.Buffer = t;
  91. } finally {
  92. ExFreePoolWithTag(Name, CM_NAME_TAG | PROTECTED_POOL);
  93. CmpUnlockRegistry();
  94. }
  95. return status;
  96. }