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.

140 lines
3.6 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. IN KPROCESSOR_MODE Mode
  23. )
  24. /*++
  25. Routine Description:
  26. This routine interfaces to the NT Object Manager. It is invoked when
  27. the object system wishes to discover the name of an object that
  28. belongs to the registry.
  29. Arguments:
  30. Object - pointer to a Key, thus -> KEY_BODY.
  31. HasObjectName - indicates whether the object manager knows about a name
  32. for this object
  33. ObjectNameInfo - place where we report the name
  34. Length - maximum length they can deal with
  35. ReturnLength - supplies variable to receive actual length
  36. Mode - Processor mode of the caller
  37. Return Value:
  38. STATUS_SUCCESS
  39. STATUS_INFO_LENGTH_MISMATCH
  40. --*/
  41. {
  42. PUNICODE_STRING Name;
  43. PWCHAR t;
  44. PWCHAR s;
  45. ULONG l;
  46. NTSTATUS status;
  47. UNREFERENCED_PARAMETER(HasObjectName);
  48. UNREFERENCED_PARAMETER(Mode);
  49. CmKdPrintEx((DPFLTR_CONFIG_ID,CML_PARSE,"CmpQueryKeyName:\n"));
  50. CmpLockRegistry();
  51. if ( ((PCM_KEY_BODY)Object)->KeyControlBlock->Delete) {
  52. CmpUnlockRegistry();
  53. return STATUS_KEY_DELETED;
  54. }
  55. Name = CmpConstructName(((PCM_KEY_BODY)Object)->KeyControlBlock);
  56. if (Name == NULL) {
  57. status = STATUS_INSUFFICIENT_RESOURCES;
  58. CmpUnlockRegistry();
  59. return status;
  60. }
  61. if (Length <= sizeof(OBJECT_NAME_INFORMATION)) {
  62. *ReturnLength = Name->Length + sizeof(WCHAR) + sizeof(OBJECT_NAME_INFORMATION);
  63. ExFreePoolWithTag(Name, CM_NAME_TAG | PROTECTED_POOL);
  64. CmpUnlockRegistry();
  65. return STATUS_INFO_LENGTH_MISMATCH; // they can't even handle null
  66. }
  67. t = (PWCHAR)(ObjectNameInfo + 1);
  68. s = Name->Buffer;
  69. l = Name->Length;
  70. l += sizeof(WCHAR); // account for null
  71. *ReturnLength = l + sizeof(OBJECT_NAME_INFORMATION);
  72. if (l > Length - sizeof(OBJECT_NAME_INFORMATION)) {
  73. l = Length - sizeof(OBJECT_NAME_INFORMATION);
  74. status = STATUS_INFO_LENGTH_MISMATCH;
  75. if( l < sizeof(WCHAR) ) {
  76. ExFreePoolWithTag(Name, CM_NAME_TAG | PROTECTED_POOL);
  77. CmpUnlockRegistry();
  78. return status; // they can't even handle null
  79. }
  80. } else {
  81. status = STATUS_SUCCESS;
  82. }
  83. l -= sizeof(WCHAR);
  84. //
  85. // The ObjectNameInfo buffer is a usermode buffer, so make sure we have an
  86. // exception handler in case a malicious app changes the protection out from
  87. // under us.
  88. //
  89. // Note the object manager is responsible for probing the buffer and ensuring
  90. // that a top-level exception handler returns the correct error code. We just
  91. // need to make sure we drop our lock.
  92. //
  93. try {
  94. RtlCopyMemory(t, s, l);
  95. t[l/sizeof(WCHAR)] = UNICODE_NULL;
  96. ObjectNameInfo->Name.Length = (USHORT)l;
  97. ObjectNameInfo->Name.MaximumLength = ObjectNameInfo->Name.Length;
  98. ObjectNameInfo->Name.Buffer = t;
  99. } finally {
  100. ExFreePoolWithTag(Name, CM_NAME_TAG | PROTECTED_POOL);
  101. CmpUnlockRegistry();
  102. }
  103. return status;
  104. }