diff --git a/2.x/trunk/phlib/basesup.c b/2.x/trunk/phlib/basesup.c index 746a83769..3470ce7d7 100644 --- a/2.x/trunk/phlib/basesup.c +++ b/2.x/trunk/phlib/basesup.c @@ -270,7 +270,9 @@ HANDLE PhCreateThread( * * \remarks If the function fails to allocate * the block of memory, it raises a - * STATUS_INSUFFICIENT_RESOURCES exception. + * STATUS_INSUFFICIENT_RESOURCES exception. The + * block is guaranteed to be aligned at + * MEMORY_ALLOCATION_ALIGNMENT bytes. */ __mayRaise PVOID PhAllocate( __in SIZE_T Size @@ -2378,6 +2380,9 @@ VOID PhpResizeHashtable( * the hashtable. This pointer is valid until * the hashtable is modified. If the hashtable * already contained an equal entry, NULL is returned. + * + * \remarks Entries are only guaranteed to be 8 byte + * aligned, even on 64-bit systems. */ PVOID PhAddHashtableEntry( __inout PPH_HASHTABLE Hashtable, @@ -2840,14 +2845,10 @@ VOID PhInitializeFreeList( __in ULONG MaximumCount ) { - // Maximum count of 0 is not allowed. - if (MaximumCount == 0) - MaximumCount = 1; - + RtlInitializeSListHead(&FreeList->ListHead); FreeList->Count = 0; FreeList->MaximumCount = MaximumCount; FreeList->Size = Size; - RtlInitializeSListHead(&FreeList->ListHead); } /** @@ -2879,7 +2880,8 @@ VOID PhDeleteFreeList( * * \return A pointer to the allocated block of * memory. The memory must be freed using - * PhFreeToFreeList(). + * PhFreeToFreeList(). The block is guaranteed to be + * aligned at MEMORY_ALLOCATION_ALIGNMENT bytes. */ PVOID PhAllocateFromFreeList( __inout PPH_FREE_LIST FreeList diff --git a/2.x/trunk/phlib/include/ntbasic.h b/2.x/trunk/phlib/include/ntbasic.h index a5a1ad833..9843a194e 100644 --- a/2.x/trunk/phlib/include/ntbasic.h +++ b/2.x/trunk/phlib/include/ntbasic.h @@ -10,6 +10,13 @@ typedef struct _QUAD double DoNotUseThisField; } QUAD, *PQUAD, UQUAD, *PUQUAD; +// This isn't in NT, but it's useful. +typedef struct DECLSPEC_ALIGN(MEMORY_ALLOCATION_ALIGNMENT) _QUAD_PTR +{ + ULONG_PTR DoNotUseThisField1; + ULONG_PTR DoNotUseThisField2; +} QUAD_PTR, *PQUAD_PTR, UQUAD_PTR, *PUQUAD_PTR; + typedef PVOID *PPVOID; typedef ULONG LOGICAL; diff --git a/2.x/trunk/phlib/include/phbase.h b/2.x/trunk/phlib/include/phbase.h index 3c97b4775..01f9ea1d0 100644 --- a/2.x/trunk/phlib/include/phbase.h +++ b/2.x/trunk/phlib/include/phbase.h @@ -148,6 +148,30 @@ PVOID PhReAllocSafe( __in SIZE_T Size ); +FORCEINLINE PVOID PhAllocateAligned( + __in SIZE_T Size, + __in ULONG Align, + __in SIZE_T AllocationBaseOffset + ) +{ + PVOID memory; + PVOID allocationBase; + + allocationBase = PhAllocate(Size + Align - 1); + memory = PTR_ALIGN(allocationBase, Align); + *(PPVOID)PTR_ADD_OFFSET(memory, AllocationBaseOffset) = allocationBase; + + return memory; +} + +FORCEINLINE VOID PhFreeAligned( + __in __post_invalid PVOID Memory, + __in SIZE_T AllocationBaseOffset + ) +{ + PhFree(*(PPVOID)PTR_ADD_OFFSET(Memory, AllocationBaseOffset)); +} + FORCEINLINE PVOID PhAllocateCopy( __in PVOID Data, __in ULONG Size @@ -1670,19 +1694,27 @@ BOOLEAN PhRemoveSimpleHashtableItem( typedef struct _PH_FREE_LIST { + SLIST_HEADER ListHead; + ULONG Count; ULONG MaximumCount; SIZE_T Size; - - SLIST_HEADER ListHead; } PH_FREE_LIST, *PPH_FREE_LIST; typedef struct _PH_FREE_LIST_ENTRY { SLIST_ENTRY ListEntry; - QUAD Body; + QUAD_PTR Body; } PH_FREE_LIST_ENTRY, *PPH_FREE_LIST_ENTRY; +#ifdef _M_IX86 +C_ASSERT(FIELD_OFFSET(PH_FREE_LIST_ENTRY, ListEntry) == 0x0); +C_ASSERT(FIELD_OFFSET(PH_FREE_LIST_ENTRY, Body) == 0x8); +#else +C_ASSERT(FIELD_OFFSET(PH_FREE_LIST_ENTRY, ListEntry) == 0x0); +C_ASSERT(FIELD_OFFSET(PH_FREE_LIST_ENTRY, Body) == 0x10); +#endif + VOID PhInitializeFreeList( __out PPH_FREE_LIST FreeList, __in SIZE_T Size, diff --git a/2.x/trunk/phlib/include/phsup.h b/2.x/trunk/phlib/include/phsup.h index 87688d15c..83d4dff20 100644 --- a/2.x/trunk/phlib/include/phsup.h +++ b/2.x/trunk/phlib/include/phsup.h @@ -13,6 +13,7 @@ #define PTR_ADD_OFFSET(Pointer, Offset) ((PVOID)((ULONG_PTR)(Pointer) + (ULONG_PTR)(Offset))) #define PTR_SUB_OFFSET(Pointer, Offset) ((PVOID)((ULONG_PTR)(Pointer) - (ULONG_PTR)(Offset))) +#define PTR_ALIGN(Pointer, Align) ((PVOID)(((ULONG_PTR)(Pointer) + (Align) - 1) & ~((Align) - 1))) #define REBASE_ADDRESS(Pointer, OldBase, NewBase) \ ((PVOID)((ULONG_PTR)(Pointer) - (ULONG_PTR)(OldBase) + (ULONG_PTR)(NewBase))) diff --git a/2.x/trunk/phlib/include/refp.h b/2.x/trunk/phlib/include/refp.h index d77abbe3d..daa942552 100644 --- a/2.x/trunk/phlib/include/refp.h +++ b/2.x/trunk/phlib/include/refp.h @@ -94,9 +94,25 @@ typedef struct _PH_OBJECT_HEADER /** The body of the object. For use by the \ref PhObjectToObjectHeader * and \ref PhObjectHeaderToObject macros. */ - QUAD Body; + QUAD_PTR Body; } PH_OBJECT_HEADER, *PPH_OBJECT_HEADER; +#ifndef DEBUG +#ifdef _M_IX86 +C_ASSERT(FIELD_OFFSET(PH_OBJECT_HEADER, RefCount) == 0x0); +C_ASSERT(FIELD_OFFSET(PH_OBJECT_HEADER, Flags) == 0x4); +C_ASSERT(FIELD_OFFSET(PH_OBJECT_HEADER, NextToFree) == 0x8); +C_ASSERT(FIELD_OFFSET(PH_OBJECT_HEADER, Type) == 0xc); +C_ASSERT(FIELD_OFFSET(PH_OBJECT_HEADER, Body) == 0x10); +#else +C_ASSERT(FIELD_OFFSET(PH_OBJECT_HEADER, RefCount) == 0x0); +C_ASSERT(FIELD_OFFSET(PH_OBJECT_HEADER, Flags) == 0x4); +C_ASSERT(FIELD_OFFSET(PH_OBJECT_HEADER, NextToFree) == 0x8); +C_ASSERT(FIELD_OFFSET(PH_OBJECT_HEADER, Type) == 0x10); +C_ASSERT(FIELD_OFFSET(PH_OBJECT_HEADER, Body) == 0x20); +#endif +#endif + /** * An object type specifies a kind of object and * its delete procedure.