Commit in reactos/lib/imagehlp on MAIN
winehq2ros.patch+1064added 1.1
Added new patch for Alex's BindImage, Map and Load and
friends to CVS for next merge. This patch applies clean to
Winehq tip.

reactos/lib/imagehlp
winehq2ros.patch added at 1.1
diff -N winehq2ros.patch
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ winehq2ros.patch	12 Nov 2004 03:55:15 -0000	1.1
@@ -0,0 +1,1064 @@
+
+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
[truncated at 1000 lines; 68 more skipped]
CVSspam 0.2.8