Commit 9ffd4030 authored by Ulrich Weigand's avatar Ulrich Weigand Committed by Alexandre Julliard

Added .spec keyword 'mode' to allow creating built-in EXE modules.

Use built-in EXE modules for WineLib apps (instead of ELF modules). Removed dummy ELF module creation. Removed LIBRES handling.
parent d3d6c4ed
......@@ -25,6 +25,7 @@ typedef struct
const unsigned int *argtypes; /* Pointer to argument types bitmask */
const char * const *imports; /* Pointer to imports */
const ENTRYPOINT32 dllentrypoint;/* Pointer to LibMain function */
int characteristics;
const void *rsrc; /* Resource descriptor */
} BUILTIN32_DESCRIPTOR;
......
/*
* WINElib-Resources
*/
#ifndef __WINE_LIBRES_H
#define __WINE_LIBRES_H
#include "windef.h"
extern HRSRC LIBRES_FindResource( HINSTANCE hModule, LPCWSTR name, LPCWSTR type );
extern HGLOBAL LIBRES_LoadResource( HINSTANCE hModule, HRSRC hRsrc );
extern DWORD LIBRES_SizeofResource( HINSTANCE hModule, HRSRC hRsrc );
#endif /* __WINE_LIBRES_H */
......@@ -236,6 +236,7 @@ HGLOBAL16 NE_LoadPEResource( NE_MODULE *pModule, WORD type, LPVOID bits, DWORD s
/* relay32/builtin.c */
extern WINE_MODREF *BUILTIN32_LoadLibraryExA(LPCSTR name, DWORD flags, DWORD *err);
extern HMODULE16 BUILTIN32_LoadExeModule(void);
extern void BUILTIN32_UnloadLibrary(WINE_MODREF *wm);
#endif /* __WINE_MODULE_H */
......@@ -64,7 +64,6 @@ typedef struct {
ELF_STDCALL_STUB *stubs;
} ELF_MODREF;
extern struct _wine_modref *ELF_CreateDummyModule(LPCSTR,LPCSTR);
extern struct _wine_modref *ELF_LoadLibraryExA( LPCSTR libname, DWORD flags, DWORD *err);
extern void ELF_UnloadLibrary(struct _wine_modref *);
extern FARPROC ELF_FindExportedFunction(struct _wine_modref *wm, LPCSTR funcName);
......
......@@ -10,31 +10,6 @@
#include "windef.h"
#include "wrc_rsc.h"
/*
* BS: I comment this out to catch all occurences
* of reference to this structure which is now
* rendered obsolete.
*
* struct resource
* {
* int id;
* int type;
* const char *name;
* const unsigned char* bytes;
* unsigned size;
* };
*/
/* Built-in resources */
typedef enum
{
SYSRES_MENU_SYSMENU,
SYSRES_MENU_EDITMENU,
SYSRES_DIALOG_MSGBOX
} SYSTEM_RESOURCE;
extern void LIBRES_RegisterResources(const wrc_resource32_t * const * Res);
#if defined(__GNUC__) && ((__GNUC__ > 2) || ((__GNUC__ == 2) && (__GNUC_MINOR__ >= 7)))
#define WINE_CONSTRUCTOR __attribute__((constructor))
#define HAVE_WINE_CONSTRUCTOR
......@@ -43,8 +18,4 @@ extern void LIBRES_RegisterResources(const wrc_resource32_t * const * Res);
#undef HAVE_WINE_CONSTRUCTOR
#endif
extern HGLOBAL16 SYSRES_LoadResource( SYSTEM_RESOURCE id );
extern void SYSRES_FreeResource( HGLOBAL16 handle );
extern LPCVOID SYSRES_GetResPtr( SYSTEM_RESOURCE id );
#endif /* __WINE_RESOURCE_H */
......@@ -8,7 +8,6 @@ MODULE = loader
C_SRCS = \
elf.c \
elfdll.c \
libres.c \
loadorder.c \
main.c \
module.c \
......
......@@ -29,7 +29,16 @@
DEFAULT_DEBUG_CHANNEL(win32)
WINE_MODREF *ELF_CreateDummyModule( LPCSTR libname, LPCSTR modname )
#if defined(HAVE_DL_API)
#define UNIX_DLL_ENDING "so"
#define STUBSIZE 4095
#include <dlfcn.h>
static WINE_MODREF *ELF_CreateDummyModule( LPCSTR libname, LPCSTR modname )
{
PIMAGE_DOS_HEADER dh;
PIMAGE_NT_HEADERS nth;
......@@ -93,15 +102,6 @@ WINE_MODREF *ELF_CreateDummyModule( LPCSTR libname, LPCSTR modname )
return wm;
}
#if defined(HAVE_DL_API)
#define UNIX_DLL_ENDING "so"
#define STUBSIZE 4095
#include <dlfcn.h>
WINE_MODREF *ELF_LoadLibraryExA( LPCSTR libname, DWORD flags, DWORD *err)
{
WINE_MODREF *wm;
......
/*
* WINElib-Resources
*
* Copied and modified heavily from loader/resource.c
*/
#include <stdlib.h>
#include "wine/winestring.h"
#include "libres.h"
#include "resource.h"
#include "debugtools.h"
#include "heap.h"
#include "crtdll.h"
#include "xmalloc.h"
DEFAULT_DEBUG_CHANNEL(resource)
typedef struct RLE
{
const wrc_resource32_t * const * Resources; /* NULL-terminated array of pointers */
struct RLE* next;
} ResListE;
static ResListE* ResourceList=NULL;
void LIBRES_RegisterResources(const wrc_resource32_t * const * Res)
{
ResListE** Curr;
ResListE* n;
for(Curr=&ResourceList; *Curr; Curr=&((*Curr)->next)) { }
n=xmalloc(sizeof(ResListE));
n->Resources=Res;
n->next=NULL;
*Curr=n;
}
/**********************************************************************
* LIBRES_FindResource
*/
typedef int (*CmpFunc_t)(LPCWSTR a, LPCWSTR b, int c);
int CompareOrdinal(LPCWSTR ordinal, LPCWSTR resstr, int resid)
{
return !resstr && (resid == LOWORD(ordinal));
}
int CompareName(LPCWSTR name, LPCWSTR resstr, int resid)
{
return resstr && !CRTDLL__wcsnicmp(resstr+1, name, *(resstr));
}
HRSRC LIBRES_FindResource( HINSTANCE hModule, LPCWSTR name, LPCWSTR type )
{
LPCWSTR nameid = name, typeid = type;
ResListE* ResBlock;
const wrc_resource32_t* const * Res;
CmpFunc_t EqualNames = CompareOrdinal;
CmpFunc_t EqualTypes = CompareOrdinal;
if(HIWORD(name))
{
if(*name=='#')
{
LPSTR nameA = HEAP_strdupWtoA( GetProcessHeap(), 0, name );
nameid = (LPCWSTR) atoi(nameA+1);
HeapFree( GetProcessHeap(), 0, nameA );
}
else
EqualNames = CompareName;
}
if(HIWORD(type))
{
if(*type=='#')
{
LPSTR typeA = HEAP_strdupWtoA( GetProcessHeap(), 0, type );
typeid= (LPCWSTR) atoi(typeA+1);
HeapFree( GetProcessHeap(), 0, typeA );
}
else
EqualTypes = CompareName;
}
for(ResBlock=ResourceList; ResBlock; ResBlock=ResBlock->next)
for(Res=ResBlock->Resources; *Res; Res++)
if (EqualNames(nameid, (*Res)->resname, (*Res)->resid) &&
EqualTypes(typeid, (*Res)->restypename, (*Res)->restype))
return (HRSRC)*Res;
return 0;
}
/**********************************************************************
* LIBRES_LoadResource
*/
HGLOBAL LIBRES_LoadResource( HINSTANCE hModule, HRSRC hRsrc )
{
return (HGLOBAL)(((wrc_resource32_t*)hRsrc)->data);
}
/**********************************************************************
* LIBRES_SizeofResource
*/
DWORD LIBRES_SizeofResource( HINSTANCE hModule, HRSRC hRsrc )
{
return (DWORD)(((wrc_resource32_t*)hRsrc)->datasize);
}
......@@ -9,6 +9,7 @@
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
#include "wine/winbase16.h"
#include "wine/winuser16.h"
#include "bitmap.h"
......@@ -292,25 +293,27 @@ BOOL WINAPI MAIN_UserInit(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserve
*/
HINSTANCE MAIN_WinelibInit( int *argc, char *argv[] )
{
WINE_MODREF *wm;
NE_MODULE *pModule;
HMODULE16 hModule;
/* Main initialization */
if (!MAIN_MainInit( argc, argv, TRUE )) return 0;
/* Create and switch to initial task */
if (!(wm = ELF_CreateDummyModule( argv[0], argv[0] )))
return 0;
PROCESS_Current()->exe_modref = wm;
if ((hModule = MODULE_CreateDummyModule( wm->filename, 0 )) < 32) return 0;
/* Load WineLib EXE module */
if ( (hModule = BUILTIN32_LoadExeModule()) < 32 ) return 0;
pModule = (NE_MODULE *)GlobalLock16( hModule );
pModule->flags = NE_FFLAGS_WIN32;
pModule->module32 = wm->module;
/* Create initial task */
if (!TASK_Create( pModule, FALSE )) return 0;
/* Create 32-bit MODREF */
if ( !PE_CreateModule( pModule->module32, NE_MODULE_NAME(pModule), 0, FALSE ) )
return 0;
/* Increment EXE refcount */
assert( PROCESS_Current()->exe_modref );
PROCESS_Current()->exe_modref->refCount++;
/* Load system DLLs into the initial process (and initialize them) */
if ( !LoadLibrary16("GDI.EXE" ) || !LoadLibraryA("GDI32.DLL" )
|| !LoadLibrary16("USER.EXE") || !LoadLibraryA("USER32.DLL"))
......@@ -319,7 +322,7 @@ HINSTANCE MAIN_WinelibInit( int *argc, char *argv[] )
/* Get pointers to USER routines called by KERNEL */
THUNK_InitCallout();
return wm->module;
return pModule->module32;
}
/***********************************************************************
......
......@@ -19,7 +19,6 @@
#include "heap.h"
#include "task.h"
#include "process.h"
#include "libres.h"
#include "stackframe.h"
#include "neexe.h"
#include "crtdll.h"
......
......@@ -28,7 +28,6 @@
#include "module.h"
#include "file.h"
#include "debugtools.h"
#include "libres.h"
#include "winerror.h"
#include "winnls.h"
......@@ -151,7 +150,7 @@ static HRSRC RES_FindResource( HMODULE hModule, LPCSTR type,
if ( wm )
{
/* 32-bit PE/ELF module */
/* 32-bit PE module */
LPWSTR typeStr, nameStr;
if ( HIWORD( type ) && !bUnicode )
......@@ -163,20 +162,7 @@ static HRSRC RES_FindResource( HMODULE hModule, LPCSTR type,
else
nameStr = (LPWSTR)name;
switch ( wm->type )
{
case MODULE32_PE:
hRsrc = PE_FindResourceExW( wm, nameStr, typeStr, lang );
break;
case MODULE32_ELF:
hRsrc = LIBRES_FindResource( hModule, nameStr, typeStr );
break;
default:
ERR("unknown module type %d\n", wm->type );
break;
}
hRsrc = PE_FindResourceExW( wm, nameStr, typeStr, lang );
if ( HIWORD( type ) && !bUnicode )
HeapFree( GetProcessHeap(), 0, typeStr );
......@@ -237,25 +223,12 @@ static DWORD RES_SizeofResource( HMODULE hModule, HRSRC hRsrc, BOOL bRet16 )
if ( wm )
{
/* 32-bit PE/ELF module */
/* 32-bit PE module */
/* If we got a 16-bit hRsrc, convert it */
HRSRC hRsrc32 = HIWORD(hRsrc)? hRsrc : MapHRsrc16To32( pModule, hRsrc );
switch ( wm->type )
{
case MODULE32_PE:
size = PE_SizeofResource( hModule, hRsrc32 );
break;
case MODULE32_ELF:
size = LIBRES_SizeofResource( hModule, hRsrc32 );
break;
default:
ERR("unknown module type %d\n", wm->type );
break;
}
size = PE_SizeofResource( hModule, hRsrc32 );
}
else
{
......@@ -288,7 +261,7 @@ static HFILE RES_AccessResource( HMODULE hModule, HRSRC hRsrc, BOOL bRet16 )
if ( wm )
{
/* 32-bit PE/ELF module */
/* 32-bit PE module */
#if 0
/* If we got a 16-bit hRsrc, convert it */
HRSRC hRsrc32 = HIWORD(hRsrc)? hRsrc : MapHRsrc16To32( pModule, hRsrc );
......@@ -336,25 +309,12 @@ static HGLOBAL RES_LoadResource( HMODULE hModule, HRSRC hRsrc, BOOL bRet16 )
if ( wm )
{
/* 32-bit PE/ELF module */
/* 32-bit PE module */
/* If we got a 16-bit hRsrc, convert it */
HRSRC hRsrc32 = HIWORD(hRsrc)? hRsrc : MapHRsrc16To32( pModule, hRsrc );
switch ( wm->type )
{
case MODULE32_PE:
hMem = PE_LoadResource( wm, hRsrc32 );
break;
case MODULE32_ELF:
hMem = LIBRES_LoadResource( hModule, hRsrc32 );
break;
default:
ERR("unknown module type %d\n", wm->type );
break;
}
hMem = PE_LoadResource( wm, hRsrc32 );
/* If we need to return a 16-bit resource, convert it */
if ( bRet16 )
......
......@@ -129,7 +129,7 @@ static HMODULE BUILTIN32_DoLoadImage( const BUILTIN32_DESCRIPTOR *descr )
nt->FileHeader.Machine = IMAGE_FILE_MACHINE_I386;
nt->FileHeader.NumberOfSections = nb_sections;
nt->FileHeader.SizeOfOptionalHeader = sizeof(nt->OptionalHeader);
nt->FileHeader.Characteristics = IMAGE_FILE_DLL;
nt->FileHeader.Characteristics = descr->characteristics;
nt->OptionalHeader.Magic = IMAGE_NT_OPTIONAL_HDR_MAGIC;
nt->OptionalHeader.SizeOfCode = 0x1000;
......@@ -391,6 +391,49 @@ WINE_MODREF *BUILTIN32_LoadLibraryExA(LPCSTR path, DWORD flags, DWORD *err)
return wm;
}
/***********************************************************************
* BUILTIN32_LoadExeModule
*/
HMODULE16 BUILTIN32_LoadExeModule( void )
{
HMODULE16 hModule16;
NE_MODULE *pModule;
int i, exe = -1;
/* Search built-in EXE descriptor */
for ( i = 0; i < nb_dlls; i++ )
if ( !(builtin_dlls[i]->characteristics & IMAGE_FILE_DLL) )
{
if ( exe != -1 )
{
MESSAGE( "More than one built-in EXE module loaded!\n" );
break;
}
exe = i;
}
if ( exe == -1 )
{
MESSAGE( "No built-in EXE module loaded! Did you create a .spec file?\n" );
return 0;
}
/* Load built-in module */
if ( !dll_modules[exe] )
if ( !(dll_modules[exe] = BUILTIN32_DoLoadImage( builtin_dlls[exe] )) )
return 0;
/* Create 16-bit dummy module */
hModule16 = MODULE_CreateDummyModule( builtin_dlls[exe]->filename, 0 );
if ( hModule16 < 32 ) return 0;
pModule = (NE_MODULE *)GlobalLock16( hModule16 );
pModule->flags = NE_FFLAGS_SINGLEDATA | NE_FFLAGS_WIN32 | NE_FFLAGS_BUILTIN;
pModule->module32 = dll_modules[exe];
return hModule16;
}
/***********************************************************************
* BUILTIN32_UnloadLibrary
......
/*
* System resources loading
*
* Copyright 1995 Alexandre Julliard
*/
#include "winbase.h"
#include "wine/winbase16.h"
#include "global.h"
#include "options.h"
#include "resource.h"
#include "wrc_rsc.h"
extern const wrc_resource32_t * const sysres_En_ResTable[];
extern const wrc_resource32_t * const sysres_Es_ResTable[];
extern const wrc_resource32_t * const sysres_De_ResTable[];
extern const wrc_resource32_t * const sysres_No_ResTable[];
extern const wrc_resource32_t * const sysres_Fr_ResTable[];
extern const wrc_resource32_t * const sysres_Fi_ResTable[];
extern const wrc_resource32_t * const sysres_Da_ResTable[];
extern const wrc_resource32_t * const sysres_Cs_ResTable[];
extern const wrc_resource32_t * const sysres_Eo_ResTable[];
extern const wrc_resource32_t * const sysres_It_ResTable[];
extern const wrc_resource32_t * const sysres_Ko_ResTable[];
extern const wrc_resource32_t * const sysres_Hu_ResTable[];
extern const wrc_resource32_t * const sysres_Pl_ResTable[];
extern const wrc_resource32_t * const sysres_Pt_ResTable[];
extern const wrc_resource32_t * const sysres_Sv_ResTable[];
extern const wrc_resource32_t * const sysres_Ca_ResTable[];
extern const wrc_resource32_t * const sysres_Nl_ResTable[];
extern const wrc_resource32_t * const sysres_Ru_ResTable[];
extern const wrc_resource32_t * const sysres_Wa_ResTable[];
static const wrc_resource32_t * const * SYSRES_Resources[] =
{
sysres_En_ResTable, /* LANG_En */
sysres_Es_ResTable, /* LANG_Es */
sysres_De_ResTable, /* LANG_De */
sysres_No_ResTable, /* LANG_No */
sysres_Fr_ResTable, /* LANG_Fr */
sysres_Fi_ResTable, /* LANG_Fi */
sysres_Da_ResTable, /* LANG_Da */
sysres_Cs_ResTable, /* LANG_Cs */
sysres_Eo_ResTable, /* LANG_Eo */
sysres_It_ResTable, /* LANG_It */
sysres_Ko_ResTable, /* LANG_Ko */
sysres_Hu_ResTable, /* LANG_Hu */
sysres_Pl_ResTable, /* LANG_Pl */
sysres_Pt_ResTable, /* LANG_Pt */
sysres_Sv_ResTable, /* LANG_Sv */
sysres_Ca_ResTable, /* LANG_Ca */
sysres_Nl_ResTable, /* LANG_Nl */
sysres_Ru_ResTable, /* LANG_Ru */
sysres_Wa_ResTable /* LANG_Wa */
};
/***********************************************************************
* SYSRES_GetResourcePtr
*
* Return a pointer to a system resource.
*/
LPCVOID SYSRES_GetResPtr( SYSTEM_RESOURCE id )
{
return SYSRES_Resources[Options.language][id]->data;
}
/***********************************************************************
* SYSRES_LoadResource
*
* Create a global memory block for a system resource.
*/
HGLOBAL16 SYSRES_LoadResource( SYSTEM_RESOURCE id )
{
const wrc_resource32_t *resPtr;
resPtr = SYSRES_Resources[Options.language][id];
return GLOBAL_CreateBlock( GMEM_FIXED, resPtr->data, resPtr->datasize,
GetCurrentPDB16(), FALSE, FALSE, TRUE, NULL );
}
/***********************************************************************
* SYSRES_FreeResource
*
* Free a global memory block for a system resource.
*/
void SYSRES_FreeResource( HGLOBAL16 handle )
{
GLOBAL_FreeBlock( handle );
}
......@@ -94,6 +94,13 @@ typedef enum
SPEC_WIN32
} SPEC_TYPE;
typedef enum
{
SPEC_MODE_DLL,
SPEC_MODE_GUIEXE,
SPEC_MODE_CUIEXE
} SPEC_MODE;
typedef struct
{
int n_values;
......@@ -144,6 +151,7 @@ static ORDDEF *Ordinals[MAX_ORDINALS];
static ORDDEF *Names[MAX_ORDINALS];
static SPEC_TYPE SpecType = SPEC_INVALID;
static SPEC_MODE SpecMode = SPEC_MODE_DLL;
static char DLLName[80];
static char DLLFileName[80];
static int Limit = 0;
......@@ -342,6 +350,8 @@ static void AssignOrdinals(void)
{
int i, ordinal;
if ( !nb_names ) return;
/* sort the list of names */
qsort( Names, nb_names, sizeof(Names[0]), name_compare );
......@@ -680,7 +690,6 @@ static void ParseTopLevel(void)
{
strcpy(DLLName, GetToken());
strupper(DLLName);
if (!DLLFileName[0]) sprintf( DLLFileName, "%s.DLL", DLLName );
}
else if (strcmp(token, "file") == 0)
{
......@@ -694,6 +703,14 @@ static void ParseTopLevel(void)
else if (!strcmp(token, "win32" )) SpecType = SPEC_WIN32;
else fatal_error( "Type must be 'win16' or 'win32'\n" );
}
else if (strcmp(token, "mode") == 0)
{
token = GetToken();
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 fatal_error( "Mode must be 'dll', 'guiexe' or 'cuiexe'\n" );
}
else if (strcmp(token, "heap") == 0)
{
token = GetToken();
......@@ -734,6 +751,12 @@ static void ParseTopLevel(void)
else
fatal_error( "Expected name, id, length or ordinal\n" );
}
if (!DLLFileName[0])
if (SpecMode == SPEC_MODE_DLL)
sprintf( DLLFileName, "%s.DLL", DLLName );
else
sprintf( DLLFileName, "%s.EXE", DLLName );
}
......@@ -998,8 +1021,10 @@ static int BuildSpec32File( FILE *outfile )
{
ORDDEF *odp;
int i, fwd_size = 0, have_regs = FALSE;
int nr_exports;
AssignOrdinals();
nr_exports = Base <= Limit ? Limit - Base + 1 : 0;
fprintf( outfile, "/* File generated automatically from %s; do not edit! */\n\n",
input_file_name );
......@@ -1072,7 +1097,7 @@ static int BuildSpec32File( FILE *outfile )
/* Output the DLL functions table */
fprintf( outfile, "\nstatic const ENTRYPOINT32 Functions[%d] =\n{\n",
Limit - Base + 1 );
nr_exports );
for (i = Base; i <= Limit; i++)
{
ORDDEF *odp = Ordinals[i];
......@@ -1126,7 +1151,7 @@ static int BuildSpec32File( FILE *outfile )
/* Output the DLL argument types */
fprintf( outfile, "static const unsigned int ArgTypes[%d] =\n{\n",
Limit - Base + 1 );
nr_exports );
for (i = Base; i <= Limit; i++)
{
ORDDEF *odp = Ordinals[i];
......@@ -1147,7 +1172,7 @@ static int BuildSpec32File( FILE *outfile )
/* Output the DLL functions arguments */
fprintf( outfile, "static const unsigned char FuncArgs[%d] =\n{\n",
Limit - Base + 1 );
nr_exports );
for (i = Base; i <= Limit; i++)
{
unsigned char args = 0xff;
......@@ -1196,8 +1221,8 @@ static int BuildSpec32File( FILE *outfile )
DLLName );
fprintf( outfile, " \"%s\",\n", DLLName );
fprintf( outfile, " \"%s\",\n", DLLFileName );
fprintf( outfile, " %d,\n", Base );
fprintf( outfile, " %d,\n", Limit - Base + 1 );
fprintf( outfile, " %d,\n", nr_exports? Base : 0 );
fprintf( outfile, " %d,\n", nr_exports );
fprintf( outfile, " %d,\n", nb_names );
fprintf( outfile, " %d,\n", nb_imports );
fprintf( outfile, " %d,\n", (fwd_size + 3) & ~3 );
......@@ -1209,6 +1234,7 @@ static int BuildSpec32File( FILE *outfile )
" ArgTypes,\n");
fprintf( outfile, " %s,\n", nb_imports ? "Imports" : "0" );
fprintf( outfile, " %s,\n", DLLInitFunc[0] ? DLLInitFunc : "0" );
fprintf( outfile, " %d,\n", SpecMode == SPEC_MODE_DLL ? IMAGE_FILE_DLL : 0 );
fprintf( outfile, " %s\n", rsrc_name[0] ? rsrc_name : "0" );
fprintf( outfile, "};\n" );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment