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 ]
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).
13 * Fixed a bug in function numbers in kernel ZwXXX stubs.
17 /* INCLUDE ******************************************************************/
23 #define PARAMETERIZED_LIBS
25 #define INPUT_BUFFER_SIZE 255
27 #define INDEX 0x1000 /* SSDT index 1 */
30 /* FUNCTIONS ****************************************************************/
32 int makeSystemServiceTable(FILE *in, FILE *out)
34 char line [INPUT_BUFFER_SIZE];
44 fprintf(out,"// Machine generated, don't edit\n");
48 * First we build the Win32k SSDT
50 fprintf(out,"SSDT Win32kSSDT[] = {\n");
52 /* First system call has index zero */
55 /* Go on until EOF or read zero bytes */
56 while ((!feof(in))&& (fgets(line, sizeof line, in) != NULL))
58 if ((s = (char *) strchr(line,'\r')) != NULL)
63 * Skip comments (#) and empty lines.
66 if ((*s) != '#' && (*s) != '\0')
68 /* Extract the NtXXX name */
69 name = (char *)strtok(s," \t");
70 /* Extract the stack size */
71 nr_args = (char *)strtok(NULL," \t");
73 * Remove, if present, the trailing LF.
75 if ((stmp = strchr(nr_args, '\n')) != NULL)
80 printf("%3d \"%s\"\n",sys_call_idx | INDEX,name);
88 * Now write the current system call's name
89 * in the service table.
91 fprintf(out,"\t\t{ (ULONG)%s }",name);
93 /* Next system call index */
97 /* Close the service table (C syntax) */
98 fprintf(out,"\n};\n");
101 * Now we build the Win32k SSPT
105 fprintf(out,"SSPT Win32kSSPT[] = {\n");
107 /* First system call has index zero */
110 /* Go on until EOF or read zero bytes */
111 while ((!feof(in))&& (fgets(line, sizeof line, in) != NULL))
113 if ((s = (char *) strchr(line,'\r')) != NULL)
118 * Skip comments (#) and empty lines.
121 if ((*s) != '#' && (*s) != '\0')
123 /* Extract the NtXXX name */
124 name = (char *)strtok(s," \t");
125 /* Extract the stack size */
126 nr_args = (char *)strtok(NULL," \t");
128 * Remove, if present, the trailing LF.
130 if ((stmp = strchr(nr_args, '\n')) != NULL)
135 printf("%3d \"%s\"\n",sys_call_idx|INDEX,name);
138 if (sys_call_idx > 0)
143 * Now write the current system call's ID
144 * in the service table along with its Parameters Size.
146 fprintf(out,"\t\t{ %d }",atoi(nr_args) * sizeof(void*));
148 /* Next system call index */
153 * Close the service table (C syntax)
155 fprintf(out,"\n};\n");
158 * We write some useful defines
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);
177 char line [INPUT_BUFFER_SIZE];
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 */
186 * GDI32 stubs file header
188 fprintf(out1,"// Machine generated, don't edit\n");
189 fprintf(out1,"\n\n");
192 * USER32 stubs file header
194 fprintf(out2,"// Machine generated, don't edit\n");
195 fprintf(out2,"\n\n");
198 * CSRSS stubs file header
200 fprintf(out3,"// Machine generated, don't edit\n");
201 fprintf(out3,"\n\n");
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:
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)
214 /* First system call has index zero */
217 /* Go on until EOF or read zero bytes */
219 && (fgets(line, sizeof line, in) != NULL)
224 * Remove, if present, the trailing CR.
227 if ((s = (char *) strchr(line,'\r')) != NULL)
232 * Skip comments (#) and empty lines.
235 if ((*s) != '#' && (*s) != '\0')
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*);
243 * Remove, if present, the trailing LF.
245 if ((stmp = strchr(nr_args, '\n')) != NULL)
250 printf("%3d \"%s\"\n",sys_call_idx | INDEX,name);
254 * Write the GDI32 stub for the current system call.
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);
260 fprintf(out1,"__asm__(\"\\n\\t.global _%s\\n\\t\"\n",name);
261 fprintf(out1,"\"_%s:\\n\\t\"\n",name);
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);
269 * Write the USER32 stub for the current system call
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);
275 fprintf(out2,"__asm__(\"\\n\\t.global _%s\\n\\t\"\n",name);
276 fprintf(out2,"\"_%s:\\n\\t\"\n",name);
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);
284 * Write the CSRSS stub for the current system call
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);
290 fprintf(out3,"__asm__(\"\\n\\t.global _%s\\n\\t\"\n",name);
291 fprintf(out3,"\"_%s:\\n\\t\"\n",name);
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);
298 /* Next system call index */
306 void usage(char * argv0)
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",
318 int main(int argc, char* argv[])
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 */
333 in = fopen(argv[1],"rb");
336 perror("Failed to open input file (system calls database)");
340 out1 = fopen(argv[2],"wb");
343 perror("Failed to open output file (WIN32K service table)");
347 out2 = fopen(argv[3],"wb");
350 perror("Failed to open output file (GDI32 stubs)");
354 out3 = fopen(argv[4],"wb");
357 perror("Failed to open output file (USER32 stubs)");
361 out4 = fopen(argv[5],"wb");
364 perror("Failed to open output file (CSRSS stubs)");
368 ret = process(in,out2,out3,out4);
370 ret = makeSystemServiceTable(in, out1);