mirror of
https://github.com/reactos/reactos.git
synced 2025-04-21 12:40:33 +00:00
172 lines
4.6 KiB
C
172 lines
4.6 KiB
C
#ifndef REACTOS_EXEFORMAT_H_INCLUDED_
|
|
#define REACTOS_EXEFORMAT_H_INCLUDED_ 1
|
|
|
|
/*
|
|
* LOADER API
|
|
*/
|
|
/* OUT flags returned by a loader */
|
|
#define EXEFMT_LOAD_ASSUME_SEGMENTS_SORTED (1 << 0)
|
|
#define EXEFMT_LOAD_ASSUME_SEGMENTS_NO_OVERLAP (1 << 1)
|
|
#define EXEFMT_LOAD_ASSUME_SEGMENTS_PAGE_ALIGNED (1 << 2)
|
|
|
|
#define EXEFMT_LOAD_ASSUME_SEGMENTS_OK \
|
|
( \
|
|
EXEFMT_LOAD_ASSUME_SEGMENTS_SORTED | \
|
|
EXEFMT_LOAD_ASSUME_SEGMENTS_NO_OVERLAP | \
|
|
EXEFMT_LOAD_ASSUME_SEGMENTS_PAGE_ALIGNED \
|
|
)
|
|
|
|
/*
|
|
Minumum size of the buffer passed to each loader for identification of the
|
|
executable
|
|
*/
|
|
#define EXEFMT_LOAD_HEADER_SIZE (0x2000)
|
|
|
|
/* Special values for the base address of images */
|
|
/*
|
|
Base address can't be represented in an ULONG_PTR: any effective load address
|
|
will require relocation
|
|
*/
|
|
#define EXEFMT_LOAD_BASE_NONE ((ULONG_PTR)-1)
|
|
|
|
/* Base address never matters, relocation never required */
|
|
#define EXEFMT_LOAD_BASE_ANY ((ULONG_PTR)-2)
|
|
|
|
typedef NTSTATUS (NTAPI * PEXEFMT_CB_READ_FILE)
|
|
(
|
|
IN PVOID File,
|
|
IN PLARGE_INTEGER Offset,
|
|
IN ULONG Length,
|
|
OUT PVOID * Data,
|
|
OUT PVOID * AllocBase,
|
|
OUT PULONG ReadSize
|
|
);
|
|
|
|
typedef PMM_SECTION_SEGMENT (NTAPI * PEXEFMT_CB_ALLOCATE_SEGMENTS)
|
|
(
|
|
IN ULONG NrSegments
|
|
);
|
|
|
|
typedef NTSTATUS (NTAPI * PEXEFMT_LOADER)
|
|
(
|
|
IN CONST VOID * FileHeader,
|
|
IN SIZE_T FileHeaderSize,
|
|
IN PVOID File,
|
|
OUT PMM_IMAGE_SECTION_OBJECT ImageSectionObject,
|
|
OUT PULONG Flags,
|
|
IN PEXEFMT_CB_READ_FILE ReadFileCb,
|
|
IN PEXEFMT_CB_ALLOCATE_SEGMENTS AllocateSegmentsCb
|
|
);
|
|
|
|
/*
|
|
* STATUS CONSTANTS
|
|
*/
|
|
|
|
#define FACILITY_ROS_EXEFMT (0x10)
|
|
|
|
/*
|
|
* Returned by ExeFormat loaders to tell the caller the format isn't supported,
|
|
* as opposed to STATUS_INVALID_IMAGE_FORMAT meaning the format is supported,
|
|
* but the particular file is malformed
|
|
*/
|
|
#define STATUS_ROS_EXEFMT_UNKNOWN_FORMAT ((NTSTATUS)0xA0100001)
|
|
|
|
/*
|
|
* Returned by MmCreateSection to signal successful loading of an executable
|
|
* image, saving the caller the effort of determining the executable's format
|
|
* again. The full status to return is obtained by performing a bitwise OR of
|
|
* STATUS_ROS_EXEFMT_LOADED_FORMAT and the appropriate EXEFMT_LOADED_XXX
|
|
*/
|
|
#define FACILITY_ROS_EXEFMT_FORMAT (0x11)
|
|
#define STATUS_ROS_EXEFMT_LOADED_FORMAT ((NTSTATUS)0x60110000)
|
|
|
|
/* non-standard format, ZwQuerySection required to retrieve the format tag */
|
|
#define EXEFMT_LOADED_EXTENDED (0x0000FFFF)
|
|
|
|
/* Windows PE32/PE32+ */
|
|
#define EXEFMT_LOADED_PE32 (0x00000000)
|
|
#define EXEFMT_LOADED_PE64 (0x00000001)
|
|
|
|
/* Wine ELF */
|
|
#define EXEFMT_LOADED_WINE32 (0x00000002)
|
|
#define EXEFMT_LOADED_WINE64 (0x00000003)
|
|
|
|
/* regular ELF */
|
|
#define EXEFMT_LOADED_ELF32 (0x00000004)
|
|
#define EXEFMT_LOADED_ELF64 (0x00000005)
|
|
|
|
/* TODO: Intsafe should be made into a library, as it's generally useful */
|
|
static __inline BOOLEAN Intsafe_CanAddULongPtr(IN ULONG_PTR Addend1, IN ULONG_PTR Addend2)
|
|
{
|
|
return Addend1 <= (MAXULONG_PTR - Addend2);
|
|
}
|
|
|
|
static __inline BOOLEAN Intsafe_CanAddLong64(IN LONG64 Addend1, IN LONG64 Addend2)
|
|
{
|
|
return Addend1 <= (MAXLONGLONG - Addend2);
|
|
}
|
|
|
|
static __inline BOOLEAN Intsafe_CanAddULong32(IN ULONG Addend1, IN ULONG Addend2)
|
|
{
|
|
return Addend1 <= (MAXULONG - Addend2);
|
|
}
|
|
|
|
static __inline BOOLEAN Intsafe_AddULong32(OUT PULONG Result, IN ULONG Addend1, IN ULONG Addend2)
|
|
{
|
|
if(!Intsafe_CanAddULong32(Addend1, Addend2))
|
|
return FALSE;
|
|
|
|
*Result = Addend1 + Addend2;
|
|
return TRUE;
|
|
}
|
|
|
|
static __inline BOOLEAN Intsafe_CanMulULong32(IN ULONG Factor1, IN ULONG Factor2)
|
|
{
|
|
return Factor1 <= (MAXULONG / Factor2);
|
|
}
|
|
|
|
static __inline BOOLEAN Intsafe_CanOffsetPointer(IN CONST VOID * Pointer, IN SIZE_T Offset)
|
|
{
|
|
/* FIXME: (PVOID)MAXULONG_PTR isn't necessarily a valid address */
|
|
return Intsafe_CanAddULongPtr((ULONG_PTR)Pointer, Offset);
|
|
}
|
|
|
|
static __inline BOOLEAN IsPowerOf2(IN ULONG Number)
|
|
{
|
|
if(Number == 0)
|
|
return FALSE;
|
|
return (Number & (Number - 1)) == 0;
|
|
}
|
|
|
|
static __inline ULONG ModPow2(IN ULONG Address, IN ULONG Alignment)
|
|
{
|
|
ASSERT(IsPowerOf2(Alignment));
|
|
return Address & (Alignment - 1);
|
|
}
|
|
|
|
static __inline BOOLEAN IsAligned(IN ULONG Address, IN ULONG Alignment)
|
|
{
|
|
return ModPow2(Address, Alignment) == 0;
|
|
}
|
|
|
|
static __inline BOOLEAN AlignUp(OUT PULONG AlignedAddress, IN ULONG Address, IN ULONG Alignment)
|
|
{
|
|
ULONG nExcess = ModPow2(Address, Alignment);
|
|
|
|
if(nExcess == 0)
|
|
{
|
|
*AlignedAddress = Address;
|
|
return nExcess == 0;
|
|
}
|
|
else
|
|
return Intsafe_AddULong32(AlignedAddress, Address, Alignment - nExcess);
|
|
}
|
|
|
|
#define PEFMT_FIELDS_EQUAL(TYPE1_, TYPE2_, FIELD_) \
|
|
( \
|
|
(FIELD_OFFSET(TYPE1_, FIELD_) == FIELD_OFFSET(TYPE2_, FIELD_)) && \
|
|
(RTL_FIELD_SIZE(TYPE1_, FIELD_) == RTL_FIELD_SIZE(TYPE2_, FIELD_)) \
|
|
)
|
|
#endif
|
|
|
|
/* EOF */
|