From: Bernhard Reiter Subject: [2/2] imagehlp: Implement (parts of) BindImageEx (try 7) Message-Id: <538A55A6.5000603@raz.or.at> Date: Sun, 01 Jun 2014 00:20:22 +0200 * Return TRUE if modules are being imported (no modules means nothing to bind). * Remove bug URL from comment. From c693a43334d9b8a30c50c7a3ecf04cc2192137de Mon Sep 17 00:00:00 2001 From: Bernhard Reiter Date: Wed, 9 Apr 2014 00:52:31 +0200 Subject: Implement parts of BindImageEx so at least freezing Python scripts works. Fixes http://bugs.winehq.org/show_bug.cgi?id=3591 --- dlls/imagehlp/modify.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 80 insertions(+), 2 deletions(-) diff --git a/dlls/imagehlp/modify.c b/dlls/imagehlp/modify.c index debccc0..ff0a1df 100644 --- a/dlls/imagehlp/modify.c +++ b/dlls/imagehlp/modify.c @@ -29,11 +29,15 @@ WINE_DEFAULT_DEBUG_CHANNEL(imagehlp); +PVOID WINAPI ImageDirectoryEntryToDataEx( PVOID base, BOOLEAN image, USHORT dir, + PULONG size, PIMAGE_SECTION_HEADER *section ); static WORD CalcCheckSum(DWORD StartValue, LPVOID BaseAddress, DWORD WordCount); - /*********************************************************************** * BindImage (IMAGEHLP.@) + * + * NOTES + * See BindImageEx */ BOOL WINAPI BindImage( PCSTR ImageName, PCSTR DllPath, PCSTR SymbolPath) @@ -43,15 +47,89 @@ BOOL WINAPI BindImage( /*********************************************************************** * BindImageEx (IMAGEHLP.@) + * + * Compute the virtual address of each function imported by a PE image + * + * PARAMS + * + * Flags [in] Bind options + * ImageName [in] File name of the image to be bound + * DllPath [in] Root of the fallback search path in case the ImageName file cannot be opened + * SymbolPath [in] Symbol file root search path + * StatusRoutine [in] Pointer to a status routine which will be called during the binding process + * + * RETURNS + * Success: TRUE + * Failure: FALSE + * + * NOTES + * The main purpose of this stub implementation is to allow "freezing" of Python packages + * (as performed by cx_Freeze or py2exe) which usually invokes BindImageEx to determine what DLLs + * to add to the frozen package by passing a StatusRoutine to it that listens for the + * BindImportModule and BindImportProcedure statuses to determine the imported modules and + * procedures. */ BOOL WINAPI BindImageEx( DWORD Flags, PCSTR ImageName, PCSTR DllPath, PCSTR SymbolPath, PIMAGEHLP_STATUS_ROUTINE StatusRoutine) { - FIXME("(%d, %s, %s, %s, %p): stub\n", + LOADED_IMAGE loadedImage; + const IMAGE_IMPORT_DESCRIPTOR *importDesc; + ULONG size; + CHAR DllFullName[MAX_PATH]; + + FIXME("(%d, %s, %s, %s, %p)\n", Flags, debugstr_a(ImageName), debugstr_a(DllPath), debugstr_a(SymbolPath), StatusRoutine ); + + if (!(MapAndLoad( ImageName, DllPath, &loadedImage, TRUE, TRUE ))) return FALSE; + + if (!(importDesc = (IMAGE_IMPORT_DESCRIPTOR *) + ImageDirectoryEntryToDataEx( loadedImage.MappedAddress, FALSE, + IMAGE_DIRECTORY_ENTRY_IMPORT, &size, NULL ))) + return TRUE; // No imported modules means nothing to bind, so we're done. + + for (; importDesc->Name && importDesc->OriginalFirstThunk; ++importDesc) { + IMAGE_THUNK_DATA *thunk; + char *DllName = ImageRvaToVa( loadedImage.FileHeader, loadedImage.MappedAddress, + importDesc->Name, NULL ); + + (*StatusRoutine)( BindImportModule, ImageName, DllName, 0, 0); + + FIXME("Actual image loading not implemented, only looking up its location instead\n"); + if (!SearchPathA( DllPath, DllName, NULL, + sizeof(DllFullName), DllFullName, NULL)) + { + SetLastError(ERROR_FILE_NOT_FOUND); + return FALSE; + } + + thunk = ImageRvaToVa( loadedImage.FileHeader, loadedImage.MappedAddress, + importDesc->OriginalFirstThunk, NULL ); + + for (; thunk->u1.Function; ++thunk) { + if(thunk->u1.Ordinal & IMAGE_ORDINAL_FLAG) { + /* Ordinal, i.e. unnamed function. Not sure if/how to properly pass this + * on to StatusRoutine... */ + /* DWORD ordinal = (DWORD) (thunk->u1.Ordinal & (~IMAGE_ORDINAL_FLAG)); */ + } else { + IMAGE_IMPORT_BY_NAME *funcNameStruct = + ImageRvaToVa( loadedImage.FileHeader, loadedImage.MappedAddress, + thunk->u1.AddressOfData, NULL ); + (*StatusRoutine)( BindImportProcedure, ImageName, DllFullName, 0, + (ULONG_PTR) funcNameStruct->Name ); + FIXME("Actual binding not implemented yet\n"); + /* The actual binding was implemented by a 2004 patch from ReactOS submitted to Wine at + * http://www.winehq.org/pipermail/wine-patches/2004-September/013039.html + * which curiously seems to not have made it into the Wine code. Hopefully, some of it can + * be reused. Note however that e.g. it doesn't call StatusRoutine at all. + */ + } + } + } + + UnMapAndLoad( &loadedImage ); return TRUE; } -- 1.9.1