implemented sweeping of handle tables

svn path=/trunk/; revision=19951
This commit is contained in:
Thomas Bluemel 2005-12-07 17:06:48 +00:00
parent e6894eb9f9
commit db41ecbbff
4 changed files with 69 additions and 105 deletions

View file

@ -11,7 +11,6 @@
* *
* - the last entry of a subhandle list should be reserved for auditing * - the last entry of a subhandle list should be reserved for auditing
* *
* ExSweepHandleTable (???)
* ExReferenceHandleDebugInfo * ExReferenceHandleDebugInfo
* ExSnapShotHandleTables * ExSnapShotHandleTables
* ExpMoveFreeHandles (???) * ExpMoveFreeHandles (???)
@ -163,63 +162,12 @@ ExCreateHandleTable(IN PEPROCESS QuotaProcess OPTIONAL)
return HandleTable; return HandleTable;
} }
static BOOLEAN
ExLockHandleTableEntryNoDestructionCheck(IN PHANDLE_TABLE HandleTable,
IN PHANDLE_TABLE_ENTRY Entry)
{
ULONG_PTR Current, New;
PAGED_CODE();
DPRINT("Entering handle table entry 0x%p lock...\n", Entry);
ASSERT(HandleTable);
ASSERT(Entry);
for(;;)
{
Current = (volatile ULONG_PTR)Entry->u1.Object;
if(!Current)
{
DPRINT("Attempted to lock empty handle table entry 0x%p or handle table shut down\n", Entry);
break;
}
if(!(Current & EX_HANDLE_ENTRY_LOCKED))
{
New = Current | EX_HANDLE_ENTRY_LOCKED;
if(InterlockedCompareExchangePointer(&Entry->u1.Object,
(PVOID)New,
(PVOID)Current) == (PVOID)Current)
{
DPRINT("SUCCESS handle table 0x%p entry 0x%p lock\n", HandleTable, Entry);
/* we acquired the lock */
return TRUE;
}
}
/* wait about 5ms at maximum so we don't wait forever in unfortunate
co-incidences where releasing the lock in another thread happens right
before we're waiting on the contention event to get pulsed, which might
never happen again... */
KeWaitForSingleObject(&HandleTable->HandleContentionEvent,
Executive,
KernelMode,
FALSE,
&ExpHandleShortWait);
}
return FALSE;
}
VOID VOID
ExDestroyHandleTable(IN PHANDLE_TABLE HandleTable, ExSweepHandleTable(IN PHANDLE_TABLE HandleTable,
IN PEX_DESTROY_HANDLE_CALLBACK DestroyHandleCallback OPTIONAL, IN PEX_SWEEP_HANDLE_CALLBACK SweepHandleCallback OPTIONAL,
IN PVOID Context OPTIONAL) IN PVOID Context OPTIONAL)
{ {
PHANDLE_TABLE_ENTRY **tlp, **lasttlp, *mlp, *lastmlp; PHANDLE_TABLE_ENTRY **tlp, **lasttlp, *mlp, *lastmlp;
PEPROCESS QuotaProcess;
PAGED_CODE(); PAGED_CODE();
@ -238,15 +186,8 @@ ExDestroyHandleTable(IN PHANDLE_TABLE HandleTable,
EVENT_INCREMENT, EVENT_INCREMENT,
FALSE); FALSE);
/* remove the handle table from the global handle table list */
ExAcquireHandleTableListLock();
RemoveEntryList(&HandleTable->HandleTableList);
ExReleaseHandleTableListLock();
/* call the callback function to cleanup the objects associated with the /* call the callback function to cleanup the objects associated with the
handle table */ handle table */
if(DestroyHandleCallback != NULL)
{
for(tlp = HandleTable->Table, lasttlp = HandleTable->Table + N_TOPLEVEL_POINTERS; for(tlp = HandleTable->Table, lasttlp = HandleTable->Table + N_TOPLEVEL_POINTERS;
tlp != lasttlp; tlp != lasttlp;
tlp++) tlp++)
@ -265,11 +206,10 @@ ExDestroyHandleTable(IN PHANDLE_TABLE HandleTable,
curee != laste; curee != laste;
curee++) curee++)
{ {
if(curee->u1.Object != NULL && ExLockHandleTableEntryNoDestructionCheck(HandleTable, curee)) if(curee->u1.Object != NULL && SweepHandleCallback != NULL)
{ {
DestroyHandleCallback(HandleTable, curee->u1.Object, curee->u2.GrantedAccess, Context); curee->u1.ObAttributes |= EX_HANDLE_ENTRY_LOCKED;
ExUnlockHandleTableEntry(HandleTable, curee); SweepHandleCallback(HandleTable, curee->u1.Object, curee->u2.GrantedAccess, Context);
}
} }
} }
} }
@ -277,6 +217,34 @@ ExDestroyHandleTable(IN PHANDLE_TABLE HandleTable,
} }
} }
ExReleaseHandleTableLock(HandleTable);
KeLeaveCriticalRegion();
}
VOID
ExDestroyHandleTable(IN PHANDLE_TABLE HandleTable)
{
PHANDLE_TABLE_ENTRY **tlp, **lasttlp, *mlp, *lastmlp;
PEPROCESS QuotaProcess;
PAGED_CODE();
ASSERT(HandleTable);
ASSERT(HandleTable->Flags & EX_HANDLE_TABLE_CLOSING);
KeEnterCriticalRegion();
/* at this point the table should not be queried or altered anymore,
no locks should be necessary */
ASSERT(HandleTable->Flags & EX_HANDLE_TABLE_CLOSING);
/* remove the handle table from the global handle table list */
ExAcquireHandleTableListLock();
RemoveEntryList(&HandleTable->HandleTableList);
ExReleaseHandleTableListLock();
QuotaProcess = HandleTable->QuotaProcess; QuotaProcess = HandleTable->QuotaProcess;
/* free the tables */ /* free the tables */
@ -310,8 +278,6 @@ ExDestroyHandleTable(IN PHANDLE_TABLE HandleTable,
} }
} }
ExReleaseHandleTableLock(HandleTable);
KeLeaveCriticalRegion(); KeLeaveCriticalRegion();
/* free the handle table */ /* free the handle table */
@ -408,9 +374,7 @@ freehandletable:
ExReleaseHandleTableLock(SourceHandleTable); ExReleaseHandleTableLock(SourceHandleTable);
ExDestroyHandleTable(HandleTable, ExDestroyHandleTable(HandleTable);
NULL,
NULL);
/* allocate an empty handle table */ /* allocate an empty handle table */
return ExCreateHandleTable(QuotaProcess); return ExCreateHandleTable(QuotaProcess);
} }

View file

@ -91,7 +91,7 @@ ExpInitializeProfileImplementation(VOID);
EX_HANDLE_ENTRY_INHERITABLE | \ EX_HANDLE_ENTRY_INHERITABLE | \
EX_HANDLE_ENTRY_AUDITONCLOSE) EX_HANDLE_ENTRY_AUDITONCLOSE)
typedef VOID (STDCALL PEX_DESTROY_HANDLE_CALLBACK)( typedef VOID (STDCALL PEX_SWEEP_HANDLE_CALLBACK)(
PHANDLE_TABLE HandleTable, PHANDLE_TABLE HandleTable,
PVOID Object, PVOID Object,
ULONG GrantedAccess, ULONG GrantedAccess,
@ -118,8 +118,13 @@ ExCreateHandleTable(IN PEPROCESS QuotaProcess OPTIONAL);
VOID VOID
ExDestroyHandleTable( ExDestroyHandleTable(
IN PHANDLE_TABLE HandleTable
);
VOID
ExSweepHandleTable(
IN PHANDLE_TABLE HandleTable, IN PHANDLE_TABLE HandleTable,
IN PEX_DESTROY_HANDLE_CALLBACK DestroyHandleCallback OPTIONAL, IN PEX_SWEEP_HANDLE_CALLBACK SweepHandleCallback OPTIONAL,
IN PVOID Context OPTIONAL IN PVOID Context OPTIONAL
); );

View file

@ -504,7 +504,7 @@ NtDuplicateObject (IN HANDLE SourceProcessHandle,
} }
static VOID STDCALL static VOID STDCALL
DeleteHandleCallback(PHANDLE_TABLE HandleTable, SweepHandleCallback(PHANDLE_TABLE HandleTable,
PVOID Object, PVOID Object,
ULONG GrantedAccess, ULONG GrantedAccess,
PVOID Context) PVOID Context)
@ -580,9 +580,12 @@ ObKillProcess(PEPROCESS Process)
{ {
PAGED_CODE(); PAGED_CODE();
ExDestroyHandleTable(Process->ObjectTable, /* FIXME - Temporary hack: sweep and destroy here, needs to be fixed!!! */
DeleteHandleCallback, ExSweepHandleTable(Process->ObjectTable,
SweepHandleCallback,
Process); Process);
ExDestroyHandleTable(Process->ObjectTable);
Process->ObjectTable = NULL;
} }

View file

@ -225,23 +225,15 @@ RtlpCreateAtomHandleTable(PRTL_ATOM_TABLE AtomTable)
return (AtomTable->ExHandleTable != NULL); return (AtomTable->ExHandleTable != NULL);
} }
static VOID STDCALL
AtomDeleteHandleCallback(PHANDLE_TABLE HandleTable,
PVOID Object,
ULONG GrantedAccess,
PVOID Context)
{
return;
}
VOID VOID
RtlpDestroyAtomHandleTable(PRTL_ATOM_TABLE AtomTable) RtlpDestroyAtomHandleTable(PRTL_ATOM_TABLE AtomTable)
{ {
if (AtomTable->ExHandleTable) if (AtomTable->ExHandleTable)
{ {
ExDestroyHandleTable(AtomTable->ExHandleTable, ExSweepHandleTable(AtomTable->ExHandleTable,
AtomDeleteHandleCallback, NULL,
AtomTable); NULL);
ExDestroyHandleTable(AtomTable->ExHandleTable);
AtomTable->ExHandleTable = NULL; AtomTable->ExHandleTable = NULL;
} }
} }