:pserver:cvsanon@mok.lvcm.com:/CVS/ReactOS reactos
[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 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         FILE    * out3
177         )
178 {
179         char            line [INPUT_BUFFER_SIZE];
180         char            * s;
181         char            * name;         /* NtXXX name */
182         int             sys_call_idx;   /* NtXXX index number in the service table */
183         char            * nr_args;      /* stack_size / machine_word_size */
184         char            * stmp;
185         int             stacksize;
186
187         /*
188          * GDI32 stubs file header
189          */
190         fprintf(out1,"// Machine generated, don't edit\n");
191         fprintf(out1,"\n\n");
192
193         /*
194          * USER32 stubs file header
195          */
196         fprintf(out2,"// Machine generated, don't edit\n");
197         fprintf(out2,"\n\n");
198
199         /*
200          * CSRSS stubs file header
201          */
202         fprintf(out3,"// Machine generated, don't edit\n");
203         fprintf(out3,"\n\n");
204
205         /*
206          * Scan the database. DB is a text file; each line
207          * is a record, which contains data for one system
208          * function. Each record has three columns:
209          *
210          * NT_NAME      (e.g. NtCreateProcess)
211          * ZW_NAME      (e.g. ZwCreateProcess)
212          * STACK_SIZE   (in machine words: for x[3456]86
213          *              processors a machine word is 4 bytes)
214          */
215
216         /* First system call has index zero */
217         sys_call_idx = 0;
218         while (
219                 /* Go on until EOF or read zero bytes */
220                 (       (!feof(in))
221                         && (fgets(line, sizeof line, in) != NULL)
222                         )
223                 )
224         {
225                 /*
226                  * Remove, if present, the trailing CR.
227                  * (os specific?)
228                  */
229                 if ((s = (char *) strchr(line,'\r')) != NULL)
230                 {
231                         *s = '\0';
232                 }
233                 /*
234                  * Skip comments (#) and empty lines.
235                  */
236                 s = & line[0];
237                 if ((*s) != '#' && (*s) != '\0')
238                 {
239                         /* Extract the NtXXX name */
240                         name = (char *)strtok(s," \t");
241                         /* Extract the stack size */
242                         nr_args = (char *)strtok(NULL," \t");
243                         stacksize = atoi(nr_args)*sizeof(void*);
244                         /*
245                          * Remove, if present, the trailing LF.
246                          */
247                         if ((stmp = strchr(nr_args, '\n')) != NULL)
248                         {
249                                 *stmp = '\0';
250                         }
251 #ifdef VERBOSE
252                         printf("%3d \"%s\"\n",sys_call_idx | INDEX,name);
253 #endif
254
255                         /*
256                          * Write the GDI32 stub for the current system call.
257                          */
258 #ifdef PARAMETERIZED_LIBS
259                         fprintf(out1,"__asm__(\"\\n\\t.global _%s@%d\\n\\t\"\n",name,stacksize);
260                         fprintf(out1,"\"_%s@%d:\\n\\t\"\n",name,stacksize);
261 #else
262                         fprintf(out1,"__asm__(\"\\n\\t.global _%s\\n\\t\"\n",name);
263                         fprintf(out1,"\"_%s:\\n\\t\"\n",name);
264 #endif
265                         fprintf(out1,"\t\"mov\t$%d,%%eax\\n\\t\"\n",sys_call_idx | INDEX);
266                         fprintf(out1,"\t\"lea\t4(%%esp),%%edx\\n\\t\"\n");
267                         fprintf(out1,"\t\"int\t$0x2E\\n\\t\"\n");
268                         fprintf(out1,"\t\"ret\t$%d\\n\\t\");\n\n",stacksize);
269
270                         /*
271                          * Write the USER32 stub for the current system call
272                          */
273 #ifdef PARAMETERIZED_LIBS
274                         fprintf(out2,"__asm__(\"\\n\\t.global _%s@%d\\n\\t\"\n",name,stacksize);
275                         fprintf(out2,"\"_%s@%d:\\n\\t\"\n",name,stacksize);
276 #else
277                         fprintf(out2,"__asm__(\"\\n\\t.global _%s\\n\\t\"\n",name);
278                         fprintf(out2,"\"_%s:\\n\\t\"\n",name);
279 #endif
280                         fprintf(out2,"\t\"mov\t$%d,%%eax\\n\\t\"\n",sys_call_idx | INDEX);
281                         fprintf(out2,"\t\"lea\t4(%%esp),%%edx\\n\\t\"\n");
282                         fprintf(out2,"\t\"int\t$0x2E\\n\\t\"\n");
283                         fprintf(out2,"\t\"ret\t$%d\\n\\t\");\n\n",stacksize);
284
285                         /*
286                          * Write the CSRSS stub for the current system call
287                          */
288 #ifdef PARAMETERIZED_LIBS
289                         fprintf(out3,"__asm__(\"\\n\\t.global _%s@%d\\n\\t\"\n",name,stacksize);
290                         fprintf(out3,"\"_%s@%d:\\n\\t\"\n",name,stacksize);
291 #else
292                         fprintf(out3,"__asm__(\"\\n\\t.global _%s\\n\\t\"\n",name);
293                         fprintf(out3,"\"_%s:\\n\\t\"\n",name);
294 #endif
295                         fprintf(out3,"\t\"mov\t$%d,%%eax\\n\\t\"\n",sys_call_idx | INDEX);
296                         fprintf(out3,"\t\"lea\t4(%%esp),%%edx\\n\\t\"\n");
297                         fprintf(out3,"\t\"int\t$0x2E\\n\\t\"\n");
298                         fprintf(out3,"\t\"ret\t$%d\\n\\t\");\n\n",stacksize);
299
300                         /* Next system call index */
301                         sys_call_idx++;
302                 }
303         }
304
305         return(0);
306 }
307
308 void usage(char * argv0)
309 {
310         printf("Usage: %s w32k.lst ssdt.h win32k.c win32k.c\n"
311                "  w32k.lst      system functions database\n"
312                "  ssdt.h        WIN32K service table\n"
313                "  win32k.c      GDI32 stubs\n"
314                "  win32k.c      USER32 stubs\n",
315                 argv0
316                 );
317 }
318
319 int main(int argc, char* argv[])
320 {
321         FILE    * in;   /* System calls database */
322         FILE    * out1; /* SERVICE_TABLE */
323         FILE    * out2; /* GDI32 stubs */
324         FILE    * out3; /* USER32 stubs */
325         FILE    * out4; /* CSRSS stubs */
326         int     ret;
327
328         if (argc != 6)
329         {
330                 usage(argv[0]);
331                 return(1);
332         }
333
334         in = fopen(argv[1],"rb");
335         if (in == NULL)
336         {
337                 perror("Failed to open input file (system calls database)");
338                 return(1);
339         }
340
341         out1 = fopen(argv[2],"wb");
342         if (out1 == NULL)
343         {
344                 perror("Failed to open output file (WIN32K service table)");
345                 return(1);
346         }
347
348         out2 = fopen(argv[3],"wb");
349         if (out2 == NULL)
350         {
351                 perror("Failed to open output file (GDI32 stubs)");
352                 return(1);
353         }
354
355         out3 = fopen(argv[4],"wb");
356         if (out3 == NULL)
357         {
358                 perror("Failed to open output file (USER32 stubs)");
359                 return(1);
360         }
361
362         out4 = fopen(argv[5],"wb");
363         if (out4 == NULL)
364           {
365             perror("Failed to open output file (CSRSS stubs)");
366             return(1);
367           }
368
369         ret = process(in,out2,out3,out4);
370         rewind(in);
371         ret = makeSystemServiceTable(in, out1);
372
373         fclose(in);
374         fclose(out1);
375         fclose(out2);
376         fclose(out3);
377
378         return(ret);
379 }