Alexandre Julliard : setupapi: Extract the 16-bit fake dll from the 32-bit PE one.
Alexandre Julliard
julliard at winehq.org
Mon May 20 15:50:46 CDT 2019
Module: wine
Branch: master
Commit: 16851b1c122e83549522ed01c3a303c2f2ca9097
URL: https://source.winehq.org/git/wine.git/?a=commit;h=16851b1c122e83549522ed01c3a303c2f2ca9097
Author: Alexandre Julliard <julliard at winehq.org>
Date: Sat May 18 09:29:04 2019 +0200
setupapi: Extract the 16-bit fake dll from the 32-bit PE one.
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/setupapi/fakedll.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 46 insertions(+)
diff --git a/dlls/setupapi/fakedll.c b/dlls/setupapi/fakedll.c
index 260eb1e..2802aed 100644
--- a/dlls/setupapi/fakedll.c
+++ b/dlls/setupapi/fakedll.c
@@ -190,6 +190,50 @@ failed:
return FALSE;
}
+static int is_valid_ptr( const void *data, SIZE_T size, const void *ptr, SIZE_T ptr_size )
+{
+ if (ptr < data) return 0;
+ if ((char *)ptr - (char *)data >= size) return 0;
+ return (size - ((char *)ptr - (char *)data) >= ptr_size);
+}
+
+/* extract the 16-bit NE dll from a PE builtin */
+static void extract_16bit_image( IMAGE_NT_HEADERS *nt, void **data, SIZE_T *size )
+{
+ DWORD exp_size, *size_ptr;
+ IMAGE_DOS_HEADER *dos;
+ IMAGE_EXPORT_DIRECTORY *exports;
+ IMAGE_SECTION_HEADER *section = NULL;
+ WORD *ordinals;
+ DWORD *names, *functions;
+ int i;
+
+ exports = RtlImageDirectoryEntryToData( *data, FALSE, IMAGE_DIRECTORY_ENTRY_EXPORT, &exp_size );
+ if (!is_valid_ptr( *data, *size, exports, exp_size )) return;
+ ordinals = RtlImageRvaToVa( nt, *data, exports->AddressOfNameOrdinals, §ion );
+ names = RtlImageRvaToVa( nt, *data, exports->AddressOfNames, §ion );
+ functions = RtlImageRvaToVa( nt, *data, exports->AddressOfFunctions, §ion );
+ if (!is_valid_ptr( *data, *size, ordinals, exports->NumberOfNames * sizeof(*ordinals) )) return;
+ if (!is_valid_ptr( *data, *size, names, exports->NumberOfNames * sizeof(*names) )) return;
+
+ for (i = 0; i < exports->NumberOfNames; i++)
+ {
+ char *ename = RtlImageRvaToVa( nt, *data, names[i], §ion );
+ if (strcmp( ename, "__wine_spec_dos_header" )) continue;
+ if (ordinals[i] >= exports->NumberOfFunctions) return;
+ if (!is_valid_ptr( *data, *size, functions, sizeof(*functions) )) return;
+ if (!functions[ordinals[i]]) return;
+ dos = RtlImageRvaToVa( nt, *data, functions[ordinals[i]], NULL );
+ if (!is_valid_ptr( *data, *size, dos, sizeof(*dos) )) return;
+ if (dos->e_magic != IMAGE_DOS_SIGNATURE) return;
+ size_ptr = (DWORD *)dos->e_res2;
+ *size = min( *size_ptr, *size - ((const char *)dos - (const char *)*data) );
+ *size_ptr = 0;
+ *data = dos;
+ break;
+ }
+}
+
/* read in the contents of a file into the global file buffer */
/* return 1 on success, 0 on nonexistent file, -1 on other error */
static int read_file( const char *name, void **data, SIZE_T *size, BOOL expect_builtin )
@@ -238,6 +282,8 @@ static int read_file( const char *name, void **data, SIZE_T *size, BOOL expect_b
st.st_size - header_size, header_size ) == st.st_size - header_size)
{
*data = file_buffer;
+ if (strlen(name) > 2 && !strcmp( name + strlen(name) - 2, "16" ))
+ extract_16bit_image( nt, data, size );
ret = 1;
}
done:
More information about the wine-cvs
mailing list