121 lines
2.9 KiB
C
121 lines
2.9 KiB
C
/*++
|
|
|
|
Copyright (c) 1991 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
cmclose.c
|
|
|
|
Abstract:
|
|
|
|
This module contains the close object method.
|
|
|
|
Author:
|
|
|
|
Bryan M. Willman (bryanwi) 07-Jan-92
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "cmp.h"
|
|
|
|
#ifdef ALLOC_PRAGMA
|
|
#pragma alloc_text(PAGE,CmpCloseKeyObject)
|
|
#endif
|
|
|
|
VOID
|
|
CmpCloseKeyObject(
|
|
IN PEPROCESS Process OPTIONAL,
|
|
IN PVOID Object,
|
|
IN ACCESS_MASK GrantedAccess,
|
|
IN ULONG ProcessHandleCount,
|
|
IN ULONG SystemHandleCount
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine interfaces to the NT Object Manager. It is invoked when
|
|
a Key object (or Key Root object) is closed.
|
|
|
|
It's function is to do cleanup processing by waking up any notifies
|
|
pending on the handle. This keeps the key object from hanging around
|
|
forever because a synchronous notify is stuck on it somewhere.
|
|
|
|
All other cleanup, in particular, the freeing of storage, will be
|
|
done in CmpDeleteKeyObject.
|
|
|
|
Arguments:
|
|
|
|
Process - ignored
|
|
|
|
Object - supplies a pointer to a KeyRoot or Key, thus -> KEY_BODY.
|
|
|
|
GrantedAccess, ProcessHandleCount, SystemHandleCount - ignored
|
|
|
|
Return Value:
|
|
|
|
NONE.
|
|
|
|
--*/
|
|
{
|
|
PCM_KEY_BODY KeyBody;
|
|
PCM_NOTIFY_BLOCK NotifyBlock;
|
|
|
|
PAGED_CODE();
|
|
CmKdPrintEx((DPFLTR_CONFIG_ID,CML_POOL,"CmpCloseKeyObject: Object = %p\n", Object));
|
|
|
|
if( SystemHandleCount > 1 ) {
|
|
//
|
|
// There are still has open handles on this key. Do nothing
|
|
//
|
|
return;
|
|
}
|
|
|
|
CmpLockRegistry();
|
|
|
|
KeyBody = (PCM_KEY_BODY)Object;
|
|
|
|
//
|
|
// Check the type, it will be something else if we are closing a predefined
|
|
// handle key
|
|
//
|
|
if (KeyBody->Type == KEY_BODY_TYPE) {
|
|
//
|
|
// Clean up any outstanding notifies attached to the KeyBody
|
|
//
|
|
if (KeyBody->NotifyBlock != NULL) {
|
|
//
|
|
// Post all PostBlocks waiting on the NotifyBlock
|
|
//
|
|
NotifyBlock = KeyBody->NotifyBlock;
|
|
if (IsListEmpty(&(NotifyBlock->PostList)) == FALSE) {
|
|
//
|
|
// we need to follow the rule here and aquire kcb lock before hive lock
|
|
// other wise we could deadlock down in CmDeleteKeyObject
|
|
//
|
|
BEGIN_KCB_LOCK_GUARD;
|
|
CmpLockKCBTreeExclusive();
|
|
CmLockHive((PCMHIVE)(KeyBody->KeyControlBlock->KeyHive));
|
|
CmpPostNotify(NotifyBlock,
|
|
NULL,
|
|
0,
|
|
STATUS_NOTIFY_CLEANUP,
|
|
NULL
|
|
#ifdef CM_NOTIFY_CHANGED_KCB_FULLPATH
|
|
,
|
|
NULL
|
|
#endif //CM_NOTIFY_CHANGED_KCB_FULLPATH
|
|
);
|
|
CmUnlockHive((PCMHIVE)(KeyBody->KeyControlBlock->KeyHive));
|
|
CmpUnlockKCBTree();
|
|
END_KCB_LOCK_GUARD;
|
|
}
|
|
}
|
|
}
|
|
|
|
CmpUnlockRegistry();
|
|
return;
|
|
}
|