#ifndef	entete_h
#define	entete_h

#include "type.h"

struct dos_header
{
	word	e_magic;
	word	e_cblp;
	word	e_cp;
	word	e_crlc;
	word	e_cparhdr;
	word	e_minalloc;
	word	e_maxalloc;
	word	e_ss;
	word	e_sp;
	word	e_csum;
	word	e_ip;
	word	e_cs;
	word	e_lfarlc;
	word	e_ovno;
	word	e_res[4];
	word	e_oemid;
	word	e_oeminfo;
	word	e_res2[10];
	dword	e_lfanew;
};

/* pour le champ e_magic */
#define	DOS_SIGNATURE	0x5a4d

/* pour le champ Machine */
#define	MACHINE_INCONNUE	0x0000
#define	MACHINE_386		0x014C
#define	MACHINE_486		0x014D
#define	MACHINE_PENTIUM		0x014E
#define	MACHINE_R3000		0x0162
#define	MACHINE_R4000		0x0166
#define	MACHINE_R10000		0x0168
#define	MACHINE_ALPHA		0x0184
#define	MACHINE_POWERPC		0x01F0

struct file_header
{
	word	Machine;
	word	NumberOfSections;
	dword	TimeDateStamp;
	dword	PointerToSymbolTable;
	dword	NumberOfSymbols;
	word	SizeOfOptionalHeader;
	word	Characteristics;
};

/* pour le champ Characteristics */
#define FILE_RELOCS_STRIPPED           0x0001  // Relocation info stripped from file.
#define FILE_EXECUTABLE_IMAGE          0x0002  // File is executable  (i.e. no unresolved externel references).
#define FILE_LINE_NUMS_STRIPPED        0x0004  // Line nunbers stripped from file.
#define FILE_LOCAL_SYMS_STRIPPED       0x0008  // Local symbols stripped from file.
#define FILE_BYTES_REVERSED_LO         0x0080  // Bytes of machine word are reversed.
#define FILE_32BIT_MACHINE             0x0100  // 32 bit word machine.
#define FILE_DEBUG_STRIPPED            0x0200  // Debugging info stripped from file in .DBG file
#define FILE_SYSTEM                    0x1000  // System File.
#define FILE_DLL                       0x2000  // File is a DLL.
#define FILE_BYTES_REVERSED_HI         0x8000  // Bytes of machine word are reversed.


struct data_directory
{
	dword	VirtualAddress;
	dword	Size;
};

struct optional_header
{
	word	Magic;
	byte	MajorLinkerVersion;
	byte	MinorLinkerVersion;
	dword	SizeOfCode;
	dword	SizeOfInitializedData;
	dword	SizeOfUninitializedData;
	dword	AddressOfEntryPoint;
	dword	BaseOfCode;
	dword	BaseOfData;
	dword	ImageBase;
	dword	SectionAlignement;
	dword	FileAlignement;
	word	MajorOperatingSystemVersion;
	word	MinorOperatingSystemVersion;
	word	MajorImageVersion;
	word	MinorImageVersion;
	word	MajorSubsystemVersion;
	word	MinorSubsystemVersion;
	dword	Reserved1;
	dword	SizeOfImage;
	dword	SizeOfHeaders;
	dword	CheckSum;
	word	Subsystem;
	word	DllCharacteristics;
	dword	SizeOfStackReserve;
	dword	SizeOfStackCommit;
	dword	SizeOfHeapReserve;
	dword	SizeOfHeapCommit;
	dword	LoaderFlags;
	dword	NumberOfRvaAndSizes;  /* le nombre d'elements valable du tableau
									suivant */
	struct data_directory DataDirectory[16];
};

// Directory Entries

#define DIRECTORY_ENTRY_EXPORT         0   // Export Directory
#define DIRECTORY_ENTRY_IMPORT         1   // Import Directory
#define DIRECTORY_ENTRY_RESOURCE       2   // Resource Directory
#define DIRECTORY_ENTRY_EXCEPTION      3   // Exception Directory
#define DIRECTORY_ENTRY_SECURITY       4   // Security Directory
#define DIRECTORY_ENTRY_BASERELOC      5   // Base Relocation Table
#define DIRECTORY_ENTRY_DEBUG          6   // Debug Directory
#define DIRECTORY_ENTRY_COPYRIGHT      7   // Description String
#define DIRECTORY_ENTRY_GLOBALPTR      8   // Machine Value (MIPS GP)
#define DIRECTORY_ENTRY_TLS            9   // TLS Directory
#define DIRECTORY_ENTRY_LOAD_CONFIG   10   // Load Configuration Directory
#define DIRECTORY_ENTRY_BOUND_IMPORT  11   // Bound Import Directory in headers
#define DIRECTORY_ENTRY_IAT           12   // Import Address Table

#define	SIGNATURE_PE	0x4550

struct nt_header
{
	dword	Signature;
	struct file_header	FileHeader;
	struct optional_header	OptionalHeader;
};

struct section_header
{
	byte	Name[8];
	union {
		dword	PhysicalAddress;
		dword	VirtualSize;
	} Misc;
	dword	VirtualAddress;
	dword	SizeOfRawData;		/* la taille des donnees dans le fichier */
	dword	PointerToRawData;	/* l'offset dans le fichier */
	dword	PointerToRelocations;
	dword	PointerToLinenumbers;
	word	NumberOfRelocations;
	word	NumberOfLinenumbers;
	dword	Characteristics;
};	

/* les valeurs predefinies du champ Characteristics */
#define	IMAGE_SCN_TYPE_NO_PAD	0x00000008 /* Reserve */
#define	IMAGE_SCN_CNT_CODE	0x00000020 /* La section contient du code de programme */
#define	IMAGE_SCN_CNT_INITIALIZED_DATA	0x00000040 /* La section contient des donnees initialisees */
#define	IMAGE_SCN_CNT_UNINITIALIZED_DATA	0x00000080 /* la section contient des donnees 
								non-initialisees */
#define	IMAGE_SCN_LNK_OTHER	0x00000100 /* reserve */
#define	IMAGE_SCN_LNK_INFO	0x00000200 /* la section contient des informations supplementaires,
						par exemple pour le debuggeur */
#define	IMAGE_SCN_LNK_REMOVE	0x00000800 /* la section ne doit pas etre reproduite en memoire */
#define	IMAGE_SCN_LNK_NRELOC_OVFL	0x01000000 /* la section contient des donnnees de relocations
							etendues */
#define	IMAGE_SCN_MEM_DISCARDABLE	0x02000000 /* le contenu de la section n'a pas besoin d'etre
							conserve */
#define	IMAGE_SCN_MEM_NOT_CACHED	0x04000000 /* ne pas mettre en memoire cache le contenu de la
							section */
#define	IMAGE_SCN_MEM_NOT_PAGED	0x08000000 /* ne pas mettre dans le fichier d'echange le contenu de la
						section */
#define	IMAGE_SCN_MEM_SHARED	0x10000000 /* la section ne peut pas etre utilise en meme temps par
						plusieurs processus */
#define	IMAGE_SCN_MEM_EXECUTE	0x20000000 /* la section est executable */
#define	IMAGE_SCN_MEM_READ	0x40000000 /* la section peut-etre lue */
#define	IMAGE_SCN_MEM_WRITE	0x80000000 /* la section peut-etre modifie */

struct export_directory
{
    dword   Characteristics;
    dword   TimeDateStamp;
    word    MajorVersion;
    word    MinorVersion;
    dword   Name;				// RVA d'une chaine C representant le nom de la dll
    dword   Base;				// ???? =1
    dword   NumberOfFunctions;
    dword   NumberOfNames;		// = NumberOfFunctions
    dword	AddressOfFunctions;	// RVA d'une liste de points d'entree RVA
    dword	AddressOfNames;		// RVA d'une liste de RVA vers de chaines C
    dword   AddressOfNameOrdinals;	// RVA d'un tableau de word, de longueur 
									// NumberOfFunctions
};

struct import_entry
{
	dword	OriginalFirstThunk;
	dword	TimeDateStamp;
	dword	ForwarderChain;
    dword	Name;
    dword	FirstThunk;
};

struct relocation_directory
{
	dword	VirtualAddress; /* adresse virtuelle du bloc ou se font les relocations */
	dword	SizeOfBlock;	// taille de cette structure + des structures 
							// relocation_entry qui suivent (ces dernieres sont
							// donc au nombre de (SizeOfBlock-8)/2
};

struct relocation_entry
{
	word	TypeOffset;
	//	(TypeOffset >> 12) est le type
	//	(TypeOffset&0xfff) est l'offset dans le bloc
};

#define	TYPE_RELOC_ABSOLUTE	0
#define	TYPE_RELOC_HIGH		1
#define	TYPE_RELOC_LOW		2
#define	TYPE_RELOC_HIGHLOW	3
#define	TYPE_RELOC_HIGHADJ	4
#define	TYPE_RELOC_MIPS_JMPADDR	5

struct debug_directory
{
	dword	Characteristics;
    dword   TimeDateStamp;
    word    MajorVersion;
    word    MinorVersion;
    dword   Type;
    dword   SizeOfData;
    dword   AddressOfRawData;
    dword   PointerToRawData;
};

#define DEBUG_TYPE_UNKNOWN          0
#define DEBUG_TYPE_COFF             1
#define DEBUG_TYPE_CODEVIEW         2
#define DEBUG_TYPE_FPO              3
#define DEBUG_TYPE_MISC             4
#define DEBUG_TYPE_EXCEPTION        5
#define DEBUG_TYPE_FIXUP            6
#define DEBUG_TYPE_OMAP_TO_SRC      7
#define DEBUG_TYPE_OMAP_FROM_SRC    8

struct fpo_entry
{
	dword	ulOffStart;             // RVA of 1st byte of function code
	dword	cbProcSize;             // # bytes in function
	dword	cdwLocals;              // # bytes in locals/4
	word	cdwParams;              // # bytes in params/4
	word	cbProlog : 8;           // # bytes in prolog
	word	cbRegs   : 3;           // # regs saved
	word	fHasSEH  : 1;           // TRUE if SEH in func
	word	fUseBP   : 1;           // TRUE if EBP has been allocated
	word	reserved : 1;           // reserved for future use
	word	cbFrame  : 2;           // frame type
};

struct linenumber_entry
{
	dword	VirtualAddress;
	word	Line;
};

#endif
