This one is for Steven... 18 months later, I kept my promise ;)
authorAlex Ionescu <aionescu@gmail.com>
Sun, 6 Nov 2005 10:48:14 +0000 (10:48 +0000)
committerAlex Ionescu <aionescu@gmail.com>
Sun, 6 Nov 2005 10:48:14 +0000 (10:48 +0000)
- BindImage & friends refactoring of my original code. Fixed two or three dozen bugs, stopped making assumptions about everything, actually checked for failure, used dynamic allocation instead of 32 static structures, fixed a lot of broken code, fixed some helper functions, made the code as 64-bit compatible as I could (checked with msvc WP64 + prefast).
- Remove internal.c and use NDK instead
- Remove debug.c and symbol.c like WINE have done
- Rewrite the entire exports file to update it for XP. Forward almost all the functions to dbghelp, like WINE have done (note: windows DLL used delayed imports instead).
- Cleanup source to add implemented/unimplemented tags, source header, and precompiled header.
- Sync with latest code from WINE.

Tested with Quicken 2004 & its patches (which make extensive use of BindImage) as well as random bindings of some applications on my disk. Worked perfectly in Windows.

svn path=/trunk/; revision=19025

13 files changed:
reactos/lib/imagehlp/access.c
reactos/lib/imagehlp/debug.c [deleted file]
reactos/lib/imagehlp/imagehlp.def
reactos/lib/imagehlp/imagehlp.xml
reactos/lib/imagehlp/imagehlp_main.c
reactos/lib/imagehlp/integrity.c
reactos/lib/imagehlp/internal.c [deleted file]
reactos/lib/imagehlp/modify.c
reactos/lib/imagehlp/precomp.h [new file with mode: 0644]
reactos/lib/imagehlp/symbol.c [deleted file]
reactos/lib/imagehlp/winehq2ros.patch [deleted file]
reactos/w32api/include/imagehlp.h
reactos/w32api/include/winnt.h

index 764ff02..7f2ce9b 100644 (file)
 /*
- *     IMAGEHLP library
- *
- *     Copyright 1998  Patrik Stridvall
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         Imagehlp Libary
+ * FILE:            lib/imagehlp/access.c
+ * PURPOSE:         Image (un)load/mapping and data directory/section access
+ * PROGRAMMER:      Patrik Stridvall
  */
 
-#include <stdarg.h>
-#include <string.h>
-#include "windef.h"
-#include "winbase.h"
-#include "winnt.h"
-#include "winerror.h"
-#include "wine/debug.h"
-#include "imagehlp.h"
-
-/* Couple of Hacks */
-extern inline DWORD WINAPI GetLastError(void)
-{
-    DWORD ret;
-    __asm__ __volatile__( ".byte 0x64\n\tmovl 0x60,%0" : "=r" (ret) );
-    return ret;
-}
+/* INCLUDES ******************************************************************/
 
-#define InitializeListHead(ListHead) (\
-    (ListHead)->Flink = (ListHead)->Blink = (ListHead))
-
-#define InsertTailList(ListHead,Entry) {\
-    PLIST_ENTRY _EX_Blink;\
-    PLIST_ENTRY _EX_ListHead;\
-    _EX_ListHead = (ListHead);\
-    _EX_Blink = _EX_ListHead->Blink;\
-    (Entry)->Flink = _EX_ListHead;\
-    (Entry)->Blink = _EX_Blink;\
-    _EX_Blink->Flink = (Entry);\
-    _EX_ListHead->Blink = (Entry);\
-    }
+#include "precomp.h"
 
-WINE_DEFAULT_DEBUG_CHANNEL(imagehlp);
+//#define NDEBUG
+#include <debug.h>
 
-/***********************************************************************
- *           Data
- */
+/* DATA **********************************************************************/
 
-static PLOADED_IMAGE IMAGEHLP_pFirstLoadedImage=NULL;
-static PLOADED_IMAGE IMAGEHLP_pLastLoadedImage=NULL;
-
-static LOADED_IMAGE IMAGEHLP_EmptyLoadedImage = {
-  NULL,       /* ModuleName */
-  0,          /* hFile */
-  NULL,       /* MappedAddress */
-  NULL,       /* FileHeader */
-  NULL,       /* LastRvaSection */
-  0,          /* NumberOfSections */
-  NULL,       /* Sections */
-  1,          /* Characteristics */
-  FALSE,      /* fSystemImage */
-  FALSE,      /* fDOSImage */
-  { &IMAGEHLP_EmptyLoadedImage.Links, &IMAGEHLP_EmptyLoadedImage.Links }, /* Links */
-  148,        /* SizeOfImage; */
-};
-
-extern HANDLE IMAGEHLP_hHeap;
 BOOLEAN DllListInitialized;
 LIST_ENTRY ImageLoadListHead;
 
-/***********************************************************************
- *             EnumerateLoadedModules (IMAGEHLP.@)
- */
-BOOL WINAPI EnumerateLoadedModules(
-  HANDLE hProcess,
-  PENUMLOADED_MODULES_CALLBACK EnumLoadedModulesCallback,
-  PVOID UserContext)
+/* FUNCTIONS *****************************************************************/
+
+PVOID
+IMAGEAPI
+ImageDirectoryEntryToData32(PVOID Base,
+                            BOOLEAN MappedAsImage,
+                            USHORT DirectoryEntry,
+                            PULONG Size,
+                            PIMAGE_SECTION_HEADER *FoundHeader OPTIONAL,
+                            PIMAGE_FILE_HEADER FileHeader,
+                            PIMAGE_OPTIONAL_HEADER OptionalHeader)
 {
-  FIXME("(%p, %p, %p): stub\n",
-    hProcess, EnumLoadedModulesCallback, UserContext
-  );
-  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-  return FALSE;
+    ULONG i;
+    PIMAGE_SECTION_HEADER CurrentSection;
+    ULONG DirectoryEntryVA;
+
+    /* Check if this entry is invalid */
+    if (DirectoryEntry >= OptionalHeader->NumberOfRvaAndSizes)
+    {
+        /* Nothing found */
+        *Size = 0;
+        return NULL;
+    }
+
+    /* Get the VA of the Directory Requested */
+    DirectoryEntryVA = OptionalHeader->DataDirectory[DirectoryEntry].VirtualAddress;
+    if (!DirectoryEntryVA)
+    {
+        /* It doesn't exist */
+        *Size = 0;
+        return NULL;
+    }
+
+    /* Get the size of the Directory Requested */
+    *Size = OptionalHeader->DataDirectory[DirectoryEntry].Size;
+
+    /* Check if it was mapped as an image or if the entry is within the headers */
+    if ((MappedAsImage) || (DirectoryEntryVA < OptionalHeader->SizeOfHeaders))
+    {
+        /* No header found */
+        if (FoundHeader) *FoundHeader = NULL;
+        
+        /* And simply return the VA */
+        return (PVOID)((ULONG_PTR)Base + DirectoryEntryVA);
+    }
+
+    /* Read the first Section */
+    CurrentSection = (PIMAGE_SECTION_HEADER)((ULONG_PTR)OptionalHeader +
+                                             FileHeader->SizeOfOptionalHeader);
+    
+    /* Loop through every section*/
+    for (i = 0; i < FileHeader->NumberOfSections; i++)
+    {    
+        /* If the Directory VA is located inside this section's VA, then this section belongs to this Directory */
+        if ((DirectoryEntryVA >= CurrentSection->VirtualAddress) && 
+            (DirectoryEntryVA < (CurrentSection->VirtualAddress +
+                                 CurrentSection->SizeOfRawData)))
+        {
+            /* Return the section header */
+            if (FoundHeader) *FoundHeader = CurrentSection;
+            return ((PVOID)((ULONG_PTR)Base +
+                            (DirectoryEntryVA - CurrentSection->VirtualAddress) +
+                            CurrentSection->PointerToRawData));
+        }
+
+        /* Move to the next section */
+        CurrentSection++;
+    }
+
+    /* If we got here, then we didn't find anything */
+    return NULL;
 }
 
-/***********************************************************************
- *             GetTimestampForLoadedLibrary (IMAGEHLP.@)
+/*
+ * @unimplemented
  */
-DWORD WINAPI GetTimestampForLoadedLibrary(HMODULE Module)
+DWORD
+IMAGEAPI
+GetTimestampForLoadedLibrary(HMODULE Module)
 {
-  FIXME("(%p): stub\n", Module);
-  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-  return 0;
+    UNIMPLEMENTED;
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return 0;
 }
 
-/***********************************************************************
- *             GetImageConfigInformation (IMAGEHLP.@)
+/*
+ * @unimplemented
  */
-BOOL WINAPI GetImageConfigInformation(
-  PLOADED_IMAGE LoadedImage,
-  PIMAGE_LOAD_CONFIG_DIRECTORY ImageConfigInformation)
+BOOL
+IMAGEAPI
+GetImageConfigInformation(PLOADED_IMAGE LoadedImage,
+                          PIMAGE_LOAD_CONFIG_DIRECTORY ImageConfigInformation)
 {
-  FIXME("(%p, %p): stub\n",
-    LoadedImage, ImageConfigInformation
-  );
-  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-  return FALSE;
+    UNIMPLEMENTED;
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return FALSE;
 }
 
-/***********************************************************************
- *             GetImageUnusedHeaderBytes (IMAGEHLP.@)
+/*
+ * @implemented
  */
 DWORD 
-WINAPI 
-GetImageUnusedHeaderBytes(
-    PLOADED_IMAGE LoadedImage,
-    LPDWORD SizeUnusedHeaderBytes
-    )
+IMAGEAPI 
+GetImageUnusedHeaderBytes(PLOADED_IMAGE LoadedImage,
+                          LPDWORD SizeUnusedHeaderBytes)
 {
-    DWORD                                              FirstFreeByte;
-    PIMAGE_OPTIONAL_HEADER             OptionalHeader32 = NULL;
-    PIMAGE_NT_HEADERS                  NtHeaders;
-       ULONG                                           i;
+    SIZE_T FirstFreeByte;
+    PIMAGE_OPTIONAL_HEADER OptionalHeader = NULL;
+    PIMAGE_NT_HEADERS NtHeaders;
+    ULONG i;
 
-       /* Read the NT Headers */
+    /* Read the NT Headers */
     NtHeaders = LoadedImage->FileHeader;
 
-       /* Find the first free byte, which is after all the headers and sections */
-    FirstFreeByte = (ULONG_PTR)NtHeaders - (ULONG_PTR)LoadedImage->MappedAddress +
-                                       FIELD_OFFSET(IMAGE_NT_HEADERS, OptionalHeader) +
-                                       NtHeaders->FileHeader.SizeOfOptionalHeader +
-                                       NtHeaders->FileHeader.NumberOfSections * sizeof(IMAGE_SECTION_HEADER);
-
-       /* Get the Optional Header */
-       OptionalHeader32 = &LoadedImage->FileHeader->OptionalHeader;
-
-       /*      There is the possibilty that one of the Data Directories is in the PE Header
-               itself, so we'll need to find such a case and add it to our PE used space */
-    for ( i = 0; i<OptionalHeader32->NumberOfRvaAndSizes; i++ ) {
-
-               /* If the VA is less then the size of headers, then the data is inside the PE header */
-        if (OptionalHeader32->DataDirectory[i].VirtualAddress < OptionalHeader32->SizeOfHeaders) {
-
-                       /* However, make sure it's not 0, which means it doesnt actually exist */
-            if (OptionalHeader32->DataDirectory[i].VirtualAddress >= FirstFreeByte) {
-
-                               /* Our first empty byte is after this Directory Data then */
-                FirstFreeByte = OptionalHeader32->DataDirectory[i].VirtualAddress +
-                                                                                               OptionalHeader32->DataDirectory[i].Size;
-                }
+    /* Find the first free byte, which is after all the headers and sections */
+    FirstFreeByte = (ULONG_PTR)NtHeaders -
+                    (ULONG_PTR)LoadedImage->MappedAddress +
+                    FIELD_OFFSET(IMAGE_NT_HEADERS, OptionalHeader) +
+                    NtHeaders->FileHeader.SizeOfOptionalHeader +
+                    NtHeaders->FileHeader.NumberOfSections * sizeof(IMAGE_SECTION_HEADER);
+
+    /* Get the Optional Header */
+    OptionalHeader = &LoadedImage->FileHeader->OptionalHeader;
+
+    /*
+     * There is the possibilty that one of the Data Directories is in the PE Header
+     * itself, so we'll need to find such a case and add it to our PE used space
+     */
+    for (i = 0; i < OptionalHeader->NumberOfRvaAndSizes; i++)
+    {
+        /* If the VA is less then the size of headers, then the data is inside the PE header */
+        if (OptionalHeader->DataDirectory[i].VirtualAddress <
+            OptionalHeader->SizeOfHeaders)
+        {
+            /* However, make sure it's not 0, which means it doesnt actually exist */
+            if (OptionalHeader->DataDirectory[i].VirtualAddress >=
+                FirstFreeByte)
+            {
+                /* Our first empty byte is after this Directory Data then */
+                FirstFreeByte = OptionalHeader->DataDirectory[i].VirtualAddress +
+                                OptionalHeader->DataDirectory[i].Size;
             }
         }
+    }
 
-       /* Return the unused Header Bytes */
-    *SizeUnusedHeaderBytes = OptionalHeader32->SizeOfHeaders - FirstFreeByte;
+    /* Return the unused Header Bytes */
+    *SizeUnusedHeaderBytes = OptionalHeader->SizeOfHeaders - (DWORD)FirstFreeByte;
 
-       /* And return the first free byte*/
-    return FirstFreeByte;
+    /* And return the first free byte*/
+    return (DWORD)FirstFreeByte;
 }
 
-/***********************************************************************
- *             ImageDirectoryEntryToData (IMAGEHLP.@)
+/*
+ * @implemented
  */
 PVOID 
-WINAPI
-ImageDirectoryEntryToData(
-       PVOID Base,
-    BOOLEAN MappedAsImage,
-    USHORT DirectoryEntry,
-    PULONG Size
-    )
+IMAGEAPI
+ImageDirectoryEntryToData(PVOID Base,
+                          BOOLEAN MappedAsImage,
+                          USHORT DirectoryEntry,
+                          PULONG Size)
 {
-    return ImageDirectoryEntryToDataEx(Base, MappedAsImage, DirectoryEntry, Size, NULL);
+    /* Let the extended function handle it */
+    return ImageDirectoryEntryToDataEx(Base,
+                                       MappedAsImage,
+                                       DirectoryEntry,
+                                       Size,
+                                       NULL);
 }
 
-/***********************************************************************
- *             RosImageDirectoryEntryToDataEx (IMAGEHLP.@)
+/*
+ * @implemented
  */
 PVOID
-WINAPI
-ImageDirectoryEntryToDataEx (
-    IN PVOID Base,
-    IN BOOLEAN MappedAsImage,
-    IN USHORT DirectoryEntry,
-    OUT PULONG Size,
-    OUT PIMAGE_SECTION_HEADER *FoundSection OPTIONAL
-    )
+IMAGEAPI
+ImageDirectoryEntryToDataEx(IN PVOID Base,
+                            IN BOOLEAN MappedAsImage,
+                            IN USHORT DirectoryEntry,
+                            OUT PULONG Size,
+                            OUT PIMAGE_SECTION_HEADER *FoundSection OPTIONAL)
 {
-    PIMAGE_NT_HEADERS                  NtHeader;
-    PIMAGE_FILE_HEADER                 FileHeader;
-       PIMAGE_OPTIONAL_HEADER          OptionalHeader;
+    PIMAGE_NT_HEADERS NtHeader;
+    PIMAGE_FILE_HEADER FileHeader;
+    PIMAGE_OPTIONAL_HEADER OptionalHeader;
 
+    /* Get the optional header ourselves */
     NtHeader = ImageNtHeader(Base);
     FileHeader = &NtHeader->FileHeader;
     OptionalHeader = &NtHeader->OptionalHeader;
 
-    return (ImageDirectoryEntryToData32(Base,
-                                        MappedAsImage,
-                                        DirectoryEntry,
-                                        Size,
-                                        FoundSection,
-                                        FileHeader,
-                                        OptionalHeader));
+    /* FIXME: Read image type and call appropriate function (32, 64, ROM) */
+    return ImageDirectoryEntryToData32(Base,
+                                       MappedAsImage,
+                                       DirectoryEntry,
+                                       Size,
+                                       FoundSection,
+                                       FileHeader,
+                                       OptionalHeader);
 }
 
-/***********************************************************************
- *             RosImageDirectoryEntryToDataEx (IMAGEHLP.@)
- */
-PVOID
-STDCALL
-ImageDirectoryEntryToData32 (
-    PVOID Base,
-    BOOLEAN MappedAsImage,
-    USHORT DirectoryEntry,
-    PULONG Size,
-    PIMAGE_SECTION_HEADER *FoundHeader OPTIONAL,
-    PIMAGE_FILE_HEADER FileHeader,
-    PIMAGE_OPTIONAL_HEADER OptionalHeader
-    )
-{
-    ULONG i;
-    PIMAGE_SECTION_HEADER      CurrentSection;
-    ULONG                                      DirectoryEntryVA;
-
-       /* Get the VA of the Directory Requested */
-       DirectoryEntryVA = OptionalHeader->DataDirectory[DirectoryEntry].VirtualAddress;
-
-       /* Get the size of the Directory Requested */
-    *Size = OptionalHeader->DataDirectory[DirectoryEntry].Size;
-
-       /* Return VA if Mapped as Image*/
-    if (MappedAsImage || DirectoryEntryVA < OptionalHeader->SizeOfHeaders) {
-        if (FoundHeader) {
-            *FoundHeader = NULL;
-        }
-        return (PVOID)((ULONG_PTR)Base + DirectoryEntryVA);
-    }
-
-       /* Read the first Section */
-    CurrentSection = (PIMAGE_SECTION_HEADER)((ULONG_PTR)OptionalHeader + FileHeader->SizeOfOptionalHeader);
-       
-       /* Loop through every section*/
-    for (i=0; i<FileHeader->NumberOfSections; i++) {
-               
-               /* If the Directory VA is located inside this section's VA, then this section belongs to this Directory */
-        if (DirectoryEntryVA >= CurrentSection->VirtualAddress && 
-                                                               DirectoryEntryVA < CurrentSection->VirtualAddress + CurrentSection->SizeOfRawData) {
-            if (FoundHeader) {
-                *FoundHeader = CurrentSection;
-            }
-                        //return( (PVOID)((ULONG_PTR)Base + (DirectoryAddress - NtSection->VirtualAddress) + NtSection->PointerToRawData) );
-            return ((PVOID)((ULONG_PTR)Base + (DirectoryEntryVA - CurrentSection->VirtualAddress) + CurrentSection->PointerToRawData));
-        }
-        ++CurrentSection;
-    }
-    return(NULL);
-}
-/***********************************************************************
- *             ImageLoad (IMAGEHLP.@)
+/*
+ * @implemented
  */
-PLOADED_IMAGE WINAPI ImageLoad(LPSTR DllName, LPSTR DllPath)
+PLOADED_IMAGE
+IMAGEAPI
+ImageLoad(LPSTR DllName,
+          LPSTR DllPath)
 {
-    PLIST_ENTRY Head,Next;
+    PLIST_ENTRY Head, Next;
     PLOADED_IMAGE LoadedImage;
+    CHAR Drive[_MAX_DRIVE], Dir[_MAX_DIR], Filename[_MAX_FNAME], Ext[_MAX_EXT];
+    BOOL CompleteName = TRUE;
+    CHAR FullName[MAX_PATH];
 
-       /* Initialize the List Head */
-    if (!DllListInitialized) {
+    /* Initialize the List Head */
+    if (!DllListInitialized)
+    {
         InitializeListHead(&ImageLoadListHead);
         DllListInitialized = TRUE;
     }
 
-       /* Move to the Next DLL */
+    /* Move to the Next DLL */
     Head = &ImageLoadListHead;
     Next = Head->Flink;
+    DPRINT("Trying to find library: %s in current ListHead \n", DllName);
 
-       //FIXME("Trying to find library: %s in current ListHead \n", DllName);
+    /* Split the path */
+    _splitpath(DllName, Drive, Dir, Filename, Ext);
 
-       /* Check if we already Loaded it */
-    while (Next != Head) {
+    /* Check if we only got a name */
+    if (!strlen(Drive) && !strlen(Dir)) CompleteName = FALSE;
 
-               /* Get the Loaded Image Structure */
+    /* Check if we already Loaded it */
+    while (Next != Head)
+    {
+        /* Get the Loaded Image Structure */
         LoadedImage = CONTAINING_RECORD(Next, LOADED_IMAGE, Links);
-               //FIXME("Found: %s in current ListHead \n", LoadedImage->ModuleName);
+        DPRINT("Found: %s in current ListHead \n", LoadedImage->ModuleName);
+
+        /* Check if we didn't have a complete name */
+        if (!CompleteName)
+        {
+            /* Split this module's name */
+            _splitpath(LoadedImage->ModuleName, NULL, NULL, Filename, Ext);
 
-               /* Check if the Names Match */
-        if (!lstrcmpi( DllName, LoadedImage->ModuleName )) {
-                       //FIXME("Found it, returning it\n");
+            /* Use only the name and extension */
+            strcpy(FullName, Filename);
+            strcat(FullName, Ext);
+        }
+        else
+        {
+            /* Use the full untouched name */
+            strcpy(FullName, LoadedImage->ModuleName);
+        }
+        
+        /* Check if the Names Match */
+        if (!_stricmp(DllName, FullName))
+        {
+            DPRINT("Found it, returning it\n");
             return LoadedImage;
         }
 
-               /* Move to next Entry */
+        /* Move to next Entry */
         Next = Next->Flink;
-               //FIXME("Moving to next List Entry\n");
     }
 
-       //FIXME("Didn't find it...allocating it for you now\n");
-
-       /* Allocate memory for the Structure, and write the Module Name under */
-    LoadedImage = HeapAlloc(IMAGEHLP_hHeap, 0, sizeof(*LoadedImage) + lstrlen(DllName) + 1);
+    /* Allocate memory for the Structure, and write the Module Name under */
+    DPRINT("Didn't find it...allocating it for you now\n");
+    LoadedImage = HeapAlloc(IMAGEHLP_hHeap,
+                            0,
+                            sizeof(*LoadedImage) + strlen(DllName) + 1);
+    if (LoadedImage)
+    {
+        /* Module Name will be after structure */
+        LoadedImage->ModuleName = (LPSTR)(LoadedImage + 1);
 
-       /* Module Name will be after structure */
-    LoadedImage->ModuleName = (LPSTR)LoadedImage + 1;
+        /* Copy the Module Name */
+        strcpy(LoadedImage->ModuleName, DllName);
 
-       /* Copy the Moduel Name */
-    lstrcpy(LoadedImage->ModuleName, DllName);
+        /* Now Load it */
+        if (MapAndLoad(DllName, DllPath, LoadedImage, TRUE, TRUE))
+        {
+            /* Add it to our list and return it */
+            InsertTailList(&ImageLoadListHead, &LoadedImage->Links);
+            return LoadedImage;
+        }
 
-       /* Now Load it and add it to our list*/
-    if (MapAndLoad(DllName, DllPath, LoadedImage, TRUE, TRUE)) {
-        InsertTailList(&ImageLoadListHead, &LoadedImage->Links);
-        return LoadedImage;
+        /* If we're here...there's been a failure */
+        HeapFree(IMAGEHLP_hHeap, 0, LoadedImage);
+        LoadedImage = NULL;
     }
-
-       /* If we're here...there's been a failure */
-    HeapFree(IMAGEHLP_hHeap, 0, LoadedImage);
-    LoadedImage = NULL;
     return LoadedImage;
 }
 
-/***********************************************************************
- *             ImageRvaToSection (IMAGEHLP.@)
+/*
+ * @implemented
  */
 PIMAGE_SECTION_HEADER 
-WINAPI
-ImageRvaToSection(
-    IN PIMAGE_NT_HEADERS NtHeaders,
-    IN PVOID Base,
-    IN ULONG Rva
-    )
+IMAGEAPI
+ImageRvaToSection(IN PIMAGE_NT_HEADERS NtHeaders,
+                  IN PVOID Base,
+                  IN ULONG Rva)
 {
-       PIMAGE_SECTION_HEADER Section;
+    PIMAGE_SECTION_HEADER Section;
     ULONG i;
 
-       /* Get the First Section */
+    /* Get the First Section */
     Section = IMAGE_FIRST_SECTION(NtHeaders);
 
-       /* Look through each section and check if the RVA is in between */
-    for (i=0; i < NtHeaders->FileHeader.NumberOfSections; i++) {
-        if (Rva >= Section->VirtualAddress && Rva < Section->VirtualAddress +
-                                                                                                       Section->SizeOfRawData) {
+    /* Look through each section */
+    for (i = 0; i < NtHeaders->FileHeader.NumberOfSections; i++)
+    {
+        /* Check if the RVA is in between */
+        if ((Rva >= Section->VirtualAddress) && 
+            (Rva < (Section->VirtualAddress + Section->SizeOfRawData)))
+        {
+            /* Return this section */
             return Section;
-            }
-        ++Section;
         }
 
-       /* Not Found */
+        /* Move to the next section */
+        Section++;
+    }
+
+    /* Not Found */
     return NULL;
 }
 
-/***********************************************************************
- *             ImageNtHeader (IMAGEHLP.@)
+/*
+ * @implemented
  */
-PIMAGE_NT_HEADERS WINAPI ImageNtHeader(PVOID Base)
+PIMAGE_NT_HEADERS
+IMAGEAPI
+ImageNtHeader(PVOID Base)
 {
-  TRACE("(%p)\n", Base);
-
-       /* Just return the e_lfanew Offset VA */
-       return (PIMAGE_NT_HEADERS)((LPBYTE)Base + 
-                       ((PIMAGE_DOS_HEADER)Base)->e_lfanew);
+    /* Let RTL do it */
+    return RtlImageNtHeader(Base);
 }
 
-/***********************************************************************
- *             ImageRvaToVa (IMAGEHLP.@)
+/*
+ * @implemented
  */
 PVOID 
-WINAPI 
-ImageRvaToVa(
-       IN PIMAGE_NT_HEADERS NtHeaders,
-    IN PVOID Base,
-    IN ULONG Rva,
-    IN OUT PIMAGE_SECTION_HEADER *LastRvaSection OPTIONAL
-    )
+IMAGEAPI 
+ImageRvaToVa(IN PIMAGE_NT_HEADERS NtHeaders,
+             IN PVOID Base,
+             IN ULONG Rva,
+             IN OUT PIMAGE_SECTION_HEADER *LastRvaSection OPTIONAL)
 {
     PIMAGE_SECTION_HEADER Section;
 
-       /* Get the Section Associated */
-       Section = ImageRvaToSection(NtHeaders, Base, Rva);
+    /* Get the Section Associated */
+    Section = ImageRvaToSection(NtHeaders, Base, Rva);
 
-       /* Return it, if specified */
+    /* Return it, if specified */
     if (LastRvaSection) *LastRvaSection = Section;
 
-       /* Return the VA */
+    /* Return the VA */
     return (PVOID)((ULONG_PTR)Base + (Rva - Section->VirtualAddress) +
-                                                                                       Section->PointerToRawData);
+                                            Section->PointerToRawData);
 }
 
-/***********************************************************************
- *             ImageUnload (IMAGEHLP.@)
+/*
+ * @implemented
  */
-BOOL WINAPI ImageUnload(PLOADED_IMAGE pLoadedImage)
+BOOL
+IMAGEAPI
+ImageUnload(PLOADED_IMAGE LoadedImage)
 {
-  LIST_ENTRY *pCurrent, *pFind;
-
-  TRACE("(%p)\n", pLoadedImage);
-  
-  if(!IMAGEHLP_pFirstLoadedImage || !pLoadedImage)
-    {
-      /* No image loaded or null pointer */
-      SetLastError(ERROR_INVALID_PARAMETER);
-      return FALSE;
-    }
+    /* If the image list isn't empty, remove this entry */
+    if (!IsListEmpty(&LoadedImage->Links)) RemoveEntryList(&LoadedImage->Links);
 
-  pFind=&pLoadedImage->Links;
-  pCurrent=&IMAGEHLP_pFirstLoadedImage->Links;
-  while((pCurrent != pFind) &&
-    (pCurrent != NULL))
-      pCurrent = pCurrent->Flink;
-  if(!pCurrent)
-    {
-      /* Not found */
-      SetLastError(ERROR_INVALID_PARAMETER);
-      return FALSE;
-    }
+    /* Unmap and unload it */
+    UnMapAndLoad(LoadedImage);
 
-  if(pCurrent->Blink)
-    pCurrent->Blink->Flink = pCurrent->Flink;
-  else
-    IMAGEHLP_pFirstLoadedImage = pCurrent->Flink?CONTAINING_RECORD(
-      pCurrent->Flink, LOADED_IMAGE, Links):NULL;
-
-  if(pCurrent->Flink)
-    pCurrent->Flink->Blink = pCurrent->Blink;
-  else
-    IMAGEHLP_pLastLoadedImage = pCurrent->Blink?CONTAINING_RECORD(
-      pCurrent->Blink, LOADED_IMAGE, Links):NULL;
+    /* Free the structure */
+    HeapFree(IMAGEHLP_hHeap, 0, LoadedImage);
 
-  return FALSE;
+    /* Return success */
+    return TRUE;
 }
 
-/***********************************************************************
- *             MapAndLoad (IMAGEHLP.@)
+/*
+ * @implemented
  */
-BOOL WINAPI MapAndLoad(
-       LPSTR ImageName, 
-       LPSTR DllPath, 
-       PLOADED_IMAGE LoadedImage,
-       BOOL DotDll, 
-       BOOL ReadOnly)
+BOOL
+IMAGEAPI
+MapAndLoad(LPSTR ImageName, 
+           LPSTR DllPath, 
+           PLOADED_IMAGE LoadedImage,
+           BOOL DotDll, 
+           BOOL ReadOnly)
 {
-  HANDLE hFileMapping = NULL;
-  PIMAGE_NT_HEADERS NtHeader = NULL;
-  ULONG        Tried = 0;
-  UCHAR Buffer[MAX_PATH];
-  LPSTR FilePart;
-  LPSTR FileToOpen;
-
-  /* So we can add the DLL Path later */
-  FileToOpen = ImageName;
+    HANDLE hFile;
+    HANDLE hFileMapping;
+    ULONG Tried = 0;
+    UCHAR Buffer[MAX_PATH];
+    LPSTR FilePart;
+    LPSTR FileToOpen;
+    PIMAGE_NT_HEADERS NtHeader;
+
+    /* So we can add the DLL Path later */
+    FileToOpen = ImageName;
+
+    /* Assume failure */
+    LoadedImage->hFile = INVALID_HANDLE_VALUE;
   
-TryAgain:
-       /* Get a handle to the file */
-       if ((LoadedImage->hFile = CreateFileA (FileToOpen, 
-                                                                                       ReadOnly ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE, 
-                                                                                       ReadOnly ? FILE_SHARE_READ : FILE_SHARE_READ | FILE_SHARE_WRITE,
-                                                                                       NULL, 
-                                                                                       OPEN_EXISTING, 
-                                                                                       0, 
-                                                                                       NULL)) == INVALID_HANDLE_VALUE)
+    /* Start open loop */
+    while (TRUE)
     {
-               /* It Failed, use the DLL Search Path then (make sure we haven't already) */
-        if (!Tried) {
-            Tried = SearchPath(DllPath, ImageName, DotDll ? ".dll" : ".exe", MAX_PATH, Buffer, &FilePart);
-            if (Tried) {
-                FileToOpen = Buffer;
-                goto TryAgain;
+        /* Get a handle to the file */
+        hFile = CreateFileA(FileToOpen, 
+                            ReadOnly ? GENERIC_READ : 
+                                       GENERIC_READ | GENERIC_WRITE,
+                            ReadOnly ? FILE_SHARE_READ :
+                                       FILE_SHARE_READ | FILE_SHARE_WRITE,
+                            NULL, 
+                            OPEN_EXISTING, 
+                            0, 
+                            NULL);
+
+        if (hFile == INVALID_HANDLE_VALUE)
+        {
+            /* Check if we already tried this once */
+            if (!Tried)
+            {
+                /* We didn't do do a path search now */
+                Tried = SearchPath(DllPath,
+                                   ImageName,
+                                   DotDll ? ".dll" : ".exe",
+                                   MAX_PATH,
+                                   Buffer,
+                                   &FilePart);
+
+                /* Check if it was successful */
+                if (Tried && (Tried < MAX_PATH))
+                {
+                    /* Change the filename to use, and try again */
+                    FileToOpen = Buffer;
+                    continue;
+                }
             }
+
+            /* Fail */
+            return FALSE;
         }
-               /* Fail */
-        return FALSE;
+
+        /* Success, break out */
+        break;
     }
 
-       /* Create the File Mapping */
-       if (!(hFileMapping = CreateFileMappingA (LoadedImage->hFile,
-                                                                                       NULL, 
-                                                                                       ReadOnly ? PAGE_READONLY : PAGE_READWRITE, 
-                                                                                       0, 
-                                                                                       0, 
-                                                                                       NULL)))
+    /* Create the File Mapping */
+    hFileMapping = CreateFileMappingA(hFile,
+                                      NULL, 
+                                      ReadOnly ? PAGE_READONLY :
+                                                 PAGE_READWRITE, 
+                                      0, 
+                                      0, 
+                                      NULL);
+    if (!hFileMapping)
     {
-      DWORD dwLastError = GetLastError();
-      SetLastError(dwLastError);
-      goto Error;
+        /* Fail */
+        SetLastError(GetLastError());
+        CloseHandle(hFile);
+        return FALSE;
     }
 
-       /* Get a pointer to the file */
-       if(!(LoadedImage->MappedAddress = MapViewOfFile(hFileMapping, 
-                                                                                                       ReadOnly ? FILE_MAP_READ : FILE_MAP_WRITE, 
-                                                                                                       0, 
-                                                                                                       0, 
-                                                                                                       0)))
+    /* Get a pointer to the file */
+    LoadedImage->MappedAddress = MapViewOfFile(hFileMapping,
+                                               ReadOnly ? FILE_MAP_READ :
+                                                          FILE_MAP_WRITE,
+                                               0,
+                                               0, 
+                                               0);
+
+    /* Close the handle to the map, we don't need it anymore */
+    CloseHandle(hFileMapping);
+
+    /* Write the image size */
+    LoadedImage->SizeOfImage = GetFileSize(hFile, NULL);
+
+    /* Get the Nt Header */
+    NtHeader = ImageNtHeader(LoadedImage->MappedAddress);
+
+    /* Allocate memory for the name and save it */
+    LoadedImage->ModuleName = HeapAlloc(IMAGEHLP_hHeap,
+                                        0,
+                                        strlen(FileToOpen) + 16);
+    strcpy(LoadedImage->ModuleName, FileToOpen);
+
+    /* Save the NT Header */
+    LoadedImage->FileHeader = NtHeader;
+
+    /* Save the section data */
+    LoadedImage->Sections = IMAGE_FIRST_SECTION(NtHeader);
+    LoadedImage->NumberOfSections = NtHeader->FileHeader.NumberOfSections;
+
+    /* Setup other data */
+    LoadedImage->SizeOfImage = NtHeader->OptionalHeader.SizeOfImage;
+    LoadedImage->Characteristics = NtHeader->FileHeader.Characteristics;
+    LoadedImage->LastRvaSection = LoadedImage->Sections;
+    LoadedImage->fSystemImage = FALSE; /* FIXME */
+    LoadedImage->fDOSImage = FALSE; /* FIXME */
+    InitializeListHead(&LoadedImage->Links);
+
+    /* Check if it was read-only */
+    if (ReadOnly)
+    {
+        /* It was, so close our handle and write it as invalid */
+        CloseHandle(hFile);
+        LoadedImage->hFile = INVALID_HANDLE_VALUE;
+    }
+    else
     {
-      DWORD dwLastError = GetLastError();
-      SetLastError(dwLastError);
-      goto Error;
+        /* Write our file handle */
+        LoadedImage->hFile = hFile;
     }
 
-       /* Close the handle to the map, we don't need it anymore */
-       CloseHandle(hFileMapping);
-       hFileMapping=NULL;
-
-       /* Get the Nt Header */
-       NtHeader = ImageNtHeader(LoadedImage->MappedAddress);
-
-       /* Write data */
-       LoadedImage->ModuleName = HeapAlloc(IMAGEHLP_hHeap, 0, lstrlen(ImageName) + 1);
-       lstrcpy(LoadedImage->ModuleName, ImageName);
-       LoadedImage->FileHeader = NtHeader;
-       LoadedImage->Sections = (PIMAGE_SECTION_HEADER)
-                                                               ((LPBYTE)&NtHeader->OptionalHeader +
-                                                               NtHeader->FileHeader.SizeOfOptionalHeader);
-       LoadedImage->NumberOfSections = NtHeader->FileHeader.NumberOfSections;
-       LoadedImage->SizeOfImage =      NtHeader->OptionalHeader.SizeOfImage;
-       LoadedImage->Characteristics =  NtHeader->FileHeader.Characteristics;
-       LoadedImage->LastRvaSection = LoadedImage->Sections;
-       LoadedImage->fSystemImage = FALSE; /* FIXME */
-       LoadedImage->fDOSImage = FALSE;    /* FIXME */
-
-       /* Read only, so no sense in keeping the handle alive */
-       if (ReadOnly) CloseHandle(LoadedImage->hFile);
-
-       /* Return Success */
-       return TRUE;
-
-Error:
-       if(LoadedImage->MappedAddress)
-               UnmapViewOfFile(LoadedImage->MappedAddress);
-       if(hFileMapping)
-               CloseHandle(hFileMapping);
-       if(LoadedImage->hFile)
-               CloseHandle(LoadedImage->hFile);
-       return FALSE;
+    /* Return Success */
+    return TRUE;
 }
 
-/***********************************************************************
- *             SetImageConfigInformation (IMAGEHLP.@)
+/*
+ * @unimplemented
  */
-BOOL WINAPI SetImageConfigInformation(
-  PLOADED_IMAGE LoadedImage,
-  PIMAGE_LOAD_CONFIG_DIRECTORY ImageConfigInformation)
+BOOL
+IMAGEAPI
+SetImageConfigInformation(PLOADED_IMAGE LoadedImage,
+                          PIMAGE_LOAD_CONFIG_DIRECTORY ImageConfigInformation)
 {
-  FIXME("(%p, %p): stub\n",
-    LoadedImage, ImageConfigInformation
-  );
-  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-  return FALSE;
+    UNIMPLEMENTED;
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return FALSE;
 }
 
-/***********************************************************************
- *             UnMapAndLoad (IMAGEHLP.@)
+/*
+ * @implemented
  */
-BOOL WINAPI UnMapAndLoad(PLOADED_IMAGE LoadedImage)
+BOOL
+IMAGEAPI
+UnMapAndLoad(PLOADED_IMAGE Image)
+{
+    PIMAGE_NT_HEADERS NtHeader;
+    DWORD HeaderCheckSum, CheckSum;
+
+    /* Check if the image was read-only */
+    if (Image->hFile == INVALID_HANDLE_VALUE)
+    {
+        /* We'll only unmap the view */
+        UnmapViewOfFile(Image->MappedAddress);
+    }
+    else
+    {
+        /* Calculate the checksum */
+        CheckSumMappedFile(Image->MappedAddress,
+                           Image->SizeOfImage,
+                           &HeaderCheckSum,
+                           &CheckSum);
+
+        /* Get the NT Header */
+        NtHeader = Image->FileHeader;
+
+        /* Write the new checksum to it */
+        NtHeader->OptionalHeader.CheckSum = CheckSum;
+
+        /* Now flush and unmap the image */
+        FlushViewOfFile(Image->MappedAddress, Image->SizeOfImage);
+        UnmapViewOfFile(Image->MappedAddress);
+
+        /* Check if the size changed */
+        if (Image->SizeOfImage != GetFileSize(Image->hFile, NULL))
+        {
+            /* Update the file pointer */
+            SetFilePointer(Image->hFile, Image->SizeOfImage, NULL, FILE_BEGIN);
+            SetEndOfFile(Image->hFile);
+        }
+    }
+
+    /* Check if the image had a valid handle, and close it */
+    if (Image->hFile != INVALID_HANDLE_VALUE) CloseHandle(Image->hFile);
+
+    /* Return success */
+    return TRUE;
+}
+
+BOOL
+IMAGEAPI
+UnloadAllImages(VOID)
 {
-  FIXME("(%p): stub\n", LoadedImage);
-  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-  return FALSE;
+    PLIST_ENTRY Head, Entry;
+    PLOADED_IMAGE CurrentImage;
+
+    /* Make sure we're initialized */
+    if (!DllListInitialized) return TRUE;
+
+    /* Get the list pointers and loop */
+    Head = &ImageLoadListHead;
+    Entry = Head->Flink;
+    while (Entry != Head)
+    {
+        /* Get this image */
+        CurrentImage = CONTAINING_RECORD(Entry, LOADED_IMAGE, Links);
+
+        /* Move to the next entry */
+        Entry = Entry->Flink;
+
+        /* Unload it */
+        ImageUnload(CurrentImage);
+    }
+
+    /* We are not initialized anymore */
+    DllListInitialized = FALSE;
+    return TRUE;
 }
diff --git a/reactos/lib/imagehlp/debug.c b/reactos/lib/imagehlp/debug.c
deleted file mode 100644 (file)
index d73c9f8..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- *     IMAGEHLP library
- *
- *     Copyright 1998  Patrik Stridvall
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include <stdarg.h>
-
-#include "winerror.h"
-#include "windef.h"
-#include "winbase.h"
-#include "wine/debug.h"
-#include "imagehlp.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(imagehlp);
-
-/***********************************************************************
- *             FindDebugInfoFile (IMAGEHLP.@)
- */
-HANDLE WINAPI FindDebugInfoFile(
-  LPSTR FileName, LPSTR SymbolPath, LPSTR DebugFilePath)
-{
-  FIXME("(%s, %s, %s): stub\n",
-    debugstr_a(FileName), debugstr_a(SymbolPath),
-    debugstr_a(DebugFilePath)
-  );
-  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-  return NULL;
-}
-
-/***********************************************************************
- *             FindExecutableImage (IMAGEHLP.@)
- */
-HANDLE WINAPI FindExecutableImage(
-  LPSTR FileName, LPSTR SymbolPath, LPSTR ImageFilePath)
-{
-  FIXME("(%s, %s, %s): stub\n",
-    debugstr_a(FileName), debugstr_a(SymbolPath),
-    debugstr_a(ImageFilePath)
-  );
-  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-  return NULL;
-}
-
-/***********************************************************************
- *             MapDebugInformation (IMAGEHLP.@)
- */
-PIMAGE_DEBUG_INFORMATION WINAPI MapDebugInformation(
-  HANDLE FileHandle, LPSTR FileName,
-  LPSTR SymbolPath, DWORD ImageBase)
-{
-  FIXME("(%p, %s, %s, 0x%08lx): stub\n",
-    FileHandle, FileName, SymbolPath, ImageBase
-  );
-  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-  return NULL;
-}
-
-/***********************************************************************
- *             StackWalk (IMAGEHLP.@)
- */
-BOOL WINAPI StackWalk(
-  DWORD MachineType, HANDLE hProcess, HANDLE hThread,
-  LPSTACKFRAME StackFrame, LPVOID ContextRecord,
-  PREAD_PROCESS_MEMORY_ROUTINE ReadMemoryRoutine,
-  PFUNCTION_TABLE_ACCESS_ROUTINE FunctionTableAccessRoutine,
-  PGET_MODULE_BASE_ROUTINE GetModuleBaseRoutine,
-  PTRANSLATE_ADDRESS_ROUTINE TranslateAddress)
-{
-  FIXME(
-    "(%ld, %p, %p, %p, %p, %p, %p, %p, %p): stub\n",
-      MachineType, hProcess, hThread, StackFrame, ContextRecord,
-      ReadMemoryRoutine, FunctionTableAccessRoutine,
-      GetModuleBaseRoutine, TranslateAddress
-  );
-  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-  return FALSE;
-}
-
-/***********************************************************************
- *             UnDecorateSymbolName (IMAGEHLP.@)
- */
-DWORD WINAPI UnDecorateSymbolName(
-  LPCSTR DecoratedName, LPSTR UnDecoratedName,
-  DWORD UndecoratedLength, DWORD Flags)
-{
-  FIXME("(%s, %s, %ld, 0x%08lx): stub\n",
-    debugstr_a(DecoratedName), debugstr_a(UnDecoratedName),
-    UndecoratedLength, Flags
-  );
-  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-  return 0;
-}
-
-/***********************************************************************
- *             UnmapDebugInformation (IMAGEHLP.@)
- */
-BOOL WINAPI UnmapDebugInformation(
-  PIMAGE_DEBUG_INFORMATION DebugInfo)
-{
-  FIXME("(%p): stub\n", DebugInfo);
-  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-  return FALSE;
-}
index 21c9bce..646c197 100644 (file)
 LIBRARY imagehlp.dll
 
 EXPORTS
-BindImage@12 @1
-BindImageEx@20 @2
-CheckSumMappedFile@16 @3
-EnumerateLoadedModules@12 @4
-FindDebugInfoFile@12 @5
-FindExecutableImage@12 @6
-GetImageConfigInformation@8 @7
-GetImageUnusedHeaderBytes@8 @8
-GetTimestampForLoadedLibrary@4 @9
-ImageAddCertificate@12 @10
-ImageDirectoryEntryToData@16 @11
-ImageEnumerateCertificates@20 @12
-ImageGetCertificateData@16 @13
-ImageGetCertificateHeader@12 @14
-ImageGetDigestStream@16 @15
-ImageLoad@8 @16
-ImageNtHeader@4 @17
-ImageRemoveCertificate@8 @18
-ImageRvaToSection@12 @19
-ImageRvaToVa@16 @20
-ImageUnload@4 @21
-ImagehlpApiVersion@0 @22
-ImagehlpApiVersionEx@4 @23
-MakeSureDirectoryPathExists@4 @24
-MapAndLoad@20 @25
-MapDebugInformation@16 @26
-MapFileAndCheckSumA@12 @27
-MapFileAndCheckSumW@12 @28
-ReBaseImage@44 @30
-RemovePrivateCvSymbolic@12 @31
-RemoveRelocations@4 @32
-SearchTreeForFile@12 @33
-SetImageConfigInformation@8 @34
-SplitSymbols@16 @35
-StackWalk@36 @36
-SymCleanup@4 @37
-SymEnumerateModules@12 @38
-SymEnumerateSymbols@16 @39
-SymFunctionTableAccess@8 @40
-SymGetModuleBase@8 @41
-SymGetModuleInfo@12 @42
-SymGetOptions@0 @43
-SymGetSearchPath@12 @44
-SymGetSymFromAddr@16 @45
-SymGetSymFromName@12 @46
-SymGetSymNext@8 @47
-SymGetSymPrev@8 @48
-SymInitialize@12 @49
-SymLoadModule@24 @50
-SymRegisterCallback@12 @51
-SymSetOptions@4 @52
-SymSetSearchPath@8 @53
-SymUnDName@12 @54
-SymUnloadModule@8 @55
-TouchFileTimes@8 @56
-UnDecorateSymbolName@16 @57
-UnMapAndLoad@4 @58
-UnmapDebugInformation@4 @59
-UpdateDebugInfoFile@16 @60
-UpdateDebugInfoFileEx@20 @61
+BindImage @2
+BindImageEx @3
+CheckSumMappedFile @4
+EnumerateLoadedModules=Dbghelp.EnumerateLoadedModules @5
+EnumerateLoadedModules64=Dbghelp.EnumerateLoadedModules64 @6
+FindDebugInfoFile=Dbghelp.FindDebugInfoFile @7
+FindDebugInfoFileEx=Dbghelp.FindDebugInfoFileEx @8
+FindExecutableImage=Dbghelp.FindExecutableImage @9
+FindExecutableImageEx=Dbghelp.FindExecutableImageEx @10
+FindFileInPath=Dbghelp.FindFileInPath @11
+FindFileInSearchPath=Dbghelp.FindFileInSearchPath @12
+GetImageConfigInformation @13
+GetImageUnusedHeaderBytes @14
+GetTimestampForLoadedLibrary @15
+ImageAddCertificate @16
+ImageDirectoryEntryToData @17
+ImageDirectoryEntryToDataEx @18
+ImageEnumerateCertificates @19
+ImageGetCertificateData @20
+ImageGetCertificateHeader @21
+ImageGetDigestStream @22
+ImagehlpApiVersion=Dbghelp.ImagehlpApiVersion @29
+ImagehlpApiVersionEx=Dbghelp.ImagehlpApiVersionEx @30
+ImageLoad @23
+ImageNtHeader @24
+ImageRemoveCertificate @25
+ImageRvaToSection @26
+ImageRvaToVa @27
+ImageUnload @28
+MakeSureDirectoryPathExists=Dbghelp.MakeSureDirectoryPathExists @31
+MapAndLoad @32
+MapDebugInformation=Dbghelp.MapDebugInformation @33
+MapFileAndCheckSumA @34
+MapFileAndCheckSumW @35
+ReBaseImage @37
+;ReBaseImage64 @36
+;RemovePrivateCvSymbolic @38
+;RemovePrivateCvSymbolicEx @39
+RemoveRelocations @1
+SearchTreeForFile=Dbghelp.SearchTreeForFile @40
+SetImageConfigInformation @41
+;SplitSymbols @42
+StackWalk=Dbghelp.StackWalk @43
+StackWalk64=Dbghelp.StackWalk64 @44
+SymCleanup=Dbghelp.SymCleanup @45
+SymEnumerateModules=Dbghelp.SymEnumerateModules @51
+SymEnumerateModules64=Dbghelp.SymEnumerateModules64 @50
+SymEnumerateSymbols=Dbghelp.SymEnumerateSymbols @53
+SymEnumerateSymbols64=Dbghelp.SymEnumerateSymbols64 @52
+SymEnumerateSymbolsW=Dbghelp.SymEnumerateSymbolsW @55
+SymEnumerateSymbolsW64=Dbghelp.SymEnumerateSymbolsW64 @54
+SymEnumSourceFiles=Dbghelp.SymEnumSourceFiles @46
+SymEnumSym=Dbghelp.SymEnumSym @47
+SymEnumSymbols=Dbghelp.SymEnumSymbols @48
+SymEnumTypes=Dbghelp.SymEnumTypes @49
+SymFindFileInPath=Dbghelp.SymFindFileInPath @56
+SymFromAddr=Dbghelp.SymFromAddr @57
+SymFromName=Dbghelp.SymFromName @58
+SymFunctionTableAccess=Dbghelp.SymFunctionTableAccess @60
+SymFunctionTableAccess64=Dbghelp.SymFunctionTableAccess64 @59
+SymGetLineFromAddr=Dbghelp.SymGetLineFromAddr @62
+SymGetLineFromAddr64=Dbghelp.SymGetLineFromAddr64 @61
+SymGetLineFromName=Dbghelp.SymGetLineFromName @64
+SymGetLineFromName64=Dbghelp.SymGetLineFromName64 @63
+SymGetLineNext=Dbghelp.SymGetLineNext @66
+SymGetLineNext64=Dbghelp.SymGetLineNext64 @65
+SymGetLinePrev=Dbghelp.SymGetLinePrev @68
+SymGetLinePrev64=Dbghelp.SymGetLinePrev64 @67
+SymGetModuleBase=Dbghelp.SymGetModuleBase @70
+SymGetModuleBase64=Dbghelp.SymGetModuleBase64 @69
+SymGetModuleInfo=Dbghelp.SymGetModuleInfo @72
+SymGetModuleInfo64=Dbghelp.SymGetModuleInfo64 @71
+SymGetModuleInfoW=Dbghelp.SymGetModuleInfoW @74
+SymGetModuleInfoW64=Dbghelp.SymGetModuleInfoW64 @73
+SymGetOptions=Dbghelp.SymGetOptions @76
+SymGetSearchPath=Dbghelp.SymGetSearchPath @75
+SymGetSymFromAddr=Dbghelp.SymGetSymFromAddr @78
+SymGetSymFromAddr64=Dbghelp.SymGetSymFromAddr64 @77
+SymGetSymFromName=Dbghelp.SymGetSymFromName @80
+SymGetSymFromName64=Dbghelp.SymGetSymFromName64 @79
+SymGetSymNext=Dbghelp.SymGetSymNext @82
+SymGetSymNext64=Dbghelp.SymGetSymNext64 @81
+SymGetSymPrev=Dbghelp.SymGetSymPrev @84
+SymGetSymPrev64=Dbghelp.SymGetSymPrev64 @83
+SymGetTypeFromName=Dbghelp.SymGetTypeFromName @85
+SymGetTypeInfo=Dbghelp.SymGetTypeInfo @86
+SymInitialize=Dbghelp.SymInitialize @87
+SymLoadModule=Dbghelp.SymLoadModule @89
+SymLoadModule64=Dbghelp.SymLoadModule64 @88
+SymMatchFileName=Dbghelp.SymMatchFileName @90
+SymMatchString=Dbghelp.SymMatchString @91
+SymRegisterCallback=Dbghelp.SymRegisterCallback @93
+SymRegisterCallback64=Dbghelp.SymRegisterCallback64 @92
+SymRegisterFunctionEntryCallback=Dbghelp.SymRegisterFunctionEntryCallback @95
+SymRegisterFunctionEntryCallback64=Dbghelp.SymRegisterFunctionEntryCallback64 @94
+SymSetContext=Dbghelp.SymSetContext @96
+SymSetOptions=Dbghelp.SymSetOptions @97
+SymSetSearchPath=Dbghelp.SymSetSearchPath @98
+SymUnDName=Dbghelp.SymUnDName @100
+SymUnDName64=Dbghelp.SymUnDName64 @99
+SymUnloadModule=Dbghelp.SymUnloadModule @102
+SymUnloadModule64=Dbghelp.SymUnloadModule64 @101
+TouchFileTimes @103
+UnDecorateSymbolName=Dbghelp.UnDecorateSymbolName @104
+UnMapAndLoad @105
+UnmapDebugInformation=Dbghelp.UnmapDebugInformation @106
+;UpdateDebugInfoFile @107
+;UpdateDebugInfoFileEx @108
index 5778485..a118d6d 100644 (file)
@@ -1,25 +1,17 @@
 <module name="imagehlp" type="win32dll" baseaddress="${BASEADDRESS_IMAGEHLP}" installbase="system32" installname="imagehlp.dll" allowwarnings="true">
        <importlibrary definition="imagehlp.def" />
        <include base="imagehlp">.</include>
-       <include base="ReactOS">include/wine</include>
-       <define name="_DISABLE_TIDENTS" />
-       <define name="__REACTOS__" />
        <define name="__USE_W32API" />
-       <define name="_WIN32_IE">0x600</define>
-       <define name="_WIN32_WINNT">0x501</define>
-       <define name="WINVER">0x501</define>
-       <define name="COBJMACROS" />
-       <define name="__need_offsetof" />
-       <define name="DCX_USESTYLE">0x10000L</define>
-       <library>wine</library>
+       <define name="_WIN32_WINNT">0x600</define>
+       <define name="WINVER">0x0600</define>
+       <define name="_IMAGEHLP_SOURCE_"></define>
        <library>ntdll</library>
        <library>kernel32</library>
        <file>access.c</file>
-       <file>debug.c</file>
        <file>imagehlp_main.c</file>
        <file>integrity.c</file>
-       <file>internal.c</file>
        <file>modify.c</file>
-       <file>symbol.c</file>
        <file>imagehlp.rc</file>
+       <pch>precomp.h</pch>
+       <linkerflag>-enable-stdcall-fixup</linkerflag>
 </module>
index 89e3c85..9442182 100644 (file)
 /*
- *     IMAGEHLP library
- *
- *     Copyright 1998  Patrik Stridvall
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         Imagehlp Libary
+ * FILE:            lib/imagehlp/imagehlp_main.c
+ * PURPOSE:         DLL Entrypoint
+ * PROGRAMMER:      Patrik Stridvall
  */
 
-#include <stdarg.h>
+/* INCLUDES ******************************************************************/
 
-#include "windef.h"
-#include "winbase.h"
-#include "imagehlp.h"
-#include "winerror.h"
-#include "wine/debug.h"
+#include "precomp.h"
 
-WINE_DEFAULT_DEBUG_CHANNEL(imagehlp);
+//#define NDEBUG
+#include <debug.h>
 
-/**********************************************************************/
+/* DATA **********************************************************************/
 
 HANDLE IMAGEHLP_hHeap = NULL;
 
-static API_VERSION IMAGEHLP_ApiVersion = { 4, 0, 0, 5 };
+/* FUNCTIONS *****************************************************************/
 
-/***********************************************************************
- *           DllMain (IMAGEHLP.init)
- */
-BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
+BOOL
+IMAGEAPI
+DllMain(HINSTANCE hinstDLL,
+        DWORD fdwReason,
+        LPVOID lpvReserved)
 {
-  switch(fdwReason)
+    switch(fdwReason)
     {
-    case DLL_PROCESS_ATTACH:
-      DisableThreadLibraryCalls(hinstDLL);
-      IMAGEHLP_hHeap = HeapCreate(0, 0x10000, 0);
-      break;
-    case DLL_PROCESS_DETACH:
-      HeapDestroy(IMAGEHLP_hHeap);
-      IMAGEHLP_hHeap = NULL;
-      break;
-    default:
-      break;
+        case DLL_PROCESS_ATTACH:
+            DisableThreadLibraryCalls(hinstDLL);
+            IMAGEHLP_hHeap = HeapCreate(0, 0x10000, 0);
+            break;
+        case DLL_PROCESS_DETACH:
+            HeapDestroy(IMAGEHLP_hHeap);
+            IMAGEHLP_hHeap = NULL;
+            break;
+        default:
+            break;
     }
-  return TRUE;
-}
-
-/***********************************************************************
- *           ImagehlpApiVersion (IMAGEHLP.@)
- */
-LPAPI_VERSION WINAPI ImagehlpApiVersion(VOID)
-{
-  return &IMAGEHLP_ApiVersion;
-}
-
-/***********************************************************************
- *           ImagehlpApiVersionEx (IMAGEHLP.@)
- */
-LPAPI_VERSION WINAPI ImagehlpApiVersionEx(LPAPI_VERSION AppVersion)
-{
-  if(!AppVersion)
-    return NULL;
-
-  AppVersion->MajorVersion = IMAGEHLP_ApiVersion.MajorVersion;
-  AppVersion->MinorVersion = IMAGEHLP_ApiVersion.MinorVersion;
-  AppVersion->Revision = IMAGEHLP_ApiVersion.Revision;
-  AppVersion->Reserved = IMAGEHLP_ApiVersion.Reserved;
-
-  return AppVersion;
-}
-
-/***********************************************************************
- *           MakeSureDirectoryPathExists (IMAGEHLP.@)
- *
- * Path may contain a file at the end. If a dir is at the end, the path 
- * must end with a backslash.
- *
- * Path may be absolute or relative (to current dir).
- *
- */
-BOOL WINAPI MakeSureDirectoryPathExists(LPCSTR DirPath)
-{
-   char Path[MAX_PATH];
-   char *SlashPos = Path;
-   char Slash;
-   BOOL bRes;
-   
-   strcpy(Path, DirPath);
-        
-   while((SlashPos=strpbrk(SlashPos+1,"\\/")))
-   {
-      Slash = *SlashPos;
-      *SlashPos = 0;
-      
-      bRes = CreateDirectoryA(Path, NULL);
-      if (bRes == FALSE && GetLastError() != ERROR_ALREADY_EXISTS)
-      {
-         return FALSE;
-      }
-      
-      *SlashPos = Slash;
-   }
-
-   return TRUE;
-}
-
-
-/***********************************************************************
- *           MarkImageAsRunFromSwap (IMAGEHLP.@)
- * FIXME
- *   No documentation available.
- */
-
-/***********************************************************************
- *           SearchTreeForFile (IMAGEHLP.@)
- */
-BOOL WINAPI SearchTreeForFile(
-  LPSTR RootPath, LPSTR InputPathName, LPSTR OutputPathBuffer)
-{
-  FIXME("(%s, %s, %s): stub\n",
-    debugstr_a(RootPath), debugstr_a(InputPathName),
-    debugstr_a(OutputPathBuffer)
-  );
-  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-  return FALSE;
-}
-
-/***********************************************************************
- *           TouchFileTimes (IMAGEHLP.@)
- */
-BOOL WINAPI TouchFileTimes(HANDLE FileHandle, LPSYSTEMTIME lpSystemTime)
-{
-  FILETIME FileTime;
-  SYSTEMTIME SystemTime;
-  
-  if(lpSystemTime == NULL)
-  {
-    GetSystemTime(&SystemTime);
-    lpSystemTime = &SystemTime;
-  }
-
-  return (SystemTimeToFileTime(lpSystemTime, &FileTime) &&
-          SetFileTime(FileHandle, NULL, NULL, &FileTime));
+    
+    return TRUE;
 }
index 2b4c5b5..d93dcf9 100644 (file)
@@ -1,61 +1,37 @@
 /*
- *     IMAGEHLP library
- *
- *     Copyright 1998  Patrik Stridvall
- *     Copyright 2003  Mike McCormack
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         Imagehlp Libary
+ * FILE:            lib/imagehlp/integrity.c
+ * PURPOSE:         Image Integrity: Security Certificates and Checksums
+ * PROGRAMMER:      Patrik Stridvall, Mike McCormack (WINE)
  */
 
-#include <stdarg.h>
-
-#include "windef.h"
-#include "winbase.h"
-#include "winerror.h"
-#include "winreg.h"
-#include "winternl.h"
-#include "winnt.h"
-//#include "ntstatus.h"
-#include "imagehlp.h"
-#include "wine/debug.h"
-
-#define IMAGE_FILE_SECURITY_DIRECTORY          4 /* winnt.h */
-
-WINE_DEFAULT_DEBUG_CHANNEL(imagehlp);
-
 /*
  * These functions are partially documented at:
  *   http://www.cs.auckland.ac.nz/~pgut001/pubs/authenticode.txt
  */
 
-/***********************************************************************
- * IMAGEHLP_GetSecurityDirOffset (INTERNAL)
- *
- * Read a file's PE header, and return the offset and size of the 
- *  security directory.
- */
-static BOOL IMAGEHLP_GetSecurityDirOffset( HANDLE handle, DWORD num,
-                                           DWORD *pdwOfs, DWORD *pdwSize )
+/* INCLUDES ******************************************************************/
+
+#include "precomp.h"
+
+//#define NDEBUG
+#include <debug.h>
+
+/* FUNCTIONS *****************************************************************/
+
+static
+BOOL
+IMAGEHLP_GetSecurityDirOffset(HANDLE handle, 
+                              DWORD *pdwOfs,
+                              DWORD *pdwSize)
 {
     IMAGE_DOS_HEADER dos_hdr;
     IMAGE_NT_HEADERS nt_hdr;
-    DWORD size, count, offset, len;
+    DWORD count;
     BOOL r;
     IMAGE_DATA_DIRECTORY *sd;
-
-    TRACE("handle %p\n", handle );
+    DPRINT("handle %p\n", handle );
 
     /* read the DOS header */
     count = SetFilePointer( handle, 0, NULL, FILE_BEGIN );
@@ -80,18 +56,35 @@ static BOOL IMAGEHLP_GetSecurityDirOffset( HANDLE handle, DWORD num,
         return FALSE;
 
     sd = &nt_hdr.OptionalHeader.
-                    DataDirectory[IMAGE_FILE_SECURITY_DIRECTORY];
+                    DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY];
 
-    TRACE("len = %lx addr = %lx\n", sd->Size, sd->VirtualAddress);
+    DPRINT("size = %lx addr = %lx\n", sd->Size, sd->VirtualAddress);
+    *pdwSize = sd->Size;
+    *pdwOfs = sd->VirtualAddress;
 
-    offset = 0;
-    size = sd->Size;
+    return TRUE;
+}
+
+static
+BOOL
+IMAGEHLP_GetCertificateOffset(HANDLE handle,
+                              DWORD num,
+                              DWORD *pdwOfs,
+                              DWORD *pdwSize)
+{
+    DWORD size, count, offset, len, sd_VirtualAddr;
+    BOOL r;
 
+    r = IMAGEHLP_GetSecurityDirOffset( handle, &sd_VirtualAddr, &size );
+    if( !r )
+        return FALSE;
+
+    offset = 0;
     /* take the n'th certificate */
     while( 1 )
     {
         /* read the length of the current certificate */
-        count = SetFilePointer( handle, sd->VirtualAddress + offset,
+        count = SetFilePointer( handle, sd_VirtualAddr + offset,
                                  NULL, FILE_BEGIN );
         if( count == INVALID_SET_FILE_POINTER )
             return FALSE;
@@ -115,57 +108,131 @@ static BOOL IMAGEHLP_GetSecurityDirOffset( HANDLE handle, DWORD num,
             return FALSE;
     }
 
-    *pdwOfs = sd->VirtualAddress + offset;
+    *pdwOfs = sd_VirtualAddr + offset;
     *pdwSize = len;
 
-    TRACE("len = %lx addr = %lx\n", len, sd->VirtualAddress + offset);
-
+    DPRINT("len = %lx addr = %lx\n", len, sd_VirtualAddr + offset);
     return TRUE;
 }
 
+static
+WORD
+CalcCheckSum(DWORD StartValue,
+             LPVOID BaseAddress,
+             DWORD WordCount)
+{
+   LPWORD Ptr;
+   DWORD Sum;
+   DWORD i;
+
+   Sum = StartValue;
+   Ptr = (LPWORD)BaseAddress;
+   for (i = 0; i < WordCount; i++)
+     {
+    Sum += *Ptr;
+    if (HIWORD(Sum) != 0)
+      {
+         Sum = LOWORD(Sum) + HIWORD(Sum);
+      }
+    Ptr++;
+     }
+
+   return (WORD)(LOWORD(Sum) + HIWORD(Sum));
+}
 
-/***********************************************************************
- *             ImageAddCertificate (IMAGEHLP.@)
+/*
+ * @unimplemented
  */
-
-BOOL WINAPI ImageAddCertificate(
-  HANDLE FileHandle, LPWIN_CERTIFICATE Certificate, PDWORD Index)
+BOOL
+IMAGEAPI
+ImageAddCertificate(HANDLE FileHandle,
+                    LPWIN_CERTIFICATE Certificate,
+                    PDWORD Index)
 {
-  FIXME("(%p, %p, %p): stub\n",
-    FileHandle, Certificate, Index
-  );
-  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-  return FALSE;
+    UNIMPLEMENTED;
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return FALSE;
 }
 
-/***********************************************************************
- *             ImageEnumerateCertificates (IMAGEHLP.@)
+/*
+ * @unimplemented
  */
-BOOL WINAPI ImageEnumerateCertificates(
-  HANDLE FileHandle, WORD TypeFilter, PDWORD CertificateCount,
-  PDWORD Indices, DWORD IndexCount)
+BOOL
+IMAGEAPI
+ImageEnumerateCertificates(HANDLE FileHandle,
+                           WORD TypeFilter,
+                           PDWORD CertificateCount,
+                           PDWORD Indices,
+                           DWORD IndexCount)
 {
-  FIXME("(%p, %hd, %p, %p, %ld): stub\n",
-    FileHandle, TypeFilter, CertificateCount, Indices, IndexCount
-  );
-  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-  return FALSE;
+    DWORD size, count, offset, sd_VirtualAddr;
+    WIN_CERTIFICATE hdr;
+    const size_t cert_hdr_size = sizeof hdr - sizeof hdr.bCertificate;
+    BOOL r;
+
+    DPRINT("%p %hd %p %p %ld\n",
+           FileHandle, TypeFilter, CertificateCount, Indices, IndexCount);
+
+    if( Indices )
+    {
+        DPRINT1("Indicies not FileHandled!\n");
+        return FALSE;
+    }
+
+    r = IMAGEHLP_GetSecurityDirOffset( FileHandle, &sd_VirtualAddr, &size );
+    if( !r )
+        return FALSE;
+
+    offset = 0;
+    *CertificateCount = 0;
+    while( offset < size )
+    {
+        /* read the length of the current certificate */
+        count = SetFilePointer( FileHandle, sd_VirtualAddr + offset,
+                                 NULL, FILE_BEGIN );
+        if( count == INVALID_SET_FILE_POINTER )
+            return FALSE;
+        r = ReadFile( FileHandle, &hdr, (DWORD)cert_hdr_size, &count, NULL );
+        if( !r )
+            return FALSE;
+        if( count != cert_hdr_size )
+            return FALSE;
+
+        DPRINT("Size = %08lx  id = %08hx\n", hdr.dwLength, hdr.wCertificateType );
+
+        /* check the certificate is not too big or too small */
+        if( hdr.dwLength < cert_hdr_size )
+            return FALSE;
+        if( hdr.dwLength > (size-offset) )
+            return FALSE;
+       
+        if( (TypeFilter == CERT_SECTION_TYPE_ANY) ||
+            (TypeFilter == hdr.wCertificateType) )
+        {
+            (*CertificateCount)++;
+        }
+
+        /* next certificate */
+        offset += hdr.dwLength;
+    }
+
+    return TRUE;
 }
 
-/***********************************************************************
- *             ImageGetCertificateData (IMAGEHLP.@)
- *
- *  FIXME: not sure that I'm dealing with the Index the right way
+/*
+ * @implemented
  */
-BOOL WINAPI ImageGetCertificateData(
-                HANDLE handle, DWORD Index,
-                LPWIN_CERTIFICATE Certificate, PDWORD RequiredLength)
+BOOL
+IMAGEAPI
+ImageGetCertificateData(HANDLE handle,
+                        DWORD Index,
+                        LPWIN_CERTIFICATE Certificate,
+                        PDWORD RequiredLength)
 {
     DWORD r, offset, ofs, size, count;
+    DPRINT("%p %ld %p %p\n", handle, Index, Certificate, RequiredLength);
 
-    TRACE("%p %ld %p %p\n", handle, Index, Certificate, RequiredLength);
-
-    if( !IMAGEHLP_GetSecurityDirOffset( handle, Index, &ofs, &size ) )
+    if( !IMAGEHLP_GetCertificateOffset( handle, Index, &ofs, &size ) )
         return FALSE;
 
     if( !Certificate )
@@ -193,45 +260,256 @@ BOOL WINAPI ImageGetCertificateData(
     if( count != size )
         return FALSE;
 
-    TRACE("OK\n");
+    DPRINT("OK\n");
+    return TRUE;
+}
+
+/*
+ * @unimplemented
+ */
+BOOL
+IMAGEAPI
+ImageGetCertificateHeader(HANDLE FileHandle,
+                          DWORD CertificateIndex,
+                          LPWIN_CERTIFICATE Certificateheader)
+{
+    DWORD r, offset, ofs, size, count;
+    const size_t cert_hdr_size = sizeof *Certificateheader -
+                                 sizeof Certificateheader->bCertificate;
+
+    DPRINT("%p %ld %p\n", FileHandle, CertificateIndex, Certificateheader);
+
+    if( !IMAGEHLP_GetCertificateOffset( FileHandle, CertificateIndex, &ofs, &size ) )
+        return FALSE;
+
+    if( size < cert_hdr_size )
+        return FALSE;
+
+    offset = SetFilePointer( FileHandle, ofs, NULL, FILE_BEGIN );
+    if( offset == INVALID_SET_FILE_POINTER )
+        return FALSE;
 
+    r = ReadFile( FileHandle, Certificateheader, (DWORD)cert_hdr_size, &count, NULL );
+    if( !r )
+        return FALSE;
+    if( count != cert_hdr_size )
+        return FALSE;
+
+    DPRINT("OK\n");
     return TRUE;
 }
 
-/***********************************************************************
- *             ImageGetCertificateHeader (IMAGEHLP.@)
+/*
+ * @unimplemented
+ */
+BOOL
+IMAGEAPI
+ImageGetDigestStream(HANDLE FileHandle,
+                     DWORD DigestLevel,
+                     DIGEST_FUNCTION DigestFunction,
+                     DIGEST_HANDLE DigestHandle)
+{
+    UNIMPLEMENTED;
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return FALSE;
+}
+
+/*
+ * @unimplemented
  */
-BOOL WINAPI ImageGetCertificateHeader(
-  HANDLE FileHandle, DWORD CertificateIndex,
-  LPWIN_CERTIFICATE Certificateheader)
+BOOL
+IMAGEAPI
+ImageRemoveCertificate(HANDLE FileHandle,
+                       DWORD Index)
 {
-  FIXME("(%p, %ld, %p): stub\n",
-    FileHandle, CertificateIndex, Certificateheader
-  );
-  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-  return FALSE;
+    UNIMPLEMENTED;
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return FALSE;
 }
 
-/***********************************************************************
- *             ImageGetDigestStream (IMAGEHLP.@)
+
+/*
+ * @implemented
  */
-BOOL WINAPI ImageGetDigestStream(
-  HANDLE FileHandle, DWORD DigestLevel,
-  DIGEST_FUNCTION DigestFunction, DIGEST_HANDLE DigestHandle)
+PIMAGE_NT_HEADERS
+IMAGEAPI
+CheckSumMappedFile(LPVOID BaseAddress,
+                   DWORD FileLength,
+                   LPDWORD HeaderSum,
+                   LPDWORD CheckSum)
 {
-  FIXME("(%p, %ld, %p, %p): stub\n",
-    FileHandle, DigestLevel, DigestFunction, DigestHandle
-  );
-  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-  return FALSE;
+  PIMAGE_NT_HEADERS Header;
+  DWORD CalcSum;
+  DWORD HdrSum;
+  DPRINT("stub\n");
+
+  CalcSum = (DWORD)CalcCheckSum(0,
+                BaseAddress,
+                (FileLength + 1) / sizeof(WORD));
+
+  Header = ImageNtHeader(BaseAddress);
+  HdrSum = Header->OptionalHeader.CheckSum;
+
+  /* Subtract image checksum from calculated checksum. */
+  /* fix low word of checksum */
+  if (LOWORD(CalcSum) >= LOWORD(HdrSum))
+  {
+    CalcSum -= LOWORD(HdrSum);
+  }
+  else
+  {
+    CalcSum = ((LOWORD(CalcSum) - LOWORD(HdrSum)) & 0xFFFF) - 1;
+  }
+
+   /* fix high word of checksum */
+  if (LOWORD(CalcSum) >= HIWORD(HdrSum))
+  {
+    CalcSum -= HIWORD(HdrSum);
+  }
+  else
+  {
+    CalcSum = ((LOWORD(CalcSum) - HIWORD(HdrSum)) & 0xFFFF) - 1;
+  }
+
+  /* add file length */
+  CalcSum += FileLength;
+
+  *CheckSum = CalcSum;
+  *HeaderSum = Header->OptionalHeader.CheckSum;
+
+  return Header;
 }
 
-/***********************************************************************
- *             ImageRemoveCertificate (IMAGEHLP.@)
+/*
+ * @implemented
+ */
+DWORD
+IMAGEAPI
+MapFileAndCheckSumA(LPSTR Filename,
+                    LPDWORD HeaderSum,
+                    LPDWORD CheckSum)
+{
+  HANDLE hFile;
+  HANDLE hMapping;
+  LPVOID BaseAddress;
+  DWORD FileLength;
+
+  DPRINT("(%s, %p, %p): stub\n", Filename, HeaderSum, CheckSum);
+
+  hFile = CreateFileA(Filename,
+              GENERIC_READ,
+              FILE_SHARE_READ | FILE_SHARE_WRITE,
+              NULL,
+              OPEN_EXISTING,
+              FILE_ATTRIBUTE_NORMAL,
+              0);
+  if (hFile == INVALID_HANDLE_VALUE)
+  {
+    return CHECKSUM_OPEN_FAILURE;
+  }
+
+  hMapping = CreateFileMappingW(hFile,
+                   NULL,
+                   PAGE_READONLY,
+                   0,
+                   0,
+                   NULL);
+  if (hMapping == 0)
+  {
+    CloseHandle(hFile);
+    return CHECKSUM_MAP_FAILURE;
+  }
+
+  BaseAddress = MapViewOfFile(hMapping,
+                  FILE_MAP_READ,
+                  0,
+                  0,
+                  0);
+  if (hMapping == 0)
+  {
+    CloseHandle(hMapping);
+    CloseHandle(hFile);
+    return CHECKSUM_MAPVIEW_FAILURE;
+  }
+
+  FileLength = GetFileSize(hFile,
+               NULL);
+
+  CheckSumMappedFile(BaseAddress,
+             FileLength,
+             HeaderSum,
+             CheckSum);
+
+  UnmapViewOfFile(BaseAddress);
+  CloseHandle(hMapping);
+  CloseHandle(hFile);
+
+  return 0;
+}
+
+/*
+ * @implemented
  */
-BOOL WINAPI ImageRemoveCertificate(HANDLE FileHandle, DWORD Index)
+DWORD
+IMAGEAPI
+MapFileAndCheckSumW(LPWSTR Filename,
+                    LPDWORD HeaderSum,
+                    LPDWORD CheckSum)
 {
-  FIXME("(%p, %ld): stub\n", FileHandle, Index);
-  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-  return FALSE;
+  HANDLE hFile;
+  HANDLE hMapping;
+  LPVOID BaseAddress;
+  DWORD FileLength;
+
+  DPRINT("(%S, %p, %p): stub\n", Filename, HeaderSum, CheckSum);
+
+  hFile = CreateFileW(Filename,
+              GENERIC_READ,
+              FILE_SHARE_READ | FILE_SHARE_WRITE,
+              NULL,
+              OPEN_EXISTING,
+              FILE_ATTRIBUTE_NORMAL,
+              0);
+  if (hFile == INVALID_HANDLE_VALUE)
+  {
+  return CHECKSUM_OPEN_FAILURE;
+  }
+
+  hMapping = CreateFileMappingW(hFile,
+                   NULL,
+                   PAGE_READONLY,
+                   0,
+                   0,
+                   NULL);
+  if (hMapping == 0)
+  {
+    CloseHandle(hFile);
+    return CHECKSUM_MAP_FAILURE;
+  }
+
+  BaseAddress = MapViewOfFile(hMapping,
+                  FILE_MAP_READ,
+                  0,
+                  0,
+                  0);
+  if (hMapping == 0)
+  {
+    CloseHandle(hMapping);
+    CloseHandle(hFile);
+    return CHECKSUM_MAPVIEW_FAILURE;
+  }
+
+  FileLength = GetFileSize(hFile,
+               NULL);
+
+  CheckSumMappedFile(BaseAddress,
+             FileLength,
+             HeaderSum,
+             CheckSum);
+
+  UnmapViewOfFile(BaseAddress);
+  CloseHandle(hMapping);
+  CloseHandle(hFile);
+
+  return 0;
 }
diff --git a/reactos/lib/imagehlp/internal.c b/reactos/lib/imagehlp/internal.c
deleted file mode 100644 (file)
index 2da3cd2..0000000
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- *     IMAGEHLP library
- *
- *     Copyright 1998  Patrik Stridvall
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include <stdarg.h>
-
-#include "windef.h"
-#include "winbase.h"
-#include "winerror.h"
-#include "wine/debug.h"
-#include "imagehlp.h"
-
-/***********************************************************************
- *             InitializeListHead
- */
-VOID InitializeListHead(PLIST_ENTRY pListHead)
-{
-  pListHead->Flink = pListHead;
-  pListHead->Blink = pListHead;
-}
-
-/***********************************************************************
- *             InsertHeadList
- */
-VOID InsertHeadList(PLIST_ENTRY pListHead, PLIST_ENTRY pEntry)
-{
-  pEntry->Blink = pListHead;
-  pEntry->Flink = pListHead->Flink;
-  pListHead->Flink = pEntry;
-}
-
-/***********************************************************************
- *             InsertTailList
- */
-VOID InsertTailList(PLIST_ENTRY pListHead, PLIST_ENTRY pEntry)
-{
-  pEntry->Flink = pListHead;
-  pEntry->Blink = pListHead->Blink;
-  pListHead->Blink = pEntry;
-}
-
-/***********************************************************************
- *             IsListEmpty
- */
-BOOLEAN IsListEmpty(PLIST_ENTRY pListHead)
-{
-  return !pListHead;
-}
-
-/***********************************************************************
- *             PopEntryList
- */
-PSINGLE_LIST_ENTRY PopEntryList(PSINGLE_LIST_ENTRY pListHead)
-{
-  pListHead->Next = NULL;
-  return pListHead;
-}
-
-/***********************************************************************
- *             PushEntryList
- */
-VOID PushEntryList(
-  PSINGLE_LIST_ENTRY pListHead, PSINGLE_LIST_ENTRY pEntry)
-{
-  pEntry->Next=pListHead;
-}
-
-/***********************************************************************
- *             RemoveEntryList
- */
-VOID RemoveEntryList(PLIST_ENTRY pEntry)
-{
-  pEntry->Flink->Blink = pEntry->Blink;
-  pEntry->Blink->Flink = pEntry->Flink;
-  pEntry->Flink = NULL;
-  pEntry->Blink = NULL;
-}
-
-/***********************************************************************
- *             RemoveHeadList
- */
-PLIST_ENTRY RemoveHeadList(PLIST_ENTRY pListHead)
-{
-  PLIST_ENTRY p = pListHead->Flink;
-
-  if(p != pListHead)
-    {
-      RemoveEntryList(pListHead);
-      return p;
-    }
-  else
-    {
-      pListHead->Flink = NULL;
-      pListHead->Blink = NULL;
-      return NULL;
-    }
-}
-
-/***********************************************************************
- *             RemoveTailList
- */
-PLIST_ENTRY RemoveTailList(PLIST_ENTRY pListHead)
-{
-  RemoveHeadList(pListHead->Blink);
-  if(pListHead != pListHead->Blink)
-    return pListHead;
-  else
-    return NULL;
-}
index 9712547..5c524c1 100644 (file)
 /*
- *     IMAGEHLP library
- *
- *     Copyright 1998  Patrik Stridvall
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         Imagehlp Libary
+ * FILE:            lib/imagehlp/modify.c
+ * PURPOSE:         Binding, Base Fixing and Rebasing
+ * PROGRAMMER:      Alex Ionescu (alex@relsoft.net)
  */
 
-#include <stdarg.h>
+/* INCLUDES ******************************************************************/
 
-#include "windef.h"
-#include "winbase.h"
-#include "winerror.h"
-#include "wine/debug.h"
-#include "imagehlp.h"
+#include "precomp.h"
 
-WINE_DEFAULT_DEBUG_CHANNEL(imagehlp);
+//#define NDEBUG
+#include <debug.h>
 
-static WORD CalcCheckSum(DWORD StartValue, LPVOID BaseAddress, DWORD WordCount);
-extern PIMAGE_NT_HEADERS WINAPI ImageNtHeader(PVOID Base);
+/* DATA **********************************************************************/
 
-/* Internal Structures we use to keep track of the Bound Imports */
-typedef struct _BOUND_FORWARDER_REFS {
-    ULONG      TimeDateStamp;
-    LPSTR      ModuleName;
-} BOUND_FORWARDER_REFS, *PBOUND_FORWARDER_REFS;
+CHAR BoundLibraries[4096];
+LPSTR BoundLibrariesPointer;
 
-typedef struct _BOUND_IMPORT_DESCRIPTOR {
-    LPSTR      ModuleName;
-    ULONG      TimeDateStamp;
-    USHORT     ForwaderReferences;
-    PBOUND_FORWARDER_REFS Forwarders;
-} BOUND_IMPORT_DESCRIPTOR, *PBOUND_IMPORT_DESCRIPTOR;
+/* FUNCTIONS *****************************************************************/
 
-
-VOID
-STDCALL
-BindpWalkAndBindImports(
-    PLOADED_IMAGE File,
-    LPSTR DllPath
-    );
-
-PBOUND_IMPORT_DESCRIPTOR
-STDCALL
-BindpCreateBoundImportDescriptor(
-       LPSTR LibraryName,
-       PLOADED_IMAGE Library,
-       PULONG BoundImportDescriptor
-    );
-
-BOOL
-STDCALL
-BindpBindThunk(
-    PIMAGE_THUNK_DATA Thunk,
-    PLOADED_IMAGE Image,
-    PIMAGE_THUNK_DATA BoundThunk,
-    PLOADED_IMAGE LoadedLibrary,
-    PIMAGE_EXPORT_DIRECTORY Exports,
-    PBOUND_IMPORT_DESCRIPTOR BoundImportDescriptor,
-    LPSTR DllPath
-    );
-
-PIMAGE_BOUND_IMPORT_DESCRIPTOR
-STDCALL
-BindpCreateBoundImportSection(
-    PULONG BoundImportDescriptor,
-    PULONG BoundImportsSize
-    );
-
-ULONG
-STDCALL
-BindpAddBoundForwarder(
-    PBOUND_IMPORT_DESCRIPTOR BoundImportDescriptor,
-    LPSTR DllPath,
-    PUCHAR ForwarderString
-    );
-
-UCHAR  BoundLibraries[4096];
-LPSTR  BoundLibrariesPointer = BoundLibraries;
-PULONG BoundImportDescriptors;
-
-/*
- * BindImageEx
- *
- * FUNCTION:
- *      Binds a PE Image File to its imported Libraries
- * ARGUMENTS:
- *      Flags                  - Caller Specified Flags
- *      ImageName              - Name of Imagefile to Bind
- *      DllPath                        - Path to search DLL Files in, can be NULL to use Default
- *      SymbolPath             - Path to search Symbol Files in, can be NULL to use Default
- *      StatusRoutine  - Callback routine to notify of Bind Events, can be NULL to disable.
- *
- * RETURNS:
- *      TRUE if Success.
- */
-BOOL 
-WINAPI 
-BindImageEx(
-    IN DWORD Flags,
-    IN LPSTR ImageName,
-    IN LPSTR DllPath,
-    IN LPSTR SymbolPath,
-    IN PIMAGEHLP_STATUS_ROUTINE StatusRoutine
-    )
+LPSTR
+IMAGEAPI
+BindpCaptureImportModuleName(LPSTR ModuleName)
 {
-       LOADED_IMAGE                            FileData;
-       PLOADED_IMAGE                           File;
-       ULONG                                           CheckSum, HeaderSum, OldChecksum;
-    SYSTEMTIME                                 SystemTime;
-    FILETIME                                   LastWriteTime;
-    
-       FIXME("BindImageEx Called for: %s \n", ImageName);
-
-       /* Set and Clear Buffer */
-       File = &FileData;
-       RtlZeroMemory(File, sizeof(*File));
-
-       /* Request Image Data */
-       if (MapAndLoad(ImageName, DllPath, File, TRUE, FALSE)) {
-
-               //FIXME("Image Mapped and Loaded\n");
-
-               /* Read Import Table */
-               BindpWalkAndBindImports(File, DllPath);
-
-               //FIXME("Binding Completed, getting Checksum\n");
-               
-               /* Update Checksum */
-               OldChecksum = File->FileHeader->OptionalHeader.CheckSum;
-           CheckSumMappedFile (File->MappedAddress,
-                                                       GetFileSize(File->hFile, NULL),
-                            &HeaderSum,
-                            &CheckSum);
-        File->FileHeader->OptionalHeader.CheckSum = CheckSum;
-
-               //FIXME("Saving Changes to file\n");
-
-               /* Save Changes */
-        UnmapViewOfFile(File->MappedAddress);
-
-               //FIXME("Setting time\n");
-
-               /* Save new Modified Time */
-        GetSystemTime(&SystemTime);
-               SystemTimeToFileTime(&SystemTime, &LastWriteTime);
-        SetFileTime(File->hFile, NULL, NULL, &LastWriteTime);
-
-               /* Close Handle */
-               CloseHandle(File->hFile);
-       }
-
-       FIXME("Done\n");
-       return TRUE;
-}
-
-/*
- * BindpWalkAndBindImports
- *
- * FUNCTION:
- *      Does the actual Binding of the Imports and Forward-Referencing
- *
- * ARGUMENTS:
- *      File                   - Name of Imagefile to Bind
- *      DllPath                        - Path to search DLL Files in, can be NULL to use Default
- *
- * RETURNS:
- *      Nothing
- */
-VOID
-STDCALL
-BindpWalkAndBindImports(
-    PLOADED_IMAGE File,
-    LPSTR DllPath
-    )
-{
-       PIMAGE_IMPORT_DESCRIPTOR        Imports;
-       PIMAGE_EXPORT_DIRECTORY         Exports;
-       ULONG                                           SizeOfImports;
-       ULONG                                           SizeOfExports;
-       ULONG                                           SizeOfThunks;
-       PIMAGE_OPTIONAL_HEADER          OptionalHeader32 = NULL;
-    PIMAGE_FILE_HEADER                 FileHeader;
-       LPSTR                                           ImportedLibrary;
-       PLOADED_IMAGE                           LoadedLibrary;
-       PBOUND_IMPORT_DESCRIPTOR        BoundImportDescriptor = NULL;
-       PIMAGE_BOUND_IMPORT_DESCRIPTOR BoundImportTable;
-       PIMAGE_THUNK_DATA                       Thunks, TempThunk;
-    PIMAGE_THUNK_DATA                  BoundThunks, TempBoundThunk;
-    ULONG                                              ThunkCount = 0;
-       ULONG                                           Thunk;
-       ULONG                                           BoundImportTableSize;
-       ULONG                                           VirtBytesFree, HeaderBytesFree, FirstFreeByte, PhysBytesFree;
-       
-       //FIXME("BindpWalkAndBindImports Called\n");
-
-       /* Load the Import Descriptor */
-       Imports = ImageDirectoryEntryToData (File->MappedAddress,
-                                                                                       FALSE, 
-                                                                                       IMAGE_DIRECTORY_ENTRY_IMPORT, 
-                                                                                       &SizeOfImports);
-
-       /* Read the File Header */
-       FileHeader = &File->FileHeader->FileHeader;
-       OptionalHeader32 = &File->FileHeader->OptionalHeader;
-
-       /* Support for up to 32 imported DLLs */
-       BoundImportDescriptors = GlobalAlloc(GMEM_ZEROINIT, 32* sizeof(*BoundImportDescriptor));
-
-       //FIXME("BoundImportDescriptors Allocated\n");
-
-       /* For each Import */
-       for(; Imports->Name ; Imports++) {
-               
-               /* Which DLL is being Imported */
-               ImportedLibrary = ImageRvaToVa (File->FileHeader, 
-                                                                               File->MappedAddress, 
-                                                                               Imports->Name, 
-                                                                               &File->LastRvaSection);
-
-               FIXME("Loading Imported DLL: %s \n", ImportedLibrary);
-
-               /* Load the DLL */
-               LoadedLibrary = ImageLoad(ImportedLibrary, DllPath);
-
-               FIXME("DLL Loaded at: %p \n", LoadedLibrary->MappedAddress);
-
-               /* Now load the Exports */
-               Exports = ImageDirectoryEntryToData (LoadedLibrary->MappedAddress, 
-                                                                                       FALSE, 
-                                                                                       IMAGE_DIRECTORY_ENTRY_EXPORT, 
-                                                                                       &SizeOfExports);
-
-               /* And load the Thunks */
-               Thunks = ImageRvaToVa (File->FileHeader, 
-                                                               File->MappedAddress, 
-                                                               (ULONG)Imports->OriginalFirstThunk, 
-                                                               &File->LastRvaSection);
-
-               /* No actual Exports (UPX Packer can do this */
-               if (!Thunks) continue;
-
-               //FIXME("Creating Bound Descriptor for this DLL\n");
-               
-               /* Create Bound Import Descriptor */
-               BoundImportDescriptor = BindpCreateBoundImportDescriptor (ImportedLibrary, 
-                                                                                                                       LoadedLibrary, 
-                                                                                                                       BoundImportDescriptors);
-
-               /* Count how many Thunks we have */
-               ThunkCount = 0;
-               TempThunk = Thunks;
-               while (TempThunk->u1.AddressOfData) {
-                       ThunkCount++;
-                       TempThunk++;
-               }
-
-               /* Allocate Memory for the Thunks we will Bind */
-               SizeOfThunks = ThunkCount * sizeof(*TempBoundThunk);
-               BoundThunks = GlobalAlloc(GMEM_ZEROINIT, SizeOfThunks);
-
-               //FIXME("Binding Thunks\n");
-
-               /* Bind the Thunks */
-               TempThunk = Thunks;
-               TempBoundThunk = BoundThunks;
-               for (Thunk=0; Thunk < ThunkCount; Thunk++) {
-                       BindpBindThunk (TempThunk, 
-                                               File, 
-                                               TempBoundThunk, 
-                                               LoadedLibrary, 
-                                               Exports, 
-                                               BoundImportDescriptor, 
-                                               DllPath);
-                       TempThunk++;
-                       TempBoundThunk++;
-               }
-
-               /* Load the Second Thunk Array */
-               TempThunk = ImageRvaToVa (File->FileHeader, 
-                                                                       File->MappedAddress, 
-                                                                       (ULONG)Imports->FirstThunk, 
-                                                                       &File->LastRvaSection);
-
-               //FIXME("Copying Bound Thunks\n");
-
-               /* Copy the Pointers */
-               if (memcmp(TempThunk, BoundThunks, SizeOfThunks)) {
-                       RtlCopyMemory(TempThunk, BoundThunks, SizeOfThunks);
-               }
-               
-               /* Set the TimeStamp */
-               if (Imports->TimeDateStamp != 0xFFFFFFFF) {
-            Imports->TimeDateStamp = 0xFFFFFFFF;
-        }
-
-               /* Free the Allocated Memory */
-               GlobalFree(BoundThunks);
-
-               //FIXME("Moving to next File\n");
-       }
-
-       //FIXME("Creating Bound Import Section\n");
-
-       /* Create the Bound Import Table */
-       BoundImportTable = BindpCreateBoundImportSection(BoundImportDescriptors, &BoundImportTableSize);
-
-       /* Zero out the Bound Import Table */
-       File->FileHeader->OptionalHeader.DataDirectory
-               [IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress = 0;
-       File->FileHeader->OptionalHeader.DataDirectory
-               [IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size = 0;
-
-       /* Check if we have enough space */
-    FirstFreeByte = GetImageUnusedHeaderBytes(File, &VirtBytesFree);
-    HeaderBytesFree = File->Sections->VirtualAddress - 
-                                               File->FileHeader->OptionalHeader.SizeOfHeaders + VirtBytesFree;
-    PhysBytesFree = File->Sections->PointerToRawData -
-                                               File->FileHeader->OptionalHeader.SizeOfHeaders + VirtBytesFree;
-
-       //FIXME("Calculating Space\n");
-
-    if (BoundImportTableSize > VirtBytesFree) {
-        if (BoundImportTableSize > HeaderBytesFree) {
-                       FIXME("Not enough Space\n");
-                       return; /* Fail...not enough space */
-        }
-        if (BoundImportTableSize <= PhysBytesFree) {
-            
-                       FIXME("Header Recalculation\n");
-                       /* We have enough NULLs to add it, simply enlarge header data */
-            File->FileHeader->OptionalHeader.SizeOfHeaders = File->FileHeader->OptionalHeader.SizeOfHeaders - 
-                                                                                                                       VirtBytesFree +
-                                                                                                                       BoundImportTableSize +
-                                                                                                                       ((File->FileHeader->OptionalHeader.FileAlignment - 1)
-                                                                                                                       & ~(File->FileHeader->OptionalHeader.FileAlignment - 1));
-
-        } else  {
-
-                       FIXME("Header Resizing\n");
-
-                       /* Resize the Headers */
-                       //UNIMPLEMENTED
-
-            /* Recalculate Headers */
-                       FileHeader = &File->FileHeader->FileHeader;
-                       OptionalHeader32 = &File->FileHeader->OptionalHeader;
-               }
-       }
-       
-       /* Set Bound Import Table Data */
-       File->FileHeader->OptionalHeader.DataDirectory
-               [IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress = FirstFreeByte;
-       File->FileHeader->OptionalHeader.DataDirectory
-               [IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size = BoundImportTableSize;
-
-       //FIXME("Copying Bound Import Table\n");
-       
-       /* Copy the Bound Import Table */
-       RtlCopyMemory(File->MappedAddress + FirstFreeByte, BoundImportTable, BoundImportTableSize);
-
-       /* Free out local copy */
-       GlobalFree(BoundImportTable);
+    LPSTR Name = BoundLibraries;
+
+    /* Check if it hasn't been initialized yet */
+    if (!BoundLibrariesPointer)
+    {
+        /* Start with a null char and set the pointer */
+        *Name = ANSI_NULL;
+        BoundLibrariesPointer = Name;
+    }
+
+    /* Loop the current buffer */
+    while (*Name)
+    {
+        /* Try to match this DLL's name and return it */
+        if (!_stricmp(Name, ModuleName)) return Name;
+
+        /* Move on to the next DLL Name */
+        Name += strlen(Name) + sizeof(CHAR);
+    }
+
+    /* If we got here, we didn't find one, so add this one to our buffer */
+    strcpy(Name, ModuleName);
+
+    /* Set the new position of the buffer, and null-terminate it */
+    BoundLibrariesPointer = Name + strlen(Name) + sizeof(CHAR);
+    *BoundLibrariesPointer = ANSI_NULL;
+
+    /* Return the pointer to the name */
+    return Name;
 }
 
-
-/*
- * BindpCreateBoundImportSection
- *
- * FUNCTION:
- *      Creates a 32-bit PE Bound Import Table
- *
- * ARGUMENTS:
- *      BoundImportDescriptor          - Pointer to the Bound Import Table
- *      BoundImportsSize                       - Size of the Bound Import Table
- *
- * RETURNS:
- *      PIMAGE_BOUND_IMPORT_DESCRIPTOR - The Bound Import Table
- */
 PIMAGE_BOUND_IMPORT_DESCRIPTOR
-STDCALL
-BindpCreateBoundImportSection(
-    PULONG BoundImportDescriptor,
-    PULONG BoundImportsSize
-    )
+IMAGEAPI
+BindpCreateNewImportSection(PIMPORT_DESCRIPTOR *BoundImportDescriptor,
+                            PULONG BoundImportsSize)
 {
-    ULONG BoundLibraryNamesSize, BoundImportTableSize;
-    PBOUND_FORWARDER_REFS BoundForwarder;
-       PBOUND_IMPORT_DESCRIPTOR CurrentBoundImportDescriptor;
-    PVOID BoundLibraryNames;
-    PIMAGE_BOUND_IMPORT_DESCRIPTOR CurrentBoundImportTableEntry, BoundImportTable;
-    PIMAGE_BOUND_FORWARDER_REF NewForwarder;
-
-       /* Zero the Sizes */
+    ULONG BoundLibraryNamesSize = 0, BoundImportTableSize = 0;
+    PBOUND_FORWARDER_REFS Forwarder, *NextForwarder;
+    PIMPORT_DESCRIPTOR Descriptor, *NextDescriptor;
+    LPSTR BoundLibraryNames;
+    PIMAGE_BOUND_IMPORT_DESCRIPTOR BoundTableEntry, BoundTable;
+    PIMAGE_BOUND_FORWARDER_REF BoundForwarder;
+
+    /* Zero the outoging size */
     *BoundImportsSize = 0;
-    BoundLibraryNamesSize = 0;
-    BoundImportTableSize = 0;
-
-       /* Start with the first Internal Descriptor */
-    CurrentBoundImportDescriptor = (PBOUND_IMPORT_DESCRIPTOR)BoundImportDescriptor;
-
-       /* Loop through every Descriptor we loaded */
-    while (CurrentBoundImportDescriptor->ModuleName) {
 
-               /* Add to the size of the Bound Import Table */
+    /* Loop the descriptors and forwarders to get the size */
+    NextDescriptor = BoundImportDescriptor;
+    while ((Descriptor = *NextDescriptor))
+    {
+        /* Add to the size of the Bound Import Table */
         BoundImportTableSize += sizeof(IMAGE_BOUND_IMPORT_DESCRIPTOR);
 
-               /* Check Forwarders */
-        BoundForwarder = CurrentBoundImportDescriptor->Forwarders;
-               while (BoundForwarder->ModuleName) {
-
-                       /* Add to size of Bound Import Table */
+        /* Check Forwarders */
+        NextForwarder = &Descriptor->Forwarders;
+        while ((Forwarder = *NextForwarder))
+        {
+            /* Add to size of Bound Import Table */
             BoundImportTableSize += sizeof(IMAGE_BOUND_FORWARDER_REF);
 
-                       /* Next Forwarder */
-            BoundForwarder++;
-            }
-
-               /* Read Next Internal Descriptor */
-        CurrentBoundImportDescriptor++;
+            /* Next Forwarder */
+            NextForwarder = &Forwarder->Next;
         }
 
-       /* Add Terminator for PE Loader*/
+        /* Read Next Internal Descriptor */
+        NextDescriptor = &Descriptor->Next;
+    }
+
+    /* Add Terminator for PE Loader*/
     BoundImportTableSize += sizeof(IMAGE_BOUND_IMPORT_DESCRIPTOR);
+    DPRINT("Table size: %lx\n", BoundImportTableSize);
 
-       /* Name of Libraries Bound in Bound Import Table */
-    BoundLibraryNamesSize = ((ULONG)BoundLibrariesPointer - (ULONG)(&BoundLibraries));
+    /* Name of Libraries Bound in Bound Import Table */
+    BoundLibraryNamesSize = (ULONG)((ULONG_PTR)BoundLibrariesPointer -
+                                    (ULONG_PTR)BoundLibraries);
+    BoundLibrariesPointer = NULL;
 
-       /* Size of the whole table, dword aligned */
+    /* Size of the whole table, dword aligned */
     *BoundImportsSize = BoundImportTableSize + 
-                                               ((BoundLibraryNamesSize + sizeof(ULONG) - 1) & ~(sizeof(ULONG)-1));
+                        ((BoundLibraryNamesSize + sizeof(ULONG) - 1) &
+                        ~(sizeof(ULONG) - 1));
 
-       /* Allocate it */
-    BoundImportTable = GlobalAlloc(GMEM_ZEROINIT, *BoundImportsSize);
+    /* Allocate it */
+    BoundTable = HeapAlloc(IMAGEHLP_hHeap, HEAP_ZERO_MEMORY, *BoundImportsSize);
     
-       /* Pointer Library Names inside the Bound Import Table */
-    BoundLibraryNames = (PIMAGE_BOUND_IMPORT_DESCRIPTOR)((ULONG_PTR)BoundImportTable + 
-                                                                                                                                       BoundImportTableSize);
+    /* Pointer Library Names inside the Bound Import Table */
+    BoundLibraryNames = (LPSTR)BoundTable + BoundImportTableSize;
 
-       /* Copy the Library Names */
+    /* Copy the Library Names */
     RtlCopyMemory(BoundLibraryNames, BoundLibraries, BoundLibraryNamesSize);
 
-       /* Go back to first Internal Descriptor and load first entry in the Bound Import Table */
-    CurrentBoundImportTableEntry = (PIMAGE_BOUND_IMPORT_DESCRIPTOR)BoundImportTable;
-    CurrentBoundImportDescriptor = (PBOUND_IMPORT_DESCRIPTOR)BoundImportDescriptor;
-
-       /* Copy the data from our Internal Structure to the Bound Import Table */
-    while (CurrentBoundImportDescriptor->ModuleName) {
-        CurrentBoundImportTableEntry->TimeDateStamp = CurrentBoundImportDescriptor->TimeDateStamp;
-        CurrentBoundImportTableEntry->OffsetModuleName = (USHORT)(BoundImportTableSize + 
-                                                                                                                               (CurrentBoundImportDescriptor->ModuleName - 
-                                                                                                                               (LPSTR) BoundLibraries));
-               CurrentBoundImportTableEntry->NumberOfModuleForwarderRefs = CurrentBoundImportDescriptor->ForwaderReferences;
-
-               /* Copy the data from our Forwader Entries to the Bound Import Table */
-        NewForwarder = (PIMAGE_BOUND_FORWARDER_REF)(CurrentBoundImportTableEntry+1);
-        BoundForwarder = CurrentBoundImportDescriptor->Forwarders;
-               while (BoundForwarder->ModuleName) {
-            NewForwarder->TimeDateStamp =BoundForwarder->TimeDateStamp;
-            NewForwarder->OffsetModuleName = (USHORT)(BoundImportTableSize + 
-                                                                                                       (BoundForwarder->ModuleName - 
-                                                                                                       (LPSTR) BoundLibraries));
-            NewForwarder++;
+    /* Now loop both tables */
+    BoundTableEntry = BoundTable;
+    NextDescriptor = BoundImportDescriptor;
+    while ((Descriptor = *NextDescriptor))
+    {
+        /* Copy the data */
+        BoundTableEntry->TimeDateStamp = Descriptor->TimeDateStamp;
+        BoundTableEntry->OffsetModuleName = (USHORT)(BoundImportTableSize +
+                                                     (Descriptor->ModuleName -
+                                                      (ULONG_PTR)BoundLibraries));
+        BoundTableEntry->NumberOfModuleForwarderRefs = Descriptor->ForwaderReferences;
+
+        /* Now loop the forwarders */
+        BoundForwarder = (PIMAGE_BOUND_FORWARDER_REF)BoundTableEntry + 1;
+        NextForwarder = &Descriptor->Forwarders;
+        while ((Forwarder = *NextForwarder))
+        {
+            /* Copy the data */
+            BoundForwarder->TimeDateStamp = Forwarder->TimeDateStamp;
+            BoundForwarder->OffsetModuleName = (USHORT)(BoundImportTableSize +
+                                                       (Forwarder->ModuleName -
+                                                       (ULONG_PTR)BoundLibraries));
+
+            /* Move to the next new forwarder, and move to the next entry */
             BoundForwarder++;
-               }
+            NextForwarder = &Forwarder->Next;
+        }
 
-               /* Move to next Bound Import Table Entry */
-        CurrentBoundImportTableEntry = (PIMAGE_BOUND_IMPORT_DESCRIPTOR)NewForwarder;
+        /* Move to next Bound Import Table Entry */
+        BoundTableEntry = (PIMAGE_BOUND_IMPORT_DESCRIPTOR)BoundForwarder;
+
+        /* Move to the next descriptor */
+        NextDescriptor = &Descriptor->Next;
+    }
+
+    /* Loop the descriptors and forwarders to free them */
+    NextDescriptor = BoundImportDescriptor;
+    while ((Descriptor = *NextDescriptor))
+    {
+        /* Read next internal descriptor */
+        *NextDescriptor = Descriptor->Next;
+
+        /* Loop its forwarders */
+        NextForwarder = &Descriptor->Forwarders;
+        while ((Forwarder = *NextForwarder))
+        {
+            /* Next Forwarder */
+            *NextForwarder = Forwarder->Next;
+
+            /* Free it */
+            HeapFree(IMAGEHLP_hHeap, 0, Forwarder);
+        }
 
-               /* move to next Internal Descriptor */
-        CurrentBoundImportDescriptor++;
-       }
+        /* Free it */
+        HeapFree(IMAGEHLP_hHeap, 0, Descriptor);
+    }
 
-       /* Now put the pointer back at the beginning and clear the buffer */
-       RtlZeroMemory(BoundLibraries, 4096);
-       BoundLibrariesPointer = BoundLibraries;
+    /* Return the Bound Import Table */
+    return BoundTable;
+}
+
+PCHAR
+IMAGEAPI
+BindpAddForwarderReference(LPSTR ModuleName,
+                           LPSTR ImportName,
+                           PIMPORT_DESCRIPTOR BoundImportDescriptor,
+                           LPSTR DllPath,
+                           PCHAR ForwarderString,
+                           PBOOL ForwarderBound)
+{
+    CHAR DllName[256];
+    PCHAR TempDllName, FunctionName;
+    PLOADED_IMAGE Library;
+    SIZE_T DllNameSize;
+    USHORT OrdinalNumber;
+    USHORT HintIndex;
+    ULONG ExportSize;
+    PIMAGE_EXPORT_DIRECTORY Exports;
+    ULONG_PTR ExportsBase;
+    PULONG AddressOfNames;
+    PUSHORT AddressOfOrdinals;
+    PULONG AddressOfPointers;
+    LPSTR ExportName;
+    ULONG_PTR ForwardedAddress;
+    PBOUND_FORWARDER_REFS Forwarder, *NextForwarder;
+    PIMAGE_OPTIONAL_HEADER OptionalHeader = NULL;
 
-    return BoundImportTable;
+NextForwarder:
+
+    /* Get the DLL Name */
+    TempDllName = ForwarderString;
+    while (*TempDllName && *TempDllName != '.') TempDllName++;
+    if (*TempDllName != '.') return ForwarderString;
+
+    /* Get the size */
+    DllNameSize = (SIZE_T)(TempDllName - ForwarderString);
+    if (DllNameSize >= MAX_PATH) return ForwarderString;
+
+    /* Now copy the name and append the extension */
+    strncpy(DllName, ForwarderString, DllNameSize);
+    DllName[DllNameSize] = ANSI_NULL;
+    strcat(DllName, ".DLL");
+
+    /* Load it */
+    DPRINT("Loading the Thunk Library: %s \n", DllName);
+    Library = ImageLoad(DllName, DllPath);
+    if (!Library) return ForwarderString;
+
+    /* Move past the name */
+    DPRINT("It Loaded at: %p \n", Library->MappedAddress);
+    FunctionName = TempDllName += 1;
+
+    /* Load Exports */
+    Exports = ImageDirectoryEntryToData(Library->MappedAddress,
+                                        FALSE,
+                                        IMAGE_DIRECTORY_ENTRY_EXPORT,
+                                        &ExportSize);
+    if (!Exports) return ForwarderString;
+
+    /* Get the Optional Header */
+    OptionalHeader = &Library->FileHeader->OptionalHeader;
+
+    /* Check if we're binding by ordinal */
+    if (*FunctionName == '#')
+    {
+        /* We are, get the number and validate it */
+        OrdinalNumber = atoi(FunctionName + 1) - (USHORT)Exports->Base;
+        if (OrdinalNumber >= Exports->NumberOfFunctions) return ForwarderString;
+    }
+    else
+    {
+        /* Binding by name... */
+        OrdinalNumber = -1;
+    }
+
+    /* Get the Pointers to the Tables */
+    AddressOfNames = ImageRvaToVa(Library->FileHeader,
+                                  Library->MappedAddress,
+                                  Exports->AddressOfNames,
+                                  &Library->LastRvaSection);
+    AddressOfOrdinals = ImageRvaToVa(Library->FileHeader,
+                                     Library->MappedAddress, 
+                                     Exports->AddressOfNameOrdinals, 
+                                     &Library->LastRvaSection);
+    AddressOfPointers = ImageRvaToVa(Library->FileHeader, 
+                                     Library->MappedAddress, 
+                                     Exports->AddressOfFunctions, 
+                                     &Library->LastRvaSection);
+
+    /* Check if we're binding by name... */
+    if (OrdinalNumber == 0xffff)
+    {
+        /* Do a full search for the ordinal */
+        for (HintIndex = 0; HintIndex < Exports->NumberOfNames; HintIndex++)
+        {
+            /* Get the Export Name */
+            ExportName = ImageRvaToVa(Library->FileHeader,
+                                      Library->MappedAddress, 
+                                      (ULONG)AddressOfNames[HintIndex], 
+                                      &Library->LastRvaSection);
+            
+            /* Check if it's the one we want */
+            if (!strcmp(FunctionName, ExportName))
+            {
+                OrdinalNumber = AddressOfOrdinals[HintIndex];
+                break;
+            }
+        }
+
+        /* Make sure it's valid */
+        if (HintIndex >= Exports->NumberOfNames) return ForwarderString;
+    }
+
+    /* Get the Forwarded Address */
+    ForwardedAddress = AddressOfPointers[OrdinalNumber] +
+                       OptionalHeader->ImageBase;
+
+    /* Loop the forwarders to see if this DLL was already processed */
+    NextForwarder = &BoundImportDescriptor->Forwarders;
+    while ((Forwarder = *NextForwarder))
+    {
+        /* Check for a name match */
+        if (!_stricmp(DllName, Forwarder->ModuleName)) break;
+
+        /* Move to the next one */
+        NextForwarder = &Forwarder->Next;
+    }
+
+    /* Check if we've went through them all without luck */
+    if (!Forwarder)
+    {
+        /* Allocate a forwarder structure */
+        Forwarder = HeapAlloc(IMAGEHLP_hHeap,
+                              HEAP_ZERO_MEMORY,
+                              sizeof(BOUND_FORWARDER_REFS));
+
+        /* Set the name */
+        Forwarder->ModuleName = BindpCaptureImportModuleName(DllName);        
+
+        /* Increase the number of forwarders */
+        BoundImportDescriptor->ForwaderReferences++;
+
+        /* Link it */
+        *NextForwarder = Forwarder;
+    }
+
+    /* Set the timestamp */
+    Forwarder->TimeDateStamp = Library->FileHeader->FileHeader.TimeDateStamp;
+
+    /* Load DLL's Exports */
+    ExportsBase = (ULONG_PTR)ImageDirectoryEntryToData(Library->MappedAddress,
+                                                       TRUE,
+                                                       IMAGE_DIRECTORY_ENTRY_EXPORT,
+                                                       &ExportSize) -
+                  (ULONG_PTR)Library->MappedAddress;
+    
+    /* Convert to VA */
+    ExportsBase += OptionalHeader->ImageBase;
+
+    /* Is this yet another Forward? */
+    DPRINT("I've thunked it\n");
+    if ((ForwardedAddress > ExportsBase) &&
+        (ForwardedAddress < (ExportsBase + ExportSize)))
+    {
+        /* Update the string pointer */
+        ForwarderString = ImageRvaToVa(Library->FileHeader, 
+                                       Library->MappedAddress, 
+                                       AddressOfPointers[OrdinalNumber], 
+                                       &Library->LastRvaSection); 
+        goto NextForwarder;
+    }
+    else
+    {
+        /* Update the pointer and return success */
+        ForwarderString = (PUCHAR)ForwardedAddress;
+        *ForwarderBound = TRUE;
+    }
+
+    /* Return the pointer */
+    return ForwarderString;
 }
 
-/*
- * BindpBindThunk
- *
- * FUNCTION:
- *      Finds the pointer of the Imported function, and writes it into the Thunk,
- *             thus making the Thunk Bound.
- *
- * ARGUMENTS:
- *      Thunk                                  - Current Thunk in Unbound File
- *      File                                   - File containing the Thunk
- *      BoundThunk                             - Pointer to the corresponding Bound Thunk
- *      LoadedLibrary                  - Library containing the Exported Function
- *      Exports                                        - Export Directory of LoadedLibrary
- *      BoundImportDescriptor  - Internal Bound Import Descriptor of LoadedLibrary
- *      DllPath                                        - DLL Search Path
- *
- * RETURNS:
- *      TRUE if Suceeded
- */
 BOOL
-STDCALL
-BindpBindThunk(
-    PIMAGE_THUNK_DATA Thunk,
-    PLOADED_IMAGE File,
-    PIMAGE_THUNK_DATA BoundThunk,
-    PLOADED_IMAGE LoadedLibrary,
-    PIMAGE_EXPORT_DIRECTORY Exports,
-    PBOUND_IMPORT_DESCRIPTOR BoundImportDescriptor,
-    LPSTR DllPath
-    )
+IMAGEAPI
+BindpLookupThunk(PIMAGE_THUNK_DATA Thunk,
+                 PLOADED_IMAGE Image,
+                 PIMAGE_THUNK_DATA BoundThunk,
+                 PIMAGE_THUNK_DATA ThunkFunction,
+                 PLOADED_IMAGE Library,
+                 PIMAGE_EXPORT_DIRECTORY Exports,
+                 PIMPORT_DESCRIPTOR BoundImportDescriptor,
+                 LPSTR DllPath,
+                 PULONG *Forwarders)
 {
-       PULONG                                  AddressOfNames;
-    PUSHORT                                    AddressOfOrdinals;
-    PULONG                                     AddressOfPointers;
-    PIMAGE_IMPORT_BY_NAME      ImportName;
-       ULONG                                   OrdinalNumber = 0;
-    USHORT                                     HintIndex;
-    LPSTR                                      ExportName;
-    ULONG                                      ExportsBase;
-    ULONG                                      ExportSize;
-    UCHAR                                      NameBuffer[32];
-    PIMAGE_OPTIONAL_HEADER     OptionalHeader32 = NULL;
-    PIMAGE_OPTIONAL_HEADER     LibraryOptionalHeader32 = NULL;
-
-       /* Get the Pointers to the Tables */
-       AddressOfNames = ImageRvaToVa (LoadedLibrary->FileHeader, 
-                                                                       LoadedLibrary->MappedAddress,
-                                                                       Exports->AddressOfNames,
-                                                                       &LoadedLibrary->LastRvaSection);
-       AddressOfOrdinals = ImageRvaToVa (LoadedLibrary->FileHeader,
-                                                                               LoadedLibrary->MappedAddress, 
-                                                                               Exports->AddressOfNameOrdinals, 
-                                                                               &LoadedLibrary->LastRvaSection);
-       AddressOfPointers = ImageRvaToVa (LoadedLibrary->FileHeader, 
-                                                                               LoadedLibrary->MappedAddress, 
-                                                                               Exports->AddressOfFunctions, 
-                                                                               &LoadedLibrary->LastRvaSection);
-
-       //FIXME("Binding a Thunk\n");
-
-       /* Get the Optional Header */
-       OptionalHeader32 = &File->FileHeader->OptionalHeader;
-       LibraryOptionalHeader32 = &LoadedLibrary->FileHeader->OptionalHeader;
+    PULONG AddressOfNames;
+    PUSHORT AddressOfOrdinals;
+    PULONG AddressOfPointers;
+    PIMAGE_IMPORT_BY_NAME ImportName;
+    ULONG OrdinalNumber = 0;
+    USHORT HintIndex;
+    LPSTR ExportName;
+    ULONG_PTR ExportsBase;
+    ULONG ExportSize;
+    UCHAR NameBuffer[32];
+    PIMAGE_OPTIONAL_HEADER OptionalHeader = NULL;
+    PIMAGE_OPTIONAL_HEADER LibraryOptionalHeader = NULL;
+    BOOL ForwarderBound = FALSE;
+    PUCHAR ForwarderName;
+    DPRINT("Binding a Thunk\n");
+
+    /* Get the Pointers to the Tables */
+    AddressOfNames = ImageRvaToVa(Library->FileHeader,
+                                  Library->MappedAddress,
+                                  Exports->AddressOfNames,
+                                  &Library->LastRvaSection);
+    AddressOfOrdinals = ImageRvaToVa(Library->FileHeader,
+                                     Library->MappedAddress, 
+                                     Exports->AddressOfNameOrdinals, 
+                                     &Library->LastRvaSection);
+    AddressOfPointers = ImageRvaToVa(Library->FileHeader, 
+                                     Library->MappedAddress, 
+                                     Exports->AddressOfFunctions, 
+                                     &Library->LastRvaSection);
+
+    /* Get the Optional Headers */
+    OptionalHeader = &Image->FileHeader->OptionalHeader;
+    LibraryOptionalHeader = &Library->FileHeader->OptionalHeader;
     
-       /* Import by Ordinal */
-       if (IMAGE_SNAP_BY_ORDINAL(Thunk->u1.Ordinal) == TRUE) {
+    /* Import by Ordinal */
+    if (IMAGE_SNAP_BY_ORDINAL(Thunk->u1.Ordinal) == TRUE)
+    {
+        /* Get the ordinal number and pointer to the name */
         OrdinalNumber = (IMAGE_ORDINAL(Thunk->u1.Ordinal) - Exports->Base);
         ImportName = (PIMAGE_IMPORT_BY_NAME)NameBuffer;
-       } else {
-               
-               /* Import by Name */
-               ImportName = ImageRvaToVa (File->FileHeader,
-                                                                       File->MappedAddress, 
-                                                                       (ULONG)Thunk->u1.AddressOfData, 
-                                                                       &File->LastRvaSection);
-
-        for (HintIndex = 0; HintIndex < Exports->NumberOfNames; HintIndex++) {
-            
-                       /* Get the Export Name */
-                       ExportName = ImageRvaToVa (LoadedLibrary->FileHeader,
-                                                                               LoadedLibrary->MappedAddress, 
-                                                                               (ULONG)AddressOfNames[HintIndex], 
-                                                                               &LoadedLibrary->LastRvaSection);
+
+        /* Setup the name for this ordinal */
+        sprintf(ImportName->Name, "Ordinal%lx\n", OrdinalNumber);
+    }
+    else
+    {    
+        /* Import by Name, get the data */
+        ImportName = ImageRvaToVa(Image->FileHeader,
+                                  Image->MappedAddress, 
+                                  (ULONG)Thunk->u1.AddressOfData, 
+                                  &Image->LastRvaSection);
+
+        /* Get the hint and see if we can use it */
+        OrdinalNumber = (USHORT)(Exports->NumberOfFunctions + 1);
+        HintIndex = ImportName->Hint;
+        if (HintIndex < Exports->NumberOfNames)
+        {
+            /* Hint seems valid, get the export name */
+            ExportName = ImageRvaToVa(Library->FileHeader,
+                                      Library->MappedAddress, 
+                                      (ULONG)AddressOfNames[HintIndex], 
+                                      &Library->LastRvaSection);
+            /* Check if it's the one we want */
+            if (!strcmp(ImportName->Name, ExportName))
+            {
+                OrdinalNumber = AddressOfOrdinals[HintIndex];
+            }
+        }
+
+        /* If the ordinal isn't valid, we'll have to do a long loop */
+        if (OrdinalNumber >= Exports->NumberOfFunctions)
+        {
+            for (HintIndex = 0; HintIndex < Exports->NumberOfNames; HintIndex++)
+            {
+                /* Get the Export Name */
+                ExportName = ImageRvaToVa(Library->FileHeader,
+                                          Library->MappedAddress, 
+                                          (ULONG)AddressOfNames[HintIndex], 
+                                          &Library->LastRvaSection);
             
-                       /* Check if it's the one we want */
-                       if (!strcmp(ImportName->Name, ExportName)) {
-                               OrdinalNumber = AddressOfOrdinals[HintIndex];
-                break;
+                /* Check if it's the one we want */
+                if (!strcmp(ImportName->Name, ExportName))
+                {
+                    OrdinalNumber = AddressOfOrdinals[HintIndex];
+                    break;
+                }
             }
-               }
-       }
-
-       /* Fail if we still didn't find anything */
-       if (!OrdinalNumber) return FALSE;
-
-       /* Write the Pointer */
-       BoundThunk->u1.Function = (PDWORD)(AddressOfPointers[OrdinalNumber] + LibraryOptionalHeader32->ImageBase);
-
-       /* Load DLL's Exports */
-    ExportsBase = (ULONG)ImageDirectoryEntryToData (LoadedLibrary->MappedAddress, 
-                                                                                                       TRUE, 
-                                                                                                       IMAGE_DIRECTORY_ENTRY_EXPORT, 
-                                                                                                       &ExportSize) - 
-                                                                                                       (ULONG_PTR)LoadedLibrary->MappedAddress;
-       /* RVA to VA */
-    ExportsBase += LibraryOptionalHeader32->ImageBase;
-
-       /* Check if the Export is forwarded (meaning that it's pointer is inside the Export Table) */
-    if (BoundThunk->u1.Function > (PDWORD)ExportsBase && BoundThunk->u1.Function < (PDWORD)(ExportsBase + ExportSize)) {
-        
-               //FIXME("This Thunk is a forward...calling forward thunk bounder\n");
 
-               /* Replace the Forwarder String by the actual Pointer */
-        BoundThunk->u1.Function = (PDWORD)BindpAddBoundForwarder (BoundImportDescriptor,
-                                                                                                               DllPath,
-                                                                                                               ImageRvaToVa (LoadedLibrary->FileHeader,
-                                                                                                                                               LoadedLibrary->MappedAddress,
-                                                                                                                                               AddressOfPointers[OrdinalNumber],
-                                                                                                                                               &LoadedLibrary->LastRvaSection));
+            /* Make sure it's valid now */
+            if (OrdinalNumber >= Exports->NumberOfFunctions) return FALSE;
+        }
+    }
+
+    /* Write the Pointer */
+    ThunkFunction->u1.Function = AddressOfPointers[OrdinalNumber] +
+                                 LibraryOptionalHeader->ImageBase;
+
+    /* Load DLL's Exports */
+    ExportsBase = (ULONG_PTR)ImageDirectoryEntryToData(Library->MappedAddress,
+                                                       TRUE, 
+                                                       IMAGE_DIRECTORY_ENTRY_EXPORT,
+                                                       &ExportSize) -
+                  (ULONG_PTR)Library->MappedAddress;
+    
+    /* RVA to VA */
+    ExportsBase += LibraryOptionalHeader->ImageBase;
+
+    /* Check if the Export is forwarded (meaning that it's pointer is inside the Export Table) */
+    if ((ThunkFunction->u1.Function > ExportsBase) &&
+        (ThunkFunction->u1.Function < ExportsBase + ExportSize))
+    {
+        /* Make sure we have a descriptor */
+        if (BoundImportDescriptor)
+        {
+            DPRINT("This Thunk is a forward...calling forward thunk bounder\n");
+
+            /* Get the VA of the pointer containg the name */
+            ForwarderName = ImageRvaToVa(Library->FileHeader,
+                                         Library->MappedAddress,
+                                         AddressOfPointers[OrdinalNumber],
+                                         &Library->LastRvaSection);
+
+            /* Replace the Forwarder String by the actual name */
+            ThunkFunction->u1.ForwarderString =
+                PtrToUlong(BindpAddForwarderReference(Image->ModuleName,
+                                                      ImportName->Name,
+                                                      BoundImportDescriptor,
+                                                      DllPath,
+                                                      ForwarderName,
+                                                      &ForwarderBound));
+        }
 
-       }
+        /* Check if it wasn't bound */
+        if (!ForwarderBound)
+        {
+            /* Set the chain to the ordinal to reflect this */
+            **Forwarders = (ULONG)(ThunkFunction - BoundThunk);
+            *Forwarders = (PULONG)&ThunkFunction->u1.Ordinal;
+        }
+    }
 
-       /* Return Success */
+    /* Return Success */
     return TRUE;
 }
 
-/*
- * BindpAddBoundForwarder
- *
- * FUNCTION:
- *      Finds the pointer of the Forwarded function, and writes it into the Thunk,
- *             thus making the Thunk Bound.
- *
- * ARGUMENTS:
- *      BoundImportDescriptor  - Internal Bound Import Descriptor of LoadedLibrary
- *      DllPath                                        - DLL Search Path
- *             ForwarderString                 - Name of the Forwader String
- *
- * RETURNS:
- *      Pointer to the Forwaded Function.
- */
-ULONG
-STDCALL
-BindpAddBoundForwarder(
-    PBOUND_IMPORT_DESCRIPTOR BoundImportDescriptor,
-    LPSTR DllPath,
-    PUCHAR ForwarderString
-    )
+PIMPORT_DESCRIPTOR
+IMAGEAPI
+BindpAddImportDescriptor(PIMPORT_DESCRIPTOR *BoundImportDescriptor,
+                         PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor,
+                         LPSTR DllName,
+                         PLOADED_IMAGE Image)
 {
-    CHAR                                       DllName[256];
-       PUCHAR                                  TempDllName;
-    PLOADED_IMAGE                      LoadedLibrary;
-    ULONG                                      DllNameSize;
-    USHORT                                     OrdinalNumber = 0;
-    USHORT                                     HintIndex;
-    ULONG                                      ExportSize;
+    PIMPORT_DESCRIPTOR Descriptor, *NextDescriptor;
+
+    /* Loop descriptors and check if this library has already been bound */
+    NextDescriptor = BoundImportDescriptor;
+    while ((Descriptor = *NextDescriptor))
+    {
+        /* Compare the names and return the descriptor if found */
+        if (!_stricmp(Descriptor->ModuleName, DllName)) return Descriptor;
+        
+        /* Move to the next one */
+        NextDescriptor = &Descriptor->Next;
+    }
+
+    /* Allocate a new descriptor */
+    Descriptor = HeapAlloc(IMAGEHLP_hHeap,
+                           HEAP_ZERO_MEMORY,
+                           sizeof(IMPORT_DESCRIPTOR));
+
+    /* Set its Data and check if we have a valid loaded image */
+    Descriptor->ModuleName = BindpCaptureImportModuleName(DllName);
+    *NextDescriptor = Descriptor;
+    if (Image)
+    {
+        /* Save the time stamp */
+        Descriptor->TimeDateStamp = Image->FileHeader->FileHeader.TimeDateStamp;
+    }
+    
+    /* Return the descriptor */
+    return Descriptor;
+}
+
+VOID
+IMAGEAPI
+BindpWalkAndProcessImports(PLOADED_IMAGE File,
+                           LPSTR DllPath,
+                           PBOOLEAN UpdateImage)
+{
+    PIMAGE_IMPORT_DESCRIPTOR Imports;
     PIMAGE_EXPORT_DIRECTORY Exports;
-       ULONG                                   ExportsBase;
-       PULONG                                  AddressOfNames;
-    PUSHORT                                    AddressOfOrdinals;
-    PULONG                                     AddressOfPointers;
-    LPSTR                                      ExportName;
-    ULONG                                      ForwardedAddress;
-    PBOUND_FORWARDER_REFS      BoundForwarder;
-    PIMAGE_OPTIONAL_HEADER     OptionalHeader32 = NULL;
+    ULONG SizeOfImports;
+    ULONG SizeOfExports;
+    ULONG SizeOfThunks;
+    PIMAGE_OPTIONAL_HEADER OptionalHeader;
+    PIMAGE_FILE_HEADER FileHeader;
+    LPSTR ImportedLibrary;
+    PLOADED_IMAGE LoadedLibrary;
+    ULONG TopForwarderChain;
+    PULONG ForwarderChain;
+    PIMPORT_DESCRIPTOR TopBoundDescriptor = NULL, BoundImportDescriptor;
+    PIMAGE_BOUND_IMPORT_DESCRIPTOR BoundImportTable, OldBoundImportTable;
+    PIMAGE_THUNK_DATA Thunks, TempThunk;
+    PIMAGE_THUNK_DATA BoundThunks, TempBoundThunk;
+    ULONG ThunkCount = 0;
+    ULONG Thunk;
+    ULONG BoundImportTableSize, OldBoundImportTableSize;
+    ULONG VirtBytesFree, HeaderBytesFree, FirstFreeByte, PhysBytesFree;
+    BOOL ThunkStatus;
+    DPRINT("BindpWalkAndBindImports Called\n");
+
+    /* Assume untouched image */
+    *UpdateImage = FALSE;
+
+    /* Load the Import Descriptor */
+    Imports = ImageDirectoryEntryToData(File->MappedAddress,
+                                        FALSE, 
+                                        IMAGE_DIRECTORY_ENTRY_IMPORT, 
+                                        &SizeOfImports);
+    if (!Imports) return;
+
+    /* Read the File Header */
+    FileHeader = &File->FileHeader->FileHeader;
+    OptionalHeader = &File->FileHeader->OptionalHeader;
+
+    /* Get the old Bound Import Table, if any */
+    OldBoundImportTable = ImageDirectoryEntryToData(File->MappedAddress,
+                                                    FALSE,
+                                                    IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT,
+                                                    &OldBoundImportTableSize);
+
+    /* For each Import */
+    while(Imports)
+    {
+        /* Make sure we have a name */
+        if (!Imports->Name) break;
+
+        /* Which DLL is being Imported */
+        ImportedLibrary = ImageRvaToVa(File->FileHeader, 
+                                       File->MappedAddress, 
+                                       Imports->Name, 
+                                       &File->LastRvaSection);
+        if (ImportedLibrary)
+        {
+            DPRINT("Loading Imported DLL: %s \n", ImportedLibrary);
+            
+            /* Load the DLL */
+            LoadedLibrary = ImageLoad(ImportedLibrary, DllPath);
+            if (!LoadedLibrary)
+            {
+                /* Create the descriptor, even if we failed */
+                BindpAddImportDescriptor(&TopBoundDescriptor,
+                                         Imports,
+                                         ImportedLibrary,
+                                         LoadedLibrary);
+
+                /* Move on the next file */
+                Imports++;
+                continue;
+            }
 
-NextForwarder:
+            /* Now load the Exports */
+            DPRINT("DLL Loaded at: %p \n", LoadedLibrary->MappedAddress);
+            Exports = ImageDirectoryEntryToData(LoadedLibrary->MappedAddress, 
+                                                FALSE, 
+                                                IMAGE_DIRECTORY_ENTRY_EXPORT, 
+                                                &SizeOfExports);
 
-       /* Get the DLL Name */
-    TempDllName = ForwarderString;
-    while (*TempDllName && *TempDllName != '.') TempDllName++;
-       DllNameSize = (ULONG) (TempDllName - ForwarderString);
-    lstrcpyn(DllName, ForwarderString, DllNameSize + 1);
-
-       /* Append .DLL extension */
-    DllName[DllNameSize] = '\0';
-    strcat(DllName, ".DLL" );
-
-       /* Load it */
-       FIXME("Loading the Thunk Library: %s \n", DllName);
-    LoadedLibrary = ImageLoad(DllName, DllPath);
-    TempDllName += 1;
-
-       /* Return whatever we got back in case of failure*/
-       if (!LoadedLibrary) return (ULONG)ForwarderString;
-       FIXME("It Loaded at: %p \n", LoadedLibrary->MappedAddress);
-
-       /* Load Exports */
-    Exports = ImageDirectoryEntryToData(LoadedLibrary->MappedAddress, FALSE, IMAGE_DIRECTORY_ENTRY_EXPORT, &ExportSize);
-
-       /* Get the Pointers to the Tables */
-       AddressOfNames = ImageRvaToVa (LoadedLibrary->FileHeader, 
-                                                                       LoadedLibrary->MappedAddress, 
-                                                                       Exports->AddressOfNames, 
-                                                                       &LoadedLibrary->LastRvaSection);
-       AddressOfOrdinals = ImageRvaToVa (LoadedLibrary->FileHeader, 
-                                                                               LoadedLibrary->MappedAddress, 
-                                                                               Exports->AddressOfNameOrdinals, 
-                                                                               &LoadedLibrary->LastRvaSection);
-       AddressOfPointers = ImageRvaToVa (LoadedLibrary->FileHeader, 
-                                                                               LoadedLibrary->MappedAddress, 
-                                                                               Exports->AddressOfFunctions, 
-                                                                               &LoadedLibrary->LastRvaSection);
-
-       /* Get the Optional Header */
-       OptionalHeader32 = &LoadedLibrary->FileHeader->OptionalHeader;
-
-       /* Get the Ordinal Number */
-    for (HintIndex = 0; HintIndex < Exports->NumberOfNames; HintIndex++) {
-               
-               /* Get the Export Name */
-               ExportName = ImageRvaToVa (LoadedLibrary->FileHeader, 
-                                                                       LoadedLibrary->MappedAddress, 
-                                                                       AddressOfNames[HintIndex],
-                                                                       &LoadedLibrary->LastRvaSection);
-
-               /* Check if it matches */
-        if (!strcmp(TempDllName, ExportName)) {
-                       OrdinalNumber = AddressOfOrdinals[HintIndex];
-            break;
+            /* Move on, if we don't have exports */
+            if (!Exports) continue;
+
+            /* And load the Thunks */
+            Thunks = ImageRvaToVa(File->FileHeader, 
+                                  File->MappedAddress, 
+                                  (ULONG)Imports->OriginalFirstThunk, 
+                                  &File->LastRvaSection);
+
+            /* No actual Exports (UPX Packer can do this */
+            if (!(Thunks) || !(Thunks->u1.Function)) continue;
+        
+            /* Create Bound Import Descriptor */
+            DPRINT("Creating Bound Descriptor for this DLL\n");
+            BoundImportDescriptor = BindpAddImportDescriptor(&TopBoundDescriptor,
+                                                             Imports,
+                                                             ImportedLibrary,
+                                                             LoadedLibrary);
+
+            /* Count how many Thunks we have */
+            ThunkCount = 0;
+            TempThunk = Thunks;
+            while (TempThunk->u1.AddressOfData)
+            {
+                ThunkCount++;
+                TempThunk++;
+            }
+
+            /* Allocate Memory for the Thunks we will Bind */
+            SizeOfThunks = ThunkCount * sizeof(*TempBoundThunk);
+            BoundThunks = HeapAlloc(IMAGEHLP_hHeap,
+                                    HEAP_ZERO_MEMORY,
+                                    SizeOfThunks);
+
+            /* Setup the initial data pointers */
+            DPRINT("Binding Thunks\n");
+            TempThunk = Thunks;
+            TempBoundThunk = BoundThunks;
+            TopForwarderChain = -1;
+            ForwarderChain = &TopForwarderChain;
+
+            /* Loop for every thunk */
+            for (Thunk = 0; Thunk < ThunkCount; Thunk++)
+            {
+                /* Bind it */
+                ThunkStatus = BindpLookupThunk(TempThunk,
+                                               File,
+                                               BoundThunks,
+                                               TempBoundThunk,
+                                               LoadedLibrary,
+                                               Exports,
+                                               BoundImportDescriptor,
+                                               DllPath,
+                                               &ForwarderChain);
+                /* Check if binding failed */
+                if (!ThunkStatus)
+                {
+                    /* If we have a descriptor */
+                    if (BoundImportDescriptor)
+                    {
+                        /* Zero the timestamp */
+                        BoundImportDescriptor->TimeDateStamp = 0;
+                    }
+
+                    /* Quit the loop */
+                    break;
+                }
+
+                /* Move on */
+                TempThunk++;
+                TempBoundThunk++;
+            }
+
+            /* Load the Second Thunk Array */
+            TempThunk = ImageRvaToVa(File->FileHeader, 
+                                     File->MappedAddress, 
+                                     (ULONG)Imports->FirstThunk, 
+                                     &File->LastRvaSection);
+            if (TempThunk)
+            {
+                /* Check if the forwarder chain changed */
+                if (TopForwarderChain != -1)
+                {
+                    /* It did. Update the chain and let caller know */
+                    *ForwarderChain = -1;
+                    *UpdateImage = TRUE;
+                }
+
+                /* Check if we're not pointing at the new top chain */
+                if (Imports->ForwarderChain != TopForwarderChain)
+                {
+                    /* Update it, and let the caller know */
+                    Imports->ForwarderChain = TopForwarderChain;
+                    *UpdateImage = TRUE;
+                }
+
+                /* Check if thunks have changed */
+                if (memcmp(TempThunk, BoundThunks, SizeOfThunks))
+                {
+                    /* Copy the Pointers and let caller know */
+                    DPRINT("Copying Bound Thunks\n");
+                    RtlCopyMemory(TempThunk, BoundThunks, SizeOfThunks);
+                    *UpdateImage = TRUE;
+                }
+
+                /* Check if we have no bound entries */
+                if (!TopBoundDescriptor)
+                {
+                    /* Check if the timestamp is different */
+                    if (Imports->TimeDateStamp != FileHeader->TimeDateStamp)
+                    {
+                        /* Update it, and let the caller knmow */
+                        Imports->TimeDateStamp = FileHeader->TimeDateStamp;
+                        *UpdateImage = TRUE;
+                    }
+                }
+                else if ((Imports->TimeDateStamp != 0xFFFFFFFF))
+                {
+                    /* Invalidate the timedate stamp */
+                    Imports->TimeDateStamp = 0xFFFFFFFF;
+                }
+            }
+
+            /* Free the Allocated Memory */
+            HeapFree(IMAGEHLP_hHeap, 0, BoundThunks);
+
+            DPRINT("Moving to next File\n");
+            Imports++;
         }
-       }
-
-    do {
-               /* Get the Forwarded Address */
-               ForwardedAddress = AddressOfPointers[OrdinalNumber] + OptionalHeader32->ImageBase;
-
-               /* Load the First Bound Forward Structure */
-               BoundForwarder = BoundImportDescriptor->Forwarders;
-
-               /* Check if we already have the Module Name written */
-               while (BoundForwarder->ModuleName) {
-                       if (!lstrcmpi(DllName, BoundForwarder->ModuleName)) break;
-                       BoundForwarder++;
-               }
-
-               if (!BoundForwarder->ModuleName) {
-
-                       /* Save Library Name in Bound Libraries Buffer */
-                       strcat((char *)BoundLibrariesPointer, DllName);
-
-                       /* Set Data */
-                       BoundForwarder->ModuleName = BoundLibrariesPointer;
-                       BoundForwarder->TimeDateStamp = LoadedLibrary->FileHeader->FileHeader.TimeDateStamp;
-       
-                       /* Next String */
-                       BoundLibrariesPointer = BoundLibrariesPointer + strlen((char *)BoundLibrariesPointer) + 1;
-                       BoundImportDescriptor->ForwaderReferences += 1;
-       }
-
-               /* Load DLL's Exports */
-               ExportsBase = (ULONG)ImageDirectoryEntryToData (LoadedLibrary->MappedAddress, 
-                                                                                                               TRUE, 
-                                                                                                               IMAGE_DIRECTORY_ENTRY_EXPORT, 
-                                                                                                               &ExportSize) - 
-                                                                                                               (ULONG_PTR)LoadedLibrary->MappedAddress;
-               ExportsBase += OptionalHeader32->ImageBase;
-
-               //FIXME("I've thunked it\n");
-
-               /* Is this yet another Forward? */
-               if (ForwardedAddress > ExportsBase && ForwardedAddress < (ExportsBase + ExportSize)) {
-                       ForwarderString = ImageRvaToVa (LoadedLibrary->FileHeader, 
-                                                                                       LoadedLibrary->MappedAddress, 
-                                                                                       AddressOfPointers[OrdinalNumber], 
-                                                                                       &LoadedLibrary->LastRvaSection); 
-                       goto NextForwarder;
-               }
-       }
-       while (0);
-    return ForwardedAddress;
-}
+    }
+
+    /* Create the Bound Import Table */
+    DPRINT("Creating Bound Import Section\n");
+    BoundImportTable = BindpCreateNewImportSection(&TopBoundDescriptor,
+                                                   &BoundImportTableSize);
+
+    /* Check if the import table changed */
+    if (OldBoundImportTableSize != BoundImportTableSize)
+    {
+        /* Let the caller know */
+        *UpdateImage = TRUE;
+    }
+
+    /* 
+     * At this point, check if anything that we've done until now has resulted
+     * in the image being touched. If not, then we'll simply return to caller.
+     */
+    if (!(*UpdateImage)) return;
+
+    /* Check if we have a new table */
+    if (BoundImportTable)
+    {
+        /* Zero it out */
+        OptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress = 0;
+        OptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size = 0;
+
+        /* Check if we have enough space */
+        DPRINT("Calculating Space\n");
+        FirstFreeByte = GetImageUnusedHeaderBytes(File, &VirtBytesFree);
+        HeaderBytesFree = File->Sections->VirtualAddress -
+                          OptionalHeader->SizeOfHeaders + VirtBytesFree;
+        PhysBytesFree = File->Sections->PointerToRawData -
+                        OptionalHeader->SizeOfHeaders + VirtBytesFree;
+
+        /* Check if we overflowed */
+        if (BoundImportTableSize > VirtBytesFree)
+        {
+            /* Check if we have no space a tall */
+            if (BoundImportTableSize > HeaderBytesFree)
+            {
+                DPRINT1("Not enough Space\n");
+                return; /* Fail...not enough space */
+            }
 
-/*
- * BindpCreateBoundImportDescriptor
- *
- * FUNCTION:
- *      Creates an Internal Structure for the Bound Library
- *
- * ARGUMENTS:
- *      LibraryName                            - Name of the Library
- *             Library                                 - Loaded Library
- *             BoundImportDescriptor   - Internal Bound Import Descriptor of Library
- *
- * RETURNS:
- *      PBOUND_IMPORT_DESCRIPTOR       - Pointer to the Internal Bind Structure
- */
-PBOUND_IMPORT_DESCRIPTOR
-STDCALL
-BindpCreateBoundImportDescriptor(
-       LPSTR LibraryName,
-       PLOADED_IMAGE Library,
-       PULONG BoundImportDescriptor
-    )
-{
-    PBOUND_IMPORT_DESCRIPTOR CurrentBoundImportDescriptor;
-
-       /* Load the First Descriptor */
-       CurrentBoundImportDescriptor = (PBOUND_IMPORT_DESCRIPTOR)BoundImportDescriptor;
-
-       /* Check if we've already bound this library */
-       while (CurrentBoundImportDescriptor->ModuleName) {
-               if (!lstrcmpi(CurrentBoundImportDescriptor->ModuleName, LibraryName)) {
-                               return CurrentBoundImportDescriptor;
-               }
-               CurrentBoundImportDescriptor++;
-       }
-
-       /* Save Library Name in Bound Libraries Buffer */
-       strcat((char *)BoundLibrariesPointer, LibraryName);
-
-       /* Set Data */
-       CurrentBoundImportDescriptor->ModuleName = BoundLibrariesPointer;
-       CurrentBoundImportDescriptor->TimeDateStamp = Library->FileHeader->FileHeader.TimeDateStamp;    
-       
-       /* Support for up to 32 Forwarded DLLs */
-       CurrentBoundImportDescriptor->Forwarders = GlobalAlloc(GMEM_ZEROINIT, 32* sizeof(BOUND_FORWARDER_REFS));
-       
-       /* Next String */
-       BoundLibrariesPointer = BoundLibrariesPointer + strlen((char *)BoundLibrariesPointer) + 1;
-
-       return CurrentBoundImportDescriptor;
+            /* Check if we have space on disk to enlarge it */
+            if (BoundImportTableSize <= PhysBytesFree)
+            {
+                /* We have enough NULLs to add it, simply enlarge header data */
+                DPRINT("Header Recalculation\n");
+                OptionalHeader->SizeOfHeaders = OptionalHeader->SizeOfHeaders -
+                                                VirtBytesFree +
+                                                BoundImportTableSize +
+                                                ((OptionalHeader->FileAlignment - 1) &
+                                                ~(OptionalHeader->FileAlignment - 1));
+            }
+            else 
+            {
+                /* Resize the Headers */
+                DPRINT1("UNIMPLEMENTED: Header Resizing\n");
+
+                /* Recalculate Headers */
+                FileHeader = &File->FileHeader->FileHeader;
+                OptionalHeader = &File->FileHeader->OptionalHeader;
+            }
+        }
+    
+        /* Set Bound Import Table Data */
+        OptionalHeader->DataDirectory
+            [IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress = FirstFreeByte;
+        OptionalHeader->DataDirectory
+            [IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size = BoundImportTableSize;
+    
+        /* Copy the Bound Import Table */
+        DPRINT("Copying Bound Import Table\n");
+        RtlCopyMemory(File->MappedAddress + FirstFreeByte,
+                      BoundImportTable,
+                      BoundImportTableSize);
+
+        /* Free the data */
+        HeapFree(IMAGEHLP_hHeap, 0, BoundImportTable);
+    }
+    
 }
 
-/***********************************************************************
- *             BindImage (IMAGEHLP.@)
+/*
+ * @implemented
  */
-BOOL WINAPI BindImage(
-  LPSTR ImageName, LPSTR DllPath, LPSTR SymbolPath)
+BOOL 
+IMAGEAPI 
+BindImageEx(IN DWORD Flags,
+            IN LPSTR ImageName,
+            IN LPSTR DllPath,
+            IN LPSTR SymbolPath,
+            IN PIMAGEHLP_STATUS_ROUTINE StatusRoutine)
 {
-  return BindImageEx(0, ImageName, DllPath, SymbolPath, NULL);
-}
+    LOADED_IMAGE FileData;
+    PLOADED_IMAGE File;
+    PIMAGE_FILE_HEADER FileHeader;
+    PIMAGE_OPTIONAL_HEADER32 OptionalHeader;
+    ULONG CheckSum, HeaderCheckSum, OldChecksum;
+    SYSTEMTIME SystemTime;
+    FILETIME LastWriteTime;
+    BOOLEAN UpdateImage;
+    DWORD DataSize;
+    DPRINT("BindImageEx Called for: %s \n", ImageName);
+
+    /* Set and Clear Buffer */
+    File = &FileData;
+    RtlZeroMemory(File, sizeof(*File));
+
+    /* Request Image Data */
+    if (MapAndLoad(ImageName, DllPath, File, TRUE, FALSE))
+    {
+        /* Write the image's name */
+        DPRINT("Image Mapped and Loaded\n");
+        File->ModuleName = ImageName;
+
+        /* Check if the image is valid and if it should be bound */
+        if ((File->FileHeader) &&
+            ((Flags & BIND_ALL_IMAGES) || (!File->fSystemImage)))
+        {
+            /* Get the optional header */
+            FileHeader = &File->FileHeader->FileHeader;
+            OptionalHeader = &File->FileHeader->OptionalHeader;
+
+            /* Check if this image should be bound */
+            if (OptionalHeader->DllCharacteristics &
+                IMAGE_DLLCHARACTERISTICS_NO_BIND)
+            {
+                /* Don't bind it */
+                goto Skip;
+            }
 
-/***********************************************************************
- *             CheckSum (internal)
- */
-static WORD CalcCheckSum(
-  DWORD StartValue, LPVOID BaseAddress, DWORD WordCount)
-{
-   LPWORD Ptr;
-   DWORD Sum;
-   DWORD i;
-
-   Sum = StartValue;
-   Ptr = (LPWORD)BaseAddress;
-   for (i = 0; i < WordCount; i++)
-     {
-       Sum += *Ptr;
-       if (HIWORD(Sum) != 0)
-         {
-            Sum = LOWORD(Sum) + HIWORD(Sum);
-         }
-       Ptr++;
-     }
-
-   return (WORD)(LOWORD(Sum) + HIWORD(Sum));
-}
+            /* Check if the image has security data */
+            if ((ImageDirectoryEntryToData(File->MappedAddress,
+                                           FALSE,
+                                           IMAGE_DIRECTORY_ENTRY_SECURITY,
+                                           &DataSize)) || DataSize)
+            {
+                /* It does, skip it */
+                goto Skip;
+            }
 
+            /* Read Import Table */
+            BindpWalkAndProcessImports(File, DllPath, &UpdateImage);
 
-/***********************************************************************
- *             CheckSumMappedFile (IMAGEHLP.@)
- */
-PIMAGE_NT_HEADERS WINAPI CheckSumMappedFile(
-  LPVOID BaseAddress, DWORD FileLength,
-  LPDWORD HeaderSum, LPDWORD CheckSum)
-{
-  PIMAGE_NT_HEADERS Header;
-  DWORD CalcSum;
-  DWORD HdrSum;
-
-  FIXME("stub\n");
-
-  CalcSum = (DWORD)CalcCheckSum(0,
-                               BaseAddress,
-                               (FileLength + 1) / sizeof(WORD));
-
-  Header = ImageNtHeader(BaseAddress);
-  HdrSum = Header->OptionalHeader.CheckSum;
-
-  /* Subtract image checksum from calculated checksum. */
-  /* fix low word of checksum */
-  if (LOWORD(CalcSum) >= LOWORD(HdrSum))
-  {
-    CalcSum -= LOWORD(HdrSum);
-  }
-  else
-  {
-    CalcSum = ((LOWORD(CalcSum) - LOWORD(HdrSum)) & 0xFFFF) - 1;
-  }
-
-   /* fix high word of checksum */
-  if (LOWORD(CalcSum) >= HIWORD(HdrSum))
-  {
-    CalcSum -= HIWORD(HdrSum);
-  }
-  else
-  {
-    CalcSum = ((LOWORD(CalcSum) - HIWORD(HdrSum)) & 0xFFFF) - 1;
-  }
-
-  /* add file length */
-  CalcSum += FileLength;
-
-  *CheckSum = CalcSum;
-  *HeaderSum = Header->OptionalHeader.CheckSum;
-
-  return Header;
-}
+            /* Check if we need to update the image */
+            if ((UpdateImage) && (File->hFile != INVALID_HANDLE_VALUE))
+            {
+                /* FIXME: Update symbols */
+        
+                /* Update Checksum */
+                DPRINT("Binding Completed, getting Checksum\n");
+                OldChecksum = File->FileHeader->OptionalHeader.CheckSum;
+                CheckSumMappedFile(File->MappedAddress,
+                                   GetFileSize(File->hFile, NULL),
+                                   &HeaderCheckSum,
+                                   &CheckSum);
+                File->FileHeader->OptionalHeader.CheckSum = CheckSum;
+
+                /* Save Changes */
+                DPRINT("Saving Changes to file\n");
+                FlushViewOfFile(File->MappedAddress, File->SizeOfImage);
+
+                /* Save new Modified Time */
+                DPRINT("Setting time\n");
+                GetSystemTime(&SystemTime);
+                SystemTimeToFileTime(&SystemTime, &LastWriteTime);
+                SetFileTime(File->hFile, NULL, NULL, &LastWriteTime);
+            }
+        }
+    }
 
-/***********************************************************************
- *             MapFileAndCheckSumA (IMAGEHLP.@)
- */
-DWORD WINAPI MapFileAndCheckSumA(
-  LPSTR Filename, LPDWORD HeaderSum, LPDWORD CheckSum)
-{
-  HANDLE hFile;
-  HANDLE hMapping;
-  LPVOID BaseAddress;
-  DWORD FileLength;
-
-  TRACE("(%s, %p, %p): stub\n",
-    debugstr_a(Filename), HeaderSum, CheckSum
-  );
-
-  hFile = CreateFileA(Filename,
-                     GENERIC_READ,
-                     FILE_SHARE_READ | FILE_SHARE_WRITE,
-                     NULL,
-                     OPEN_EXISTING,
-                     FILE_ATTRIBUTE_NORMAL,
-                     0);
-  if (hFile == INVALID_HANDLE_VALUE)
-  {
-    return CHECKSUM_OPEN_FAILURE;
-  }
-
-  hMapping = CreateFileMappingW(hFile,
-                              NULL,
-                              PAGE_READONLY,
-                              0,
-                              0,
-                              NULL);
-  if (hMapping == 0)
-  {
-    CloseHandle(hFile);
-    return CHECKSUM_MAP_FAILURE;
-  }
-
-  BaseAddress = MapViewOfFile(hMapping,
-                             FILE_MAP_READ,
-                             0,
-                             0,
-                             0);
-  if (hMapping == 0)
-  {
-    CloseHandle(hMapping);
-    CloseHandle(hFile);
-    return CHECKSUM_MAPVIEW_FAILURE;
-  }
-
-  FileLength = GetFileSize(hFile,
-                          NULL);
-
-  CheckSumMappedFile(BaseAddress,
-                    FileLength,
-                    HeaderSum,
-                    CheckSum);
-
-  UnmapViewOfFile(BaseAddress);
-  CloseHandle(hMapping);
-  CloseHandle(hFile);
-
-  return 0;
-}
+Skip:
 
-/***********************************************************************
- *             MapFileAndCheckSumW (IMAGEHLP.@)
- */
-DWORD WINAPI MapFileAndCheckSumW(
-  LPWSTR Filename, LPDWORD HeaderSum, LPDWORD CheckSum)
-{
-  HANDLE hFile;
-  HANDLE hMapping;
-  LPVOID BaseAddress;
-  DWORD FileLength;
-
-  TRACE("(%s, %p, %p): stub\n",
-    debugstr_w(Filename), HeaderSum, CheckSum
-  );
-
-  hFile = CreateFileW(Filename,
-                     GENERIC_READ,
-                     FILE_SHARE_READ | FILE_SHARE_WRITE,
-                     NULL,
-                     OPEN_EXISTING,
-                     FILE_ATTRIBUTE_NORMAL,
-                     0);
-  if (hFile == INVALID_HANDLE_VALUE)
-  {
-  return CHECKSUM_OPEN_FAILURE;
-  }
-
-  hMapping = CreateFileMappingW(hFile,
-                              NULL,
-                              PAGE_READONLY,
-                              0,
-                              0,
-                              NULL);
-  if (hMapping == 0)
-  {
-    CloseHandle(hFile);
-    return CHECKSUM_MAP_FAILURE;
-  }
-
-  BaseAddress = MapViewOfFile(hMapping,
-                             FILE_MAP_READ,
-                             0,
-                             0,
-                             0);
-  if (hMapping == 0)
-  {
-    CloseHandle(hMapping);
-    CloseHandle(hFile);
-    return CHECKSUM_MAPVIEW_FAILURE;
-  }
-
-  FileLength = GetFileSize(hFile,
-                          NULL);
-
-  CheckSumMappedFile(BaseAddress,
-                    FileLength,
-                    HeaderSum,
-                    CheckSum);
-
-  UnmapViewOfFile(BaseAddress);
-  CloseHandle(hMapping);
-  CloseHandle(hFile);
-
-  return 0;
-}
+    /* Unmap the image */
+    UnmapViewOfFile(File->MappedAddress);
 
-/***********************************************************************
- *             ReBaseImage (IMAGEHLP.@)
- */
-BOOL WINAPI ReBaseImage(
-  LPSTR CurrentImageName, LPSTR SymbolPath, BOOL fReBase,
-  BOOL fRebaseSysfileOk, BOOL fGoingDown, ULONG CheckImageSize,
-  ULONG *OldImageSize, ULONG *OldImageBase, ULONG *NewImageSize,
-  ULONG *NewImageBase, ULONG TimeStamp)
-{
-  FIXME(
-    "(%s, %s, %d, %d, %d, %ld, %p, %p, %p, %p, %ld): stub\n",
-      debugstr_a(CurrentImageName),debugstr_a(SymbolPath), fReBase,
-      fRebaseSysfileOk, fGoingDown, CheckImageSize, OldImageSize,
-      OldImageBase, NewImageSize, NewImageBase, TimeStamp
-  );
-  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-  return FALSE;
-}
+    /* Close the handle if it's valid */
+    if (File->hFile != INVALID_HANDLE_VALUE) CloseHandle(File->hFile);
 
-/***********************************************************************
- *             RemovePrivateCvSymbolic (IMAGEHLP.@)
- */
-BOOL WINAPI RemovePrivateCvSymbolic(
-  PCHAR DebugData, PCHAR *NewDebugData, ULONG *NewDebugSize)
-{
-  FIXME("(%p, %p, %p): stub\n",
-    DebugData, NewDebugData, NewDebugSize
-  );
-  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-  return FALSE;
+    /* Unload all the images if we're not supposed to cache them */
+    if (!(Flags & BIND_CACHE_IMPORT_DLLS)) UnloadAllImages();
+   
+    /* Return success */
+    DPRINT("Done\n");
+    return TRUE;
 }
 
-/***********************************************************************
- *             RemoveRelocations (IMAGEHLP.@)
+/*
+ * @implemented
  */
-VOID WINAPI RemoveRelocations(PCHAR ImageName)
+BOOL
+IMAGEAPI
+BindImage(LPSTR ImageName,
+          LPSTR DllPath,
+          LPSTR SymbolPath)
 {
-  FIXME("(%p): stub\n", ImageName);
-  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    /* Call the newer API */
+    return BindImageEx(0,
+                       ImageName,
+                       DllPath,
+                       SymbolPath,
+                       NULL);
 }
 
-/***********************************************************************
- *             SplitSymbols (IMAGEHLP.@)
+/*
+ * @unimplemented
  */
-BOOL WINAPI SplitSymbols(
-  LPSTR ImageName, LPSTR SymbolsPath,
-  LPSTR SymbolFilePath, DWORD Flags)
+BOOL
+IMAGEAPI
+ReBaseImage(LPSTR CurrentImageName,
+            LPSTR SymbolPath,
+            BOOL fReBase,
+            BOOL fRebaseSysfileOk,
+            BOOL fGoingDown,
+            ULONG CheckImageSize,
+            ULONG *OldImageSize,
+            ULONG *OldImageBase,
+            ULONG *NewImageSize,
+            ULONG *NewImageBase,
+            ULONG TimeStamp)
 {
-  FIXME("(%s, %s, %s, %ld): stub\n",
-    debugstr_a(ImageName), debugstr_a(SymbolsPath),
-    debugstr_a(SymbolFilePath), Flags
-  );
-  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-  return FALSE;
+    UNIMPLEMENTED;
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return FALSE;
 }
 
-/***********************************************************************
- *             UpdateDebugInfoFile (IMAGEHLP.@)
+/*
+ * @unimplemented
  */
-BOOL WINAPI UpdateDebugInfoFile(
-  LPSTR ImageFileName, LPSTR SymbolPath,
-  LPSTR DebugFilePath, PIMAGE_NT_HEADERS NtHeaders)
+VOID
+IMAGEAPI
+RemoveRelocations(PCHAR ImageName)
 {
-  FIXME("(%s, %s, %s, %p): stub\n",
-    debugstr_a(ImageFileName), debugstr_a(SymbolPath),
-    debugstr_a(DebugFilePath), NtHeaders
-  );
-  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-  return FALSE;
+    UNIMPLEMENTED;
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
 }
 
-/***********************************************************************
- *             UpdateDebugInfoFileEx (IMAGEHLP.@)
+/*
+ * @implemented
  */
-BOOL WINAPI UpdateDebugInfoFileEx(
-  LPSTR ImageFileName, LPSTR SymbolPath, LPSTR DebugFilePath,
-  PIMAGE_NT_HEADERS NtHeaders, DWORD OldChecksum)
+BOOL
+IMAGEAPI
+TouchFileTimes(HANDLE FileHandle,
+               LPSYSTEMTIME lpSystemTime)
 {
-  FIXME("(%s, %s, %s, %p, %ld): stub\n",
-    debugstr_a(ImageFileName), debugstr_a(SymbolPath),
-    debugstr_a(DebugFilePath), NtHeaders, OldChecksum
-  );
-  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-  return FALSE;
+    FILETIME FileTime;
+    SYSTEMTIME SystemTime;
+  
+    if(lpSystemTime == NULL)
+    {
+        GetSystemTime(&SystemTime);
+        lpSystemTime = &SystemTime;
+    }
+
+    return (SystemTimeToFileTime(lpSystemTime,
+                                 &FileTime) &&
+            SetFileTime(FileHandle,
+                        NULL,
+                        NULL,
+                        &FileTime));
 }
diff --git a/reactos/lib/imagehlp/precomp.h b/reactos/lib/imagehlp/precomp.h
new file mode 100644 (file)
index 0000000..3835a51
--- /dev/null
@@ -0,0 +1,53 @@
+/*\r
+ * COPYRIGHT:       See COPYING in the top level directory\r
+ * PROJECT:         ReactOS System Libraries\r
+ * FILE:            lib/imagehlp/precomp.h\r
+ * PURPOSE:         Imagehlp Libary Header\r
+ * PROGRAMMER:      Alex Ionescu (alex@relsoft.net)\r
+ */\r
+\r
+/* INCLUDES ******************************************************************/\r
+\r
+/* Definitions */\r
+#define _CRT_SECURE_NO_DEPRECATE\r
+#define NTOS_MODE_USER\r
+#define WIN32_NO_STATUS\r
+\r
+/* PSDK/NDK Headers */\r
+#include <windows.h>\r
+#include <imagehlp.h>\r
+#include <ndk/umtypes.h>\r
+#include <ndk/rtlfuncs.h>\r
+\r
+/* C STDLIB Headers */\r
+#include <stdio.h>\r
+\r
+/* TYPES *********************************************************************/\r
+\r
+typedef struct _BOUND_FORWARDER_REFS\r
+{\r
+    struct _BOUND_FORWARDER_REFS *Next;\r
+    ULONG TimeDateStamp;\r
+    LPSTR ModuleName;\r
+} BOUND_FORWARDER_REFS, *PBOUND_FORWARDER_REFS;\r
+\r
+typedef struct _IMPORT_DESCRIPTOR\r
+{\r
+    struct _IMPORT_DESCRIPTOR *Next;\r
+    LPSTR ModuleName;\r
+    ULONG TimeDateStamp;\r
+    USHORT ForwaderReferences;\r
+    PBOUND_FORWARDER_REFS Forwarders;\r
+} IMPORT_DESCRIPTOR, *PIMPORT_DESCRIPTOR;\r
+\r
+/* DATA **********************************************************************/\r
+\r
+extern HANDLE IMAGEHLP_hHeap;\r
+\r
+/* FUNCTIONS *****************************************************************/\r
+\r
+BOOL\r
+IMAGEAPI\r
+UnloadAllImages(VOID);\r
+\r
+/* EOF */\r
diff --git a/reactos/lib/imagehlp/symbol.c b/reactos/lib/imagehlp/symbol.c
deleted file mode 100644 (file)
index 6ab4428..0000000
+++ /dev/null
@@ -1,274 +0,0 @@
-/*
- *     IMAGEHLP library
- *
- *     Copyright 1998  Patrik Stridvall
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include <stdarg.h>
-
-#include "windef.h"
-#include "winbase.h"
-#include "winerror.h"
-#include "wine/debug.h"
-#include "imagehlp.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(imagehlp);
-
-/***********************************************************************
- *             SymCleanup (IMAGEHLP.@)
- */
-BOOL WINAPI SymCleanup(HANDLE hProcess)
-{
-  FIXME("(%p): stub\n", hProcess);
-  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-  return FALSE;
-}
-
-/***********************************************************************
- *             SymEnumerateModules (IMAGEHLP.@)
- */
-
-BOOL WINAPI SymEnumerateModules(
-  HANDLE hProcess, PSYM_ENUMMODULES_CALLBACK EnumModulesCallback,
-  PVOID UserContext)
-{
-  FIXME("(%p, %p, %p): stub\n",
-    hProcess, EnumModulesCallback, UserContext
-  );
-  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-  return FALSE;
-}
-
-/***********************************************************************
- *             SymEnumerateSymbols (IMAGEHLP.@)
- */
-BOOL WINAPI SymEnumerateSymbols(
-  HANDLE hProcess, DWORD BaseOfDll,
-  PSYM_ENUMSYMBOLS_CALLBACK EnumSymbolsCallback, PVOID UserContext)
-{
-  FIXME("(%p, 0x%08lx, %p, %p): stub\n",
-    hProcess, BaseOfDll, EnumSymbolsCallback, UserContext
-  );
-  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-  return FALSE;
-}
-
-/***********************************************************************
- *             SymFunctionTableAccess (IMAGEHLP.@)
- */
-PVOID WINAPI SymFunctionTableAccess(HANDLE hProcess, DWORD AddrBase)
-{
-  FIXME("(%p, 0x%08lx): stub\n", hProcess, AddrBase);
-  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-  return FALSE;
-}
-
-/***********************************************************************
- *             SymGetModuleBase (IMAGEHLP.@)
- */
-DWORD WINAPI SymGetModuleBase(HANDLE hProcess, DWORD dwAddr)
-{
-  FIXME("(%p, 0x%08lx): stub\n", hProcess, dwAddr);
-  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-  return 0;
-}
-
-/***********************************************************************
- *             SymGetModuleInfo (IMAGEHLP.@)
- */
-BOOL WINAPI SymGetModuleInfo(
-  HANDLE hProcess, DWORD dwAddr,
-  PIMAGEHLP_MODULE ModuleInfo)
-{
-  MEMORY_BASIC_INFORMATION mbi;
-
-  FIXME("(%p, 0x%08lx, %p): hacked stub\n",
-    hProcess, dwAddr, ModuleInfo
-  );
-
-  /*
-   * OpenOffice uses this function to get paths of it's modules
-   * from address inside the module. So return at least that for
-   * now.
-   */
-  if (VirtualQuery((PVOID)dwAddr, &mbi, sizeof(mbi)) != sizeof(mbi) ||
-      !GetModuleFileNameA((HMODULE)mbi.AllocationBase, ModuleInfo->ImageName, sizeof(ModuleInfo->ImageName)))
-  {
-    return FALSE;
-  }
-  return TRUE;
-}
-
-/***********************************************************************
- *             SymGetOptions (IMAGEHLP.@)
- */
-DWORD WINAPI SymGetOptions()
-{
-  FIXME("(): stub\n");
-  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-  return 0;
-}
-
-/***********************************************************************
- *             SymGetSearchPath (IMAGEHLP.@)
- */
-BOOL WINAPI SymGetSearchPath(
-  HANDLE hProcess, LPSTR szSearchPath, DWORD SearchPathLength)
-{
-  FIXME("(%p, %s, %ld): stub\n",
-    hProcess, debugstr_an(szSearchPath,SearchPathLength), SearchPathLength
-  );
-  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-  return FALSE;
-}
-
-/***********************************************************************
- *             SymGetSymFromAddr (IMAGEHLP.@)
- */
-BOOL WINAPI SymGetSymFromAddr(
-  HANDLE hProcess, DWORD dwAddr,
-  PDWORD pdwDisplacement, PIMAGEHLP_SYMBOL Symbol)
-{
-  FIXME("(%p, 0x%08lx, %p, %p): stub\n",
-    hProcess, dwAddr, pdwDisplacement, Symbol
-  );
-  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-  return FALSE;
-}
-
-/***********************************************************************
- *             SymGetSymFromName (IMAGEHLP.@)
- */
-BOOL WINAPI SymGetSymFromName(
-  HANDLE hProcess, LPSTR Name, PIMAGEHLP_SYMBOL Symbol)
-{
-  FIXME("(%p, %s, %p): stub\n", hProcess, Name, Symbol);
-  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-  return FALSE;
-}
-
-/***********************************************************************
- *             SymGetSymNext (IMAGEHLP.@)
- */
-BOOL WINAPI SymGetSymNext(
-  HANDLE hProcess, PIMAGEHLP_SYMBOL Symbol)
-{
-  FIXME("(%p, %p): stub\n", hProcess, Symbol);
-  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-  return FALSE;
-}
-
-/***********************************************************************
- *             SymGetSymPrev (IMAGEHLP.@)
- */
-
-BOOL WINAPI SymGetSymPrev(
-  HANDLE hProcess, PIMAGEHLP_SYMBOL Symbol)
-{
-  FIXME("(%p, %p): stub\n", hProcess, Symbol);
-  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-  return FALSE;
-}
-
-/***********************************************************************
- *             SymInitialize (IMAGEHLP.@)
- */
-BOOL WINAPI SymInitialize(
-  HANDLE hProcess, LPSTR UserSearchPath, BOOL fInvadeProcess)
-{
-  FIXME("(%p, %s, %d): stub\n",
-    hProcess, debugstr_a(UserSearchPath), fInvadeProcess
-  );
-  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-  return FALSE;
-}
-
-/***********************************************************************
- *             SymLoadModule (IMAGEHLP.@)
- */
-
-BOOL WINAPI SymLoadModule(
-  HANDLE hProcess, HANDLE hFile, LPSTR ImageName, LPSTR ModuleName,
-  DWORD BaseOfDll, DWORD SizeOfDll)
-{
-  FIXME("(%p, %p, %s, %s, %ld, %ld): stub\n",
-    hProcess, hFile, debugstr_a(ImageName), debugstr_a(ModuleName),
-    BaseOfDll, SizeOfDll
-  );
-  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-  return FALSE;
-}
-
-/***********************************************************************
- *             SymRegisterCallback (IMAGEHLP.@)
- */
-BOOL WINAPI SymRegisterCallback(
-  HANDLE hProcess, PSYMBOL_REGISTERED_CALLBACK CallbackFunction,
-  PVOID UserContext)
-{
-  FIXME("(%p, %p, %p): stub\n",
-    hProcess, CallbackFunction, UserContext
-  );
-  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-  return FALSE;
-}
-
-/***********************************************************************
- *             SymSetOptions (IMAGEHLP.@)
- */
-DWORD WINAPI SymSetOptions(DWORD SymOptions)
-{
-  FIXME("(0x%08lx): stub\n", SymOptions);
-  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-  return 0;
-}
-
-/***********************************************************************
- *             SymSetSearchPath (IMAGEHLP.@)
- */
-BOOL WINAPI SymSetSearchPath(HANDLE hProcess, LPSTR szSearchPath)
-{
-  FIXME("(%p, %s): stub\n",
-    hProcess, debugstr_a(szSearchPath)
-  );
-  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-  return FALSE;
-}
-
-/***********************************************************************
- *             SymUnDName (IMAGEHLP.@)
- */
-BOOL WINAPI SymUnDName(
-  PIMAGEHLP_SYMBOL sym, LPSTR UnDecName, DWORD UnDecNameLength)
-{
-  FIXME("(%p, %s, %ld): stub\n",
-    sym, UnDecName, UnDecNameLength
-  );
-  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-  return FALSE;
-}
-
-/***********************************************************************
- *             SymUnloadModule (IMAGEHLP.@)
- */
-BOOL WINAPI SymUnloadModule(
-  HANDLE hProcess, DWORD BaseOfDll)
-{
-  FIXME("(%p, 0x%08lx): stub\n", hProcess, BaseOfDll);
-  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-  return FALSE;
-}
diff --git a/reactos/lib/imagehlp/winehq2ros.patch b/reactos/lib/imagehlp/winehq2ros.patch
deleted file mode 100644 (file)
index b4c8ae8..0000000
+++ /dev/null
@@ -1,1064 +0,0 @@
-
-Index: dlls/imagehlp/access.c
-===================================================================
-RCS file: /home/wine/wine/dlls/imagehlp/access.c,v
-retrieving revision 1.20
-diff -u -r1.20 access.c
---- dlls/imagehlp/access.c     5 Apr 2004 22:50:45 -0000       1.20
-+++ dlls/imagehlp/access.c     29 Sep 2004 17:17:35 -0000
-@@ -54,6 +54,8 @@
- };
- extern HANDLE IMAGEHLP_hHeap;
-+BOOLEAN DllListInitialized;
-+LIST_ENTRY ImageLoadListHead;
- /***********************************************************************
-  *            GetImageConfigInformation (IMAGEHLP.@)
-@@ -76,11 +78,45 @@
-   PLOADED_IMAGE LoadedImage,
-   LPDWORD SizeUnusedHeaderBytes)
- {
--  FIXME("(%p, %p): stub\n",
--    LoadedImage, SizeUnusedHeaderBytes
--  );
--  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
--  return 0;
-+  DWORD                        FirstFreeByte;
-+  PIMAGE_OPTIONAL_HEADER        OptionalHeader32 = NULL;
-+  PIMAGE_NT_HEADERS            NtHeaders;
-+  ULONG                        i;
-+
-+  /* Read the NT Headers */
-+  NtHeaders = LoadedImage->FileHeader;
-+
-+  /* Find the first free byte, which is after all the headers and sections */
-+  FirstFreeByte = (ULONG_PTR)NtHeaders - (ULONG_PTR)LoadedImage->MappedAddress +
-+                  FIELD_OFFSET(IMAGE_NT_HEADERS, OptionalHeader) +
-+                  NtHeaders->FileHeader.SizeOfOptionalHeader +
-+                  NtHeaders->FileHeader.NumberOfSections * sizeof(IMAGE_SECTION_HEADER);
-+
-+  /* Get the Optional Header */
-+  OptionalHeader32 = &LoadedImage->FileHeader->OptionalHeader;
-+
-+  /* There is the possibilty that one of the Data Directories is in the PE Header
-+     itself, so we'll need to find such a case and add it to our PE used space */
-+  for ( i = 0; i<OptionalHeader32->NumberOfRvaAndSizes; i++ ) {
-+
-+      /* If the VA is less then the size of headers, then the data is inside the PE header */
-+      if (OptionalHeader32->DataDirectory[i].VirtualAddress < OptionalHeader32->SizeOfHeaders) {
-+
-+          /* However, make sure it's not 0, which means it doesnt actually exist */
-+          if (OptionalHeader32->DataDirectory[i].VirtualAddress >= FirstFreeByte) {
-+
-+              /* Our first empty byte is after this Directory Data then */
-+              FirstFreeByte = OptionalHeader32->DataDirectory[i].VirtualAddress +
-+                                                OptionalHeader32->DataDirectory[i].Size;
-+              }
-+          }
-+      }
-+
-+  /* Return the unused Header Bytes */
-+   *SizeUnusedHeaderBytes = OptionalHeader32->SizeOfHeaders - FirstFreeByte;
-+
-+  /* And return the first free byte*/
-+  return FirstFreeByte;
- }
- /***********************************************************************
-@@ -88,15 +124,58 @@
-  */
- PLOADED_IMAGE WINAPI ImageLoad(LPSTR DllName, LPSTR DllPath)
- {
--  PLOADED_IMAGE pLoadedImage;
-+  PLIST_ENTRY Head,Next;
-+  PLOADED_IMAGE LoadedImage;
-+ 
-+  /* Initialize the List Head */
-+  if (!DllListInitialized) {
-+      InitializeListHead(&ImageLoadListHead);
-+      DllListInitialized = TRUE;
-+  }
-+
-+  /* Move to the Next DLL */
-+  Head = &ImageLoadListHead;
-+  Next = Head->Flink;
-+
-+  TRACE("Trying to find library: %s in current ListHead \n", DllName);
-+
-+  /* Check if we already Loaded it */
-+  while (Next != Head) {
-+
-+      /* Get the Loaded Image Structure */
-+      LoadedImage = CONTAINING_RECORD(Next, LOADED_IMAGE, Links);
-+      TRACE("Found: %s in current ListHead \n", LoadedImage->ModuleName);
-+
-+      /* Check if the Names Match */
-+      if (!lstrcmpiA( DllName, LoadedImage->ModuleName )) {
-+          TRACE("Found: %s\n the names match",DllName);
-+          return LoadedImage;
-+      }
-+
-+      /* Move to next Entry */
-+      Next = Next->Flink;
-+      TRACE("Moving to next List Entry\n");
-+  }
-+
-+  /* Allocate memory for the Structure, and write the Module Name under */
-+  LoadedImage = HeapAlloc(IMAGEHLP_hHeap, 0, sizeof(*LoadedImage) + lstrlenA(DllName) + 1);
--  FIXME("(%s, %s): stub\n", DllName, DllPath);
-+  /* Module Name will be after structure */
-+  LoadedImage->ModuleName = (LPSTR)LoadedImage + 1;
-         
--  pLoadedImage = HeapAlloc(IMAGEHLP_hHeap, 0, sizeof(LOADED_IMAGE));
--  if (pLoadedImage)
--    pLoadedImage->FileHeader = HeapAlloc(IMAGEHLP_hHeap, 0, sizeof(IMAGE_NT_HEADERS));
-+  /* Copy the Moduel Name */
-+  lstrcpyA(LoadedImage->ModuleName, DllName);
-   
--  return pLoadedImage;
-+  /* Now Load it and add it to our list*/
-+  if (MapAndLoad(DllName, DllPath, LoadedImage, TRUE, TRUE)) {
-+      InsertTailList(&ImageLoadListHead, &LoadedImage->Links);
-+      return LoadedImage;
-+  }
-+
-+  /* If we're here...there's been a failure */
-+  HeapFree(IMAGEHLP_hHeap, 0, LoadedImage);
-+  LoadedImage = NULL;
-+  return LoadedImage;
- }
- /***********************************************************************
-@@ -149,40 +228,62 @@
-   LPSTR pszImageName, LPSTR pszDllPath, PLOADED_IMAGE pLoadedImage,
-   BOOL bDotDll, BOOL bReadOnly)
- {
--  CHAR szFileName[MAX_PATH];
--  HANDLE hFile = NULL;
-   HANDLE hFileMapping = NULL;
--  HMODULE hModule = NULL;
--  PIMAGE_NT_HEADERS pNtHeader = NULL;
-+  PIMAGE_NT_HEADERS NtHeader = NULL;
-+  ULONG    Tried = 0;
-+  UCHAR Buffer[MAX_PATH];
-+  LPSTR FilePart;
-+  LPSTR FileToOpen;
-+ 
--  TRACE("(%s, %s, %p, %d, %d)\n", pszImageName, pszDllPath, pLoadedImage,
--                                    bDotDll, bReadOnly);
-+  /* So we can add the DLL Path later */
-+  FileToOpen = pszImageName;
-   
--  /* PathCombine(&szFileName, pszDllPath, pszImageName); */
--  /* PathRenameExtension(&szFileName, bDotDll?:"dll":"exe"); */
--  /* FIXME: Check if the file already loaded (use IMAGEHLP_pFirstLoadedImage) */
--  if(!(hFile = CreateFileA(
--    szFileName, GENERIC_READ, 1, /* FIXME: FILE_SHARE_READ not defined */
--    NULL, OPEN_EXISTING, 0, NULL)))
-+TryAgain:
-+    /* Get a handle to the file */
-+    if ((pLoadedImage->hFile = CreateFileA (FileToOpen, 
-+                                            bReadOnly ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE, 
-+                                            bReadOnly ? FILE_SHARE_READ : FILE_SHARE_READ | FILE_SHARE_WRITE,
-+                                            NULL, 
-+                                            OPEN_EXISTING, 
-+                                            0, 
-+                                            NULL)) == INVALID_HANDLE_VALUE)
-     {
--      SetLastError(ERROR_FILE_NOT_FOUND);
--      goto Error;
-+
-+        /* It Failed, use the DLL Search Path then (make sure we haven't already) */
-+        if (!Tried) {
-+            Tried = SearchPathA(pszDllPath, pszImageName, bDotDll ? ".dll" : ".exe", MAX_PATH, Buffer, &FilePart);
-+            if (Tried) {
-+                FileToOpen = Buffer;
-+                goto TryAgain;
-+            }
-+        }
-+        /* Fail */
-+        return FALSE;
-     }
--  if(!(hFileMapping = CreateFileMappingA(
--    hFile, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL)))
-+
-+    /* Create the File Mapping */
-+    if (!(hFileMapping = CreateFileMappingA (pLoadedImage->hFile,
-+                                            NULL, 
-+                                            bReadOnly ? PAGE_READONLY : PAGE_READWRITE, 
-+                                            0, 
-+                                            0, 
-+                                            NULL)))
-     {
-       DWORD dwLastError = GetLastError();
-       WARN("CreateFileMapping: Error = %ld\n", dwLastError);
-       SetLastError(dwLastError);
-       goto Error;
-     }
--  CloseHandle(hFile);
--  hFile = NULL;
--  if(!(hModule = (HMODULE) MapViewOfFile(
--    hFileMapping, FILE_MAP_READ, 0, 0, 0)))
-+    /* Get a pointer to the file */
-+    if(!(pLoadedImage->MappedAddress = MapViewOfFile(hFileMapping, 
-+                                                    bReadOnly ? FILE_MAP_READ : FILE_MAP_WRITE, 
-+                                                    0, 
-+                                                    0, 
-+                                                    0)))
-     {
-       DWORD dwLastError = GetLastError();
-       WARN("MapViewOfFile: Error = %ld\n", dwLastError);
-@@ -190,52 +291,43 @@
-       goto Error;
-     }
-+
-+  /* Close the handle to the map, we don't need it anymore */
-   CloseHandle(hFileMapping);
-   hFileMapping=NULL;
--  pLoadedImage = (PLOADED_IMAGE) HeapAlloc(
--    IMAGEHLP_hHeap, 0, sizeof(LOADED_IMAGE)
--  );
-+  /* Get the Nt Header */
-+  NtHeader = ImageNtHeader(pLoadedImage->MappedAddress);
--  pNtHeader = RtlImageNtHeader(hModule);
--
--  pLoadedImage->ModuleName = HeapAlloc(IMAGEHLP_hHeap, 0, strlen(pszDllPath)+1); /* FIXME: Correct? */
--  strcpy( pLoadedImage->ModuleName, pszDllPath );
--  pLoadedImage->hFile = hFile;
--  pLoadedImage->MappedAddress = (PUCHAR) hModule;
--  pLoadedImage->FileHeader = pNtHeader;
-+  /* Write data */
-+  pLoadedImage->ModuleName = HeapAlloc(IMAGEHLP_hHeap, 0, lstrlenA(pszImageName) + 1);
-+  lstrcpyA(pLoadedImage->ModuleName, pszImageName);
-+  pLoadedImage->FileHeader = NtHeader;
-   pLoadedImage->Sections = (PIMAGE_SECTION_HEADER)
--    ((LPBYTE) &pNtHeader->OptionalHeader +
--      pNtHeader->FileHeader.SizeOfOptionalHeader);
--  pLoadedImage->NumberOfSections =
--    pNtHeader->FileHeader.NumberOfSections;
--  pLoadedImage->SizeOfImage =
--    pNtHeader->OptionalHeader.SizeOfImage;
--  pLoadedImage->Characteristics =
--    pNtHeader->FileHeader.Characteristics;
-+                                ((LPBYTE)&NtHeader->OptionalHeader +
-+                                NtHeader->FileHeader.SizeOfOptionalHeader);
-+  pLoadedImage->NumberOfSections = NtHeader->FileHeader.NumberOfSections;
-+  pLoadedImage->SizeOfImage =    NtHeader->OptionalHeader.SizeOfImage;
-+  pLoadedImage->Characteristics =    NtHeader->FileHeader.Characteristics;
-   pLoadedImage->LastRvaSection = pLoadedImage->Sections;
--
-   pLoadedImage->fSystemImage = FALSE; /* FIXME */
-   pLoadedImage->fDOSImage = FALSE;    /* FIXME */
--  /* FIXME: Make thread safe */
--  pLoadedImage->Links.Flink = NULL;
--  pLoadedImage->Links.Blink = &IMAGEHLP_pLastLoadedImage->Links;
--  if(IMAGEHLP_pLastLoadedImage)
--    IMAGEHLP_pLastLoadedImage->Links.Flink = &pLoadedImage->Links;
--  IMAGEHLP_pLastLoadedImage = pLoadedImage;
--  if(!IMAGEHLP_pFirstLoadedImage)
--    IMAGEHLP_pFirstLoadedImage = pLoadedImage;
-+  /* Read only, so no sense in keeping the handle alive */
-+  if (bReadOnly) CloseHandle(pLoadedImage->hFile);
-+ 
-+
-+  /* Return Success */
-   return TRUE;
- Error:
--  if(hModule)
--    UnmapViewOfFile((PVOID) hModule);
-+  if(pLoadedImage->MappedAddress)
-+    UnmapViewOfFile(pLoadedImage->MappedAddress);
-   if(hFileMapping)
-     CloseHandle(hFileMapping);
--  if(hFile)
--    CloseHandle(hFile);
-+    if(pLoadedImage->hFile)
-+        CloseHandle(pLoadedImage->hFile);
-   return FALSE;
- }
-Index: dlls/imagehlp/modify.c
-===================================================================
-RCS file: /home/wine/wine/dlls/imagehlp/modify.c,v
-retrieving revision 1.13
-diff -u -r1.13 modify.c
---- dlls/imagehlp/modify.c     21 Nov 2003 21:31:35 -0000      1.13
-+++ dlls/imagehlp/modify.c     29 Sep 2004 17:17:37 -0000
-@@ -30,8 +30,669 @@
- WINE_DEFAULT_DEBUG_CHANNEL(imagehlp);
-+/* Internal Structures we use to keep track of the Bound Imports */
-+typedef struct _BOUND_FORWARDER_REFS {
-+    ULONG    TimeDateStamp;
-+    LPSTR    ModuleName;
-+} BOUND_FORWARDER_REFS, *PBOUND_FORWARDER_REFS;
-+
-+typedef struct _BOUND_IMPORT_DESCRIPTOR {
-+    LPSTR    ModuleName;
-+    ULONG    TimeDateStamp;
-+    USHORT    ForwaderReferences;
-+    PBOUND_FORWARDER_REFS Forwarders;
-+} BOUND_IMPORT_DESCRIPTOR, *PBOUND_IMPORT_DESCRIPTOR;
-+
-+UCHAR    BoundLibraries[4096];
-+LPSTR    BoundLibrariesPointer = BoundLibraries;
-+PULONG    BoundImportDescriptors;
-+
- static WORD CalcCheckSum(DWORD StartValue, LPVOID BaseAddress, DWORD WordCount);
-+/*
-+ * BindpCreateBoundImportDescriptor
-+ *
-+ * FUNCTION:
-+ *      Creates an Internal Structure for the Bound Library
-+ *
-+ * ARGUMENTS:
-+ *      LibraryName                - Name of the Library
-+ *        Library                    - Loaded Library
-+ *        BoundImportDescriptor    - Internal Bound Import Descriptor of Library
-+ *
-+ * RETURNS:
-+ *      PBOUND_IMPORT_DESCRIPTOR    - Pointer to the Internal Bind Structure
-+ */
-+PBOUND_IMPORT_DESCRIPTOR
-+WINAPI
-+BindpCreateBoundImportDescriptor(
-+    LPSTR LibraryName,
-+    PLOADED_IMAGE Library,
-+    PULONG BoundImportDescriptor
-+    )
-+{
-+    PBOUND_IMPORT_DESCRIPTOR CurrentBoundImportDescriptor;
-+
-+    /* Load the First Descriptor */
-+    CurrentBoundImportDescriptor = (PBOUND_IMPORT_DESCRIPTOR)BoundImportDescriptor;
-+
-+    /* Check if we've already bound this library */
-+    while (CurrentBoundImportDescriptor->ModuleName) {
-+        if (!lstrcmpiA(CurrentBoundImportDescriptor->ModuleName, LibraryName)) {
-+                return CurrentBoundImportDescriptor;
-+        }
-+        CurrentBoundImportDescriptor++;
-+    }
-+
-+    /* Save Library Name in Bound Libraries Buffer */
-+    strcat((char *)BoundLibrariesPointer, LibraryName);
-+
-+    /* Set Data */
-+    CurrentBoundImportDescriptor->ModuleName = BoundLibrariesPointer;
-+    CurrentBoundImportDescriptor->TimeDateStamp = Library->FileHeader->FileHeader.TimeDateStamp;    
-+    
-+    /* Support for up to 32 Forwarded DLLs */
-+    CurrentBoundImportDescriptor->Forwarders = GlobalAlloc(GMEM_ZEROINIT, 32* sizeof(BOUND_FORWARDER_REFS));
-+    
-+    /* Next String */
-+    BoundLibrariesPointer = BoundLibrariesPointer + strlen((char *)BoundLibrariesPointer) + 1;
-+
-+    return CurrentBoundImportDescriptor;
-+}
-+
-+/*
-+ * BindpAddBoundForwarder
-+ *
-+ * FUNCTION:
-+ *      Finds the pointer of the Forwarded function, and writes it into the Thunk,
-+ *        thus making the Thunk Bound.
-+ *
-+ * ARGUMENTS:
-+ *      BoundImportDescriptor    - Internal Bound Import Descriptor of LoadedLibrary
-+ *      DllPath                    - DLL Search Path
-+ *        ForwarderString            - Name of the Forwader String
-+ *
-+ * RETURNS:
-+ *      Pointer to the Forwaded Function.
-+ */
-+ULONG
-+WINAPI
-+BindpAddBoundForwarder(
-+    PBOUND_IMPORT_DESCRIPTOR BoundImportDescriptor,
-+    LPSTR DllPath,
-+    PUCHAR ForwarderString
-+    )
-+{
-+    CHAR                    DllName[256];
-+    PUCHAR                    TempDllName;
-+    PLOADED_IMAGE            LoadedLibrary;
-+    ULONG                    DllNameSize;
-+    USHORT                    OrdinalNumber = 0;
-+    USHORT                    HintIndex;
-+    ULONG                    ExportSize;
-+    PIMAGE_EXPORT_DIRECTORY Exports;
-+    ULONG                    ExportsBase;
-+    PULONG                    AddressOfNames;
-+    PUSHORT                    AddressOfOrdinals;
-+    PULONG                    AddressOfPointers;
-+    LPSTR                    ExportName;
-+    ULONG                    ForwardedAddress;
-+    PBOUND_FORWARDER_REFS    BoundForwarder;
-+    PIMAGE_OPTIONAL_HEADER    OptionalHeader32 = NULL;
-+
-+NextForwarder:
-+
-+    /* Get the DLL Name */
-+    TempDllName = ForwarderString;
-+    while (*TempDllName && *TempDllName != '.') TempDllName++;
-+    DllNameSize = (ULONG) (TempDllName - ForwarderString);
-+    lstrcpynA(DllName, ForwarderString, DllNameSize + 1);
-+
-+    /* Append .DLL extension */
-+    DllName[DllNameSize] = '\0';
-+    strcat(DllName, ".DLL" );
-+
-+    /* Load it */
-+    TRACE("Loading the Thunk Library: %s \n", DllName);
-+    LoadedLibrary = ImageLoad(DllName, DllPath);
-+    TempDllName += 1;
-+
-+    /* Return whatever we got back in case of failure*/
-+    if (!LoadedLibrary) return (ULONG)ForwarderString;
-+    TRACE("It Loaded at: %p \n", LoadedLibrary->MappedAddress);
-+
-+    /* Load Exports */
-+    Exports = RtlImageDirectoryEntryToData((HMODULE)LoadedLibrary->MappedAddress, FALSE, IMAGE_DIRECTORY_ENTRY_EXPORT, &ExportSize);
-+
-+    /* Get the Pointers to the Tables */
-+    AddressOfNames = ImageRvaToVa (LoadedLibrary->FileHeader, 
-+                                    LoadedLibrary->MappedAddress, 
-+                                    Exports->AddressOfNames, 
-+                                    &LoadedLibrary->LastRvaSection);
-+    AddressOfOrdinals = ImageRvaToVa (LoadedLibrary->FileHeader, 
-+                                        LoadedLibrary->MappedAddress, 
-+                                        Exports->AddressOfNameOrdinals, 
-+                                        &LoadedLibrary->LastRvaSection);
-+    AddressOfPointers = ImageRvaToVa (LoadedLibrary->FileHeader, 
-+                                        LoadedLibrary->MappedAddress, 
-+                                        Exports->AddressOfFunctions, 
-+                                        &LoadedLibrary->LastRvaSection);
-+
-+    /* Get the Optional Header */
-+    OptionalHeader32 = &LoadedLibrary->FileHeader->OptionalHeader;
-+
-+    /* Get the Ordinal Number */
-+    for (HintIndex = 0; HintIndex < Exports->NumberOfNames; HintIndex++) {
-+        
-+        /* Get the Export Name */
-+        ExportName = ImageRvaToVa (LoadedLibrary->FileHeader, 
-+                                    LoadedLibrary->MappedAddress, 
-+                                    AddressOfNames[HintIndex],
-+                                    &LoadedLibrary->LastRvaSection);
-+
-+        /* Check if it matches */
-+        if (!strcmp(TempDllName, ExportName)) {
-+            OrdinalNumber = AddressOfOrdinals[HintIndex];
-+            break;
-+        }
-+    }
-+
-+    do {
-+        /* Get the Forwarded Address */
-+        ForwardedAddress = AddressOfPointers[OrdinalNumber] + OptionalHeader32->ImageBase;
-+
-+        /* Load the First Bound Forward Structure */
-+        BoundForwarder = BoundImportDescriptor->Forwarders;
-+
-+        /* Check if we already have the Module Name written */
-+        while (BoundForwarder->ModuleName) {
-+            if (!lstrcmpiA(DllName, BoundForwarder->ModuleName)) break;
-+            BoundForwarder++;
-+        }
-+
-+        if (!BoundForwarder->ModuleName) {
-+
-+            /* Save Library Name in Bound Libraries Buffer */
-+            strcat((char *)BoundLibrariesPointer, DllName);
-+
-+            /* Set Data */
-+            BoundForwarder->ModuleName = BoundLibrariesPointer;
-+            BoundForwarder->TimeDateStamp = LoadedLibrary->FileHeader->FileHeader.TimeDateStamp;
-+    
-+            /* Next String */
-+            BoundLibrariesPointer = BoundLibrariesPointer + strlen((char *)BoundLibrariesPointer) + 1;
-+            BoundImportDescriptor->ForwaderReferences += 1;
-+       }
-+
-+        /* Load DLL's Exports */
-+        ExportsBase = (ULONG)RtlImageDirectoryEntryToData ((HMODULE)LoadedLibrary->MappedAddress, 
-+                                                        TRUE, 
-+                                                        IMAGE_DIRECTORY_ENTRY_EXPORT, 
-+                                                        &ExportSize) - 
-+                                                        (ULONG_PTR)LoadedLibrary->MappedAddress;
-+        ExportsBase += OptionalHeader32->ImageBase;
-+
-+        TRACE("I've thunked it\n");
-+
-+        /* Is this yet another Forward? */
-+        if (ForwardedAddress > ExportsBase && ForwardedAddress < (ExportsBase + ExportSize)) {
-+            ForwarderString = ImageRvaToVa (LoadedLibrary->FileHeader, 
-+                                            LoadedLibrary->MappedAddress, 
-+                                            AddressOfPointers[OrdinalNumber], 
-+                                            &LoadedLibrary->LastRvaSection); 
-+            goto NextForwarder;
-+        }
-+    }
-+    while (0);
-+    return ForwardedAddress;
-+}
-+
-+/*
-+ * BindpBindThunk
-+ *
-+ * FUNCTION:
-+ *      Finds the pointer of the Imported function, and writes it into the Thunk,
-+ *        thus making the Thunk Bound.
-+ *
-+ * ARGUMENTS:
-+ *      Thunk                    - Current Thunk in Unbound File
-+ *      File                    - File containing the Thunk
-+ *      BoundThunk                - Pointer to the corresponding Bound Thunk
-+ *      LoadedLibrary            - Library containing the Exported Function
-+ *      Exports                    - Export Directory of LoadedLibrary
-+ *      BoundImportDescriptor    - Internal Bound Import Descriptor of LoadedLibrary
-+ *      DllPath                    - DLL Search Path
-+ *
-+ * RETURNS:
-+ *      TRUE if Suceeded
-+ */
-+BOOL
-+WINAPI
-+BindpBindThunk(
-+    PIMAGE_THUNK_DATA Thunk,
-+    PLOADED_IMAGE File,
-+    PIMAGE_THUNK_DATA BoundThunk,
-+    PLOADED_IMAGE LoadedLibrary,
-+    PIMAGE_EXPORT_DIRECTORY Exports,
-+    PBOUND_IMPORT_DESCRIPTOR BoundImportDescriptor,
-+    LPSTR DllPath
-+    )
-+{
-+    PULONG                    AddressOfNames;
-+    PUSHORT                    AddressOfOrdinals;
-+    PULONG                    AddressOfPointers;
-+    PIMAGE_IMPORT_BY_NAME    ImportName;
-+    ULONG                    OrdinalNumber = 0;
-+    USHORT                    HintIndex;
-+    LPSTR                    ExportName;
-+    ULONG                    ExportsBase;
-+    ULONG                    ExportSize;
-+    UCHAR                    NameBuffer[32];
-+    PIMAGE_OPTIONAL_HEADER    OptionalHeader32 = NULL;
-+    PIMAGE_OPTIONAL_HEADER    LibraryOptionalHeader32 = NULL;
-+
-+    /* Get the Pointers to the Tables */
-+    AddressOfNames = ImageRvaToVa (LoadedLibrary->FileHeader, 
-+                                    LoadedLibrary->MappedAddress,
-+                                    Exports->AddressOfNames,
-+                                    &LoadedLibrary->LastRvaSection);
-+    AddressOfOrdinals = ImageRvaToVa (LoadedLibrary->FileHeader,
-+                                        LoadedLibrary->MappedAddress, 
-+                                        Exports->AddressOfNameOrdinals, 
-+                                        &LoadedLibrary->LastRvaSection);
-+    AddressOfPointers = ImageRvaToVa (LoadedLibrary->FileHeader, 
-+                                        LoadedLibrary->MappedAddress, 
-+                                        Exports->AddressOfFunctions, 
-+                                        &LoadedLibrary->LastRvaSection);
-+
-+    TRACE("Binding a Thunk\n");
-+
-+    /* Get the Optional Header */
-+    OptionalHeader32 = &File->FileHeader->OptionalHeader;
-+    LibraryOptionalHeader32 = &LoadedLibrary->FileHeader->OptionalHeader;
-+    
-+    /* Import by Ordinal */
-+    if (IMAGE_SNAP_BY_ORDINAL(Thunk->u1.Ordinal) == TRUE) {
-+        OrdinalNumber = (IMAGE_ORDINAL(Thunk->u1.Ordinal) - Exports->Base);
-+        ImportName = (PIMAGE_IMPORT_BY_NAME)NameBuffer;
-+    } else {
-+        
-+        /* Import by Name */
-+        ImportName = ImageRvaToVa (File->FileHeader,
-+                                    File->MappedAddress, 
-+                                    (ULONG)Thunk->u1.AddressOfData, 
-+                                    &File->LastRvaSection);
-+
-+        for (HintIndex = 0; HintIndex < Exports->NumberOfNames; HintIndex++) {
-+            
-+            /* Get the Export Name */
-+            ExportName = ImageRvaToVa (LoadedLibrary->FileHeader,
-+                                        LoadedLibrary->MappedAddress, 
-+                                        (ULONG)AddressOfNames[HintIndex], 
-+                                        &LoadedLibrary->LastRvaSection);
-+            
-+            /* Check if it's the one we want */
-+            if (!strcmp(ImportName->Name, ExportName)) {
-+                OrdinalNumber = AddressOfOrdinals[HintIndex];
-+                break;
-+            }
-+        }
-+    }
-+
-+    /* Fail if we still didn't find anything */
-+    if (!OrdinalNumber) return FALSE;
-+
-+    /* Write the Pointer */
-+    (ULONG)BoundThunk->u1.Function = AddressOfPointers[OrdinalNumber] + LibraryOptionalHeader32->ImageBase;
-+
-+    /* Load DLL's Exports */
-+    ExportsBase = (ULONG)RtlImageDirectoryEntryToData ((HMODULE)LoadedLibrary->MappedAddress, 
-+                                                    TRUE, 
-+                                                    IMAGE_DIRECTORY_ENTRY_EXPORT, 
-+                                                    &ExportSize) - 
-+                                                    (ULONG_PTR)LoadedLibrary->MappedAddress;
-+    /* RVA to VA */
-+    ExportsBase += LibraryOptionalHeader32->ImageBase;
-+
-+    /* Check if the Export is forwarded (meaning that it's pointer is inside the Export Table) */
-+    if ((ULONG)BoundThunk->u1.Function > ExportsBase && (ULONG)BoundThunk->u1.Function < (ExportsBase + ExportSize)) {
-+        
-+        TRACE("This Thunk is a forward...calling forward thunk bounder\n");
-+
-+        /* Replace the Forwarder String by the actual Pointer */
-+        (ULONG)BoundThunk->u1.Function = BindpAddBoundForwarder (BoundImportDescriptor,
-+                                                        DllPath,
-+                                                        ImageRvaToVa (LoadedLibrary->FileHeader,
-+                                                                        LoadedLibrary->MappedAddress,
-+                                                                        AddressOfPointers[OrdinalNumber],
-+                                                                        &LoadedLibrary->LastRvaSection));
-+
-+    }
-+
-+    /* Return Success */
-+    return TRUE;
-+}
-+
-+/*
-+ * BindpCreateBoundImportSection
-+ *
-+ * FUNCTION:
-+ *      Creates a 32-bit PE Bound Import Table
-+ *
-+ * ARGUMENTS:
-+ *      BoundImportDescriptor        - Pointer to the Bound Import Table
-+ *      BoundImportsSize            - Size of the Bound Import Table
-+ *
-+ * RETURNS:
-+ *      PIMAGE_BOUND_IMPORT_DESCRIPTOR    - The Bound Import Table
-+ */
-+PIMAGE_BOUND_IMPORT_DESCRIPTOR
-+WINAPI
-+BindpCreateBoundImportSection(
-+    PULONG BoundImportDescriptor,
-+    PULONG BoundImportsSize
-+    )
-+{
-+    ULONG BoundLibraryNamesSize, BoundImportTableSize;
-+    PBOUND_FORWARDER_REFS BoundForwarder;
-+    PBOUND_IMPORT_DESCRIPTOR CurrentBoundImportDescriptor;
-+    PVOID BoundLibraryNames;
-+    PIMAGE_BOUND_IMPORT_DESCRIPTOR CurrentBoundImportTableEntry, BoundImportTable;
-+    PIMAGE_BOUND_FORWARDER_REF NewForwarder;
-+
-+    /* Zero the Sizes */
-+    *BoundImportsSize = 0;
-+    BoundLibraryNamesSize = 0;
-+    BoundImportTableSize = 0;
-+
-+    /* Start with the first Internal Descriptor */
-+    CurrentBoundImportDescriptor = (PBOUND_IMPORT_DESCRIPTOR)BoundImportDescriptor;
-+
-+    /* Loop through every Descriptor we loaded */
-+    while (CurrentBoundImportDescriptor->ModuleName) {
-+
-+        /* Add to the size of the Bound Import Table */
-+        BoundImportTableSize += sizeof(IMAGE_BOUND_IMPORT_DESCRIPTOR);
-+
-+        /* Check Forwarders */
-+        BoundForwarder = CurrentBoundImportDescriptor->Forwarders;
-+        while (BoundForwarder->ModuleName) {
-+
-+            /* Add to size of Bound Import Table */
-+            BoundImportTableSize += sizeof(IMAGE_BOUND_FORWARDER_REF);
-+
-+            /* Next Forwarder */
-+            BoundForwarder++;
-+            }
-+
-+        /* Read Next Internal Descriptor */
-+        CurrentBoundImportDescriptor++;
-+        }
-+
-+    /* Add Terminator for PE Loader*/
-+    BoundImportTableSize += sizeof(IMAGE_BOUND_IMPORT_DESCRIPTOR);
-+
-+    /* Name of Libraries Bound in Bound Import Table */
-+    BoundLibraryNamesSize = ((ULONG)BoundLibrariesPointer - (ULONG)(&BoundLibraries));
-+
-+    /* Size of the whole table, dword aligned */
-+    *BoundImportsSize = BoundImportTableSize + 
-+                        ((BoundLibraryNamesSize + sizeof(ULONG) - 1) & ~(sizeof(ULONG)-1));
-+
-+    /* Allocate it */
-+    BoundImportTable = GlobalAlloc(GMEM_ZEROINIT, *BoundImportsSize);
-+    
-+    /* Pointer Library Names inside the Bound Import Table */
-+    BoundLibraryNames = (PIMAGE_BOUND_IMPORT_DESCRIPTOR)((ULONG_PTR)BoundImportTable + 
-+                                                                    BoundImportTableSize);
-+
-+    /* Copy the Library Names */
-+    RtlCopyMemory(BoundLibraryNames, BoundLibraries, BoundLibraryNamesSize);
-+
-+    /* Go back to first Internal Descriptor and load first entry in the Bound Import Table */
-+    CurrentBoundImportTableEntry = (PIMAGE_BOUND_IMPORT_DESCRIPTOR)BoundImportTable;
-+    CurrentBoundImportDescriptor = (PBOUND_IMPORT_DESCRIPTOR)BoundImportDescriptor;
-+
-+    /* Copy the data from our Internal Structure to the Bound Import Table */
-+    while (CurrentBoundImportDescriptor->ModuleName) {
-+        CurrentBoundImportTableEntry->TimeDateStamp = CurrentBoundImportDescriptor->TimeDateStamp;
-+        CurrentBoundImportTableEntry->OffsetModuleName = (USHORT)(BoundImportTableSize + 
-+                                                                (CurrentBoundImportDescriptor->ModuleName - 
-+                                                                (LPSTR) BoundLibraries));
-+        CurrentBoundImportTableEntry->NumberOfModuleForwarderRefs = CurrentBoundImportDescriptor->ForwaderReferences;
-+
-+        /* Copy the data from our Forwader Entries to the Bound Import Table */
-+        NewForwarder = (PIMAGE_BOUND_FORWARDER_REF)(CurrentBoundImportTableEntry+1);
-+        BoundForwarder = CurrentBoundImportDescriptor->Forwarders;
-+        while (BoundForwarder->ModuleName) {
-+            NewForwarder->TimeDateStamp =BoundForwarder->TimeDateStamp;
-+            NewForwarder->OffsetModuleName = (USHORT)(BoundImportTableSize + 
-+                                                    (BoundForwarder->ModuleName - 
-+                                                    (LPSTR) BoundLibraries));
-+            NewForwarder++;
-+            BoundForwarder++;
-+        }
-+
-+        /* Move to next Bound Import Table Entry */
-+        CurrentBoundImportTableEntry = (PIMAGE_BOUND_IMPORT_DESCRIPTOR)NewForwarder;
-+
-+        /* move to next Internal Descriptor */
-+        CurrentBoundImportDescriptor++;
-+    }
-+
-+    /* Now put the pointer back at the beginning and clear the buffer */
-+    RtlZeroMemory(BoundLibraries, 4096);
-+    BoundLibrariesPointer = BoundLibraries;
-+
-+    return BoundImportTable;
-+}
-+
-+/*
-+ * BindpWalkAndBindImports
-+ *
-+ * FUNCTION:
-+ *      Does the actual Binding of the Imports and Forward-Referencing
-+ *
-+ * ARGUMENTS:
-+ *      File            - Name of Imagefile to Bind
-+ *      DllPath            - Path to search DLL Files in, can be NULL to use Default
-+ *
-+ * RETURNS:
-+ *      Nothing
-+ */
-+VOID
-+WINAPI
-+BindpWalkAndBindImports(
-+    PLOADED_IMAGE File,
-+    LPSTR DllPath
-+    )
-+{
-+    PIMAGE_IMPORT_DESCRIPTOR    Imports;
-+    PIMAGE_EXPORT_DIRECTORY        Exports;
-+    ULONG                        SizeOfImports;
-+    ULONG                        SizeOfExports;
-+    ULONG                        SizeOfThunks;
-+    PIMAGE_OPTIONAL_HEADER        OptionalHeader32 = NULL;
-+    PIMAGE_FILE_HEADER            FileHeader;
-+    LPSTR                        ImportedLibrary;
-+    PLOADED_IMAGE                LoadedLibrary;
-+    PBOUND_IMPORT_DESCRIPTOR    BoundImportDescriptor = NULL;
-+    PIMAGE_BOUND_IMPORT_DESCRIPTOR BoundImportTable;
-+    PIMAGE_THUNK_DATA            Thunks, TempThunk;
-+    PIMAGE_THUNK_DATA            BoundThunks, TempBoundThunk;
-+    ULONG                        ThunkCount = 0;
-+    ULONG                        Thunk;
-+    ULONG                        BoundImportTableSize;
-+    ULONG                        VirtBytesFree, HeaderBytesFree, FirstFreeByte, PhysBytesFree;
-+    
-+    TRACE("BindpWalkAndBindImports Called\n");
-+
-+    /* Load the Import Descriptor */
-+    Imports = RtlImageDirectoryEntryToData ((HMODULE)File->MappedAddress,
-+                                            FALSE, 
-+                                            IMAGE_DIRECTORY_ENTRY_IMPORT, 
-+                                            &SizeOfImports);
-+
-+    /* Read the File Header */
-+    FileHeader = &File->FileHeader->FileHeader;
-+    OptionalHeader32 = &File->FileHeader->OptionalHeader;
-+
-+    /* Support for up to 32 imported DLLs */
-+    BoundImportDescriptors = GlobalAlloc(GMEM_ZEROINIT, 32* sizeof(*BoundImportDescriptor));
-+
-+    TRACE("BoundImportDescriptors Allocated\n");
-+
-+    /* For each Import */
-+    for(; Imports->Name ; Imports++) {
-+        
-+        /* Which DLL is being Imported */
-+        ImportedLibrary = ImageRvaToVa (File->FileHeader, 
-+                                        File->MappedAddress, 
-+                                        Imports->Name, 
-+                                        &File->LastRvaSection);
-+
-+        TRACE("Loading Imported DLL: %s \n", ImportedLibrary);
-+
-+        /* Load the DLL */
-+        LoadedLibrary = ImageLoad(ImportedLibrary, DllPath);
-+
-+        TRACE("DLL Loaded at: %p \n", LoadedLibrary->MappedAddress);
-+
-+        /* Now load the Exports */
-+        Exports = RtlImageDirectoryEntryToData ((HMODULE)LoadedLibrary->MappedAddress, 
-+                                            FALSE, 
-+                                            IMAGE_DIRECTORY_ENTRY_EXPORT, 
-+                                            &SizeOfExports);
-+
-+        /* And load the Thunks */
-+        Thunks = ImageRvaToVa (File->FileHeader, 
-+                                File->MappedAddress, 
-+                                (ULONG)Imports->u.OriginalFirstThunk, 
-+                                &File->LastRvaSection);
-+
-+        /* No actual Exports (UPX Packer can do this */
-+        if (!Thunks) continue;
-+
-+        TRACE("Creating Bound Descriptor for this DLL\n");
-+        
-+        /* Create Bound Import Descriptor */
-+        BoundImportDescriptor = BindpCreateBoundImportDescriptor (ImportedLibrary, 
-+                                                            LoadedLibrary, 
-+                                                            BoundImportDescriptors);
-+
-+        /* Count how many Thunks we have */
-+        ThunkCount = 0;
-+        TempThunk = Thunks;
-+        while (TempThunk->u1.AddressOfData) {
-+            ThunkCount++;
-+            TempThunk++;
-+        }
-+
-+        /* Allocate Memory for the Thunks we will Bind */
-+        SizeOfThunks = ThunkCount * sizeof(*TempBoundThunk);
-+        BoundThunks = GlobalAlloc(GMEM_ZEROINIT, SizeOfThunks);
-+
-+        TRACE("Binding Thunks %p\n",BoundThunks);
-+
-+        /* Bind the Thunks */
-+        TempThunk = Thunks;
-+        TempBoundThunk = BoundThunks;
-+        for (Thunk=0; Thunk < ThunkCount; Thunk++) {
-+            BindpBindThunk (TempThunk, 
-+                        File, 
-+                        TempBoundThunk, 
-+                        LoadedLibrary, 
-+                        Exports, 
-+                        BoundImportDescriptor, 
-+                        DllPath);
-+            TempThunk++;
-+            TempBoundThunk++;
-+        }
-+
-+        /* Load the Second Thunk Array */
-+        TempThunk = ImageRvaToVa (File->FileHeader, 
-+                                    File->MappedAddress, 
-+                                    (ULONG)Imports->FirstThunk, 
-+                                    &File->LastRvaSection);
-+
-+        TRACE("Copying Bound Thunks %p\n",TempThunk);
-+
-+        /* Copy the Pointers */
-+        if (memcmp(TempThunk, BoundThunks, SizeOfThunks)) {
-+            RtlCopyMemory(TempThunk, BoundThunks, SizeOfThunks);
-+        }
-+        
-+        /* Set the TimeStamp */
-+        if (Imports->TimeDateStamp != 0xFFFFFFFF) {
-+            Imports->TimeDateStamp = 0xFFFFFFFF;
-+        }
-+
-+        /* Free the Allocated Memory */
-+        GlobalFree(BoundThunks);
-+
-+        TRACE("Moving to next File\n");
-+    }
-+
-+    TRACE("Creating Bound Import Section\n");
-+
-+    /* Create the Bound Import Table */
-+    BoundImportTable = BindpCreateBoundImportSection(BoundImportDescriptors, &BoundImportTableSize);
-+
-+    /* Zero out the Bound Import Table */
-+    File->FileHeader->OptionalHeader.DataDirectory
-+        [IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress = 0;
-+    File->FileHeader->OptionalHeader.DataDirectory
-+        [IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size = 0;
-+
-+    /* Check if we have enough space */
-+    FirstFreeByte = GetImageUnusedHeaderBytes(File, &VirtBytesFree);
-+    HeaderBytesFree = File->Sections->VirtualAddress - 
-+                        File->FileHeader->OptionalHeader.SizeOfHeaders + VirtBytesFree;
-+    PhysBytesFree = File->Sections->PointerToRawData -
-+                        File->FileHeader->OptionalHeader.SizeOfHeaders + VirtBytesFree;
-+
-+    TRACE("Calculating Space, %lx bytes free\n",PhysBytesFree);
-+
-+    if (BoundImportTableSize > VirtBytesFree) {
-+        if (BoundImportTableSize > HeaderBytesFree) {
-+            TRACE("Only %lx bytes free. Not enough Space\n",HeaderBytesFree);
-+            return; /* Fail...not enough space */
-+        }
-+        if (BoundImportTableSize <= PhysBytesFree) {
-+            
-+            TRACE("Header Recalculation\n");
-+            /* We have enough NULLs to add it, simply enlarge header data */
-+            File->FileHeader->OptionalHeader.SizeOfHeaders = File->FileHeader->OptionalHeader.SizeOfHeaders - 
-+        VirtBytesFree +
-+        BoundImportTableSize +
-+        ((File->FileHeader->OptionalHeader.FileAlignment - 1)
-+        & ~(File->FileHeader->OptionalHeader.FileAlignment - 1));
-+
-+        } else  {
-+
-+            /* Resize the Headers */
-+            FIXME("Add support for Header Resizing\n");
-+
-+            /* Recalculate Headers */
-+            FileHeader = &File->FileHeader->FileHeader;
-+            OptionalHeader32 = &File->FileHeader->OptionalHeader;
-+        }
-+    }
-+    
-+    /* Set Bound Import Table Data */
-+    File->FileHeader->OptionalHeader.DataDirectory
-+        [IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress = FirstFreeByte;
-+    File->FileHeader->OptionalHeader.DataDirectory
-+        [IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size = BoundImportTableSize;
-+
-+    TRACE("Copying Bound Import Table\n");
-+    
-+    /* Copy the Bound Import Table */
-+    RtlCopyMemory(File->MappedAddress + FirstFreeByte, BoundImportTable, BoundImportTableSize);
-+
-+    /* Free out local copy */
-+    GlobalFree(BoundImportTable);
-+}
- /***********************************************************************
-  *            BindImage (IMAGEHLP.@)
-@@ -42,21 +703,80 @@
-   return BindImageEx(0, ImageName, DllPath, SymbolPath, NULL);
- }
--/***********************************************************************
-- *            BindImageEx (IMAGEHLP.@)
-+/*
-+ * BindImageEx
-+ *
-+ * FUNCTION:
-+ *      Binds a PE Image File to its imported Libraries
-+ * ARGUMENTS:
-+ *      Flags            - Caller Specified Flags
-+ *      ImageName        - Name of Imagefile to Bind
-+ *      DllPath            - Path to search DLL Files in, can be NULL to use Default
-+ *      SymbolPath        - Path to search Symbol Files in, can be NULL to use Default
-+ *      StatusRoutine    - Callback routine to notify of Bind Events, can be NULL to disable.
-+ *
-+ * RETURNS:
-+ *      TRUE if Success.
-  */
--BOOL WINAPI BindImageEx(
--  DWORD Flags, LPSTR ImageName, LPSTR DllPath, LPSTR SymbolPath,
--  PIMAGEHLP_STATUS_ROUTINE StatusRoutine)
--{
--  FIXME("(%ld, %s, %s, %s, %p): stub\n",
--    Flags, debugstr_a(ImageName), debugstr_a(DllPath),
--    debugstr_a(SymbolPath), StatusRoutine
--  );
--  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
--  return FALSE;
--}
-+BOOL 
-+WINAPI 
-+BindImageEx(
-+    IN DWORD Flags,
-+    IN LPSTR ImageName,
-+    IN LPSTR DllPath,
-+    IN LPSTR SymbolPath,
-+    IN PIMAGEHLP_STATUS_ROUTINE StatusRoutine
-+    )
-+{
-+    LOADED_IMAGE                FileData;
-+    PLOADED_IMAGE                File;
-+    ULONG                        CheckSum, HeaderSum, OldChecksum;
-+    SYSTEMTIME                    SystemTime;
-+    FILETIME                    LastWriteTime;
-+    
-+    TRACE("BindImageEx Called for: %s \n", ImageName);
-+
-+    /* Set and Clear Buffer */
-+    File = &FileData;
-+    RtlZeroMemory(File, sizeof(*File));
-+
-+    /* Request Image Data */
-+    if (MapAndLoad(ImageName, DllPath, File, TRUE, FALSE)) {
-+
-+        TRACE("Image Mapped and Loaded\n");
-+
-+        /* Read Import Table */
-+        BindpWalkAndBindImports(File, DllPath);
-+        TRACE("Binding Completed, getting Checksum\n");
-+        
-+        /* Update Checksum */
-+        OldChecksum = File->FileHeader->OptionalHeader.CheckSum;
-+        CheckSumMappedFile (File->MappedAddress,
-+                            GetFileSize(File->hFile, NULL),
-+                            &HeaderSum,
-+                            &CheckSum);
-+        File->FileHeader->OptionalHeader.CheckSum = CheckSum;
-+
-+        TRACE("Saving Changes to file\n");
-+
-+    /* Save Changes */
-+        UnmapViewOfFile(File->MappedAddress);
-+
-+        TRACE("Setting time\n");
-+
-+    /* Save new Modified Time */
-+        GetSystemTime(&SystemTime);
-+    SystemTimeToFileTime(&SystemTime, &LastWriteTime);
-+        SetFileTime(File->hFile, NULL, NULL, &LastWriteTime);
-+
-+        /* Close Handle */
-+        CloseHandle(File->hFile);
-+    }
-+
-+    TRACE("Done\n");
-+    return TRUE;
-+}
- /***********************************************************************
-  *            CheckSum (internal)
-
-
index 5e64e7d..9139547 100644 (file)
@@ -75,7 +75,19 @@ extern "C" {
 #define UNDNAME_NO_ARGUMENTS   8192
 #define UNDNAME_NO_SPECIAL_SYMS        16384
 
-#define _IMAGEHLPAPI WINAPI
+#ifdef _IMAGEHLP_SOURCE_
+    #define IMAGEAPI __stdcall
+    #define DBHLP_DEPRECIATED
+#else
+    #define IMAGEAPI DECLSPEC_IMPORT __stdcall
+    #if (_MSC_VER >= 1300) && !defined(MIDL_PASS)
+        #define DBHLP_DEPRECIATED __declspec(deprecated)
+    #else
+        #define DBHLP_DEPRECIATED
+    #endif
+#endif
+
+#define DBHLPAPI IMAGEAPI
 
 #ifndef RC_INVOKED
 
@@ -241,79 +253,79 @@ typedef struct _IMAGEHLP_DUPLICATE_SYMBOL {
 typedef PVOID DIGEST_HANDLE;
 typedef BOOL(WINAPI*DIGEST_FUNCTION)(DIGEST_HANDLE refdata,PBYTE pData,DWORD dwLength);
 
-PIMAGE_NT_HEADERS _IMAGEHLPAPI CheckSumMappedFile(LPVOID,DWORD,LPDWORD,LPDWORD);
-DWORD _IMAGEHLPAPI MapFileAndCheckSumA(LPSTR,LPDWORD,LPDWORD);
-DWORD _IMAGEHLPAPI MapFileAndCheckSumW(PWSTR,LPDWORD,LPDWORD);
-BOOL _IMAGEHLPAPI TouchFileTimes(HANDLE,LPSYSTEMTIME);
-BOOL _IMAGEHLPAPI SplitSymbols(LPSTR,LPSTR,LPSTR,DWORD);
-HANDLE _IMAGEHLPAPI FindDebugInfoFile(LPSTR,LPSTR,LPSTR);
-HANDLE _IMAGEHLPAPI FindExecutableImage(LPSTR,LPSTR,LPSTR);
-BOOL _IMAGEHLPAPI UpdateDebugInfoFile(LPSTR,LPSTR,LPSTR,PIMAGE_NT_HEADERS);
-BOOL _IMAGEHLPAPI UpdateDebugInfoFileEx(LPSTR,LPSTR,LPSTR,PIMAGE_NT_HEADERS,DWORD);
-BOOL _IMAGEHLPAPI BindImage(IN LPSTR,IN LPSTR,IN LPSTR);
-BOOL _IMAGEHLPAPI BindImageEx(IN DWORD,IN LPSTR,IN LPSTR,IN LPSTR,IN PIMAGEHLP_STATUS_ROUTINE);
-BOOL _IMAGEHLPAPI ReBaseImage(IN LPSTR,IN LPSTR,IN BOOL, IN BOOL,IN BOOL, IN ULONG, OUT ULONG*, OUT ULONG*, OUT ULONG*, IN OUT ULONG*, IN ULONG);
+PIMAGE_NT_HEADERS IMAGEAPI CheckSumMappedFile(LPVOID,DWORD,LPDWORD,LPDWORD);
+DWORD IMAGEAPI MapFileAndCheckSumA(LPSTR,LPDWORD,LPDWORD);
+DWORD IMAGEAPI MapFileAndCheckSumW(PWSTR,LPDWORD,LPDWORD);
+BOOL IMAGEAPI TouchFileTimes(HANDLE,LPSYSTEMTIME);
+BOOL IMAGEAPI SplitSymbols(LPSTR,LPSTR,LPSTR,DWORD);
+HANDLE IMAGEAPI FindDebugInfoFile(LPSTR,LPSTR,LPSTR);
+HANDLE IMAGEAPI FindExecutableImage(LPSTR,LPSTR,LPSTR);
+BOOL IMAGEAPI UpdateDebugInfoFile(LPSTR,LPSTR,LPSTR,PIMAGE_NT_HEADERS);
+BOOL IMAGEAPI UpdateDebugInfoFileEx(LPSTR,LPSTR,LPSTR,PIMAGE_NT_HEADERS,DWORD);
+BOOL IMAGEAPI BindImage(IN LPSTR,IN LPSTR,IN LPSTR);
+BOOL IMAGEAPI BindImageEx(IN DWORD,IN LPSTR,IN LPSTR,IN LPSTR,IN PIMAGEHLP_STATUS_ROUTINE);
+BOOL IMAGEAPI ReBaseImage(IN LPSTR,IN LPSTR,IN BOOL, IN BOOL,IN BOOL, IN ULONG, OUT ULONG*, OUT ULONG*, OUT ULONG*, IN OUT ULONG*, IN ULONG);
 
-PLOADED_IMAGE _IMAGEHLPAPI ImageLoad(LPSTR,LPSTR);
-BOOL _IMAGEHLPAPI ImageUnload(PLOADED_IMAGE);
-PIMAGE_NT_HEADERS _IMAGEHLPAPI ImageNtHeader(IN PVOID);
-PVOID _IMAGEHLPAPI ImageDirectoryEntryToData(IN PVOID,IN BOOLEAN,IN USHORT,OUT PULONG);
-PVOID _IMAGEHLPAPI ImageDirectoryEntryToDataEx(IN PVOID Base, IN BOOLEAN MappedAsImage, IN USHORT DirectoryEntry, OUT PULONG Size, OUT PIMAGE_SECTION_HEADER *FoundSection OPTIONAL);
-PVOID _IMAGEHLPAPI ImageDirectoryEntryToData32(PVOID Base, BOOLEAN MappedAsImage, USHORT DirectoryEntry, PULONG Size, PIMAGE_SECTION_HEADER *FoundHeader OPTIONAL, PIMAGE_FILE_HEADER FileHeader, PIMAGE_OPTIONAL_HEADER OptionalHeader);
-PIMAGE_SECTION_HEADER _IMAGEHLPAPI ImageRvaToSection(IN PIMAGE_NT_HEADERS,IN PVOID,IN ULONG);
-PVOID _IMAGEHLPAPI ImageRvaToVa(IN PIMAGE_NT_HEADERS,IN PVOID,IN ULONG,IN OUT PIMAGE_SECTION_HEADER*);
-BOOL _IMAGEHLPAPI MapAndLoad(LPSTR,LPSTR,PLOADED_IMAGE,BOOL,BOOL);
-BOOL _IMAGEHLPAPI GetImageConfigInformation(PLOADED_IMAGE,PIMAGE_LOAD_CONFIG_DIRECTORY);
-DWORD _IMAGEHLPAPI GetImageUnusedHeaderBytes(PLOADED_IMAGE,LPDWORD);
-BOOL _IMAGEHLPAPI SetImageConfigInformation(PLOADED_IMAGE,PIMAGE_LOAD_CONFIG_DIRECTORY);
-BOOL _IMAGEHLPAPI UnMapAndLoad(PLOADED_IMAGE);
-PIMAGE_DEBUG_INFORMATION _IMAGEHLPAPI MapDebugInformation(HANDLE,LPSTR,LPSTR,DWORD);
-BOOL _IMAGEHLPAPI UnmapDebugInformation(PIMAGE_DEBUG_INFORMATION);
-HANDLE _IMAGEHLPAPI FindExecutableImage(LPSTR,LPSTR,LPSTR);
-BOOL _IMAGEHLPAPI SearchTreeForFile(LPSTR,LPSTR,LPSTR);
-BOOL _IMAGEHLPAPI MakeSureDirectoryPathExists(LPCSTR);
-DWORD _IMAGEHLPAPI WINAPI UnDecorateSymbolName(LPCSTR,LPSTR,DWORD, DWORD);
+PLOADED_IMAGE IMAGEAPI ImageLoad(LPSTR,LPSTR);
+BOOL IMAGEAPI ImageUnload(PLOADED_IMAGE);
+PIMAGE_NT_HEADERS IMAGEAPI ImageNtHeader(IN PVOID);
+PVOID IMAGEAPI ImageDirectoryEntryToData(IN PVOID,IN BOOLEAN,IN USHORT,OUT PULONG);
+PVOID IMAGEAPI ImageDirectoryEntryToDataEx(IN PVOID Base, IN BOOLEAN MappedAsImage, IN USHORT DirectoryEntry, OUT PULONG Size, OUT PIMAGE_SECTION_HEADER *FoundSection OPTIONAL);
+PVOID IMAGEAPI ImageDirectoryEntryToData32(PVOID Base, BOOLEAN MappedAsImage, USHORT DirectoryEntry, PULONG Size, PIMAGE_SECTION_HEADER *FoundHeader OPTIONAL, PIMAGE_FILE_HEADER FileHeader, PIMAGE_OPTIONAL_HEADER OptionalHeader);
+PIMAGE_SECTION_HEADER IMAGEAPI ImageRvaToSection(IN PIMAGE_NT_HEADERS,IN PVOID,IN ULONG);
+PVOID IMAGEAPI ImageRvaToVa(IN PIMAGE_NT_HEADERS,IN PVOID,IN ULONG,IN OUT PIMAGE_SECTION_HEADER*);
+BOOL IMAGEAPI MapAndLoad(LPSTR,LPSTR,PLOADED_IMAGE,BOOL,BOOL);
+BOOL IMAGEAPI GetImageConfigInformation(PLOADED_IMAGE,PIMAGE_LOAD_CONFIG_DIRECTORY);
+DWORD IMAGEAPI GetImageUnusedHeaderBytes(PLOADED_IMAGE,LPDWORD);
+BOOL IMAGEAPI SetImageConfigInformation(PLOADED_IMAGE,PIMAGE_LOAD_CONFIG_DIRECTORY);
+BOOL IMAGEAPI UnMapAndLoad(PLOADED_IMAGE);
+PIMAGE_DEBUG_INFORMATION IMAGEAPI MapDebugInformation(HANDLE,LPSTR,LPSTR,DWORD);
+BOOL IMAGEAPI UnmapDebugInformation(PIMAGE_DEBUG_INFORMATION);
+HANDLE IMAGEAPI FindExecutableImage(LPSTR,LPSTR,LPSTR);
+BOOL IMAGEAPI SearchTreeForFile(LPSTR,LPSTR,LPSTR);
+BOOL IMAGEAPI MakeSureDirectoryPathExists(LPCSTR);
+DWORD IMAGEAPI WINAPI UnDecorateSymbolName(LPCSTR,LPSTR,DWORD, DWORD);
 BOOL
-_IMAGEHLPAPI
+IMAGEAPI
 StackWalk(DWORD,HANDLE,HANDLE,LPSTACKFRAME,LPVOID,PREAD_PROCESS_MEMORY_ROUTINE,PFUNCTION_TABLE_ACCESS_ROUTINE,PGET_MODULE_BASE_ROUTINE,PTRANSLATE_ADDRESS_ROUTINE);
-LPAPI_VERSION _IMAGEHLPAPI ImagehlpApiVersion(VOID);
-LPAPI_VERSION _IMAGEHLPAPI ImagehlpApiVersionEx(LPAPI_VERSION);
-DWORD _IMAGEHLPAPI GetTimestampForLoadedLibrary(HMODULE);
-BOOL _IMAGEHLPAPI RemovePrivateCvSymbolic(PCHAR,PCHAR*,ULONG*);
-VOID _IMAGEHLPAPI RemoveRelocations(PCHAR);
-DWORD _IMAGEHLPAPI SymSetOptions(IN DWORD);
-DWORD _IMAGEHLPAPI SymGetOptions(VOID);
-BOOL _IMAGEHLPAPI SymCleanup(IN HANDLE);
-BOOL _IMAGEHLPAPI SymEnumerateModules(IN HANDLE,IN PSYM_ENUMMODULES_CALLBACK,IN PVOID);
-BOOL _IMAGEHLPAPI SymEnumerateSymbols(IN HANDLE,IN DWORD,IN PSYM_ENUMSYMBOLS_CALLBACK,IN PVOID);
-BOOL _IMAGEHLPAPI EnumerateLoadedModules(IN HANDLE,IN PENUMLOADED_MODULES_CALLBACK,IN PVOID);
-LPVOID _IMAGEHLPAPI SymFunctionTableAccess(HANDLE,DWORD);
-BOOL _IMAGEHLPAPI SymGetModuleInfo(IN HANDLE,IN DWORD,OUT PIMAGEHLP_MODULE);
-DWORD _IMAGEHLPAPI SymGetModuleBase(IN HANDLE,IN DWORD);
-BOOL _IMAGEHLPAPI SymGetSymFromAddr(IN HANDLE,IN DWORD,OUT PDWORD,OUT PIMAGEHLP_SYMBOL);
-BOOL _IMAGEHLPAPI SymGetSymFromName(IN HANDLE,IN LPSTR,OUT PIMAGEHLP_SYMBOL);
-BOOL _IMAGEHLPAPI SymGetSymNext(IN HANDLE,IN OUT PIMAGEHLP_SYMBOL);
-BOOL _IMAGEHLPAPI SymGetSymPrev(IN HANDLE,IN OUT PIMAGEHLP_SYMBOL);
-BOOL _IMAGEHLPAPI SymGetLineFromAddr(IN HANDLE,IN DWORD,OUT PDWORD,OUT PIMAGEHLP_LINE);
-BOOL _IMAGEHLPAPI SymGetLineFromName(IN HANDLE,IN LPSTR,IN LPSTR,IN DWORD,OUT PLONG,IN OUT PIMAGEHLP_LINE);
-BOOL _IMAGEHLPAPI SymGetLineNext(IN HANDLE,IN OUT PIMAGEHLP_LINE);
-BOOL _IMAGEHLPAPI SymGetLinePrev(IN HANDLE,IN OUT PIMAGEHLP_LINE);
-BOOL _IMAGEHLPAPI SymMatchFileName(IN LPSTR,IN LPSTR,OUT LPSTR*,OUT LPSTR*);
-BOOL _IMAGEHLPAPI SymInitialize(IN HANDLE,IN LPSTR,IN BOOL);
-BOOL _IMAGEHLPAPI SymGetSearchPath(IN HANDLE,OUT LPSTR,IN DWORD);
-BOOL _IMAGEHLPAPI SymSetSearchPath(IN HANDLE,IN LPSTR);
-BOOL _IMAGEHLPAPI SymLoadModule(IN HANDLE,IN HANDLE,IN PSTR,IN PSTR,IN DWORD,IN DWORD);
-BOOL _IMAGEHLPAPI SymUnloadModule(IN HANDLE,IN DWORD);
-BOOL _IMAGEHLPAPI SymUnDName(IN PIMAGEHLP_SYMBOL,OUT LPSTR,IN DWORD);
-BOOL _IMAGEHLPAPI SymRegisterCallback(IN HANDLE,IN PSYMBOL_REGISTERED_CALLBACK,IN PVOID);
-BOOL _IMAGEHLPAPI ImageGetDigestStream(IN HANDLE,IN DWORD,IN DIGEST_FUNCTION,IN DIGEST_HANDLE);
-//BOOL _IMAGEHLPAPI ImageAddCertificate(IN HANDLE,IN LPWIN_CERTIFICATE,OUT PDWORD);
-BOOL _IMAGEHLPAPI ImageRemoveCertificate(IN HANDLE,IN DWORD);
-BOOL _IMAGEHLPAPI ImageEnumerateCertificates(IN HANDLE,IN WORD,OUT PDWORD,IN OUT PDWORD OPTIONAL,IN OUT DWORD OPTIONAL);
-//BOOL _IMAGEHLPAPI ImageGetCertificateData(IN HANDLE,IN DWORD,OUT LPWIN_CERTIFICATE,IN OUT PDWORD);
-//BOOL _IMAGEHLPAPI ImageGetCertificateHeader(IN HANDLE,IN DWORD,IN OUT LPWIN_CERTIFICATE);
-BOOL _IMAGEHLPAPI CopyPdb(CHAR const*,CHAR const*,BOOL);
-BOOL _IMAGEHLPAPI RemovePrivateCvSymbolicEx(PCHAR,ULONG,PCHAR*,ULONG*);
+LPAPI_VERSION IMAGEAPI ImagehlpApiVersion(VOID);
+LPAPI_VERSION IMAGEAPI ImagehlpApiVersionEx(LPAPI_VERSION);
+DWORD IMAGEAPI GetTimestampForLoadedLibrary(HMODULE);
+BOOL IMAGEAPI RemovePrivateCvSymbolic(PCHAR,PCHAR*,ULONG*);
+VOID IMAGEAPI RemoveRelocations(PCHAR);
+DWORD IMAGEAPI SymSetOptions(IN DWORD);
+DWORD IMAGEAPI SymGetOptions(VOID);
+BOOL IMAGEAPI SymCleanup(IN HANDLE);
+BOOL IMAGEAPI SymEnumerateModules(IN HANDLE,IN PSYM_ENUMMODULES_CALLBACK,IN PVOID);
+BOOL IMAGEAPI SymEnumerateSymbols(IN HANDLE,IN DWORD,IN PSYM_ENUMSYMBOLS_CALLBACK,IN PVOID);
+BOOL IMAGEAPI EnumerateLoadedModules(IN HANDLE,IN PENUMLOADED_MODULES_CALLBACK,IN PVOID);
+LPVOID IMAGEAPI SymFunctionTableAccess(HANDLE,DWORD);
+BOOL IMAGEAPI SymGetModuleInfo(IN HANDLE,IN DWORD,OUT PIMAGEHLP_MODULE);
+DWORD IMAGEAPI SymGetModuleBase(IN HANDLE,IN DWORD);
+BOOL IMAGEAPI SymGetSymFromAddr(IN HANDLE,IN DWORD,OUT PDWORD,OUT PIMAGEHLP_SYMBOL);
+BOOL IMAGEAPI SymGetSymFromName(IN HANDLE,IN LPSTR,OUT PIMAGEHLP_SYMBOL);
+BOOL IMAGEAPI SymGetSymNext(IN HANDLE,IN OUT PIMAGEHLP_SYMBOL);
+BOOL IMAGEAPI SymGetSymPrev(IN HANDLE,IN OUT PIMAGEHLP_SYMBOL);
+BOOL IMAGEAPI SymGetLineFromAddr(IN HANDLE,IN DWORD,OUT PDWORD,OUT PIMAGEHLP_LINE);
+BOOL IMAGEAPI SymGetLineFromName(IN HANDLE,IN LPSTR,IN LPSTR,IN DWORD,OUT PLONG,IN OUT PIMAGEHLP_LINE);
+BOOL IMAGEAPI SymGetLineNext(IN HANDLE,IN OUT PIMAGEHLP_LINE);
+BOOL IMAGEAPI SymGetLinePrev(IN HANDLE,IN OUT PIMAGEHLP_LINE);
+BOOL IMAGEAPI SymMatchFileName(IN LPSTR,IN LPSTR,OUT LPSTR*,OUT LPSTR*);
+BOOL IMAGEAPI SymInitialize(IN HANDLE,IN LPSTR,IN BOOL);
+BOOL IMAGEAPI SymGetSearchPath(IN HANDLE,OUT LPSTR,IN DWORD);
+BOOL IMAGEAPI SymSetSearchPath(IN HANDLE,IN LPSTR);
+DWORD IMAGEAPI SymLoadModule(IN HANDLE,IN HANDLE,IN PSTR,IN PSTR,IN DWORD,IN DWORD);
+BOOL IMAGEAPI SymUnloadModule(IN HANDLE,IN DWORD);
+BOOL IMAGEAPI SymUnDName(IN PIMAGEHLP_SYMBOL,OUT LPSTR,IN DWORD);
+BOOL IMAGEAPI SymRegisterCallback(IN HANDLE,IN PSYMBOL_REGISTERED_CALLBACK,IN PVOID);
+BOOL IMAGEAPI ImageGetDigestStream(IN HANDLE,IN DWORD,IN DIGEST_FUNCTION,IN DIGEST_HANDLE);
+//BOOL IMAGEAPI ImageAddCertificate(IN HANDLE,IN LPWIN_CERTIFICATE,OUT PDWORD);
+BOOL IMAGEAPI ImageRemoveCertificate(IN HANDLE,IN DWORD);
+BOOL IMAGEAPI ImageEnumerateCertificates(IN HANDLE,IN WORD,OUT PDWORD,IN OUT PDWORD OPTIONAL,IN OUT DWORD OPTIONAL);
+//BOOL IMAGEAPI ImageGetCertificateData(IN HANDLE,IN DWORD,OUT LPWIN_CERTIFICATE,IN OUT PDWORD);
+//BOOL IMAGEAPI ImageGetCertificateHeader(IN HANDLE,IN DWORD,IN OUT LPWIN_CERTIFICATE);
+BOOL IMAGEAPI CopyPdb(CHAR const*,CHAR const*,BOOL);
+BOOL IMAGEAPI RemovePrivateCvSymbolicEx(PCHAR,ULONG,PCHAR*,ULONG*);
 
 #endif /* RC_INVOKED */
 
index 0109bdb..08281be 100644 (file)
@@ -952,6 +952,11 @@ typedef enum
 #define IMAGE_SUBSYSTEM_OS2_CUI        5
 #define IMAGE_SUBSYSTEM_POSIX_CUI      7
 #define IMAGE_SUBSYSTEM_XBOX   14
+#define IMAGE_DLLCHARACTERISTICS_NO_ISOLATION 0x0200
+#define IMAGE_DLLCHARACTERISTICS_NO_SEH 0x0400
+#define IMAGE_DLLCHARACTERISTICS_NO_BIND 0x0800
+#define IMAGE_DLLCHARACTERISTICS_WDM_DRIVER 0x2000
+#define IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE 0x8000
 #define IMAGE_FIRST_SECTION(h) ((PIMAGE_SECTION_HEADER) ((DWORD)h+FIELD_OFFSET(IMAGE_NT_HEADERS,OptionalHeader)+((PIMAGE_NT_HEADERS)(h))->FileHeader.SizeOfOptionalHeader))
 #define IMAGE_DIRECTORY_ENTRY_EXPORT   0
 #define IMAGE_DIRECTORY_ENTRY_IMPORT   1