This one is for Steven... 18 months later, I kept my promise ;)
- 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.
Modified: trunk/reactos/lib/imagehlp/access.c
Deleted: trunk/reactos/lib/imagehlp/debug.c
Modified: trunk/reactos/lib/imagehlp/imagehlp.def
Modified: trunk/reactos/lib/imagehlp/imagehlp.xml
Modified: trunk/reactos/lib/imagehlp/imagehlp_main.c
Modified: trunk/reactos/lib/imagehlp/integrity.c
Deleted: trunk/reactos/lib/imagehlp/internal.c
Modified: trunk/reactos/lib/imagehlp/modify.c
Added: trunk/reactos/lib/imagehlp/precomp.h
Deleted: trunk/reactos/lib/imagehlp/symbol.c
Deleted: trunk/reactos/lib/imagehlp/winehq2ros.patch
Modified: trunk/reactos/w32api/include/imagehlp.h
Modified: trunk/reactos/w32api/include/winnt.h

Modified: trunk/reactos/lib/imagehlp/access.c
--- trunk/reactos/lib/imagehlp/access.c	2005-11-06 01:24:21 UTC (rev 19024)
+++ trunk/reactos/lib/imagehlp/access.c	2005-11-06 10:48:14 UTC (rev 19025)
@@ -1,564 +1,634 @@
 /*
- *	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"
+/* INCLUDES ******************************************************************/
 
-/* Couple of Hacks */
-extern inline DWORD WINAPI GetLastError(void)
+#include "precomp.h"
+
+//#define NDEBUG
+#include <debug.h>
+
+/* DATA **********************************************************************/
+
+BOOLEAN DllListInitialized;
+LIST_ENTRY ImageLoadListHead;
+
+/* 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)
 {
-    DWORD ret;
-    __asm__ __volatile__( ".byte 0x64\n\tmovl 0x60,%0" : "=r" (ret) );
-    return ret;
-}
+    ULONG i;
+    PIMAGE_SECTION_HEADER CurrentSection;
+    ULONG DirectoryEntryVA;
 
-#define InitializeListHead(ListHead) (\
-    (ListHead)->Flink = (ListHead)->Blink = (ListHead))
+    /* Check if this entry is invalid */
+    if (DirectoryEntry >= OptionalHeader->NumberOfRvaAndSizes)
+    {
+        /* Nothing found */
+        *Size = 0;
+        return NULL;
+    }
 
-#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);\
+    /* Get the VA of the Directory Requested */
+    DirectoryEntryVA = OptionalHeader->DataDirectory[DirectoryEntry].VirtualAddress;
+    if (!DirectoryEntryVA)
+    {
+        /* It doesn't exist */
+        *Size = 0;
+        return NULL;
     }
 
-WINE_DEFAULT_DEBUG_CHANNEL(imagehlp);
+    /* Get the size of the Directory Requested */
+    *Size = OptionalHeader->DataDirectory[DirectoryEntry].Size;
 
-/***********************************************************************
- *           Data
- */
+    /* 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);
+    }
 
-static PLOADED_IMAGE IMAGEHLP_pFirstLoadedImage=NULL;
-static PLOADED_IMAGE IMAGEHLP_pLastLoadedImage=NULL;
+    /* 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));
+        }
 
-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; */
-};
+        /* Move to the next section */
+        CurrentSection++;
+    }
 
-extern HANDLE IMAGEHLP_hHeap;
-BOOLEAN DllListInitialized;
-LIST_ENTRY ImageLoadListHead;
-
-/***********************************************************************
- *		EnumerateLoadedModules (IMAGEHLP.@)
- */
-BOOL WINAPI EnumerateLoadedModules(
-  HANDLE hProcess,
-  PENUMLOADED_MODULES_CALLBACK EnumLoadedModulesCallback,
-  PVOID UserContext)
-{
-  FIXME("(%p, %p, %p): stub\n",
-    hProcess, EnumLoadedModulesCallback, UserContext
-  );
-  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-  return FALSE;
+    /* 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);
+    /* 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;
+    /* 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<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;
-                }
+    /*
+     * 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.@)
+/*
+ * @implemented
  */
-PVOID
-STDCALL
-ImageDirectoryEntryToData32 (
-    PVOID Base,
-    BOOLEAN MappedAsImage,
-    USHORT DirectoryEntry,
-    PULONG Size,
-    PIMAGE_SECTION_HEADER *FoundHeader OPTIONAL,
-    PIMAGE_FILE_HEADER FileHeader,
-    PIMAGE_OPTIONAL_HEADER OptionalHeader
-    )
+PLOADED_IMAGE
+IMAGEAPI
+ImageLoad(LPSTR DllName,
+          LPSTR DllPath)
 {
-    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.@)
- */
-PLOADED_IMAGE WINAPI 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 the Names Match */
-        if (!lstrcmpi( DllName, LoadedImage->ModuleName )) {
-			//FIXME("Found it, returning it\n");
+        /* Check if we didn't have a complete name */
+        if (!CompleteName)
+        {
+            /* Split this module's name */
+            _splitpath(LoadedImage->ModuleName, NULL, NULL, Filename, Ext);
+
+            /* 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 */
+    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);
 
-	/* Allocate memory for the Structure, and write the Module Name under */
-    LoadedImage = HeapAlloc(IMAGEHLP_hHeap, 0, sizeof(*LoadedImage) + lstrlen(DllName) + 1);
+        /* Copy the Module Name */
+        strcpy(LoadedImage->ModuleName, DllName);
 
-	/* Module Name will be after structure */
-    LoadedImage->ModuleName = (LPSTR)LoadedImage + 1;
+        /* Now Load it */
+        if (MapAndLoad(DllName, DllPath, LoadedImage, TRUE, TRUE))
+        {
+            /* Add it to our list and return it */
+            InsertTailList(&ImageLoadListHead, &LoadedImage->Links);
+            return LoadedImage;
+        }
 
-	/* Copy the Moduel Name */
-    lstrcpy(LoadedImage->ModuleName, DllName);
-
-	/* 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;
+    /* If the image list isn't empty, remove this entry */
+    if (!IsListEmpty(&LoadedImage->Links)) RemoveEntryList(&LoadedImage->Links);
 
-  TRACE("(%p)\n", pLoadedImage);
-  
-  if(!IMAGEHLP_pFirstLoadedImage || !pLoadedImage)
-    {
-      /* No image loaded or null pointer */
-      SetLastError(ERROR_INVALID_PARAMETER);
-      return FALSE;
-    }
+    /* Unmap and unload it */
+    UnMapAndLoad(LoadedImage);
 
-  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;
-    }
+    /* Free the structure */
+    HeapFree(IMAGEHLP_hHeap, 0, 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;
-
-  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;
+    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;
+    /* 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;
-    }
 
-	/* Create the File Mapping */
-	if (!(hFileMapping = CreateFileMappingA (LoadedImage->hFile,
-											NULL, 
-											ReadOnly ? PAGE_READONLY : PAGE_READWRITE, 
-											0, 
-											0, 
-											NULL)))
-    {
-      DWORD dwLastError = GetLastError();
-      SetLastError(dwLastError);
-      goto Error;
+        /* Success, break out */
+        break;
     }
 
-	/* Get a pointer to the file */
-	if(!(LoadedImage->MappedAddress = MapViewOfFile(hFileMapping, 
-													ReadOnly ? FILE_MAP_READ : FILE_MAP_WRITE, 
-													0, 
-													0, 
-													0)))
+    /* 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;
     }
 
-	/* Close the handle to the map, we don't need it anymore */
-	CloseHandle(hFileMapping);
-	hFileMapping=NULL;
+    /* Get a pointer to the file */
+    LoadedImage->MappedAddress = MapViewOfFile(hFileMapping,
+                                               ReadOnly ? FILE_MAP_READ :
+                                                          FILE_MAP_WRITE,
+                                               0,
+                                               0, 
+                                               0);
 
-	/* Get the Nt Header */
-	NtHeader = ImageNtHeader(LoadedImage->MappedAddress);
+    /* Close the handle to the map, we don't need it anymore */
+    CloseHandle(hFileMapping);
 
-	/* 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 */
+    /* Write the image size */
+    LoadedImage->SizeOfImage = GetFileSize(hFile, NULL);
 
-	/* Read only, so no sense in keeping the handle alive */
-	if (ReadOnly) CloseHandle(LoadedImage->hFile);
+    /* Get the Nt Header */
+    NtHeader = ImageNtHeader(LoadedImage->MappedAddress);
 
-	/* Return Success */
-	return TRUE;
+    /* Allocate memory for the name and save it */
+    LoadedImage->ModuleName = HeapAlloc(IMAGEHLP_hHeap,
+                                        0,
+                                        strlen(FileToOpen) + 16);
+    strcpy(LoadedImage->ModuleName, FileToOpen);
 
-Error:
-	if(LoadedImage->MappedAddress)
-		UnmapViewOfFile(LoadedImage->MappedAddress);
-	if(hFileMapping)
-		CloseHandle(hFileMapping);
-	if(LoadedImage->hFile)
-		CloseHandle(LoadedImage->hFile);
-	return FALSE;
+    /* 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
+    {
+        /* Write our file handle */
+        LoadedImage->hFile = hFile;
+    }
+
+    /* 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)
 {
-  FIXME("(%p): stub\n", LoadedImage);
-  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-  return FALSE;
+    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
+    {
[truncated at 1000 lines; 4883 more skipped]