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, &section );
+    names = RtlImageRvaToVa( nt, *data, exports->AddressOfNames, &section );
+    functions = RtlImageRvaToVa( nt, *data, exports->AddressOfFunctions, &section );
+    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], &section );
+        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