425 lines
9.9 KiB
C++
425 lines
9.9 KiB
C++
//#pragma hdrstop
|
|
/*++
|
|
Kernel mode definitions and function prototypes for wdm model
|
|
--*/
|
|
#ifndef WDM_INCD
|
|
#define WDM_INCD
|
|
|
|
#pragma PAGEDCODE
|
|
#ifdef __cplusplus
|
|
extern "C"{
|
|
#endif
|
|
|
|
#include <wdm.h>
|
|
#include <stdio.h>
|
|
#include <stdarg.h>
|
|
|
|
#ifndef IRP_MN_QUERY_LEGACY_BUS_INFORMATION
|
|
#define IRP_MN_QUERY_LEGACY_BUS_INFORMATION 0x18
|
|
#endif
|
|
|
|
#if DBG && defined(_X86_)
|
|
#undef ASSERT
|
|
#define ASSERT(e) if(!(e)){DbgPrint("Assertion failure in"\
|
|
__FILE__", line %d: " #e "\n", __LINE__);\
|
|
_asm int 3\
|
|
}
|
|
#endif
|
|
|
|
|
|
#define BOOL BOOLEAN
|
|
#define FALSE 0
|
|
typedef UCHAR* PBYTE;
|
|
|
|
|
|
#define MSEC *(-(LONGLONG)10000); //milliseconds
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
/************************* LISTS MANIPULATION MACROS **************************/
|
|
// Doubly-linked list manipulation routines. Implemented as macros
|
|
// but logically these are procedures.
|
|
|
|
/*
|
|
typedef struct _LIST_ENTRY {
|
|
struct _LIST_ENTRY * volatile Flink;
|
|
struct _LIST_ENTRY * volatile Blink;
|
|
} LIST_ENTRY, *PLIST_ENTRY, *RESTRICTED_POINTER PRLIST_ENTRY;
|
|
|
|
*/
|
|
#ifndef LIST_ENTRY_DEF
|
|
#define LIST_ENTRY_DEF
|
|
|
|
// VOID
|
|
// InitializeListHead(
|
|
// PLIST_ENTRY ListHead
|
|
// );
|
|
#define InitializeListHead(ListHead) (\
|
|
(ListHead)->Flink = (ListHead)->Blink = (ListHead))
|
|
|
|
// BOOLEAN
|
|
// IsListEmpty(
|
|
// PLIST_ENTRY ListHead
|
|
// );
|
|
#define IsListEmpty(ListHead) \
|
|
((ListHead)->Flink == (ListHead))
|
|
|
|
// PLIST_ENTRY
|
|
// RemoveHeadList(
|
|
// PLIST_ENTRY ListHead
|
|
// );
|
|
#define RemoveHeadList(ListHead) \
|
|
(ListHead)->Flink;\
|
|
{RemoveEntryList((ListHead)->Flink)}
|
|
|
|
// PLIST_ENTRY
|
|
// RemoveTailList(
|
|
// PLIST_ENTRY ListHead
|
|
// );
|
|
#define RemoveTailList(ListHead) \
|
|
(ListHead)->Blink;\
|
|
{RemoveEntryList((ListHead)->Blink)}
|
|
|
|
// VOID
|
|
// RemoveEntryList(
|
|
// PLIST_ENTRY Entry
|
|
// );
|
|
#define RemoveEntryList(Entry) {\
|
|
PLIST_ENTRY _EX_Blink;\
|
|
PLIST_ENTRY _EX_Flink;\
|
|
_EX_Flink = (Entry)->Flink;\
|
|
_EX_Blink = (Entry)->Blink;\
|
|
_EX_Blink->Flink = _EX_Flink;\
|
|
_EX_Flink->Blink = _EX_Blink;\
|
|
}
|
|
|
|
// VOID
|
|
// InsertTailList(
|
|
// PLIST_ENTRY ListHead,
|
|
// PLIST_ENTRY Entry
|
|
// );
|
|
#define InsertTailList(ListHead,Entry) {\
|
|
PLIST_ENTRY _EX_Blink;\
|
|
PLIST_ENTRY _EX_ListHead;\
|
|
_EX_ListHead = (ListHead);\
|
|
_EX_Blink = _EX_ListHead->Blink;\
|
|
(Entry)->Flink = _EX_ListHead;\
|
|
(Entry)->Blink = _EX_Blink;\
|
|
_EX_Blink->Flink = (Entry);\
|
|
_EX_ListHead->Blink = (Entry);\
|
|
}
|
|
|
|
// VOID
|
|
// InsertHeadList(
|
|
// PLIST_ENTRY ListHead,
|
|
// PLIST_ENTRY Entry
|
|
// );
|
|
#define InsertHeadList(ListHead,Entry) {\
|
|
PLIST_ENTRY _EX_Flink;\
|
|
PLIST_ENTRY _EX_ListHead;\
|
|
_EX_ListHead = (ListHead);\
|
|
_EX_Flink = _EX_ListHead->Flink;\
|
|
(Entry)->Flink = _EX_Flink;\
|
|
(Entry)->Blink = _EX_ListHead;\
|
|
_EX_Flink->Blink = (Entry);\
|
|
_EX_ListHead->Flink = (Entry);\
|
|
}
|
|
|
|
// PSINGLE_LIST_ENTRY
|
|
// PopEntryList(
|
|
// PSINGLE_LIST_ENTRY ListHead
|
|
// );
|
|
#define PopEntryList(ListHead) \
|
|
(ListHead)->Next;\
|
|
{\
|
|
PSINGLE_LIST_ENTRY FirstEntry;\
|
|
FirstEntry = (ListHead)->Next;\
|
|
if (FirstEntry != NULL) { \
|
|
(ListHead)->Next = FirstEntry->Next;\
|
|
} \
|
|
}
|
|
|
|
// VOID
|
|
// PushEntryList(
|
|
// PSINGLE_LIST_ENTRY ListHead,
|
|
// PSINGLE_LIST_ENTRY Entry
|
|
// );
|
|
#define PushEntryList(ListHead,Entry) \
|
|
(Entry)->Next = (ListHead)->Next; \
|
|
(ListHead)->Next = (Entry)
|
|
|
|
#endif //LIST_ENTRY
|
|
|
|
#ifndef CONTAINING_RECORD
|
|
#define CONTAINING_RECORD(address, type, field) ((type *)( \
|
|
(PCHAR)(address) - \
|
|
(ULONG_PTR)(&((type *)0)->field)))
|
|
#endif
|
|
|
|
/*******************************************************************************/
|
|
|
|
#ifndef FIELDOFFSET
|
|
#define FIELDOFFSET(type, field) ((DWORD)(&((type *)0)->field))
|
|
#endif
|
|
|
|
|
|
#ifndef CONTAINING_RECORD
|
|
#define CONTAINING_RECORD(address, type, field) ((type *)( \
|
|
(PCHAR)(address) - \
|
|
(ULONG_PTR)(&((type *)0)->field)))
|
|
#endif
|
|
|
|
/**********************************************************************************/
|
|
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
// Macros to verify allocated objects
|
|
#define ALLOCATED_OK(obj) \
|
|
((obj!=(VOID *)0) && NT_SUCCESS((obj)->m_Status))
|
|
|
|
#define DISPOSE_OBJECT(obj) \
|
|
{if((obj!=(VOID *)0)) obj->dispose(); obj = NULL;}
|
|
|
|
#define RETURN_VERIFIED_OBJECT(obj) \
|
|
if(ALLOCATED_OK(obj)) return obj; \
|
|
else \
|
|
{ \
|
|
DISPOSE_OBJECT(obj); \
|
|
return NULL; \
|
|
}
|
|
|
|
// derived class Unicode string
|
|
#define TYPE_SYSTEM_ALLOCATED 0
|
|
#define TYPE_DRIVER_ALLOCATED 1
|
|
|
|
extern ULONG ObjectCounter;
|
|
//::DBG_PRINT("=== Deleting Object %8.8lX",ptr);\
|
|
// Overrides for library new and delete operators.
|
|
|
|
/*
|
|
inline VOID* __cdecl operator new(ULONG size, POOL_TYPE iType)\
|
|
{PVOID pMem; if(pMem = ::ExAllocatePoolWithTag(iType,size,'_GRU'))\
|
|
{ ObjectCounter++; ::RtlZeroMemory(pMem,size); DBG_PRINT("\n=== New Object %8.8lX, %d\n",pMem,ObjectCounter);\
|
|
return pMem; \
|
|
} else return NULL; };
|
|
|
|
inline VOID __cdecl operator delete(VOID* ptr)\
|
|
{ if(ptr){ObjectCounter--; DBG_PRINT("\n=== Deleting Object %8.8lX, %d\n",ptr,ObjectCounter); ::ExFreePool((PVOID)ptr);}\
|
|
};
|
|
*/
|
|
|
|
|
|
#pragma LOCKEDCODE
|
|
inline VOID* __cdecl operator new(size_t size, POOL_TYPE iType)\
|
|
{PVOID pMem; if(pMem = ::ExAllocatePoolWithTag(iType,size,'URG_'))\
|
|
{ ObjectCounter++; ::RtlZeroMemory(pMem,size);\
|
|
return pMem; \
|
|
} else return NULL; };
|
|
|
|
inline VOID __cdecl operator delete(VOID* ptr)\
|
|
{ if(ptr){ObjectCounter--; ::ExFreePool((PVOID)ptr);}\
|
|
};
|
|
|
|
|
|
#include "generic.h"
|
|
|
|
#pragma PAGEDCODE
|
|
template <class T>
|
|
class CLinkedList
|
|
{
|
|
public:
|
|
NTSTATUS m_Status;
|
|
VOID self_delete(VOID){delete this;};
|
|
virtual VOID dispose(VOID){self_delete();};
|
|
protected:
|
|
LIST_ENTRY head;
|
|
KSPIN_LOCK splock;
|
|
|
|
public:
|
|
CLinkedList()
|
|
{
|
|
InitializeListHead(&head);
|
|
KeInitializeSpinLock(&splock);
|
|
};
|
|
|
|
BOOLEAN IsEmpty(VOID) { return IsListEmpty(&head); };
|
|
~CLinkedList()
|
|
{ // if list is still not empty, free all items
|
|
T *p;
|
|
while (p=(T *) ExInterlockedRemoveHeadList(&head,&splock))
|
|
{
|
|
CONTAINING_RECORD(p,T,entry)->dispose();
|
|
}
|
|
};
|
|
|
|
VOID New(T *p)
|
|
{
|
|
ExInterlockedInsertTailList(&head,&(p->entry),&splock);
|
|
};
|
|
|
|
VOID insertHead(T *p)
|
|
{
|
|
ExInterlockedInsertHeadList(&head,&(p->entry),&splock);
|
|
};
|
|
|
|
T* removeHead(VOID)
|
|
{
|
|
T *p=(T *) ExInterlockedRemoveHeadList(&head,&splock);
|
|
if (p) p=CONTAINING_RECORD(p,T,entry);
|
|
return p;
|
|
};
|
|
VOID remove(T *p)
|
|
{
|
|
RemoveEntryList(&(p->entry));
|
|
};
|
|
|
|
T* getNext(T* p)
|
|
{
|
|
if (p)
|
|
{
|
|
PLIST_ENTRY Next;
|
|
Next = p->entry.Flink;
|
|
if (Next && (Next!= &head))
|
|
{
|
|
T* pp=CONTAINING_RECORD(Next,T,entry);
|
|
return pp;
|
|
}
|
|
else return NULL;
|
|
}
|
|
return NULL;
|
|
};
|
|
|
|
T* getFirst()
|
|
{
|
|
PLIST_ENTRY Next = head.Flink;
|
|
if (Next && Next!= &head)
|
|
{
|
|
T* p = CONTAINING_RECORD(Next,T,entry);
|
|
return p;
|
|
}
|
|
return NULL;
|
|
};
|
|
};
|
|
|
|
#pragma PAGEDCODE
|
|
class CUString
|
|
{
|
|
public:
|
|
NTSTATUS m_Status;
|
|
VOID self_delete(VOID){delete this;};
|
|
virtual VOID dispose(VOID){self_delete();};
|
|
private:
|
|
UCHAR m_bType;
|
|
public:
|
|
UNICODE_STRING m_String;
|
|
public:
|
|
CUString(USHORT nSize)
|
|
{
|
|
m_Status = STATUS_INSUFFICIENT_RESOURCES;
|
|
m_bType = TYPE_DRIVER_ALLOCATED;
|
|
RtlInitUnicodeString(&m_String,NULL);
|
|
m_String.MaximumLength = nSize;
|
|
m_String.Buffer = (USHORT *)
|
|
ExAllocatePool(PagedPool,nSize);
|
|
if (!m_String.Buffer) return; // leaving status the way it is
|
|
RtlZeroMemory(m_String.Buffer,m_String.MaximumLength);
|
|
m_Status = STATUS_SUCCESS;
|
|
};
|
|
|
|
CUString(PWCHAR uszString)
|
|
{
|
|
m_Status = STATUS_SUCCESS;
|
|
m_bType = TYPE_SYSTEM_ALLOCATED;
|
|
RtlInitUnicodeString(&m_String,uszString);
|
|
};
|
|
|
|
CUString(ANSI_STRING* pString)
|
|
{
|
|
m_Status = STATUS_SUCCESS;
|
|
m_bType = TYPE_SYSTEM_ALLOCATED;
|
|
RtlAnsiStringToUnicodeString(&m_String,pString,TRUE);
|
|
};
|
|
|
|
CUString(PCSTR pString)
|
|
{
|
|
ANSI_STRING AnsiString;
|
|
m_Status = STATUS_SUCCESS;
|
|
m_bType = TYPE_SYSTEM_ALLOCATED;
|
|
RtlInitAnsiString(&AnsiString,pString);
|
|
RtlAnsiStringToUnicodeString(&m_String,&AnsiString,TRUE);
|
|
};
|
|
|
|
|
|
|
|
CUString(PUNICODE_STRING uString)
|
|
{
|
|
m_Status = STATUS_INSUFFICIENT_RESOURCES;
|
|
m_bType = TYPE_DRIVER_ALLOCATED;
|
|
RtlInitUnicodeString(&m_String,NULL);
|
|
m_String.MaximumLength = MAXIMUM_FILENAME_LENGTH;
|
|
m_String.Buffer = (USHORT *)
|
|
ExAllocatePool(PagedPool,MAXIMUM_FILENAME_LENGTH);
|
|
if (!m_String.Buffer) return; // leaving status the way it is
|
|
RtlZeroMemory(m_String.Buffer,m_String.MaximumLength);
|
|
|
|
RtlCopyUnicodeString(&m_String,uString);
|
|
m_Status = STATUS_SUCCESS;
|
|
};
|
|
|
|
|
|
CUString(LONG iVal, LONG iBase)
|
|
{
|
|
m_Status = STATUS_INSUFFICIENT_RESOURCES;
|
|
m_bType = TYPE_DRIVER_ALLOCATED;
|
|
RtlInitUnicodeString(&m_String,NULL);
|
|
USHORT iSize=1;
|
|
LONG iValCopy=(!iVal)?1:iVal;
|
|
while (iValCopy>=1)
|
|
{
|
|
iValCopy/=iBase;
|
|
iSize++;
|
|
} // now iSize carries the number of digits
|
|
|
|
iSize*=sizeof(WCHAR);
|
|
|
|
m_String.MaximumLength = iSize;
|
|
m_String.Buffer = (USHORT *)
|
|
ExAllocatePool(PagedPool,iSize);
|
|
if (!m_String.Buffer) return;
|
|
RtlZeroMemory(m_String.Buffer,m_String.MaximumLength);
|
|
m_Status = RtlIntegerToUnicodeString(iVal, iBase, &m_String);
|
|
};
|
|
|
|
~CUString()
|
|
{
|
|
if ((m_bType == TYPE_DRIVER_ALLOCATED) && m_String.Buffer)
|
|
ExFreePool(m_String.Buffer);
|
|
};
|
|
|
|
VOID append(UNICODE_STRING *uszString)
|
|
{
|
|
m_Status = RtlAppendUnicodeStringToString(&m_String,uszString);
|
|
};
|
|
|
|
VOID copyTo(CUString *pTarget)
|
|
{
|
|
RtlCopyUnicodeString(&pTarget->m_String,&m_String);
|
|
};
|
|
|
|
BOOL operator==(CUString cuArg)
|
|
{
|
|
return (!RtlCompareUnicodeString(&m_String,
|
|
&cuArg.m_String,FALSE));
|
|
};
|
|
|
|
LONG inline getLength() { return m_String.Length; };
|
|
PWCHAR inline getString() { return m_String.Buffer; };
|
|
VOID inline setLength(USHORT i) { m_String.Length = i; };
|
|
};
|
|
|
|
|
|
// already included
|
|
#endif
|