Release 0.0.3
[wine/multimedia.git] / relay.c
blob0dc6d493936a24ebfcf264f00690bfb85a5e67e9
1 static char RCSId[] = "$Id: relay.c,v 1.1 1993/06/29 15:55:18 root Exp $";
2 static char Copyright[] = "Copyright Robert J. Amstadt, 1993";
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <sys/types.h>
7 #include <sys/stat.h>
8 #include <fcntl.h>
9 #include <unistd.h>
10 #include <linux/unistd.h>
11 #include <linux/head.h>
12 #include <linux/ldt.h>
13 #include <linux/segment.h>
14 #include <errno.h>
15 #include "neexe.h"
16 #include "segmem.h"
17 #include "prototypes.h"
18 #include "dlls.h"
20 #define N_BUILTINS 6
22 struct dll_name_table_entry_s dll_builtin_table[N_BUILTINS] =
24 { "KERNEL", KERNEL_table, 410, 1 },
25 { "USER", USER_table, 540, 2 },
26 { "GDI", GDI_table, 490, 3 },
27 { "UNIXLIB", UNIXLIB_table, 10, 4 },
28 { "WIN87EM", WIN87EM_table, 10, 5 },
29 { "SHELL", SHELL_table, 256, 6 },
32 unsigned short *Stack16Frame;
34 /**********************************************************************
35 * DLLRelay
37 * We get a stack frame pointer to data that looks like this:
39 * Hex Offset Contents
40 * ---------- -------
41 * +00 previous saved_16ss
42 * +02 previous saved_16ebp
43 * +06 previous saved_16esp
44 * +0A 16-bit es
45 * +0C 16-bit ds
46 * +0E 16-bit ebp
47 * +12 length of 16-bit arguments
48 * +14 16-bit ip
49 * +16 16-bit cs
50 * +18 arguments
52 int
53 DLLRelay(unsigned int func_num, unsigned int seg_off)
55 struct dll_table_entry_s *dll_p;
56 unsigned int segment;
57 unsigned int offset;
58 unsigned int dll_id;
59 unsigned int ordinal;
60 int arg_table[DLL_MAX_ARGS];
61 void *arg_ptr;
62 int (*func_ptr)();
63 int i;
66 * Determine address of arguments.
68 Stack16Frame = (unsigned short *) seg_off;
69 arg_ptr = (void *) (seg_off + 0x18);
72 * Extract the DLL number and ordinal number.
74 dll_id = ((func_num >> 16) & 0xffff) - 1;
75 ordinal = func_num & 0xffff;
76 dll_p = &dll_builtin_table[dll_id].dll_table[ordinal];
78 #ifdef RELAY_DEBUG
80 unsigned int *ret_addr;
81 unsigned short *stack_p;
83 ret_addr = (unsigned int *) ((char *) seg_off + 0x14);
84 printf("RELAY: Calling %s.%d, 16-bit stack at %04x:%04x, ",
85 dll_builtin_table[dll_id].dll_name, ordinal,
86 seg_off >> 16, seg_off & 0xffff);
87 printf("return to %08x\n", *ret_addr);
89 #ifdef STACK_DEBUG
90 stack_p = (unsigned short *) seg_off;
91 for (i = 0; i < 24; i++, stack_p++)
93 printf("%04x ", *stack_p);
94 if ((i & 7) == 7)
95 printf("\n");
97 printf("\n");
98 #endif /* STACK_DEBUG */
100 #endif /* RELAY_DEBUG */
103 * Make sure we have a handler defined for this call.
105 if (dll_p->handler == NULL)
107 char buffer[100];
109 sprintf(buffer, "No handler for routine %s.%d",
110 dll_builtin_table[dll_id].dll_name, ordinal);
111 myerror(buffer);
113 func_ptr = dll_p->handler;
116 * OK, special case. If the handler is define as taking no arguments
117 * then pass the address of the arguments on the 16-bit stack to the
118 * handler. It will just ignore the pointer if it really takes no
119 * arguments. This allows us to write slightly faster library routines
120 * if we choose.
122 if (dll_p->n_args == 0)
123 return (*func_ptr)(arg_ptr);
126 * Getting this far means we need to convert the 16-bit argument stack.
128 for (i = 0; i < dll_p->n_args; i++)
130 short *sp;
131 int *ip;
133 offset = dll_p->args[i].dst_arg;
135 switch (dll_p->args[i].src_type)
137 case DLL_ARGTYPE_SIGNEDWORD:
138 sp = (short *) ((char *) arg_ptr + offset);
139 arg_table[i] = *sp;
140 break;
142 case DLL_ARGTYPE_WORD:
143 sp = (short *) ((char *) arg_ptr + offset);
144 arg_table[i] = (int) *sp & 0xffff;
145 break;
147 case DLL_ARGTYPE_LONG:
148 case DLL_ARGTYPE_FARPTR:
149 ip = (int *) ((char *) arg_ptr + offset);
150 arg_table[i] = *ip;
151 break;
156 * Call the handler
158 return (*func_ptr)(arg_table[0], arg_table[1], arg_table[2],
159 arg_table[3], arg_table[4], arg_table[5],
160 arg_table[6], arg_table[7], arg_table[8],
161 arg_table[9], arg_table[10], arg_table[11],
162 arg_table[12], arg_table[13], arg_table[14],
163 arg_table[15]);
166 /**********************************************************************
167 * FindDLLTable
169 struct dll_table_entry_s *
170 FindDLLTable(char *dll_name)
172 int i;
174 for (i = 0; i < N_BUILTINS; i++)
175 if (strcmp(dll_builtin_table[i].dll_name, dll_name) == 0)
176 return dll_builtin_table[i].dll_table;
178 return NULL;
181 /**********************************************************************
182 * FindOrdinalFromName
185 FindOrdinalFromName(struct dll_table_entry_s *dll_table, char *func_name)
187 int i, limit;
189 for (i = 0; i < N_BUILTINS; i++)
190 if (dll_table == dll_builtin_table[i].dll_table)
191 break;
193 if (i == N_BUILTINS)
194 return 0;
196 limit = dll_builtin_table[i].dll_table_length;
197 for (i = 0; i < limit; i++)
198 if (strcasecmp(dll_table[i].export_name, func_name) == 0)
199 return i;
201 return 0;