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.

137 lines
3.8 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. cmclose.c
  5. Abstract:
  6. This module contains the close object method.
  7. Author:
  8. Bryan M. Willman (bryanwi) 07-Jan-92
  9. Revision History:
  10. --*/
  11. #include "cmp.h"
  12. VOID
  13. CmpDelayedDerefKeys(
  14. PLIST_ENTRY DelayedDeref
  15. );
  16. #ifdef ALLOC_PRAGMA
  17. #pragma alloc_text(PAGE,CmpCloseKeyObject)
  18. #endif
  19. VOID
  20. CmpCloseKeyObject(
  21. IN PEPROCESS Process OPTIONAL,
  22. IN PVOID Object,
  23. IN ACCESS_MASK GrantedAccess,
  24. IN ULONG_PTR ProcessHandleCount,
  25. IN ULONG_PTR SystemHandleCount
  26. )
  27. /*++
  28. Routine Description:
  29. This routine interfaces to the NT Object Manager. It is invoked when
  30. a Key object (or Key Root object) is closed.
  31. It's function is to do cleanup processing by waking up any notifies
  32. pending on the handle. This keeps the key object from hanging around
  33. forever because a synchronous notify is stuck on it somewhere.
  34. All other cleanup, in particular, the freeing of storage, will be
  35. done in CmpDeleteKeyObject.
  36. Arguments:
  37. Process - ignored
  38. Object - supplies a pointer to a KeyRoot or Key, thus -> KEY_BODY.
  39. GrantedAccess, ProcessHandleCount, SystemHandleCount - ignored
  40. Return Value:
  41. NONE.
  42. --*/
  43. {
  44. PCM_KEY_BODY KeyBody;
  45. PCM_NOTIFY_BLOCK NotifyBlock;
  46. PAGED_CODE();
  47. UNREFERENCED_PARAMETER (Process);
  48. UNREFERENCED_PARAMETER (GrantedAccess);
  49. UNREFERENCED_PARAMETER (ProcessHandleCount);
  50. CmKdPrintEx((DPFLTR_CONFIG_ID,CML_POOL,"CmpCloseKeyObject: Object = %p\n", Object));
  51. if( SystemHandleCount > 1 ) {
  52. //
  53. // There are still has open handles on this key. Do nothing
  54. //
  55. return;
  56. }
  57. CmpLockRegistry();
  58. KeyBody = (PCM_KEY_BODY)Object;
  59. //
  60. // Check the type, it will be something else if we are closing a predefined
  61. // handle key
  62. //
  63. if (KeyBody->Type == KEY_BODY_TYPE) {
  64. //
  65. // Clean up any outstanding notifies attached to the KeyBody
  66. //
  67. if (KeyBody->NotifyBlock != NULL) {
  68. //
  69. // Post all PostBlocks waiting on the NotifyBlock
  70. //
  71. NotifyBlock = KeyBody->NotifyBlock;
  72. if (IsListEmpty(&(NotifyBlock->PostList)) == FALSE) {
  73. LIST_ENTRY DelayedDeref;
  74. //
  75. // we need to follow the rule here the hive lock
  76. // otherwise we could deadlock down in CmDeleteKeyObject. We don't acquire the kcb lock,
  77. // but we make sure that in subsequent places where we get the hive lock we get it before
  78. // the kcb lock, ie. we follow the precedence rule below.
  79. //
  80. // NB: the order of these locks is First the hive lock, then the kcb lock
  81. //
  82. InitializeListHead(&DelayedDeref);
  83. CmLockHive((PCMHIVE)(KeyBody->KeyControlBlock->KeyHive));
  84. CmpPostNotify(NotifyBlock,
  85. NULL,
  86. 0,
  87. STATUS_NOTIFY_CLEANUP,
  88. &DelayedDeref
  89. #ifdef CM_NOTIFY_CHANGED_KCB_FULLPATH
  90. ,
  91. NULL
  92. #endif //CM_NOTIFY_CHANGED_KCB_FULLPATH
  93. );
  94. CmUnlockHive((PCMHIVE)(KeyBody->KeyControlBlock->KeyHive));
  95. //
  96. // finish the job started in CmpPostNotify (i.e. dereference the keybodies
  97. // we prevented. this may cause some notifyblocks to be freed
  98. //
  99. CmpDelayedDerefKeys(&DelayedDeref);
  100. }
  101. }
  102. }
  103. CmpUnlockRegistry();
  104. return;
  105. }