wine/tools/build.c
Alexandre Julliard 5819953c2a Release 940420
Wed Apr 20 14:53:35 1994  Bob Amstadt  (bob@pooh)

	* [tools/build.c] [if1632/call.S] [if1632/Imakefile]
	Fixed bug for non-Linux systems.

Apr 18, 94 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte)

	* [windows/win.c]
	Bug fixed in CreateWindowEx() : Now use SetMenu() for menubar setup.
	New empty stub for function SetSysModalWindow().

	* [misc/exec.c]
	New empty stub for function ExitWindows().

	* [objects/font.c]
	New empty stub for function EnumFonts().

	* New file [misc/property.c]
	New functions RemoveProp(), GetProp(), SetProp() & EnumProps().

	* New file [misc/shell.c]
	New empty stubs for function RegisterShellProc(), 
			ShellExecute() & ShellProc().

	* New files [loader/task.c] & [include/task.h]
	Move functions GetWindowTask(), GetNumTask(), EnumTaskWindows()
		from 'loader/library.c'.

	* [if1632/user.c] [if1632/kernel.c]
	Put Atoms functions entries.

	* [controls/combo.c]
	New functions DirDlgSelectComboBox() & DirDlgListComboBox().

	* [controls/listbox.c]
	New functions DirDlgSelect() & DirDlgList().

Sun Apr 17 20:57:59 1994  Erik Bos (erik@trashcan.hacktic.nl)

	* [objects/test.c]
	GrayString() added.

	* [if1632/callback.c]
	CallGrayStringProc() added.

	* [if1632/relay.c] [if1632/mmsystem.spec]
	Added.

	* [if1632/kernel.spec] [if1632/user.spec]
	Added forgotten specs for atom functions.

Tue Apr 12 00:05:31 1994  Bob Amstadt  (bob@pooh)

	* misc/spy.c (SpyInit): Added more message types

	* [windows/mdi.c] [include/mdi.h]
	Maximizing and restoring child windows.
	Tiling of child windows.

Mon Apr 11 20:48:28 1994  Alexandre Julliard  (julliard@lamisun.epfl.ch)

	* [windows/winpos.c]
	Revert focus and activation to previous window when hiding a window.

	* [windows/syscolor.c]
	Implemented system color objects (brushes and pens created at
	SetSysColor() time for better performance).

	* [windows/graphics.c] [windows/nonclient.c] [controls/button.c]
	Changed painting code to use system color objects.

	* [windows/message.c]
	New function MSG_InternalGetMessage() for internal messages
	loops (e.g. for dialogs or menus).

	* [windows/hook.c] [include/hook.h]  (New files)
	Beginning of the window hooks implementation.

	* [windows/dialog.c]
	Use new function MSG_InternalGetMessage() in DialogBox().

	* [if1632/callback.c]
	Added function CallHookProc().

Apr 11, 94 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte)

	* [windows/event.c]
	Bug fix : WM_CHARs are sent to focused window like WM_KEY???.

	* [misc/exec.c]
	Nothing much more than a stub for LoadModule(), I saw there a lot
		to be done in that corner, I will come back later ...

	* [loader/library.c]
	New functions GetWindowTask(), GetNumTask(), EnumTaskWindows() 
			and associated modules & tasks linked-lists.
	(it's only an 'emerging bud', more to come next weeks).

	* [loader/wine.c]
	Use LoadLibrary() instead of LoadImage() for 'sysres.dll'.

	* [control/menu.c]
	You can now click outside menu region without problem.
	Keyboard navig more smootly, even if a child has the focus.
	Bug fix in InsertItem(), (bad linklist when insert point not found).
	change Realloc for Free & Alloc in ModifyItem().
	MF_STRING now set BLACK_PEN to fix bug of bad color of the underscores 
		done by DrawText(), (maybe it should done in DrawText() itself ?).

Sun Apr 10 14:06:08 1994  Erik Bos (erik@trashcan.hacktic.nl)

	* [misc/profile.c]
	.INI files will now be stored in / loaded from the windows dir
	if no path is supplied.

	* [if1632/kernel.spec]
	Fixed GetDriveType's prototype.

	* [if1632/winsock.spec] [include/winsock.h] [misc/winsocket.c]
	Fixed prototypes: winsock uses a word as socket handle not an int.

	* [misc/winsocket.c]
	Added heap allocation for returned structures.
	Added non-blocking WSAAsyncGetXbyY() functions as blocking ones.

	* [loader/wine.c]
	Added IsDLLLoaded(), used in LoadImage() to prevent loading
	a dll multiple times.
	Directory is added to wine's path when a fullpath is supplied when
	starting wine.
	LoadImage(): DLL filename used instead DLL's own internal name,
	fixes 'Bad DLL name' errors.

Sat Apr  9 08:26:03 1994  David Metcalfe <david@prism.demon.co.uk>

	* [controls/edit.c] [controls/widgets.c]
	First release of edit control.
1994-04-21 01:20:00 +00:00

943 lines
21 KiB
C

static char RCSId[] = "$Id: build.c,v 1.3 1993/07/04 04:04:21 root Exp root $";
static char Copyright[] = "Copyright Robert J. Amstadt, 1993";
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "wine.h"
#ifdef linux
#define UTEXTSEL 0x23
#endif
#if defined(__NetBSD__) || defined(__FreeBSD__)
#define UTEXTSEL 0x1f
#endif
#define VARTYPE_BYTE 0
#define VARTYPE_SIGNEDWORD 0
#define VARTYPE_WORD 1
#define VARTYPE_LONG 2
#define VARTYPE_FARPTR 3
#define FUNCTYPE_PASCAL 16
#define FUNCTYPE_C 17
#define FUNCTYPE_REG 19
#define EQUATETYPE_ABS 18
#define TYPE_RETURN 20
#define MAX_ORDINALS 1024
#define PUSH_0 "\tpushl\t$0\n"
#define PUSH_SS "\tpushw\t$0\n\tpushw\t%%ss\n"
#define PUSH_ESP "\tpushl\t%%esp\n"
#define PUSH_EFL "\tpushfl\n"
#define PUSH_CS "\tpushw\t$0\n\tpushw\t%%cs\n"
#define PUSH_EIP "\tpushl\t$0\n"
#define PUSH_DS "\tpushw\t$0\n\tpushw\t%%ds\n"
#define PUSH_ES "\tpushw\t$0\n\tpushw\t%%es\n"
#define PUSH_FS "\tpushw\t$0\n\tpushw\t%%fs\n"
#define PUSH_GS "\tpushw\t$0\n\tpushw\t%%gs\n"
#define PUSH_EAX "\tpushl\t%%eax\n"
#define PUSH_ECX "\tpushl\t%%ecx\n"
#define PUSH_EDX "\tpushl\t%%edx\n"
#define PUSH_EBX "\tpushl\t%%ebx\n"
#define PUSH_EBP "\tpushl\t%%ebp\n"
#define PUSH_ESI "\tpushl\t%%esi\n"
#define PUSH_EDI "\tpushl\t%%edi\n"
#define POP_0 "\tadd\t$4,%%esp\n"
#define POP_SS "\tpopw\t%%ss\n\tadd\t$2,%%esp\n"
#define POP_ESP "\tpopl\t%%esp\n"
#define POP_EFL "\tpopfl\n"
#define POP_CS "\tpopw\t%%cs\n\tadd\t$2,%%esp\n"
#define POP_EIP "\tpopl\t$0\n"
#define POP_DS "\tpopw\t%%ds\n\tadd\t$2,%%esp\n"
#define POP_ES "\tpopw\t%%es\n\tadd\t$2,%%esp\n"
#define POP_FS "\tpopw\t%%fs\n\tadd\t$2,%%esp\n"
#define POP_GS "\tpopw\t%%gs\n\tadd\t$2,%%esp\n"
#define POP_EAX "\tpopl\t%%eax\n"
#define POP_ECX "\tpopl\t%%ecx\n"
#define POP_EDX "\tpopl\t%%edx\n"
#define POP_EBX "\tpopl\t%%ebx\n"
#define POP_EBP "\tpopl\t%%ebp\n"
#define POP_ESI "\tpopl\t%%esi\n"
#define POP_EDI "\tpopl\t%%edi\n"
char **context_strings;
char **pop_strings;
int n_context_strings;
typedef struct ordinal_definition_s
{
int valid;
int type;
char export_name[80];
void *additional_data;
} ORDDEF;
typedef struct ordinal_variable_definition_s
{
int n_values;
int *values;
} ORDVARDEF;
typedef struct ordinal_function_definition_s
{
int n_args_16;
int arg_types_16[16];
int arg_16_offsets[16];
int arg_16_size;
char internal_name[80];
int n_args_32;
int arg_indices_32[16];
} ORDFUNCDEF;
typedef struct ordinal_return_definition_s
{
int arg_size;
int ret_value;
} ORDRETDEF;
ORDDEF OrdinalDefinitions[MAX_ORDINALS];
char LowerDLLName[80];
char UpperDLLName[80];
int Limit;
int DLLId;
FILE *SpecFp;
char *ParseBuffer = NULL;
char *ParseNext;
char ParseSaveChar;
int Line;
int IsNumberString(char *s)
{
while (*s != '\0')
if (!isdigit(*s++))
return 0;
return 1;
}
char *strlower(char *s)
{
char *p;
for(p = s; *p != '\0'; p++)
*p = tolower(*p);
return s;
}
char *strupper(char *s)
{
char *p;
for(p = s; *p != '\0'; p++)
*p = toupper(*p);
return s;
}
int stricmp(char *s1, char *s2)
{
if (strlen(s1) != strlen(s2))
return -1;
while (*s1 != '\0')
if (*s1++ != *s2++)
return -1;
return 0;
}
char *
GetTokenInLine(void)
{
char *p;
char *token;
if (ParseNext != ParseBuffer)
{
if (ParseSaveChar == '\0')
return NULL;
*ParseNext = ParseSaveChar;
}
/*
* Remove initial white space.
*/
for (p = ParseNext; isspace(*p); p++)
;
if (*p == '\0')
return NULL;
/*
* Find end of token.
*/
token = p++;
if (*token != '(' && *token != ')')
while (*p != '\0' && *p != '(' && *p != ')' && !isspace(*p))
p++;
ParseSaveChar = *p;
ParseNext = p;
*p = '\0';
return token;
}
char *
GetToken(void)
{
char *token;
if (ParseBuffer == NULL)
{
ParseBuffer = malloc(512);
ParseNext = ParseBuffer;
Line++;
while (1)
{
if (fgets(ParseBuffer, 511, SpecFp) == NULL)
return NULL;
if (ParseBuffer[0] != '#')
break;
}
}
while ((token = GetTokenInLine()) == NULL)
{
ParseNext = ParseBuffer;
Line++;
while (1)
{
if (fgets(ParseBuffer, 511, SpecFp) == NULL)
return NULL;
if (ParseBuffer[0] != '#')
break;
}
}
return token;
}
int
ParseVariable(int ordinal, int type)
{
ORDDEF *odp;
ORDVARDEF *vdp;
char export_name[80];
char *token;
char *endptr;
int *value_array;
int n_values;
int value_array_size;
strcpy(export_name, GetToken());
token = GetToken();
if (*token != '(')
{
fprintf(stderr, "%d: Expected '(' got '%s'\n", Line, token);
exit(1);
}
n_values = 0;
value_array_size = 25;
value_array = malloc(sizeof(*value_array) * value_array_size);
while ((token = GetToken()) != NULL)
{
if (*token == ')')
break;
value_array[n_values++] = strtol(token, &endptr, 0);
if (n_values == value_array_size)
{
value_array_size += 25;
value_array = realloc(value_array,
sizeof(*value_array) * value_array_size);
}
if (endptr == NULL || *endptr != '\0')
{
fprintf(stderr, "%d: Expected number value, got '%s'\n", Line,
token);
exit(1);
}
}
if (token == NULL)
{
fprintf(stderr, "%d: End of file in variable declaration\n", Line);
exit(1);
}
if (ordinal >= MAX_ORDINALS)
{
fprintf(stderr, "%d: Ordinal number too large\n", Line);
exit(1);
}
odp = &OrdinalDefinitions[ordinal];
odp->valid = 1;
odp->type = type;
strcpy(odp->export_name, export_name);
vdp = malloc(sizeof(*vdp));
odp->additional_data = vdp;
vdp->n_values = n_values;
vdp->values = realloc(value_array, sizeof(*value_array) * n_values);
return 0;
}
int
ParseExportFunction(int ordinal, int type)
{
char *token;
ORDDEF *odp;
ORDFUNCDEF *fdp;
int arg_types[16];
int i;
int arg_num;
int current_offset;
int arg_size;
if (ordinal >= MAX_ORDINALS)
{
fprintf(stderr, "%d: Ordinal number too large\n", Line);
exit(1);
}
odp = &OrdinalDefinitions[ordinal];
strcpy(odp->export_name, GetToken());
odp->valid = 1;
odp->type = type;
fdp = malloc(sizeof(*fdp));
odp->additional_data = fdp;
token = GetToken();
if (*token != '(')
{
fprintf(stderr, "%d: Expected '(' got '%s'\n", Line, token);
exit(1);
}
fdp->arg_16_size = 0;
for (i = 0; i < 16; i++)
{
token = GetToken();
if (*token == ')')
break;
if (stricmp(token, "byte") == 0 || stricmp(token, "word") == 0)
{
fdp->arg_types_16[i] = VARTYPE_WORD;
fdp->arg_16_size += 2;
fdp->arg_16_offsets[i] = 2;
}
else if (stricmp(token, "s_byte") == 0 ||
stricmp(token, "s_word") == 0)
{
fdp->arg_types_16[i] = VARTYPE_SIGNEDWORD;
fdp->arg_16_size += 2;
fdp->arg_16_offsets[i] = 2;
}
else if (stricmp(token, "long") == 0 || stricmp(token, "s_long") == 0)
{
fdp->arg_types_16[i] = VARTYPE_LONG;
fdp->arg_16_size += 4;
fdp->arg_16_offsets[i] = 4;
}
else if (stricmp(token, "ptr") == 0)
{
fdp->arg_types_16[i] = VARTYPE_FARPTR;
fdp->arg_16_size += 4;
fdp->arg_16_offsets[i] = 4;
}
else
{
fprintf(stderr, "%d: Unknown variable type '%s'\n", Line, token);
exit(1);
}
}
fdp->n_args_16 = i;
if (type == FUNCTYPE_PASCAL || type == FUNCTYPE_REG)
{
current_offset = 0;
for (i--; i >= 0; i--)
{
arg_size = fdp->arg_16_offsets[i];
fdp->arg_16_offsets[i] = current_offset;
current_offset += arg_size;
}
}
else
{
current_offset = 0;
for (i = 0; i < fdp->n_args_16; i++)
{
arg_size = fdp->arg_16_offsets[i];
fdp->arg_16_offsets[i] = current_offset;
current_offset += arg_size;
}
}
strcpy(fdp->internal_name, GetToken());
token = GetToken();
if (*token != '(')
{
fprintf(stderr, "%d: Expected '(' got '%s'\n", Line, token);
exit(1);
}
for (i = 0; i < 16; i++)
{
token = GetToken();
if (*token == ')')
break;
fdp->arg_indices_32[i] = atoi(token);
if (fdp->arg_indices_32[i] < 1 ||
fdp->arg_indices_32[i] > fdp->n_args_16)
{
fprintf(stderr, "%d: Bad argument index %d\n", Line,
fdp->arg_indices_32[i]);
exit(1);
}
}
fdp->n_args_32 = i;
return 0;
}
int
ParseEquate(int ordinal)
{
ORDDEF *odp;
char *token;
char *endptr;
int value;
if (ordinal >= MAX_ORDINALS)
{
fprintf(stderr, "%d: Ordinal number too large\n", Line);
exit(1);
}
odp = &OrdinalDefinitions[ordinal];
strcpy(odp->export_name, GetToken());
token = GetToken();
value = strtol(token, &endptr, 0);
if (endptr == NULL || *endptr != '\0')
{
fprintf(stderr, "%d: Expected number value, got '%s'\n", Line,
token);
exit(1);
}
odp->valid = 1;
odp->type = EQUATETYPE_ABS;
odp->additional_data = (void *) value;
return 0;
}
int
ParseReturn(int ordinal)
{
ORDDEF *odp;
ORDRETDEF *rdp;
char *token;
char *endptr;
int value;
if (ordinal >= MAX_ORDINALS)
{
fprintf(stderr, "%d: Ordinal number too large\n", Line);
exit(1);
}
rdp = malloc(sizeof(*rdp));
odp = &OrdinalDefinitions[ordinal];
strcpy(odp->export_name, GetToken());
odp->valid = 1;
odp->type = TYPE_RETURN;
odp->additional_data = rdp;
token = GetToken();
rdp->arg_size = strtol(token, &endptr, 0);
if (endptr == NULL || *endptr != '\0')
{
fprintf(stderr, "%d: Expected number value, got '%s'\n", Line,
token);
exit(1);
}
token = GetToken();
rdp->ret_value = strtol(token, &endptr, 0);
if (endptr == NULL || *endptr != '\0')
{
fprintf(stderr, "%d: Expected number value, got '%s'\n", Line,
token);
exit(1);
}
return 0;
}
int
ParseOrdinal(int ordinal)
{
char *token;
token = GetToken();
if (token == NULL)
{
fprintf(stderr, "%d: Expected type after ordinal\n", Line);
exit(1);
}
if (stricmp(token, "byte") == 0)
return ParseVariable(ordinal, VARTYPE_BYTE);
else if (stricmp(token, "word") == 0)
return ParseVariable(ordinal, VARTYPE_WORD);
else if (stricmp(token, "long") == 0)
return ParseVariable(ordinal, VARTYPE_LONG);
else if (stricmp(token, "c") == 0)
return ParseExportFunction(ordinal, FUNCTYPE_C);
else if (stricmp(token, "p") == 0)
return ParseExportFunction(ordinal, FUNCTYPE_PASCAL);
else if (stricmp(token, "pascal") == 0)
return ParseExportFunction(ordinal, FUNCTYPE_PASCAL);
else if (stricmp(token, "register") == 0)
return ParseExportFunction(ordinal, FUNCTYPE_REG);
else if (stricmp(token, "equate") == 0)
return ParseEquate(ordinal);
else if (stricmp(token, "return") == 0)
return ParseReturn(ordinal);
else
{
fprintf(stderr,
"%d: Expected type after ordinal, found '%s' instead\n",
Line, token);
exit(1);
}
}
int
ParseTopLevel(void)
{
char *token;
while ((token = GetToken()) != NULL)
{
if (stricmp(token, "name") == 0)
{
strcpy(LowerDLLName, GetToken());
strlower(LowerDLLName);
strcpy(UpperDLLName, LowerDLLName);
strupper(UpperDLLName);
}
else if (stricmp(token, "id") == 0)
{
token = GetToken();
if (!IsNumberString(token))
{
fprintf(stderr, "%d: Expected number after id\n", Line);
exit(1);
}
DLLId = atoi(token);
}
else if (stricmp(token, "length") == 0)
{
token = GetToken();
if (!IsNumberString(token))
{
fprintf(stderr, "%d: Expected number after length\n", Line);
exit(1);
}
Limit = atoi(token);
}
else if (IsNumberString(token))
{
int ordinal;
int rv;
ordinal = atoi(token);
if ((rv = ParseOrdinal(ordinal)) < 0)
return rv;
}
else
{
fprintf(stderr,
"%d: Expected name, id, length or ordinal\n", Line);
exit(1);
}
}
return 0;
}
InitContext()
{
struct sigcontext_struct context;
int i;
int j;
n_context_strings = sizeof(context) / 4;
context_strings = (char **) malloc(n_context_strings * sizeof(char **));
pop_strings = (char **) malloc(n_context_strings * sizeof(char **));
for (i = 0; i < n_context_strings; i++)
{
context_strings[i] = PUSH_0;
pop_strings[i] = POP_0;
}
i = n_context_strings - 1 + ((int) &context - (int) &context.sc_esp) / 4;
context_strings[i] = PUSH_ESP;
i = n_context_strings - 1 + ((int) &context - (int) &context.sc_ebp) / 4;
context_strings[i] = PUSH_EBP;
pop_strings[n_context_strings - 1 - i] = POP_EBP;
i = n_context_strings - 1 + ((int) &context - (int) &context.sc_eip) / 4;
context_strings[i] = PUSH_EIP;
i = n_context_strings - 1 + ((int) &context - (int) &context.sc_efl) / 4;
context_strings[i] = PUSH_EFL;
pop_strings[n_context_strings - 1 - i] = POP_EFL;
i = n_context_strings - 1 + ((int) &context - (int) &context.sc_es) / 4;
context_strings[i] = PUSH_ES;
pop_strings[n_context_strings - 1 - i] = POP_ES;
i = n_context_strings - 1 + ((int) &context - (int) &context.sc_ds) / 4;
context_strings[i] = PUSH_DS;
pop_strings[n_context_strings - 1 - i] = POP_DS;
i = n_context_strings - 1 + ((int) &context - (int) &context.sc_cs) / 4;
context_strings[i] = PUSH_CS;
i = n_context_strings - 1 + ((int) &context - (int) &context.sc_ss) / 4;
context_strings[i] = PUSH_SS;
i = n_context_strings - 1 + ((int) &context - (int) &context.sc_edi) / 4;
context_strings[i] = PUSH_EDI;
pop_strings[n_context_strings - 1 - i] = POP_EDI;
i = n_context_strings - 1 + ((int) &context - (int) &context.sc_esi) / 4;
context_strings[i] = PUSH_ESI;
pop_strings[n_context_strings - 1 - i] = POP_ESI;
i = n_context_strings - 1 + ((int) &context - (int) &context.sc_ebx) / 4;
context_strings[i] = PUSH_EBX;
pop_strings[n_context_strings - 1 - i] = POP_EBX;
i = n_context_strings - 1 + ((int) &context - (int) &context.sc_edx) / 4;
context_strings[i] = PUSH_EDX;
pop_strings[n_context_strings - 1 - i] = POP_EDX;
i = n_context_strings - 1 + ((int) &context - (int) &context.sc_ecx) / 4;
context_strings[i] = PUSH_ECX;
pop_strings[n_context_strings - 1 - i] = POP_ECX;
i = n_context_strings - 1 + ((int) &context - (int) &context.sc_eax) / 4;
context_strings[i] = PUSH_EAX;
pop_strings[n_context_strings - 1 - i] = POP_EAX;
}
void
OutputVariableCode(FILE *fp, char *storage, ORDDEF *odp)
{
ORDVARDEF *vdp;
int i;
fprintf(fp, "_%s_Ordinal_%d:\n", UpperDLLName, i);
vdp = odp->additional_data;
for (i = 0; i < vdp->n_values; i++)
{
if ((i & 7) == 0)
fprintf(fp, "\t%s\t", storage);
fprintf(fp, "%d", vdp->values[i]);
if ((i & 7) == 7 || i == vdp->n_values - 1)
fprintf(fp, "\n");
else
fprintf(fp, ", ");
}
fprintf(fp, "\n");
}
main(int argc, char **argv)
{
ORDDEF *odp;
ORDFUNCDEF *fdp;
ORDRETDEF *rdp;
FILE *fp;
char filename[80];
char buffer[80];
char *p;
int i, ci;
int add_count;
if (argc < 2)
{
fprintf(stderr, "usage: build SPECNAME\n build -p\n");
exit(1);
}
InitContext();
if (strcmp("-p", argv[1]) == 0)
{
fp = fopen("pop.h", "w");
add_count = 0;
for (i = 0; i < n_context_strings; i++)
{
if (strncmp(pop_strings[i], "\tadd\t", 5) == 0)
{
add_count += atoi(pop_strings[i] + 6);
}
else
{
if (add_count > 0)
{
fprintf(fp, "\tadd\t$%d,%%esp\n", add_count);
add_count = 0;
}
fprintf(fp, pop_strings[i]);
}
}
if (add_count > 0)
fprintf(fp, "\tadd\t$%d,%%esp\n", add_count);
fclose(fp);
exit(0);
}
SpecFp = fopen(argv[1], "r");
if (SpecFp == NULL)
{
fprintf(stderr, "Could not open specification file, '%s'\n", argv[1]);
exit(1);
}
ParseTopLevel();
sprintf(filename, "dll_%s.S", LowerDLLName);
fp = fopen(filename, "w");
fprintf(fp, "\t.globl _%s_Dispatch\n", UpperDLLName);
fprintf(fp, "_%s_Dispatch:\n", UpperDLLName);
fprintf(fp, "\tandl\t$0x0000ffff,%%esp\n");
fprintf(fp, "\tandl\t$0x0000ffff,%%ebp\n");
fprintf(fp, "\torl\t$0x%08x,%%eax\n", DLLId << 16);
fprintf(fp, "\tjmp\t_CallTo32\n\n");
odp = OrdinalDefinitions;
for (i = 0; i <= Limit; i++, odp++)
{
fprintf(fp, "\t.globl _%s_Ordinal_%d\n", UpperDLLName, i);
if (!odp->valid)
{
fprintf(fp, "_%s_Ordinal_%d:\n", UpperDLLName, i);
fprintf(fp, "\tmovl\t$%d,%%eax\n", i);
fprintf(fp, "\tpushw\t$0\n");
fprintf(fp, "\tjmp\t_%s_Dispatch\n\n", UpperDLLName);
}
else
{
fdp = odp->additional_data;
rdp = odp->additional_data;
switch (odp->type)
{
case EQUATETYPE_ABS:
fprintf(fp, "_%s_Ordinal_%d = %d\n\n",
UpperDLLName, i, (int) odp->additional_data);
break;
case VARTYPE_BYTE:
OutputVariableCode(fp, ".byte", odp);
break;
case VARTYPE_WORD:
OutputVariableCode(fp, ".word", odp);
break;
case VARTYPE_LONG:
OutputVariableCode(fp, ".long", odp);
break;
case TYPE_RETURN:
fprintf(fp, "_%s_Ordinal_%d:\n", UpperDLLName, i);
fprintf(fp, "\tmovw\t$%d,%%ax\n", rdp->ret_value & 0xffff);
fprintf(fp, "\tmovw\t$%d,%%dx\n",
(rdp->ret_value >> 16) & 0xffff);
fprintf(fp, "\t.byte\t0x66\n");
if (rdp->arg_size != 0)
fprintf(fp, "\tlret\t$%d\n", rdp->arg_size);
else
fprintf(fp, "\tlret\n");
break;
case FUNCTYPE_REG:
fprintf(fp, "_%s_Ordinal_%d:\n", UpperDLLName, i);
fprintf(fp, "\tandl\t$0x0000ffff,%%esp\n");
fprintf(fp, "\tandl\t$0x0000ffff,%%ebp\n");
for (ci = 0; ci < n_context_strings; ci++)
fprintf(fp, context_strings[ci]);
fprintf(fp, "\tmovl\t%%ebp,%%eax\n");
fprintf(fp, "\tmovw\t%%esp,%%ebp\n");
fprintf(fp, "\tpushl\t%d(%%ebp)\n",
sizeof(struct sigcontext_struct));
fprintf(fp, "\tmovl\t%%eax,%%ebp\n");
fprintf(fp, "\tmovl\t$%d,%%eax\n", i);
fprintf(fp, "\tpushw\t$%d\n",
sizeof(struct sigcontext_struct) + 4);
fprintf(fp, "\tjmp\t_%s_Dispatch\n\n", UpperDLLName);
break;
case FUNCTYPE_PASCAL:
fprintf(fp, "_%s_Ordinal_%d:\n", UpperDLLName, i);
fprintf(fp, "\tmovl\t$%d,%%eax\n", i);
fprintf(fp, "\tpushw\t$%d\n", fdp->arg_16_size);
fprintf(fp, "\tjmp\t_%s_Dispatch\n\n", UpperDLLName);
break;
case FUNCTYPE_C:
default:
fprintf(fp, "_%s_Ordinal_%d:\n", UpperDLLName, i);
fprintf(fp, "\tmovl\t$%d,%%eax\n", i);
fprintf(fp, "\tpushw\t$0\n");
fprintf(fp, "\tjmp\t_%s_Dispatch\n\n", UpperDLLName);
break;
}
}
}
fclose(fp);
#ifndef SHORTNAMES
sprintf(filename, "dll_%s_tab.c", LowerDLLName);
#else
sprintf(filename, "dtb_%s.c", LowerDLLName);
#endif
fp = fopen(filename, "w");
fprintf(fp, "#include <stdio.h>\n");
fprintf(fp, "#include <stdlib.h>\n");
fprintf(fp, "#include \042dlls.h\042\n\n");
for (i = 0; i <= Limit; i++)
{
fprintf(fp, "extern void %s_Ordinal_%d();\n", UpperDLLName, i);
}
odp = OrdinalDefinitions;
for (i = 0; i <= Limit; i++, odp++)
{
if (odp->valid &&
(odp->type == FUNCTYPE_PASCAL || odp->type == FUNCTYPE_C ||
odp->type == FUNCTYPE_REG))
{
fdp = odp->additional_data;
fprintf(fp, "extern int %s();\n", fdp->internal_name);
}
}
fprintf(fp, "\nstruct dll_table_entry_s %s_table[%d] =\n",
UpperDLLName, Limit + 1);
fprintf(fp, "{\n");
odp = OrdinalDefinitions;
for (i = 0; i <= Limit; i++, odp++)
{
fdp = odp->additional_data;
if (!odp->valid)
odp->type = -1;
switch (odp->type)
{
case FUNCTYPE_PASCAL:
case FUNCTYPE_REG:
fprintf(fp, " { 0x%x, %s_Ordinal_%d, ", UTEXTSEL, UpperDLLName, i);
fprintf(fp, "\042%s\042, ", odp->export_name);
fprintf(fp, "%s, DLL_HANDLERTYPE_PASCAL, ", fdp->internal_name);
#ifdef WINESTAT
fprintf(fp, "0, ");
#endif
fprintf(fp, "%d, ", fdp->n_args_32);
if (fdp->n_args_32 > 0)
{
int argnum;
fprintf(fp, "\n {\n");
for (argnum = 0; argnum < fdp->n_args_32; argnum++)
{
fprintf(fp, " { %d, %d },\n",
fdp->arg_16_offsets[fdp->arg_indices_32[argnum]-1],
fdp->arg_types_16[argnum]);
}
fprintf(fp, " }\n ");
}
fprintf(fp, "}, \n");
break;
case FUNCTYPE_C:
fprintf(fp, " { 0x%x, %s_Ordinal_%d, ", UTEXTSEL, UpperDLLName, i);
fprintf(fp, "\042%s\042, ", odp->export_name);
fprintf(fp, "%s, DLL_HANDLERTYPE_C, ", fdp->internal_name);
#ifdef WINESTAT
fprintf(fp, "0, ");
#endif
fprintf(fp, "%d, ", fdp->n_args_32);
if (fdp->n_args_32 > 0)
{
int argnum;
fprintf(fp, "\n {\n");
for (argnum = 0; argnum < fdp->n_args_32; argnum++)
{
fprintf(fp, " { %d, %d },\n",
fdp->arg_16_offsets[fdp->arg_indices_32[argnum]-1],
fdp->arg_types_16[argnum]);
}
fprintf(fp, " }\n ");
}
fprintf(fp, "}, \n");
break;
default:
fprintf(fp, " { 0x%x, %s_Ordinal_%d, \042\042, NULL },\n",
UTEXTSEL, UpperDLLName, i);
break;
}
}
fprintf(fp, "};\n");
fclose(fp);
}