update for HEAD-2003091401
[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 /*
21  * @implemented
22  */
23 PIMAGE_NT_HEADERS STDCALL
24 RtlImageNtHeader (IN PVOID BaseAddress)
25 {
26   PIMAGE_NT_HEADERS NtHeader;
27   PIMAGE_DOS_HEADER DosHeader = (PIMAGE_DOS_HEADER)BaseAddress;
28
29   if (DosHeader && DosHeader->e_magic != IMAGE_DOS_SIGNATURE)
30     {
31       DPRINT1("DosHeader->e_magic %x\n", DosHeader->e_magic);
32       DPRINT1("NtHeader %x\n", (BaseAddress + DosHeader->e_lfanew));
33     }
34
35   if (DosHeader && DosHeader->e_magic == IMAGE_DOS_SIGNATURE)
36     {
37       NtHeader = (PIMAGE_NT_HEADERS)(BaseAddress + DosHeader->e_lfanew);
38       if (NtHeader->Signature == IMAGE_NT_SIGNATURE)
39         return NtHeader;
40     }
41
42   return NULL;
43 }
44
45
46 /*
47  * @implemented
48  */
49 PVOID
50 STDCALL
51 RtlImageDirectoryEntryToData (
52         PVOID   BaseAddress,
53         BOOLEAN bFlag,
54         ULONG   Directory,
55         PULONG  Size
56         )
57 {
58         PIMAGE_NT_HEADERS NtHeader;
59         PIMAGE_SECTION_HEADER SectionHeader;
60         ULONG Va;
61         ULONG Count;
62
63         NtHeader = RtlImageNtHeader (BaseAddress);
64         if (NtHeader == NULL)
65                 return NULL;
66
67         if (Directory >= NtHeader->OptionalHeader.NumberOfRvaAndSizes)
68                 return NULL;
69
70         Va = NtHeader->OptionalHeader.DataDirectory[Directory].VirtualAddress;
71         if (Va == 0)
72                 return NULL;
73
74         if (Size)
75                 *Size = NtHeader->OptionalHeader.DataDirectory[Directory].Size;
76
77         if (bFlag)
78                 return (PVOID)(BaseAddress + Va);
79
80         /* image mapped as ordinary file, we must find raw pointer */
81         SectionHeader = (PIMAGE_SECTION_HEADER)(NtHeader + 1);
82         Count = NtHeader->FileHeader.NumberOfSections;
83         while (Count--)
84         {
85                 if (SectionHeader->VirtualAddress == Va)
86                         return (PVOID)(BaseAddress + SectionHeader->PointerToRawData);
87                 SectionHeader++;
88         }
89
90         return NULL;
91 }
92
93
94 /*
95  * @implemented
96  */
97 PIMAGE_SECTION_HEADER
98 STDCALL
99 RtlImageRvaToSection (
100         PIMAGE_NT_HEADERS       NtHeader,
101         PVOID                   BaseAddress,
102         ULONG                   Rva
103         )
104 {
105         PIMAGE_SECTION_HEADER Section;
106         ULONG Va;
107         ULONG Count;
108
109         Count = NtHeader->FileHeader.NumberOfSections;
110         Section = (PIMAGE_SECTION_HEADER)((ULONG)&NtHeader->OptionalHeader +
111                                           NtHeader->FileHeader.SizeOfOptionalHeader);
112         while (Count)
113         {
114                 Va = Section->VirtualAddress;
115                 if ((Va <= Rva) &&
116                     (Rva < Va + Section->SizeOfRawData))
117                         return Section;
118                 Section++;
119         }
120         return NULL;
121 }
122
123
124 /*
125  * @implemented
126  */
127 ULONG
128 STDCALL
129 RtlImageRvaToVa (
130         PIMAGE_NT_HEADERS       NtHeader,
131         PVOID                   BaseAddress,
132         ULONG                   Rva,
133         PIMAGE_SECTION_HEADER   *SectionHeader
134         )
135 {
136         PIMAGE_SECTION_HEADER Section = NULL;
137
138         if (SectionHeader)
139                 Section = *SectionHeader;
140
141         if (Section == NULL ||
142             Rva < Section->VirtualAddress ||
143             Rva >= Section->VirtualAddress + Section->SizeOfRawData)
144         {
145                 Section = RtlImageRvaToSection (NtHeader, BaseAddress, Rva);
146                 if (Section == NULL)
147                         return 0;
148
149                 if (SectionHeader)
150                         *SectionHeader = Section;
151         }
152
153         return (ULONG)(BaseAddress +
154                        Rva +
155                        Section->PointerToRawData -
156                        Section->VirtualAddress);
157 }
158
159 /* EOF */