Added support for Unicode applications in winebuild.
Removed cuiexe_no_main hack. Avoid stdcall function declarations inside functions because of gcc bug.
This commit is contained in:
parent
57f8eb71da
commit
909eff9932
|
@ -1027,6 +1027,7 @@ debug_channels (aspi atom cdrom console ddraw debug delayhlp dll dosfs dosmem
|
||||||
|
|
||||||
# Command-line
|
# Command-line
|
||||||
@ cdecl __wine_get_main_args(ptr) __wine_get_main_args
|
@ cdecl __wine_get_main_args(ptr) __wine_get_main_args
|
||||||
|
@ cdecl __wine_get_wmain_args(ptr) __wine_get_wmain_args
|
||||||
|
|
||||||
# Server interface
|
# Server interface
|
||||||
@ cdecl -norelay wine_server_call(long) wine_server_call
|
@ cdecl -norelay wine_server_call(long) wine_server_call
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "winbase.h"
|
#include "winbase.h"
|
||||||
|
#include "winnls.h"
|
||||||
#include "wine/library.h"
|
#include "wine/library.h"
|
||||||
#include "options.h"
|
#include "options.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
|
@ -42,6 +43,7 @@ static char *inherit_str; /* options to pass to child processes */
|
||||||
|
|
||||||
static int app_argc; /* argc/argv to pass to application */
|
static int app_argc; /* argc/argv to pass to application */
|
||||||
static char **app_argv;
|
static char **app_argv;
|
||||||
|
static WCHAR **app_wargv;
|
||||||
|
|
||||||
static void out_of_memory(void) WINE_NORETURN;
|
static void out_of_memory(void) WINE_NORETURN;
|
||||||
static void out_of_memory(void)
|
static void out_of_memory(void)
|
||||||
|
@ -358,3 +360,35 @@ int __wine_get_main_args( char ***argv )
|
||||||
return app_argc;
|
return app_argc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* __wine_get_wmain_args
|
||||||
|
*
|
||||||
|
* Same as __wine_get_main_args but for Unicode.
|
||||||
|
*/
|
||||||
|
int __wine_get_wmain_args( WCHAR ***argv )
|
||||||
|
{
|
||||||
|
if (!app_wargv)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
WCHAR *p;
|
||||||
|
DWORD total = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < app_argc; i++)
|
||||||
|
total += MultiByteToWideChar( CP_ACP, 0, app_argv[i], -1, NULL, 0 );
|
||||||
|
|
||||||
|
app_wargv = HeapAlloc( GetProcessHeap(), 0,
|
||||||
|
total * sizeof(WCHAR) + (app_argc + 1) * sizeof(*app_wargv) );
|
||||||
|
p = (WCHAR *)(app_wargv + app_argc + 1);
|
||||||
|
for (i = 0; i < app_argc; i++)
|
||||||
|
{
|
||||||
|
DWORD len = MultiByteToWideChar( CP_ACP, 0, app_argv[i], -1, p, total );
|
||||||
|
app_wargv[i] = p;
|
||||||
|
p += len;
|
||||||
|
total -= len;
|
||||||
|
}
|
||||||
|
app_wargv[app_argc] = NULL;
|
||||||
|
}
|
||||||
|
*argv = app_wargv;
|
||||||
|
return app_argc;
|
||||||
|
}
|
||||||
|
|
|
@ -18,11 +18,10 @@ extern void PROCESS_InitWine( int argc, char *argv[] ) WINE_NORETURN;
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* Main loop of initial task
|
* Main loop of initial task
|
||||||
*/
|
*/
|
||||||
void wine_initial_task(void)
|
int WINAPI wine_initial_task( HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, INT show )
|
||||||
{
|
{
|
||||||
MSG msg;
|
MSG msg;
|
||||||
HINSTANCE16 instance;
|
HINSTANCE16 instance;
|
||||||
STARTUPINFOA info;
|
|
||||||
|
|
||||||
if (!LoadLibraryA( "user32.dll" ))
|
if (!LoadLibraryA( "user32.dll" ))
|
||||||
{
|
{
|
||||||
|
@ -31,10 +30,7 @@ void wine_initial_task(void)
|
||||||
}
|
}
|
||||||
THUNK_InitCallout();
|
THUNK_InitCallout();
|
||||||
|
|
||||||
GetStartupInfoA( &info );
|
if ((instance = WinExec16( GetCommandLineA(), show )) < 32)
|
||||||
if (!(info.dwFlags & STARTF_USESHOWWINDOW)) info.wShowWindow = SW_SHOWNORMAL;
|
|
||||||
|
|
||||||
if ((instance = WinExec16( GetCommandLineA(), info.wShowWindow )) < 32)
|
|
||||||
{
|
{
|
||||||
if (instance == 11) /* try DOS format */
|
if (instance == 11) /* try DOS format */
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
name wine
|
name wine
|
||||||
mode cuiexe_no_main
|
mode guiexe
|
||||||
type win32
|
type win32
|
||||||
init wine_initial_task
|
init wine_initial_task
|
||||||
|
|
||||||
|
|
|
@ -4,11 +4,13 @@
|
||||||
name NAME
|
name NAME
|
||||||
type win16|win32
|
type win16|win32
|
||||||
[file WINFILENAME]
|
[file WINFILENAME]
|
||||||
[mode dll|cuiexe|guiexe]
|
[mode dll|cuiexe|guiexe|cuiexe_unicode|guiexe_unicode]
|
||||||
[heap SIZE]
|
[heap SIZE]
|
||||||
[init FUNCTION]
|
[init FUNCTION]
|
||||||
[import DLL]
|
[import DLL]
|
||||||
[rsrc RESFILE]
|
[rsrc RESFILE]
|
||||||
|
[debug_channels ([CHANNEL [CHANNEL...]])]
|
||||||
|
[ignore ([SYMBOL [SYMBOL...]])]
|
||||||
|
|
||||||
ORDINAL FUNCTYPE [FLAGS] EXPORTNAME([ARGTYPE [ARGTYPE [...]]]) HANDLERNAME
|
ORDINAL FUNCTYPE [FLAGS] EXPORTNAME([ARGTYPE [ARGTYPE [...]]]) HANDLERNAME
|
||||||
|
|
||||||
|
@ -51,6 +53,11 @@ times.
|
||||||
|
|
||||||
"rsrc" specifies the path of the compiled resource file.
|
"rsrc" specifies the path of the compiled resource file.
|
||||||
|
|
||||||
|
"debug_channels" specifies the list of debug channels used by the dll.
|
||||||
|
|
||||||
|
"ignore" specifies a list of symbols that should be ignored when
|
||||||
|
resolving undefined symbols against the imported libraries.
|
||||||
|
|
||||||
"ORDINAL" specified the ordinal number corresponding to the entry
|
"ORDINAL" specified the ordinal number corresponding to the entry
|
||||||
point, or "@" for automatic ordinal allocation (Win32 only).
|
point, or "@" for automatic ordinal allocation (Win32 only).
|
||||||
|
|
||||||
|
|
|
@ -60,8 +60,8 @@ typedef enum
|
||||||
SPEC_MODE_DLL,
|
SPEC_MODE_DLL,
|
||||||
SPEC_MODE_GUIEXE,
|
SPEC_MODE_GUIEXE,
|
||||||
SPEC_MODE_CUIEXE,
|
SPEC_MODE_CUIEXE,
|
||||||
SPEC_MODE_GUIEXE_NO_MAIN,
|
SPEC_MODE_GUIEXE_UNICODE,
|
||||||
SPEC_MODE_CUIEXE_NO_MAIN
|
SPEC_MODE_CUIEXE_UNICODE
|
||||||
} SPEC_MODE;
|
} SPEC_MODE;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
|
|
@ -205,6 +205,8 @@ static void add_extra_undef_symbols(void)
|
||||||
/* add symbols that will be contained in the spec file itself */
|
/* add symbols that will be contained in the spec file itself */
|
||||||
switch (SpecMode)
|
switch (SpecMode)
|
||||||
{
|
{
|
||||||
|
case SPEC_MODE_DLL:
|
||||||
|
break;
|
||||||
case SPEC_MODE_GUIEXE:
|
case SPEC_MODE_GUIEXE:
|
||||||
ADD_SYM( "GetCommandLineA" );
|
ADD_SYM( "GetCommandLineA" );
|
||||||
ADD_SYM( "GetStartupInfoA" );
|
ADD_SYM( "GetStartupInfoA" );
|
||||||
|
@ -213,13 +215,19 @@ static void add_extra_undef_symbols(void)
|
||||||
case SPEC_MODE_CUIEXE:
|
case SPEC_MODE_CUIEXE:
|
||||||
ADD_SYM( "__wine_get_main_args" );
|
ADD_SYM( "__wine_get_main_args" );
|
||||||
ADD_SYM( "ExitProcess" );
|
ADD_SYM( "ExitProcess" );
|
||||||
|
break;
|
||||||
|
case SPEC_MODE_GUIEXE_UNICODE:
|
||||||
|
ADD_SYM( "GetCommandLineA" );
|
||||||
|
ADD_SYM( "GetStartupInfoA" );
|
||||||
|
ADD_SYM( "GetModuleHandleA" );
|
||||||
/* fall through */
|
/* fall through */
|
||||||
case SPEC_MODE_DLL:
|
case SPEC_MODE_CUIEXE_UNICODE:
|
||||||
case SPEC_MODE_GUIEXE_NO_MAIN:
|
ADD_SYM( "__wine_get_wmain_args" );
|
||||||
case SPEC_MODE_CUIEXE_NO_MAIN:
|
ADD_SYM( "ExitProcess" );
|
||||||
ADD_SYM( "RtlRaiseException" );
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
ADD_SYM( "RtlRaiseException" );
|
||||||
|
|
||||||
if (count)
|
if (count)
|
||||||
{
|
{
|
||||||
for (i = 0; i < count; i++) add_undef_symbol( extras[i] );
|
for (i = 0; i < count; i++) add_undef_symbol( extras[i] );
|
||||||
|
|
|
@ -560,9 +560,9 @@ SPEC_TYPE ParseTopLevel( FILE *file )
|
||||||
if (!strcmp(token, "dll" )) SpecMode = SPEC_MODE_DLL;
|
if (!strcmp(token, "dll" )) SpecMode = SPEC_MODE_DLL;
|
||||||
else if (!strcmp(token, "guiexe" )) SpecMode = SPEC_MODE_GUIEXE;
|
else if (!strcmp(token, "guiexe" )) SpecMode = SPEC_MODE_GUIEXE;
|
||||||
else if (!strcmp(token, "cuiexe" )) SpecMode = SPEC_MODE_CUIEXE;
|
else if (!strcmp(token, "cuiexe" )) SpecMode = SPEC_MODE_CUIEXE;
|
||||||
else if (!strcmp(token, "guiexe_no_main" )) SpecMode = SPEC_MODE_GUIEXE_NO_MAIN;
|
else if (!strcmp(token, "guiexe_unicode" )) SpecMode = SPEC_MODE_GUIEXE_UNICODE;
|
||||||
else if (!strcmp(token, "cuiexe_no_main" )) SpecMode = SPEC_MODE_CUIEXE_NO_MAIN;
|
else if (!strcmp(token, "cuiexe_unicode" )) SpecMode = SPEC_MODE_CUIEXE_UNICODE;
|
||||||
else fatal_error( "Mode must be 'dll', 'guiexe', 'cuiexe', 'guiexe_no_main' or 'cuiexe_no_main'\n" );
|
else fatal_error( "Mode must be 'dll', 'guiexe', 'cuiexe', 'guiexe_unicode' or 'cuiexe_unicode'\n" );
|
||||||
}
|
}
|
||||||
else if (strcmp(token, "heap") == 0)
|
else if (strcmp(token, "heap") == 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -341,15 +341,16 @@ static void output_stub_funcs( FILE *outfile )
|
||||||
if (odp->type != TYPE_STUB) continue;
|
if (odp->type != TYPE_STUB) continue;
|
||||||
fprintf( outfile, "#ifdef __GNUC__\n" );
|
fprintf( outfile, "#ifdef __GNUC__\n" );
|
||||||
fprintf( outfile, "static void __wine_unimplemented( const char *func ) __attribute__((noreturn));\n" );
|
fprintf( outfile, "static void __wine_unimplemented( const char *func ) __attribute__((noreturn));\n" );
|
||||||
fprintf( outfile, "#endif\n" );
|
fprintf( outfile, "#endif\n\n" );
|
||||||
|
fprintf( outfile, "struct exc_record {\n" );
|
||||||
|
fprintf( outfile, " unsigned int code, flags;\n" );
|
||||||
|
fprintf( outfile, " void *rec, *addr;\n" );
|
||||||
|
fprintf( outfile, " unsigned int params;\n" );
|
||||||
|
fprintf( outfile, " const void *info[15];\n" );
|
||||||
|
fprintf( outfile, "};\n\n" );
|
||||||
|
fprintf( outfile, "extern void __stdcall RtlRaiseException( struct exc_record * );\n\n" );
|
||||||
fprintf( outfile, "static void __wine_unimplemented( const char *func )\n{\n" );
|
fprintf( outfile, "static void __wine_unimplemented( const char *func )\n{\n" );
|
||||||
fprintf( outfile, " struct exc_record {\n" );
|
fprintf( outfile, " struct exc_record rec;\n" );
|
||||||
fprintf( outfile, " unsigned int code, flags;\n" );
|
|
||||||
fprintf( outfile, " void *rec, *addr;\n" );
|
|
||||||
fprintf( outfile, " unsigned int params;\n" );
|
|
||||||
fprintf( outfile, " const void *info[15];\n" );
|
|
||||||
fprintf( outfile, " } rec;\n" );
|
|
||||||
fprintf( outfile, " extern void __stdcall RtlRaiseException( struct exc_record * );\n\n" );
|
|
||||||
fprintf( outfile, " rec.code = 0x%08x;\n", EXCEPTION_WINE_STUB );
|
fprintf( outfile, " rec.code = 0x%08x;\n", EXCEPTION_WINE_STUB );
|
||||||
fprintf( outfile, " rec.flags = %d;\n", EH_NONCONTINUABLE );
|
fprintf( outfile, " rec.flags = %d;\n", EH_NONCONTINUABLE );
|
||||||
fprintf( outfile, " rec.rec = 0;\n" );
|
fprintf( outfile, " rec.rec = 0;\n" );
|
||||||
|
@ -414,7 +415,7 @@ void BuildSpec32File( FILE *outfile )
|
||||||
{
|
{
|
||||||
int exports_size = 0;
|
int exports_size = 0;
|
||||||
int nr_exports, nr_imports, nr_resources, nr_debug;
|
int nr_exports, nr_imports, nr_resources, nr_debug;
|
||||||
int characteristics, subsystem, has_imports;
|
int characteristics, subsystem;
|
||||||
const char *init_func;
|
const char *init_func;
|
||||||
DWORD page_size;
|
DWORD page_size;
|
||||||
|
|
||||||
|
@ -431,7 +432,7 @@ void BuildSpec32File( FILE *outfile )
|
||||||
AssignOrdinals();
|
AssignOrdinals();
|
||||||
nr_exports = Base <= Limit ? Limit - Base + 1 : 0;
|
nr_exports = Base <= Limit ? Limit - Base + 1 : 0;
|
||||||
|
|
||||||
has_imports = resolve_imports( outfile );
|
resolve_imports( outfile );
|
||||||
|
|
||||||
fprintf( outfile, "/* File generated automatically from %s; do not edit! */\n\n",
|
fprintf( outfile, "/* File generated automatically from %s; do not edit! */\n\n",
|
||||||
input_file_name );
|
input_file_name );
|
||||||
|
@ -503,9 +504,9 @@ void BuildSpec32File( FILE *outfile )
|
||||||
"\n#include <winbase.h>\n"
|
"\n#include <winbase.h>\n"
|
||||||
"int _ARGC;\n"
|
"int _ARGC;\n"
|
||||||
"char **_ARGV;\n"
|
"char **_ARGV;\n"
|
||||||
|
"extern int __stdcall %s(HINSTANCE,HINSTANCE,LPSTR,INT);\n"
|
||||||
"static void __wine_exe_main(void)\n"
|
"static void __wine_exe_main(void)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" extern int PASCAL %s(HINSTANCE,HINSTANCE,LPSTR,INT);\n"
|
|
||||||
" extern int __wine_get_main_args( char ***argv );\n"
|
" extern int __wine_get_main_args( char ***argv );\n"
|
||||||
" STARTUPINFOA info;\n"
|
" STARTUPINFOA info;\n"
|
||||||
" LPSTR cmdline = GetCommandLineA();\n"
|
" LPSTR cmdline = GetCommandLineA();\n"
|
||||||
|
@ -516,47 +517,62 @@ void BuildSpec32File( FILE *outfile )
|
||||||
" _ARGC = __wine_get_main_args( &_ARGV );\n"
|
" _ARGC = __wine_get_main_args( &_ARGV );\n"
|
||||||
" ExitProcess( %s( GetModuleHandleA(0), 0, cmdline, info.wShowWindow ) );\n"
|
" ExitProcess( %s( GetModuleHandleA(0), 0, cmdline, info.wShowWindow ) );\n"
|
||||||
"}\n\n", init_func, init_func );
|
"}\n\n", init_func, init_func );
|
||||||
if (!has_imports)
|
init_func = "__wine_exe_main";
|
||||||
fprintf( outfile,
|
subsystem = IMAGE_SUBSYSTEM_WINDOWS_GUI;
|
||||||
"int main( int argc, char *argv[] )\n"
|
break;
|
||||||
"{\n"
|
case SPEC_MODE_GUIEXE_UNICODE:
|
||||||
" extern void PROCESS_InitWinelib( int, char ** );\n"
|
if (!init_func) init_func = "WinMain";
|
||||||
" PROCESS_InitWinelib( argc, argv );\n"
|
fprintf( outfile,
|
||||||
" return 1;\n"
|
"\n#include <winbase.h>\n"
|
||||||
"}\n\n" );
|
"int _ARGC;\n"
|
||||||
|
"WCHAR **_ARGV;\n"
|
||||||
|
"extern int __stdcall %s(HINSTANCE,HINSTANCE,LPSTR,INT);\n"
|
||||||
|
"static void __wine_exe_main(void)\n"
|
||||||
|
"{\n"
|
||||||
|
" extern int __wine_get_wmain_args( WCHAR ***argv );\n"
|
||||||
|
" STARTUPINFOA info;\n"
|
||||||
|
" LPSTR cmdline = GetCommandLineA();\n"
|
||||||
|
" while (*cmdline && *cmdline != ' ') cmdline++;\n"
|
||||||
|
" if (*cmdline) cmdline++;\n"
|
||||||
|
" GetStartupInfoA( &info );\n"
|
||||||
|
" if (!(info.dwFlags & STARTF_USESHOWWINDOW)) info.wShowWindow = 1;\n"
|
||||||
|
" _ARGC = __wine_get_wmain_args( &_ARGV );\n"
|
||||||
|
" ExitProcess( %s( GetModuleHandleA(0), 0, cmdline, info.wShowWindow ) );\n"
|
||||||
|
"}\n\n", init_func, init_func );
|
||||||
init_func = "__wine_exe_main";
|
init_func = "__wine_exe_main";
|
||||||
subsystem = IMAGE_SUBSYSTEM_WINDOWS_GUI;
|
subsystem = IMAGE_SUBSYSTEM_WINDOWS_GUI;
|
||||||
break;
|
break;
|
||||||
case SPEC_MODE_CUIEXE:
|
case SPEC_MODE_CUIEXE:
|
||||||
if (!init_func) init_func = has_imports ? "main" : "wine_main";
|
if (!init_func) init_func = "main";
|
||||||
fprintf( outfile,
|
fprintf( outfile,
|
||||||
"\nint _ARGC;\n"
|
"\nint _ARGC;\n"
|
||||||
"char **_ARGV;\n"
|
"char **_ARGV;\n"
|
||||||
|
"extern void __stdcall ExitProcess(int);\n"
|
||||||
"static void __wine_exe_main(void)\n"
|
"static void __wine_exe_main(void)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" extern int %s( int argc, char *argv[] );\n"
|
" extern int %s( int argc, char *argv[] );\n"
|
||||||
" extern int __wine_get_main_args( char ***argv );\n"
|
" extern int __wine_get_main_args( char ***argv );\n"
|
||||||
" extern void __stdcall ExitProcess(int);\n"
|
|
||||||
" _ARGC = __wine_get_main_args( &_ARGV );\n"
|
" _ARGC = __wine_get_main_args( &_ARGV );\n"
|
||||||
" ExitProcess( %s( _ARGC, _ARGV ) );\n"
|
" ExitProcess( %s( _ARGC, _ARGV ) );\n"
|
||||||
"}\n\n", init_func, init_func );
|
"}\n\n", init_func, init_func );
|
||||||
if (!has_imports)
|
|
||||||
fprintf( outfile,
|
|
||||||
"int main( int argc, char *argv[] )\n"
|
|
||||||
"{\n"
|
|
||||||
" extern void PROCESS_InitWinelib( int, char ** );\n"
|
|
||||||
" PROCESS_InitWinelib( argc, argv );\n"
|
|
||||||
" return 1;\n"
|
|
||||||
"}\n\n" );
|
|
||||||
init_func = "__wine_exe_main";
|
init_func = "__wine_exe_main";
|
||||||
subsystem = IMAGE_SUBSYSTEM_WINDOWS_CUI;
|
subsystem = IMAGE_SUBSYSTEM_WINDOWS_CUI;
|
||||||
break;
|
break;
|
||||||
case SPEC_MODE_GUIEXE_NO_MAIN:
|
case SPEC_MODE_CUIEXE_UNICODE:
|
||||||
if (init_func) fprintf( outfile, "extern void %s();\n", init_func );
|
if (!init_func) init_func = "wmain";
|
||||||
subsystem = IMAGE_SUBSYSTEM_WINDOWS_GUI;
|
fprintf( outfile,
|
||||||
break;
|
"\ntypedef unsigned short WCHAR;\n"
|
||||||
case SPEC_MODE_CUIEXE_NO_MAIN:
|
"int _ARGC;\n"
|
||||||
if (init_func) fprintf( outfile, "extern void %s();\n", init_func );
|
"WCHAR **_ARGV;\n"
|
||||||
|
"extern void __stdcall ExitProcess(int);\n"
|
||||||
|
"static void __wine_exe_main(void)\n"
|
||||||
|
"{\n"
|
||||||
|
" extern int %s( int argc, WCHAR *argv[] );\n"
|
||||||
|
" extern int __wine_get_wmain_args( WCHAR ***argv );\n"
|
||||||
|
" _ARGC = __wine_get_wmain_args( &_ARGV );\n"
|
||||||
|
" ExitProcess( %s( _ARGC, _ARGV ) );\n"
|
||||||
|
"}\n\n", init_func, init_func );
|
||||||
|
init_func = "__wine_exe_main";
|
||||||
subsystem = IMAGE_SUBSYSTEM_WINDOWS_CUI;
|
subsystem = IMAGE_SUBSYSTEM_WINDOWS_CUI;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue