2002-07-04 David Welch <welch@computer2.darkstar.org>
[reactos.git] / reactos / iface / addsys / genw32k.c
1 /* $Id: genw32k.c,v 1.2 2002/07/04 19:56:33 dwelch Exp $
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS version of ntdll
5 * FILE: iface/native/genntdll.c
6 * PURPOSE: Generates the system call stubs in ntdll
7 * CHANGE HISTORY: Added a '@xx' to deal with stdcall [ Ariadne ]
8 * 19990616 (ea)
9 * Four arguments now required; 4th is the file
10 * for ntoskrnl ZwXXX functions (which are merely calls
11 * to twin NtXXX calls, via int 0x2e (x86).
12 * 19990617 (ea)
13 * Fixed a bug in function numbers in kernel ZwXXX stubs.
14 *
15 */
16
17 /* INCLUDE ******************************************************************/
18
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22
23 #define PARAMETERIZED_LIBS
24
25 #define VERBOSE
26
27 #define INPUT_BUFFER_SIZE 255
28
29 #define INDEX 0x1000 /* SSDT index 1 */
30
31
32 /* FUNCTIONS ****************************************************************/
33
34 int makeSystemServiceTable(FILE *in, FILE *out)
35 {
36 char line [INPUT_BUFFER_SIZE];
37 char *s;
38 char *name;
39 int sys_call_idx;
40 char *nr_args;
41 char *stmp;
42
43 /*
44 * Main SSDT Header
45 */
46 fprintf(out,"// Machine generated, don't edit\n");
47 fprintf(out,"\n\n");
48
49 /*
50 * First we build the Win32k SSDT
51 */
52 fprintf(out,"SSDT Win32kSSDT[] = {\n");
53
54 /* First system call has index zero */
55 sys_call_idx = 0;
56
57 /* Go on until EOF or read zero bytes */
58 while ((!feof(in))&& (fgets(line, sizeof line, in) != NULL))
59 {
60 if ((s = (char *) strchr(line,'\r')) != NULL)
61 {
62 *s = '\0';
63 }
64 /*
65 * Skip comments (#) and empty lines.
66 */
67 s = & line[0];
68 if ((*s) != '#' && (*s) != '\0')
69 {
70 /* Extract the NtXXX name */
71 name = (char *)strtok(s," \t");
72 /* Extract the stack size */
73 nr_args = (char *)strtok(NULL," \t");
74 /*
75 * Remove, if present, the trailing LF.
76 */
77 if ((stmp = strchr(nr_args, '\n')) != NULL)
78 {
79 *stmp = '\0';
80 }
81 #ifdef VERBOSE
82 printf("%3d \"%s\"\n",sys_call_idx | INDEX,name);
83 #endif
84
85 if (sys_call_idx > 0)
86 {
87 fprintf(out,",\n");
88 }
89 /*
90 * Now write the current system call's name
91 * in the service table.
92 */
93 fprintf(out,"\t\t{ (ULONG)%s }",name);
94
95 /* Next system call index */
96 sys_call_idx++;
97 }
98 }
99 /* Close the service table (C syntax) */
100 fprintf(out,"\n};\n");
101
102 /*
103 * Now we build the Win32k SSPT
104 */
105 rewind(in);
106 fprintf(out,"\n\n");
107 fprintf(out,"SSPT Win32kSSPT[] = {\n");
108
109 /* First system call has index zero */
110 sys_call_idx = 0;
111
112 /* Go on until EOF or read zero bytes */
113 while ((!feof(in))&& (fgets(line, sizeof line, in) != NULL))
114 {
115 if ((s = (char *) strchr(line,'\r')) != NULL)
116 {
117 *s = '\0';
118 }
119 /*
120 * Skip comments (#) and empty lines.
121 */
122 s = & line[0];
123 if ((*s) != '#' && (*s) != '\0')
124 {
125 /* Extract the NtXXX name */
126 name = (char *)strtok(s," \t");
127 /* Extract the stack size */
128 nr_args = (char *)strtok(NULL," \t");
129 /*
130 * Remove, if present, the trailing LF.
131 */
132 if ((stmp = strchr(nr_args, '\n')) != NULL)
133 {
134 *stmp = '\0';
135 }
136 #ifdef VERBOSE
137 printf("%3d \"%s\"\n",sys_call_idx|INDEX,name);
138 #endif
139
140 if (sys_call_idx > 0)
141 {
142 fprintf(out,",\n");
143 }
144 /*
145 * Now write the current system call's ID
146 * in the service table along with its Parameters Size.
147 */
148 fprintf(out,"\t\t{ %d }",atoi(nr_args) * sizeof(void*));
149
150 /* Next system call index */
151 sys_call_idx++;
152 }
153 }
154 /*
155 * Close the service table (C syntax)
156 */
157 fprintf(out,"\n};\n");
158
159 /*
160 * We write some useful defines
161 */
162 fprintf(out, "\n\n#define MIN_SYSCALL_NUMBER 0\n");
163 fprintf(out, "#define MAX_SYSCALL_NUMBER %d\n", sys_call_idx-1);
164 fprintf(out, "#define NUMBER_OF_SYSCALLS %d\n", sys_call_idx);
165 fprintf(out, "ULONG Win32kNumberOfSysCalls = %d;\n", sys_call_idx);
166
167 return(0);
168 }
169
170
171 int
172 process(
173 FILE * in,
174 FILE * out1,
175 FILE * out2
176 )
177 {
178 char line [INPUT_BUFFER_SIZE];
179 char * s;
180 char * name; /* NtXXX name */
181 int sys_call_idx; /* NtXXX index number in the service table */
182 char * nr_args; /* stack_size / machine_word_size */
183 char * stmp;
184 int stacksize;
185
186 /*
187 * GDI32 stubs file header
188 */
189 fprintf(out1,"// Machine generated, don't edit\n");
190 fprintf(out1,"\n\n");
191
192 /*
193 * USER32 stubs file header
194 */
195 fprintf(out2,"// Machine generated, don't edit\n");
196 fprintf(out2,"\n\n");
197 /*
198 * Scan the database. DB is a text file; each line
199 * is a record, which contains data for one system
200 * function. Each record has three columns:
201 *
202 * NT_NAME (e.g. NtCreateProcess)
203 * ZW_NAME (e.g. ZwCreateProcess)
204 * STACK_SIZE (in machine words: for x[3456]86
205 * processors a machine word is 4 bytes)
206 */
207
208 /* First system call has index zero */
209 sys_call_idx = 0;
210 while (
211 /* Go on until EOF or read zero bytes */
212 ( (!feof(in))
213 && (fgets(line, sizeof line, in) != NULL)
214 )
215 )
216 {
217 /*
218 * Remove, if present, the trailing CR.
219 * (os specific?)
220 */
221 if ((s = (char *) strchr(line,'\r')) != NULL)
222 {
223 *s = '\0';
224 }
225 /*
226 * Skip comments (#) and empty lines.
227 */
228 s = & line[0];
229 if ((*s) != '#' && (*s) != '\0')
230 {
231 /* Extract the NtXXX name */
232 name = (char *)strtok(s," \t");
233 /* Extract the stack size */
234 nr_args = (char *)strtok(NULL," \t");
235 stacksize = atoi(nr_args)*sizeof(void*);
236 /*
237 * Remove, if present, the trailing LF.
238 */
239 if ((stmp = strchr(nr_args, '\n')) != NULL)
240 {
241 *stmp = '\0';
242 }
243 #ifdef VERBOSE
244 printf("%3d \"%s\"\n",sys_call_idx | INDEX,name);
245 #endif
246
247 /*
248 * Write the GDI32 stub for the current system call.
249 */
250 #ifdef PARAMETERIZED_LIBS
251 fprintf(out1,"__asm__(\"\\n\\t.global _%s@%d\\n\\t\"\n",name,stacksize);
252 fprintf(out1,"\"_%s@%d:\\n\\t\"\n",name,stacksize);
253 #else
254 fprintf(out1,"__asm__(\"\\n\\t.global _%s\\n\\t\"\n",name);
255 fprintf(out1,"\"_%s:\\n\\t\"\n",name);
256 #endif
257 fprintf(out1,"\t\"mov\t$%d,%%eax\\n\\t\"\n",sys_call_idx | INDEX);
258 fprintf(out1,"\t\"lea\t4(%%esp),%%edx\\n\\t\"\n");
259 fprintf(out1,"\t\"int\t$0x2E\\n\\t\"\n");
260 fprintf(out1,"\t\"ret\t$%d\\n\\t\");\n\n",stacksize);
261
262 /*
263 * Write the USER32 stub for the current system call
264 */
265 #ifdef PARAMETERIZED_LIBS
266 fprintf(out2,"__asm__(\"\\n\\t.global _%s@%d\\n\\t\"\n",name,stacksize);
267 fprintf(out2,"\"_%s@%d:\\n\\t\"\n",name,stacksize);
268 #else
269 fprintf(out2,"__asm__(\"\\n\\t.global _%s\\n\\t\"\n",name);
270 fprintf(out2,"\"_%s:\\n\\t\"\n",name);
271 #endif
272 fprintf(out2,"\t\"mov\t$%d,%%eax\\n\\t\"\n",sys_call_idx | INDEX);
273 fprintf(out2,"\t\"lea\t4(%%esp),%%edx\\n\\t\"\n");
274 fprintf(out2,"\t\"int\t$0x2E\\n\\t\"\n");
275 fprintf(out2,"\t\"ret\t$%d\\n\\t\");\n\n",stacksize);
276
277 /* Next system call index */
278 sys_call_idx++;
279 }
280 }
281
282 return(0);
283 }
284
285 void usage(char * argv0)
286 {
287 printf("Usage: %s w32k.lst ssdt.h win32k.c win32k.c\n"
288 " w32k.lst system functions database\n"
289 " ssdt.h WIN32K service table\n"
290 " win32k.c GDI32 stubs\n"
291 " win32k.c USER32 stubs\n",
292 argv0
293 );
294 }
295
296 int main(int argc, char* argv[])
297 {
298 FILE * in; /* System calls database */
299 FILE * out1; /* SERVICE_TABLE */
300 FILE * out2; /* GDI32 stubs */
301 FILE * out3; /* USER32 stubs */
302 int ret;
303
304 if (argc != 5)
305 {
306 usage(argv[0]);
307 return(1);
308 }
309
310 in = fopen(argv[1],"rb");
311 if (in == NULL)
312 {
313 perror("Failed to open input file (system calls database)");
314 return(1);
315 }
316
317 out1 = fopen(argv[2],"wb");
318 if (out1 == NULL)
319 {
320 perror("Failed to open output file (WIN32K service table)");
321 return(1);
322 }
323
324 out2 = fopen(argv[3],"wb");
325 if (out2 == NULL)
326 {
327 perror("Failed to open output file (GDI32 stubs)");
328 return(1);
329 }
330
331 out3 = fopen(argv[4],"wb");
332 if (out3 == NULL)
333 {
334 perror("Failed to open output file (USER32 stubs)");
335 return(1);
336 }
337
338 ret = process(in,out2,out3);
339 rewind(in);
340 ret = makeSystemServiceTable(in, out1);
341
342 fclose(in);
343 fclose(out1);
344 fclose(out2);
345 fclose(out3);
346
347 return(ret);
348 }