:pserver:cvsanon@mok.lvcm.com:/CVS/ReactOS reactos
[reactos.git] / lib / ntdll / rtl / image.c
1 /* $Id$
2  *
3  * COPYRIGHT:       See COPYING in the top level directory
4  * PROJECT:         ReactOS kernel
5  * FILE:            lib/ntdll/rtl/image.c
6  * PURPOSE:         Image handling functions
7  * PROGRAMMER:      Eric Kohl
8  * UPDATE HISTORY:
9  *                  17/03/2000 Created
10  */
11
12 #include <ddk/ntddk.h>
13 #include <ntdll/rtl.h>
14
15 #define NDEBUG
16 #include <ntdll/ntdll.h>
17
18 /* FUNCTIONS ****************************************************************/
19
20 PIMAGE_NT_HEADERS STDCALL
21 RtlImageNtHeader (IN PVOID BaseAddress)
22 {
23         PIMAGE_NT_HEADERS NtHeader;
24         PIMAGE_DOS_HEADER DosHeader = (PIMAGE_DOS_HEADER)BaseAddress;
25
26         if (DosHeader && DosHeader->e_magic != IMAGE_DOS_SIGNATURE)
27         {
28                 DPRINT1("DosHeader->e_magic %x\n", DosHeader->e_magic);
29                 DPRINT1("NtHeader %x\n", (BaseAddress + DosHeader->e_lfanew));
30         }
31
32 //      if (DosHeader && DosHeader->e_magic == IMAGE_DOS_SIGNATURE)
33 //      {
34                 NtHeader = (PIMAGE_NT_HEADERS)(BaseAddress + DosHeader->e_lfanew);
35                 if (NtHeader->Signature == IMAGE_NT_SIGNATURE)
36                         return NtHeader;
37 //      }
38         return NULL;
39 }
40
41
42 PVOID
43 STDCALL
44 RtlImageDirectoryEntryToData (
45         PVOID   BaseAddress,
46         BOOLEAN bFlag,
47         ULONG   Directory,
48         PULONG  Size
49         )
50 {
51         PIMAGE_NT_HEADERS NtHeader;
52         PIMAGE_SECTION_HEADER SectionHeader;
53         ULONG Va;
54         ULONG Count;
55
56         NtHeader = RtlImageNtHeader (BaseAddress);
57         if (NtHeader == NULL)
58                 return NULL;
59
60         if (Directory >= NtHeader->OptionalHeader.NumberOfRvaAndSizes)
61                 return NULL;
62
63         Va = NtHeader->OptionalHeader.DataDirectory[Directory].VirtualAddress;
64         if (Va == 0)
65                 return NULL;
66
67         if (Size)
68                 *Size = NtHeader->OptionalHeader.DataDirectory[Directory].Size;
69
70         if (bFlag)
71                 return (PVOID)(BaseAddress + Va);
72
73         /* image mapped as ordinary file, we must find raw pointer */
74         SectionHeader = (PIMAGE_SECTION_HEADER)(NtHeader + 1);
75         Count = NtHeader->FileHeader.NumberOfSections;
76         while (Count--)
77         {
78                 if (SectionHeader->VirtualAddress == Va)
79                         return (PVOID)(BaseAddress + SectionHeader->PointerToRawData);
80                 SectionHeader++;
81         }
82
83         return NULL;
84 }
85
86
87 PIMAGE_SECTION_HEADER
88 STDCALL
89 RtlImageRvaToSection (
90         PIMAGE_NT_HEADERS       NtHeader,
91         PVOID                   BaseAddress,
92         ULONG                   Rva
93         )
94 {
95         PIMAGE_SECTION_HEADER Section;
96         ULONG Va;
97         ULONG Count;
98
99         Count = NtHeader->FileHeader.NumberOfSections;
100         Section = (PIMAGE_SECTION_HEADER)((ULONG)&NtHeader->OptionalHeader +
101                                           NtHeader->FileHeader.SizeOfOptionalHeader);
102         while (Count)
103         {
104                 Va = Section->VirtualAddress;
105                 if ((Va <= Rva) &&
106                     (Rva < Va + Section->SizeOfRawData))
107                         return Section;
108                 Section++;
109         }
110         return NULL;
111 }
112
113
114 ULONG
115 STDCALL
116 RtlImageRvaToVa (
117         PIMAGE_NT_HEADERS       NtHeader,
118         PVOID                   BaseAddress,
119         ULONG                   Rva,
120         PIMAGE_SECTION_HEADER   *SectionHeader
121         )
122 {
123         PIMAGE_SECTION_HEADER Section = NULL;
124
125         if (SectionHeader)
126                 Section = *SectionHeader;
127
128         if (Section == NULL ||
129             Rva < Section->VirtualAddress ||
130             Rva >= Section->VirtualAddress + Section->SizeOfRawData)
131         {
132                 Section = RtlImageRvaToSection (NtHeader, BaseAddress, Rva);
133                 if (Section == NULL)
134                         return 0;
135
136                 if (SectionHeader)
137                         *SectionHeader = Section;
138         }
139
140         return (ULONG)(BaseAddress +
141                        Rva +
142                        Section->PointerToRawData -
143                        Section->VirtualAddress);
144 }
145
146 /* EOF */