1 #ifndef REACTOS_EXEFORMAT_H_INCLUDED_
2 #define REACTOS_EXEFORMAT_H_INCLUDED_ 1
7 /* OUT flags returned by a loader */
8 #define EXEFMT_LOAD_ASSUME_SEGMENTS_SORTED (1 << 0)
9 #define EXEFMT_LOAD_ASSUME_SEGMENTS_NO_OVERLAP (1 << 1)
10 #define EXEFMT_LOAD_ASSUME_SEGMENTS_PAGE_ALIGNED (1 << 2)
12 #define EXEFMT_LOAD_ASSUME_SEGMENTS_OK \
14 EXEFMT_LOAD_ASSUME_SEGMENTS_SORTED | \
15 EXEFMT_LOAD_ASSUME_SEGMENTS_NO_OVERLAP | \
16 EXEFMT_LOAD_ASSUME_SEGMENTS_PAGE_ALIGNED \
20 Minumum size of the buffer passed to each loader for identification of the
23 #define EXEFMT_LOAD_HEADER_SIZE (0x2000)
25 /* Special values for the base address of images */
27 Base address can't be represented in an ULONG_PTR: any effective load address
28 will require relocation
30 #define EXEFMT_LOAD_BASE_NONE ((ULONG_PTR)-1)
32 /* Base address never matters, relocation never required */
33 #define EXEFMT_LOAD_BASE_ANY ((ULONG_PTR)-2)
35 typedef NTSTATUS (NTAPI
* PEXEFMT_CB_READ_FILE
)
38 IN PLARGE_INTEGER Offset
,
41 OUT PVOID
* AllocBase
,
45 typedef PMM_SECTION_SEGMENT (NTAPI
* PEXEFMT_CB_ALLOCATE_SEGMENTS
)
50 typedef NTSTATUS (NTAPI
* PEXEFMT_LOADER
)
52 IN CONST VOID
* FileHeader
,
53 IN SIZE_T FileHeaderSize
,
55 OUT PMM_IMAGE_SECTION_OBJECT ImageSectionObject
,
57 IN PEXEFMT_CB_READ_FILE ReadFileCb
,
58 IN PEXEFMT_CB_ALLOCATE_SEGMENTS AllocateSegmentsCb
65 #define FACILITY_ROS_EXEFMT (0x10)
68 * Returned by ExeFormat loaders to tell the caller the format isn't supported,
69 * as opposed to STATUS_INVALID_IMAGE_FORMAT meaning the format is supported,
70 * but the particular file is malformed
72 #define STATUS_ROS_EXEFMT_UNKNOWN_FORMAT ((NTSTATUS)0xA0100001)
75 * Returned by MmCreateSection to signal successful loading of an executable
76 * image, saving the caller the effort of determining the executable's format
77 * again. The full status to return is obtained by performing a bitwise OR of
78 * STATUS_ROS_EXEFMT_LOADED_FORMAT and the appropriate EXEFMT_LOADED_XXX
80 #define FACILITY_ROS_EXEFMT_FORMAT (0x11)
81 #define STATUS_ROS_EXEFMT_LOADED_FORMAT ((NTSTATUS)0x60110000)
83 /* non-standard format, ZwQuerySection required to retrieve the format tag */
84 #define EXEFMT_LOADED_EXTENDED (0x0000FFFF)
86 /* Windows PE32/PE32+ */
87 #define EXEFMT_LOADED_PE32 (0x00000000)
88 #define EXEFMT_LOADED_PE64 (0x00000001)
91 #define EXEFMT_LOADED_WINE32 (0x00000002)
92 #define EXEFMT_LOADED_WINE64 (0x00000003)
95 #define EXEFMT_LOADED_ELF32 (0x00000004)
96 #define EXEFMT_LOADED_ELF64 (0x00000005)
98 /* TODO: Intsafe should be made into a library, as it's generally useful */
99 static __inline BOOLEAN
Intsafe_CanAddULongPtr(IN ULONG_PTR Addend1
, IN ULONG_PTR Addend2
)
101 return Addend1
<= (MAXULONG_PTR
- Addend2
);
104 static __inline BOOLEAN
Intsafe_CanAddLong64(IN LONG64 Addend1
, IN LONG64 Addend2
)
106 return Addend1
<= (MAXLONGLONG
- Addend2
);
109 static __inline BOOLEAN
Intsafe_CanAddULong32(IN ULONG Addend1
, IN ULONG Addend2
)
111 return Addend1
<= (MAXULONG
- Addend2
);
114 static __inline BOOLEAN
Intsafe_AddULong32(OUT PULONG Result
, IN ULONG Addend1
, IN ULONG Addend2
)
116 if(!Intsafe_CanAddULong32(Addend1
, Addend2
))
119 *Result
= Addend1
+ Addend2
;
123 static __inline BOOLEAN
Intsafe_CanMulULong32(IN ULONG Factor1
, IN ULONG Factor2
)
125 return Factor1
<= (MAXULONG
/ Factor2
);
128 static __inline BOOLEAN
Intsafe_CanOffsetPointer(IN CONST VOID
* Pointer
, IN SIZE_T Offset
)
130 /* FIXME: (PVOID)MAXULONG_PTR isn't necessarily a valid address */
131 return Intsafe_CanAddULongPtr((ULONG_PTR
)Pointer
, Offset
);
134 static __inline BOOLEAN
IsPowerOf2(IN ULONG Number
)
138 return (Number
& (Number
- 1)) == 0;
141 static __inline ULONG
ModPow2(IN ULONG Address
, IN ULONG Alignment
)
143 ASSERT(IsPowerOf2(Alignment
));
144 return Address
& (Alignment
- 1);
147 static __inline BOOLEAN
IsAligned(IN ULONG Address
, IN ULONG Alignment
)
149 return ModPow2(Address
, Alignment
) == 0;
152 static __inline BOOLEAN
AlignUp(OUT PULONG AlignedAddress
, IN ULONG Address
, IN ULONG Alignment
)
154 ULONG nExcess
= ModPow2(Address
, Alignment
);
158 *AlignedAddress
= Address
;
162 return Intsafe_AddULong32(AlignedAddress
, Address
, Alignment
- nExcess
);
165 #define PEFMT_FIELDS_EQUAL(TYPE1_, TYPE2_, FIELD_) \
167 (FIELD_OFFSET(TYPE1_, FIELD_) == FIELD_OFFSET(TYPE2_, FIELD_)) && \
168 (RTL_FIELD_SIZE(TYPE1_, FIELD_) == RTL_FIELD_SIZE(TYPE2_, FIELD_)) \