Avoid excessive heap memory reallocation when generating EMF
[wine] / dlls / imagehlp / access.c
1 /*
2  *      IMAGEHLP library
3  *
4  *      Copyright 1998  Patrik Stridvall
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include <stdarg.h>
22 #include <string.h>
23 #include "windef.h"
24 #include "winbase.h"
25 #include "winnt.h"
26 #include "winerror.h"
27 #include "wine/debug.h"
28 #include "imagehlp.h"
29
30 WINE_DEFAULT_DEBUG_CHANNEL(imagehlp);
31
32 /***********************************************************************
33  *           Data
34  */
35
36 static PLOADED_IMAGE IMAGEHLP_pFirstLoadedImage=NULL;
37 static PLOADED_IMAGE IMAGEHLP_pLastLoadedImage=NULL;
38
39 static LOADED_IMAGE IMAGEHLP_EmptyLoadedImage = {
40   NULL,       /* ModuleName */
41   0,          /* hFile */
42   NULL,       /* MappedAddress */
43   NULL,       /* FileHeader */
44   NULL,       /* LastRvaSection */
45   0,          /* NumberOfSections */
46   NULL,       /* Sections */
47   1,          /* Characteristics */
48   FALSE,      /* fSystemImage */
49   FALSE,      /* fDOSImage */
50   { &IMAGEHLP_EmptyLoadedImage.Links, &IMAGEHLP_EmptyLoadedImage.Links }, /* Links */
51   148,        /* SizeOfImage; */
52 };
53
54 extern HANDLE IMAGEHLP_hHeap;
55
56 /***********************************************************************
57  *              EnumerateLoadedModules (IMAGEHLP.@)
58  */
59 BOOL WINAPI EnumerateLoadedModules(
60   HANDLE hProcess,
61   PENUMLOADED_MODULES_CALLBACK EnumLoadedModulesCallback,
62   PVOID UserContext)
63 {
64   FIXME("(%p, %p, %p): stub\n",
65     hProcess, EnumLoadedModulesCallback, UserContext
66   );
67   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
68   return FALSE;
69 }
70
71 /***********************************************************************
72  *              GetTimestampForLoadedLibrary (IMAGEHLP.@)
73  */
74 DWORD WINAPI GetTimestampForLoadedLibrary(HMODULE Module)
75 {
76   FIXME("(%p): stub\n", Module);
77   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
78   return 0;
79 }
80
81 /***********************************************************************
82  *              GetImageConfigInformation (IMAGEHLP.@)
83  */
84 BOOL WINAPI GetImageConfigInformation(
85   PLOADED_IMAGE LoadedImage,
86   PIMAGE_LOAD_CONFIG_DIRECTORY ImageConfigInformation)
87 {
88   FIXME("(%p, %p): stub\n",
89     LoadedImage, ImageConfigInformation
90   );
91   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
92   return FALSE;
93 }
94
95 /***********************************************************************
96  *              GetImageUnusedHeaderBytes (IMAGEHLP.@)
97  */
98 DWORD WINAPI GetImageUnusedHeaderBytes(
99   PLOADED_IMAGE LoadedImage,
100   LPDWORD SizeUnusedHeaderBytes)
101 {
102   FIXME("(%p, %p): stub\n",
103     LoadedImage, SizeUnusedHeaderBytes
104   );
105   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
106   return 0;
107 }
108
109 /***********************************************************************
110  *              ImageDirectoryEntryToData (IMAGEHLP.@)
111  */
112 PVOID WINAPI ImageDirectoryEntryToData(
113   PVOID Base, BOOLEAN MappedAsImage, USHORT DirectoryEntry, PULONG Size)
114 {
115   FIXME("(%p, %d, %hd, %p): stub\n",
116     Base, MappedAsImage, DirectoryEntry, Size
117   );
118   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
119   return NULL;
120 }
121
122 /***********************************************************************
123  *              ImageLoad (IMAGEHLP.@)
124  */
125 PLOADED_IMAGE WINAPI ImageLoad(LPSTR DllName, LPSTR DllPath)
126 {
127   PLOADED_IMAGE pLoadedImage;
128
129   FIXME("(%s, %s): stub\n", DllName, DllPath);
130           
131   pLoadedImage = HeapAlloc(IMAGEHLP_hHeap, 0, sizeof(LOADED_IMAGE));
132   if (pLoadedImage)
133     pLoadedImage->FileHeader = HeapAlloc(IMAGEHLP_hHeap, 0, sizeof(IMAGE_NT_HEADERS));
134   
135   return pLoadedImage;
136 }
137
138 /***********************************************************************
139  *              ImageNtHeader (IMAGEHLP.@)
140  */
141 PIMAGE_NT_HEADERS WINAPI ImageNtHeader(PVOID Base)
142 {
143   TRACE("(%p)\n", Base);
144   return (PIMAGE_NT_HEADERS)
145     ((LPBYTE) Base + ((PIMAGE_DOS_HEADER) Base)->e_lfanew);
146 }
147
148 /***********************************************************************
149  *              ImageRvaToSection (IMAGEHLP.@)
150  */
151 PIMAGE_SECTION_HEADER WINAPI ImageRvaToSection(
152   PIMAGE_NT_HEADERS NtHeaders, PVOID Base, ULONG Rva)
153 {
154   FIXME("(%p, %p, %ld): stub\n", NtHeaders, Base, Rva);
155   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
156   return NULL;
157 }
158
159 /***********************************************************************
160  *              ImageRvaToVa (IMAGEHLP.@)
161  */
162 PVOID WINAPI ImageRvaToVa(
163   PIMAGE_NT_HEADERS NtHeaders, PVOID Base, ULONG Rva,
164   PIMAGE_SECTION_HEADER *LastRvaSection)
165 {
166   FIXME("(%p, %p, %ld, %p): stub\n",
167     NtHeaders, Base, Rva, LastRvaSection
168   );
169   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
170   return NULL;
171 }
172
173 /***********************************************************************
174  *              ImageUnload (IMAGEHLP.@)
175  */
176 BOOL WINAPI ImageUnload(PLOADED_IMAGE pLoadedImage)
177 {
178   LIST_ENTRY *pCurrent, *pFind;
179
180   TRACE("(%p)\n", pLoadedImage);
181   
182   if(!IMAGEHLP_pFirstLoadedImage || !pLoadedImage)
183     {
184       /* No image loaded or null pointer */
185       SetLastError(ERROR_INVALID_PARAMETER);
186       return FALSE;
187     }
188
189   pFind=&pLoadedImage->Links;
190   pCurrent=&IMAGEHLP_pFirstLoadedImage->Links;
191   while((pCurrent != pFind) &&
192     (pCurrent != NULL))
193       pCurrent = pCurrent->Flink;
194   if(!pCurrent)
195     {
196       /* Not found */
197       SetLastError(ERROR_INVALID_PARAMETER);
198       return FALSE;
199     }
200
201   if(pCurrent->Blink)
202     pCurrent->Blink->Flink = pCurrent->Flink;
203   else
204     IMAGEHLP_pFirstLoadedImage = pCurrent->Flink?CONTAINING_RECORD(
205       pCurrent->Flink, LOADED_IMAGE, Links):NULL;
206
207   if(pCurrent->Flink)
208     pCurrent->Flink->Blink = pCurrent->Blink;
209   else
210     IMAGEHLP_pLastLoadedImage = pCurrent->Blink?CONTAINING_RECORD(
211       pCurrent->Blink, LOADED_IMAGE, Links):NULL;
212
213   return FALSE;
214 }
215
216 /***********************************************************************
217  *              MapAndLoad (IMAGEHLP.@)
218  */
219 BOOL WINAPI MapAndLoad(
220   LPSTR pszImageName, LPSTR pszDllPath, PLOADED_IMAGE pLoadedImage,
221   BOOL bDotDll, BOOL bReadOnly)
222 {
223   CHAR szFileName[MAX_PATH];
224   HANDLE hFile = NULL;
225   HANDLE hFileMapping = NULL;
226   HMODULE hModule = NULL;
227   PIMAGE_NT_HEADERS pNtHeader = NULL;
228
229   TRACE("(%s, %s, %p, %d, %d)\n", pszImageName, pszDllPath, pLoadedImage,
230                                     bDotDll, bReadOnly);
231   
232   /* PathCombine(&szFileName, pszDllPath, pszImageName); */
233   /* PathRenameExtension(&szFileName, bDotDll?:"dll":"exe"); */
234
235   /* FIXME: Check if the file already loaded (use IMAGEHLP_pFirstLoadedImage) */
236   if(!(hFile = CreateFileA(
237     szFileName, GENERIC_READ, 1, /* FIXME: FILE_SHARE_READ not defined */
238     NULL, OPEN_EXISTING, 0, NULL)))
239     {
240       SetLastError(ERROR_FILE_NOT_FOUND);
241       goto Error;
242     }
243
244   if(!(hFileMapping = CreateFileMappingA(
245     hFile, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL)))
246     {
247       DWORD dwLastError = GetLastError();
248       WARN("CreateFileMapping: Error = %ld\n", dwLastError);
249       SetLastError(dwLastError);
250       goto Error;
251     }
252   CloseHandle(hFile);
253   hFile = NULL;
254
255   if(!(hModule = (HMODULE) MapViewOfFile(
256     hFileMapping, FILE_MAP_READ, 0, 0, 0)))
257     {
258       DWORD dwLastError = GetLastError();
259       WARN("MapViewOfFile: Error = %ld\n", dwLastError);
260       SetLastError(dwLastError);
261       goto Error;
262     }
263
264   CloseHandle(hFileMapping);
265   hFileMapping=NULL;
266
267   pLoadedImage = (PLOADED_IMAGE) HeapAlloc(
268     IMAGEHLP_hHeap, 0, sizeof(LOADED_IMAGE)
269   );
270
271   pNtHeader = ImageNtHeader((PVOID) hModule);
272
273   pLoadedImage->ModuleName = HeapAlloc(IMAGEHLP_hHeap, 0, strlen(pszDllPath)+1); /* FIXME: Correct? */
274   strcpy( pLoadedImage->ModuleName, pszDllPath );
275   pLoadedImage->hFile = hFile;
276   pLoadedImage->MappedAddress = (PUCHAR) hModule;
277   pLoadedImage->FileHeader = pNtHeader;
278   pLoadedImage->Sections = (PIMAGE_SECTION_HEADER)
279     ((LPBYTE) &pNtHeader->OptionalHeader +
280       pNtHeader->FileHeader.SizeOfOptionalHeader);
281   pLoadedImage->NumberOfSections =
282     pNtHeader->FileHeader.NumberOfSections;
283   pLoadedImage->SizeOfImage =
284     pNtHeader->OptionalHeader.SizeOfImage;
285   pLoadedImage->Characteristics =
286     pNtHeader->FileHeader.Characteristics;
287   pLoadedImage->LastRvaSection = pLoadedImage->Sections;
288
289   pLoadedImage->fSystemImage = FALSE; /* FIXME */
290   pLoadedImage->fDOSImage = FALSE;    /* FIXME */
291
292   /* FIXME: Make thread safe */
293   pLoadedImage->Links.Flink = NULL;
294   pLoadedImage->Links.Blink = &IMAGEHLP_pLastLoadedImage->Links;
295   if(IMAGEHLP_pLastLoadedImage)
296     IMAGEHLP_pLastLoadedImage->Links.Flink = &pLoadedImage->Links;
297   IMAGEHLP_pLastLoadedImage = pLoadedImage;
298   if(!IMAGEHLP_pFirstLoadedImage)
299     IMAGEHLP_pFirstLoadedImage = pLoadedImage;
300
301   return TRUE;
302
303 Error:
304   if(hModule)
305     UnmapViewOfFile((PVOID) hModule);
306   if(hFileMapping)
307     CloseHandle(hFileMapping);
308   if(hFile)
309     CloseHandle(hFile);
310   return FALSE;
311 }
312
313 /***********************************************************************
314  *              SetImageConfigInformation (IMAGEHLP.@)
315  */
316 BOOL WINAPI SetImageConfigInformation(
317   PLOADED_IMAGE LoadedImage,
318   PIMAGE_LOAD_CONFIG_DIRECTORY ImageConfigInformation)
319 {
320   FIXME("(%p, %p): stub\n",
321     LoadedImage, ImageConfigInformation
322   );
323   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
324   return FALSE;
325 }
326
327 /***********************************************************************
328  *              UnMapAndLoad (IMAGEHLP.@)
329  */
330 BOOL WINAPI UnMapAndLoad(PLOADED_IMAGE LoadedImage)
331 {
332   FIXME("(%p): stub\n", LoadedImage);
333   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
334   return FALSE;
335 }