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.

120 lines
2.9 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. #ifdef ALLOC_PRAGMA
  13. #pragma alloc_text(PAGE,CmpCloseKeyObject)
  14. #endif
  15. VOID
  16. CmpCloseKeyObject(
  17. IN PEPROCESS Process OPTIONAL,
  18. IN PVOID Object,
  19. IN ACCESS_MASK GrantedAccess,
  20. IN ULONG ProcessHandleCount,
  21. IN ULONG SystemHandleCount
  22. )
  23. /*++
  24. Routine Description:
  25. This routine interfaces to the NT Object Manager. It is invoked when
  26. a Key object (or Key Root object) is closed.
  27. It's function is to do cleanup processing by waking up any notifies
  28. pending on the handle. This keeps the key object from hanging around
  29. forever because a synchronous notify is stuck on it somewhere.
  30. All other cleanup, in particular, the freeing of storage, will be
  31. done in CmpDeleteKeyObject.
  32. Arguments:
  33. Process - ignored
  34. Object - supplies a pointer to a KeyRoot or Key, thus -> KEY_BODY.
  35. GrantedAccess, ProcessHandleCount, SystemHandleCount - ignored
  36. Return Value:
  37. NONE.
  38. --*/
  39. {
  40. PCM_KEY_BODY KeyBody;
  41. PCM_NOTIFY_BLOCK NotifyBlock;
  42. PAGED_CODE();
  43. CmKdPrintEx((DPFLTR_CONFIG_ID,CML_POOL,"CmpCloseKeyObject: Object = %p\n", Object));
  44. if( SystemHandleCount > 1 ) {
  45. //
  46. // There are still has open handles on this key. Do nothing
  47. //
  48. return;
  49. }
  50. CmpLockRegistry();
  51. KeyBody = (PCM_KEY_BODY)Object;
  52. //
  53. // Check the type, it will be something else if we are closing a predefined
  54. // handle key
  55. //
  56. if (KeyBody->Type == KEY_BODY_TYPE) {
  57. //
  58. // Clean up any outstanding notifies attached to the KeyBody
  59. //
  60. if (KeyBody->NotifyBlock != NULL) {
  61. //
  62. // Post all PostBlocks waiting on the NotifyBlock
  63. //
  64. NotifyBlock = KeyBody->NotifyBlock;
  65. if (IsListEmpty(&(NotifyBlock->PostList)) == FALSE) {
  66. //
  67. // we need to follow the rule here and aquire kcb lock before hive lock
  68. // other wise we could deadlock down in CmDeleteKeyObject
  69. //
  70. BEGIN_KCB_LOCK_GUARD;
  71. CmpLockKCBTreeExclusive();
  72. CmLockHive((PCMHIVE)(KeyBody->KeyControlBlock->KeyHive));
  73. CmpPostNotify(NotifyBlock,
  74. NULL,
  75. 0,
  76. STATUS_NOTIFY_CLEANUP,
  77. NULL
  78. #ifdef CM_NOTIFY_CHANGED_KCB_FULLPATH
  79. ,
  80. NULL
  81. #endif //CM_NOTIFY_CHANGED_KCB_FULLPATH
  82. );
  83. CmUnlockHive((PCMHIVE)(KeyBody->KeyControlBlock->KeyHive));
  84. CmpUnlockKCBTree();
  85. END_KCB_LOCK_GUARD;
  86. }
  87. }
  88. }
  89. CmpUnlockRegistry();
  90. return;
  91. }