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