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.
397 lines
8.5 KiB
397 lines
8.5 KiB
/*++
|
|
|
|
Copyright (c) 1999-2000 Microsoft Corporation
|
|
|
|
Module Name :
|
|
|
|
kernutil.h
|
|
|
|
Abstract:
|
|
|
|
Kernel mode utilities
|
|
|
|
Revision History:
|
|
--*/
|
|
#ifndef __KERNUTIL_H__
|
|
#define __KERNUTIL_H__
|
|
|
|
BOOL InitializeKernelUtilities();
|
|
VOID UninitializeKernelUtilities();
|
|
|
|
|
|
//
|
|
// For frequent identically-sized allocations, Lookaside Lists are faster
|
|
// and less susceptible to the low memory conditions (though not exempt)
|
|
//
|
|
class NPagedLookasideList : public TopObj
|
|
{
|
|
private:
|
|
NPAGED_LOOKASIDE_LIST _Lookaside;
|
|
|
|
public:
|
|
NPagedLookasideList(ULONG Size, ULONG Tag)
|
|
{
|
|
SetClassName("NPagedLookasideList");
|
|
|
|
ExInitializeNPagedLookasideList(&_Lookaside, DRALLOCATEPOOL, DRFREEPOOL,
|
|
0, Size, Tag, 0);
|
|
}
|
|
|
|
virtual ~NPagedLookasideList()
|
|
{
|
|
ExDeleteNPagedLookasideList(&_Lookaside);
|
|
}
|
|
|
|
//
|
|
// Ordinarily I'd want tracing here, but it's more important these be
|
|
// inline for retail
|
|
//
|
|
inline PVOID Allocate()
|
|
{
|
|
return ExAllocateFromNPagedLookasideList(&_Lookaside);
|
|
}
|
|
|
|
inline VOID Free(PVOID Entry)
|
|
{
|
|
ExFreeToNPagedLookasideList(&_Lookaside, Entry);
|
|
}
|
|
|
|
//
|
|
// Memory Management Operators
|
|
//
|
|
inline void *__cdecl operator new(size_t sz)
|
|
{
|
|
return DRALLOCATEPOOL(NonPagedPool, sz, 'LLPN');
|
|
}
|
|
|
|
inline void __cdecl operator delete(void *ptr)
|
|
{
|
|
DRFREEPOOL(ptr);
|
|
}
|
|
};
|
|
|
|
class PagedLookasideList : public TopObj
|
|
{
|
|
private:
|
|
PAGED_LOOKASIDE_LIST _Lookaside;
|
|
|
|
public:
|
|
PagedLookasideList(ULONG Size, ULONG Tag)
|
|
{
|
|
SetClassName("PagedLookasideList");
|
|
|
|
ExInitializePagedLookasideList(&_Lookaside, DRALLOCATEPOOL, DRFREEPOOL,
|
|
0, Size, Tag, 0);
|
|
}
|
|
|
|
virtual ~PagedLookasideList()
|
|
{
|
|
ExDeletePagedLookasideList(&_Lookaside);
|
|
}
|
|
|
|
//
|
|
// Ordinarily I'd want tracing here, but it's more important these be
|
|
// inline for retail
|
|
//
|
|
inline PVOID Allocate()
|
|
{
|
|
return ExAllocateFromPagedLookasideList(&_Lookaside);
|
|
}
|
|
|
|
inline VOID Free(PVOID Entry)
|
|
{
|
|
ExFreeToPagedLookasideList(&_Lookaside, Entry);
|
|
}
|
|
|
|
inline void *__cdecl operator new(size_t sz)
|
|
{
|
|
return DRALLOCATEPOOL(NonPagedPool, sz, 'LLgP');
|
|
}
|
|
|
|
inline void __cdecl operator delete(void *ptr)
|
|
{
|
|
DRFREEPOOL(ptr);
|
|
}
|
|
};
|
|
|
|
class KernelResource : public TopObj
|
|
{
|
|
private:
|
|
ERESOURCE _Resource;
|
|
|
|
public:
|
|
KernelResource();
|
|
virtual ~KernelResource();
|
|
|
|
inline VOID AcquireResourceExclusive()
|
|
{
|
|
KeEnterCriticalRegion();
|
|
ExAcquireResourceExclusiveLite(&_Resource, TRUE);
|
|
}
|
|
|
|
inline VOID AcquireResourceShared()
|
|
{
|
|
KeEnterCriticalRegion();
|
|
ExAcquireResourceSharedLite(&_Resource, TRUE);
|
|
}
|
|
|
|
inline VOID ReleaseResource()
|
|
{
|
|
ExReleaseResourceLite(&_Resource);
|
|
KeLeaveCriticalRegion();
|
|
}
|
|
|
|
inline ULONG IsAcquiredShared()
|
|
{
|
|
return ExIsResourceAcquiredSharedLite(&_Resource);
|
|
}
|
|
|
|
inline BOOLEAN IsAcquiredExclusive()
|
|
{
|
|
return ExIsResourceAcquiredExclusiveLite(&_Resource);
|
|
}
|
|
|
|
inline BOOLEAN IsAcquired()
|
|
{
|
|
return (IsAcquiredShared() != 0) || IsAcquiredExclusive();
|
|
}
|
|
};
|
|
|
|
class KernelEvent : public TopObj
|
|
{
|
|
private:
|
|
KEVENT _KernelEvent;
|
|
static NPagedLookasideList *_Lookaside;
|
|
|
|
public:
|
|
KernelEvent(IN EVENT_TYPE Type, IN BOOLEAN State)
|
|
{
|
|
KeInitializeEvent(&_KernelEvent, Type, State);
|
|
}
|
|
|
|
virtual ~KernelEvent()
|
|
{
|
|
}
|
|
|
|
static inline BOOL StaticInitialization()
|
|
{
|
|
_Lookaside = new NPagedLookasideList(sizeof(KernelEvent), 'tnvE');
|
|
return _Lookaside != NULL;
|
|
}
|
|
|
|
static inline VOID StaticUninitialization()
|
|
{
|
|
if (_Lookaside != NULL) {
|
|
delete _Lookaside;
|
|
_Lookaside = NULL;
|
|
}
|
|
}
|
|
|
|
NTSTATUS Wait(IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode,
|
|
IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout = NULL)
|
|
{
|
|
return KeWaitForSingleObject(&_KernelEvent, WaitReason, WaitMode,
|
|
Alertable, Timeout);
|
|
}
|
|
|
|
inline LONG SetEvent(KPRIORITY Increment = IO_NO_INCREMENT,
|
|
BOOLEAN Wait = FALSE)
|
|
{
|
|
return KeSetEvent(&_KernelEvent, Increment, Wait);
|
|
}
|
|
|
|
inline LONG ResetEvent()
|
|
{
|
|
return KeResetEvent(&_KernelEvent);
|
|
}
|
|
|
|
inline VOID ClearEvent()
|
|
{
|
|
KeClearEvent(&_KernelEvent);
|
|
}
|
|
|
|
//
|
|
// Maybe need to WaitForMultipleObjects
|
|
//
|
|
inline PKEVENT GetEvent()
|
|
{
|
|
return &_KernelEvent;
|
|
}
|
|
|
|
//
|
|
// Memory Management Operators
|
|
//
|
|
inline void *__cdecl operator new(size_t sz)
|
|
{
|
|
return _Lookaside->Allocate();
|
|
}
|
|
|
|
inline void __cdecl operator delete(void *ptr)
|
|
{
|
|
_Lookaside->Free(ptr);
|
|
}
|
|
};
|
|
|
|
class SharedLock
|
|
{
|
|
private:
|
|
KernelResource &_Lock;
|
|
|
|
public:
|
|
SharedLock(KernelResource &Lock) : _Lock(Lock)
|
|
{
|
|
_Lock.AcquireResourceShared();
|
|
}
|
|
~SharedLock()
|
|
{
|
|
_Lock.ReleaseResource();
|
|
}
|
|
};
|
|
|
|
class ExclusiveLock
|
|
{
|
|
private:
|
|
KernelResource &_Lock;
|
|
|
|
public:
|
|
ExclusiveLock(KernelResource &Lock) : _Lock(Lock)
|
|
{
|
|
_Lock.AcquireResourceExclusive();
|
|
}
|
|
~ExclusiveLock()
|
|
{
|
|
_Lock.ReleaseResource();
|
|
}
|
|
};
|
|
|
|
class DoubleList;
|
|
|
|
class ListEntry {
|
|
friend class DoubleList; // so it can access _List and constructor
|
|
|
|
private:
|
|
LIST_ENTRY _List; // really here for DoubleList
|
|
|
|
ListEntry(PVOID Node)
|
|
{
|
|
_Node = Node;
|
|
}
|
|
PVOID _Node; // What it is we're tracking in the list
|
|
static NPagedLookasideList *_Lookaside;
|
|
|
|
public:
|
|
PVOID Node() { return _Node; }
|
|
|
|
static inline BOOL StaticInitialization()
|
|
{
|
|
_Lookaside = new NPagedLookasideList(sizeof(ListEntry), 'tsiL');
|
|
return _Lookaside != NULL;
|
|
}
|
|
|
|
static inline VOID StaticUninitialization()
|
|
{
|
|
if (_Lookaside != NULL) {
|
|
delete _Lookaside;
|
|
_Lookaside = NULL;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Memory Management Operators
|
|
//
|
|
inline void *__cdecl operator new(size_t sz)
|
|
{
|
|
return _Lookaside->Allocate();
|
|
}
|
|
|
|
inline void __cdecl operator delete(void *ptr)
|
|
{
|
|
_Lookaside->Free(ptr);
|
|
}
|
|
};
|
|
|
|
class DoubleList : public TopObj {
|
|
private:
|
|
LIST_ENTRY _List;
|
|
KernelResource _Resource; // Writes require an exclusive lock
|
|
// reads require a shared lock
|
|
public:
|
|
DoubleList()
|
|
{
|
|
SetClassName("DoubleList");
|
|
InitializeListHead(&_List);
|
|
}
|
|
|
|
BOOL CreateEntry(PVOID Node);
|
|
|
|
//
|
|
// Enumeration of the list
|
|
//
|
|
// You can't add to the list while enumerating
|
|
//
|
|
// Sample enumeration of the list
|
|
// In this sample find a smart pointer
|
|
//
|
|
/*
|
|
SmartPtr<NodeThing> *NodeEnum;
|
|
SmartPtr<NodeThing> NodeFound;
|
|
DoubleList List;
|
|
ListEntry *ListEnum;
|
|
|
|
List.LockShared(); // or exclusive
|
|
ListEnum = List.First();
|
|
while (ListEnum != NULL) {
|
|
|
|
//
|
|
// do something with ListEnum->Node()
|
|
//
|
|
// In this sample, look to see if it is
|
|
// the item we're looking for
|
|
//
|
|
|
|
NodeEnum = (SmartPtr<NodeThing> *)ListEnum->Node();
|
|
|
|
if ((*NodeEnum)->NodeThingProperty == NodeThingPropertyCriteria) {
|
|
NodeFound = (*NodeEnum);
|
|
|
|
//
|
|
// These aren't guaranteed valid once the resource is released
|
|
//
|
|
|
|
NodeEnum = NULL;
|
|
ListEnum = NULL;
|
|
break;
|
|
}
|
|
|
|
ListEnum = List.Next(ListEnum);
|
|
}
|
|
List.Unlock();
|
|
|
|
// Do something with NodeFound;
|
|
if (NodeFound != NULL) {
|
|
|
|
}
|
|
*/
|
|
//
|
|
|
|
VOID RemoveEntry(ListEntry *Entry);
|
|
ListEntry *First();
|
|
ListEntry *Next(ListEntry *ListEnum);
|
|
|
|
inline VOID LockShared()
|
|
{
|
|
_Resource.AcquireResourceShared();
|
|
}
|
|
|
|
inline VOID LockExclusive()
|
|
{
|
|
_Resource.AcquireResourceExclusive();
|
|
}
|
|
|
|
inline VOID Unlock()
|
|
{
|
|
_Resource.ReleaseResource();
|
|
}
|
|
};
|
|
|
|
#endif // __KERNUTIL_H__
|