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
|
||||
@ cdecl __wine_get_main_args(ptr) __wine_get_main_args
|
||||
@ cdecl __wine_get_wmain_args(ptr) __wine_get_wmain_args
|
||||
|
||||
# Server interface
|
||||
@ cdecl -norelay wine_server_call(long) wine_server_call
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <stdlib.h>
|
||||
|
||||
#include "winbase.h"
|
||||
#include "winnls.h"
|
||||
#include "wine/library.h"
|
||||
#include "options.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 char **app_argv;
|
||||
static WCHAR **app_wargv;
|
||||
|
||||
static void out_of_memory(void) WINE_NORETURN;
|
||||
static void out_of_memory(void)
|
||||
|
@ -358,3 +360,35 @@ int __wine_get_main_args( char ***argv )
|
|||
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
|
||||
*/
|
||||
void wine_initial_task(void)
|
||||
int WINAPI wine_initial_task( HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, INT show )
|
||||
{
|
||||
MSG msg;
|
||||
HINSTANCE16 instance;
|
||||
STARTUPINFOA info;
|
||||
|
||||
if (!LoadLibraryA( "user32.dll" ))
|
||||
{
|
||||
|
@ -31,10 +30,7 @@ void wine_initial_task(void)
|
|||
}
|
||||
THUNK_InitCallout();
|
||||
|
||||
GetStartupInfoA( &info );
|
||||
if (!(info.dwFlags & STARTF_USESHOWWINDOW)) info.wShowWindow = SW_SHOWNORMAL;
|
||||
|
||||
if ((instance = WinExec16( GetCommandLineA(), info.wShowWindow )) < 32)
|
||||
if ((instance = WinExec16( GetCommandLineA(), show )) < 32)
|
||||
{
|
||||
if (instance == 11) /* try DOS format */
|
||||
{
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
name wine
|
||||
mode cuiexe_no_main
|
||||
mode guiexe
|
||||
type win32
|
||||
init wine_initial_task
|
||||
|
||||
|
|
|
@ -4,11 +4,13 @@
|
|||
name NAME
|
||||
type win16|win32
|
||||
[file WINFILENAME]
|
||||
[mode dll|cuiexe|guiexe]
|
||||
[mode dll|cuiexe|guiexe|cuiexe_unicode|guiexe_unicode]
|
||||
[heap SIZE]
|
||||
[init FUNCTION]
|
||||
[import DLL]
|
||||
[rsrc RESFILE]
|
||||
[debug_channels ([CHANNEL [CHANNEL...]])]
|
||||
[ignore ([SYMBOL [SYMBOL...]])]
|
||||
|
||||
ORDINAL FUNCTYPE [FLAGS] EXPORTNAME([ARGTYPE [ARGTYPE [...]]]) HANDLERNAME
|
||||
|
||||
|
@ -51,6 +53,11 @@ times.
|
|||
|
||||
"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
|
||||
point, or "@" for automatic ordinal allocation (Win32 only).
|
||||
|
||||
|
|
|
@ -60,8 +60,8 @@ typedef enum
|
|||
SPEC_MODE_DLL,
|
||||
SPEC_MODE_GUIEXE,
|
||||
SPEC_MODE_CUIEXE,
|
||||
SPEC_MODE_GUIEXE_NO_MAIN,
|
||||
SPEC_MODE_CUIEXE_NO_MAIN
|
||||
SPEC_MODE_GUIEXE_UNICODE,
|
||||
SPEC_MODE_CUIEXE_UNICODE
|
||||
} SPEC_MODE;
|
||||
|
||||
typedef struct
|
||||
|
|
|
@ -205,6 +205,8 @@ static void add_extra_undef_symbols(void)
|
|||
/* add symbols that will be contained in the spec file itself */
|
||||
switch (SpecMode)
|
||||
{
|
||||
case SPEC_MODE_DLL:
|
||||
break;
|
||||
case SPEC_MODE_GUIEXE:
|
||||
ADD_SYM( "GetCommandLineA" );
|
||||
ADD_SYM( "GetStartupInfoA" );
|
||||
|
@ -213,13 +215,19 @@ static void add_extra_undef_symbols(void)
|
|||
case SPEC_MODE_CUIEXE:
|
||||
ADD_SYM( "__wine_get_main_args" );
|
||||
ADD_SYM( "ExitProcess" );
|
||||
break;
|
||||
case SPEC_MODE_GUIEXE_UNICODE:
|
||||
ADD_SYM( "GetCommandLineA" );
|
||||
ADD_SYM( "GetStartupInfoA" );
|
||||
ADD_SYM( "GetModuleHandleA" );
|
||||
/* fall through */
|
||||
case SPEC_MODE_DLL:
|
||||
case SPEC_MODE_GUIEXE_NO_MAIN:
|
||||
case SPEC_MODE_CUIEXE_NO_MAIN:
|
||||
ADD_SYM( "RtlRaiseException" );
|
||||
case SPEC_MODE_CUIEXE_UNICODE:
|
||||
ADD_SYM( "__wine_get_wmain_args" );
|
||||
ADD_SYM( "ExitProcess" );
|
||||
break;
|
||||
}
|
||||
ADD_SYM( "RtlRaiseException" );
|
||||
|
||||
if (count)
|
||||
{
|
||||
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;
|
||||
else if (!strcmp(token, "guiexe" )) SpecMode = SPEC_MODE_GUIEXE;
|
||||
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, "cuiexe_no_main" )) SpecMode = SPEC_MODE_CUIEXE_NO_MAIN;
|
||||
else fatal_error( "Mode must be 'dll', 'guiexe', 'cuiexe', 'guiexe_no_main' or 'cuiexe_no_main'\n" );
|
||||
else if (!strcmp(token, "guiexe_unicode" )) SpecMode = SPEC_MODE_GUIEXE_UNICODE;
|
||||
else if (!strcmp(token, "cuiexe_unicode" )) SpecMode = SPEC_MODE_CUIEXE_UNICODE;
|
||||
else fatal_error( "Mode must be 'dll', 'guiexe', 'cuiexe', 'guiexe_unicode' or 'cuiexe_unicode'\n" );
|
||||
}
|
||||
else if (strcmp(token, "heap") == 0)
|
||||
{
|
||||
|
|
|
@ -341,15 +341,16 @@ static void output_stub_funcs( FILE *outfile )
|
|||
if (odp->type != TYPE_STUB) continue;
|
||||
fprintf( outfile, "#ifdef __GNUC__\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, " 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, " } rec;\n" );
|
||||
fprintf( outfile, " extern void __stdcall RtlRaiseException( struct exc_record * );\n\n" );
|
||||
fprintf( outfile, " struct exc_record rec;\n" );
|
||||
fprintf( outfile, " rec.code = 0x%08x;\n", EXCEPTION_WINE_STUB );
|
||||
fprintf( outfile, " rec.flags = %d;\n", EH_NONCONTINUABLE );
|
||||
fprintf( outfile, " rec.rec = 0;\n" );
|
||||
|
@ -414,7 +415,7 @@ void BuildSpec32File( FILE *outfile )
|
|||
{
|
||||
int exports_size = 0;
|
||||
int nr_exports, nr_imports, nr_resources, nr_debug;
|
||||
int characteristics, subsystem, has_imports;
|
||||
int characteristics, subsystem;
|
||||
const char *init_func;
|
||||
DWORD page_size;
|
||||
|
||||
|
@ -431,7 +432,7 @@ void BuildSpec32File( FILE *outfile )
|
|||
AssignOrdinals();
|
||||
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",
|
||||
input_file_name );
|
||||
|
@ -503,9 +504,9 @@ void BuildSpec32File( FILE *outfile )
|
|||
"\n#include <winbase.h>\n"
|
||||
"int _ARGC;\n"
|
||||
"char **_ARGV;\n"
|
||||
"extern int __stdcall %s(HINSTANCE,HINSTANCE,LPSTR,INT);\n"
|
||||
"static void __wine_exe_main(void)\n"
|
||||
"{\n"
|
||||
" extern int PASCAL %s(HINSTANCE,HINSTANCE,LPSTR,INT);\n"
|
||||
" extern int __wine_get_main_args( char ***argv );\n"
|
||||
" STARTUPINFOA info;\n"
|
||||
" LPSTR cmdline = GetCommandLineA();\n"
|
||||
|
@ -516,47 +517,62 @@ void BuildSpec32File( FILE *outfile )
|
|||
" _ARGC = __wine_get_main_args( &_ARGV );\n"
|
||||
" ExitProcess( %s( GetModuleHandleA(0), 0, cmdline, info.wShowWindow ) );\n"
|
||||
"}\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";
|
||||
subsystem = IMAGE_SUBSYSTEM_WINDOWS_GUI;
|
||||
break;
|
||||
case SPEC_MODE_GUIEXE_UNICODE:
|
||||
if (!init_func) init_func = "WinMain";
|
||||
fprintf( outfile,
|
||||
"\n#include <winbase.h>\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";
|
||||
subsystem = IMAGE_SUBSYSTEM_WINDOWS_GUI;
|
||||
break;
|
||||
case SPEC_MODE_CUIEXE:
|
||||
if (!init_func) init_func = has_imports ? "main" : "wine_main";
|
||||
if (!init_func) init_func = "main";
|
||||
fprintf( outfile,
|
||||
"\nint _ARGC;\n"
|
||||
"char **_ARGV;\n"
|
||||
"extern void __stdcall ExitProcess(int);\n"
|
||||
"static void __wine_exe_main(void)\n"
|
||||
"{\n"
|
||||
" extern int %s( int argc, 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"
|
||||
" ExitProcess( %s( _ARGC, _ARGV ) );\n"
|
||||
"}\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";
|
||||
subsystem = IMAGE_SUBSYSTEM_WINDOWS_CUI;
|
||||
break;
|
||||
case SPEC_MODE_GUIEXE_NO_MAIN:
|
||||
if (init_func) fprintf( outfile, "extern void %s();\n", init_func );
|
||||
subsystem = IMAGE_SUBSYSTEM_WINDOWS_GUI;
|
||||
break;
|
||||
case SPEC_MODE_CUIEXE_NO_MAIN:
|
||||
if (init_func) fprintf( outfile, "extern void %s();\n", init_func );
|
||||
case SPEC_MODE_CUIEXE_UNICODE:
|
||||
if (!init_func) init_func = "wmain";
|
||||
fprintf( outfile,
|
||||
"\ntypedef unsigned short WCHAR;\n"
|
||||
"int _ARGC;\n"
|
||||
"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;
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue