From ad438726691e6b8077e7f1ddcbee9abf67f3840e Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Thu, 18 Feb 2021 11:06:06 +0100 Subject: [PATCH] winebuild: Add a --prefer-native option to set a Wine-specific flag in the PE header. Signed-off-by: Alexandre Julliard --- tools/winebuild/build.h | 4 +++- tools/winebuild/main.c | 8 ++++++++ tools/winebuild/spec32.c | 13 +++++++++++++ tools/winebuild/winebuild.man.in | 4 ++++ 4 files changed, 28 insertions(+), 1 deletion(-) diff --git a/tools/winebuild/build.h b/tools/winebuild/build.h index 104c77db593..84938aabf4f 100644 --- a/tools/winebuild/build.h +++ b/tools/winebuild/build.h @@ -217,7 +217,8 @@ struct strarray #define IMAGE_FILE_UP_SYSTEM_ONLY 0x4000 #define IMAGE_FILE_BYTES_REVERSED_HI 0x8000 -#define IMAGE_DLLCHARACTERISTICS_NX_COMPAT 0x0100 +#define IMAGE_DLLCHARACTERISTICS_PREFER_NATIVE 0x0010 /* Wine extension */ +#define IMAGE_DLLCHARACTERISTICS_NX_COMPAT 0x0100 #define IMAGE_SUBSYSTEM_NATIVE 1 #define IMAGE_SUBSYSTEM_WINDOWS_GUI 2 @@ -380,6 +381,7 @@ extern int unwind_tables; extern int use_msvcrt; extern int unix_lib; extern int safe_seh; +extern int prefer_native; extern char *input_file_name; extern char *spec_file_name; diff --git a/tools/winebuild/main.c b/tools/winebuild/main.c index 1477df7f259..72e13b7992b 100644 --- a/tools/winebuild/main.c +++ b/tools/winebuild/main.c @@ -49,6 +49,7 @@ int unwind_tables = 0; int use_msvcrt = 0; int unix_lib = 0; int safe_seh = 0; +int prefer_native = 0; #ifdef __i386__ enum target_cpu target_cpu = CPU_x86; @@ -294,6 +295,7 @@ static const char usage_str[] = " --nxcompat=y|n Set the NX compatibility flag (default: yes)\n" " -N, --dll-name=DLLNAME Set the DLL name (default: from input file name)\n" " -o, --output=NAME Set the output file name (default: stdout)\n" +" --prefer-native Set the flag to prefer loading native at run time\n" " -r, --res=RSRC.RES Load resources from RSRC.RES\n" " --safeseh Mark object files as SEH compatible\n" " --save-temps Do not delete the generated intermediate files\n" @@ -329,6 +331,7 @@ enum long_options_values LONG_OPT_LDCMD, LONG_OPT_NMCMD, LONG_OPT_NXCOMPAT, + LONG_OPT_PREFER_NATIVE, LONG_OPT_RESOURCES, LONG_OPT_SAFE_SEH, LONG_OPT_SAVE_TEMPS, @@ -356,6 +359,7 @@ static const struct option long_options[] = { "ld-cmd", 1, 0, LONG_OPT_LDCMD }, { "nm-cmd", 1, 0, LONG_OPT_NMCMD }, { "nxcompat", 1, 0, LONG_OPT_NXCOMPAT }, + { "prefer-native", 0, 0, LONG_OPT_PREFER_NATIVE }, { "resources", 0, 0, LONG_OPT_RESOURCES }, { "safeseh", 0, 0, LONG_OPT_SAFE_SEH }, { "save-temps", 0, 0, LONG_OPT_SAVE_TEMPS }, @@ -575,6 +579,10 @@ static char **parse_options( int argc, char **argv, DLLSPEC *spec ) case LONG_OPT_SAFE_SEH: safe_seh = 1; break; + case LONG_OPT_PREFER_NATIVE: + prefer_native = 1; + spec->dll_characteristics |= IMAGE_DLLCHARACTERISTICS_PREFER_NATIVE; + break; case LONG_OPT_RESOURCES: set_exec_mode( MODE_RESOURCES ); break; diff --git a/tools/winebuild/spec32.c b/tools/winebuild/spec32.c index 678f104c555..8d7e48d2da4 100644 --- a/tools/winebuild/spec32.c +++ b/tools/winebuild/spec32.c @@ -1076,6 +1076,19 @@ void make_builtin_files( char *argv[] ) if (header.e_lfanew < sizeof(header) + sizeof(builtin_signature)) fatal_error( "%s: Not enough space (%x) for Wine signature\n", argv[i], header.e_lfanew ); write( fd, builtin_signature, sizeof(builtin_signature) ); + + if (prefer_native) + { + unsigned int pos = header.e_lfanew + 0x5e; /* OptionalHeader.DllCharacteristics */ + unsigned short dll_charact; + lseek( fd, pos, SEEK_SET ); + if (read( fd, &dll_charact, sizeof(dll_charact) ) == sizeof(dll_charact)) + { + dll_charact |= IMAGE_DLLCHARACTERISTICS_PREFER_NATIVE; + lseek( fd, pos, SEEK_SET ); + write( fd, &dll_charact, sizeof(dll_charact) ); + } + } } else fatal_error( "%s: Unrecognized file format\n", argv[i] ); close( fd ); diff --git a/tools/winebuild/winebuild.man.in b/tools/winebuild/winebuild.man.in index c1de885dac2..d55c00b2d24 100644 --- a/tools/winebuild/winebuild.man.in +++ b/tools/winebuild/winebuild.man.in @@ -209,6 +209,10 @@ output file name ends in .o, the text output is sent to a temporary file that is then assembled to produce the specified .o file. .TP +.B --prefer-native +Specify that the native DLL should be preferred if available at run +time. This can be used on modules that are mostly unimplemented. +.TP .BI \-r,\ --res= rsrc.res Load resources from the specified binary resource file. The \fIrsrc.res\fR file can be produced from a source resource file with