mirror of
https://github.com/reactos/reactos.git
synced 2025-04-27 17:10:22 +00:00
SYSENTER support, INT2E Optimization, new Syscall Table/Stub generator and svn:ignore fixes. Please read associated Mailing List Post.
svn path=/trunk/; revision=13090
This commit is contained in:
parent
0eab4e1544
commit
f6559e22c4
26 changed files with 1361 additions and 1560 deletions
|
@ -130,7 +130,7 @@ REGTESTS = regtests
|
|||
all: bootstrap $(BOOT_LOADERS) $(COMPONENTS) $(REGTESTS) $(HALS) $(BUS) $(LIB_FSLIB) \
|
||||
$(DLLS) $(SUBSYS) $(KERNEL_DRIVERS) $(SYS_APPS) $(SYS_SVC) $(APPS) $(EXT_MODULES)
|
||||
|
||||
bootstrap: dk implib iface_native iface_additional
|
||||
bootstrap: dk implib iface_native
|
||||
|
||||
depends: $(LIB_STATIC:%=%_depends) $(LIB_FSLIB:%=%_depends) msvcrt_depends $(DLLS:%=%_depends) \
|
||||
$(SUBSYS:%=%_depends) $(SYS_SVC:%=%_depends) \
|
||||
|
@ -147,7 +147,7 @@ test: $(BOOT_LOADERS:%=%_test) $(COMPONENTS:%=%_test) $(HALS:%=%_test) $(BUS:%=%
|
|||
$(KERNEL_DRIVERS:%=%_test) $(SUBSYS:%=%_test) \
|
||||
$(SYS_SVC:%=%_test) $(EXT_MODULES:%=%_test)
|
||||
|
||||
clean: tools dk_clean iface_native_clean iface_additional_clean hallib_clean \
|
||||
clean: tools dk_clean iface_native_clean hallib_clean \
|
||||
$(BOOT_LOADERS:%=%_clean) $(HALS:%=%_clean) $(COMPONENTS:%=%_clean) \
|
||||
$(BUS:%=%_clean) $(LIB_STATIC:%=%_clean) $(LIB_FSLIB:%=%_clean) \
|
||||
msvcrt_clean $(DLLS:%=%_clean) $(KERNEL_DRIVERS:%=%_clean) \
|
||||
|
@ -462,37 +462,21 @@ dk_install:
|
|||
# Interfaces
|
||||
#
|
||||
iface_native:
|
||||
$(MAKE) --silent -C iface/native
|
||||
$(MAKE) --silent -C tools/nci
|
||||
|
||||
iface_native_implib:
|
||||
|
||||
iface_native_test:
|
||||
|
||||
iface_native_clean:
|
||||
$(MAKE) --silent -C iface/native clean
|
||||
$(MAKE) --silent -C tools/nci clean
|
||||
|
||||
iface_native_install:
|
||||
|
||||
iface_native_bootcd:
|
||||
|
||||
iface_additional:
|
||||
$(MAKE) --silent -C iface/addsys
|
||||
|
||||
iface_additional_implib:
|
||||
|
||||
iface_additional_test:
|
||||
|
||||
iface_additional_clean:
|
||||
$(MAKE) --silent -C iface/addsys clean
|
||||
|
||||
iface_additional_install:
|
||||
|
||||
iface_additional_bootcd:
|
||||
|
||||
.PHONY: iface_native iface_native_implib iface_native_test iface_native_clean \
|
||||
iface_native_install iface_native_bootcd iface_additional \
|
||||
iface_additional_implib iface_additional_test iface_additional_clean \
|
||||
iface_additional_install iface_additional_bootcd
|
||||
iface_native_install iface_native_bootcd
|
||||
|
||||
|
||||
#
|
||||
|
|
|
@ -25,7 +25,7 @@ KDBG := 0
|
|||
#
|
||||
# Whether to compile for debugging
|
||||
#
|
||||
DBG := 0
|
||||
DBG := 0
|
||||
|
||||
#
|
||||
# Whether to compile with optimizations
|
||||
|
|
|
@ -1,363 +0,0 @@
|
|||
/* $Id$
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS version of ntdll
|
||||
* FILE: iface/native/genntdll.c
|
||||
* PURPOSE: Generates the system call stubs in ntdll
|
||||
* CHANGE HISTORY: Added a '@xx' to deal with stdcall [ Ariadne ]
|
||||
* 19990616 (ea)
|
||||
* Four arguments now required; 4th is the file
|
||||
* for ntoskrnl ZwXXX functions (which are merely calls
|
||||
* to twin NtXXX calls, via int 0x2e (x86).
|
||||
* 19990617 (ea)
|
||||
* Fixed a bug in function numbers in kernel ZwXXX stubs.
|
||||
*
|
||||
*/
|
||||
|
||||
/* INCLUDE ******************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define PARAMETERIZED_LIBS
|
||||
|
||||
#define INPUT_BUFFER_SIZE 255
|
||||
|
||||
#define INDEX 0x1000 /* SSDT index 1 */
|
||||
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
void write_stub_header(FILE * out)
|
||||
{
|
||||
fputs
|
||||
(
|
||||
"/* Machine generated, don't edit */\n"
|
||||
"\n"
|
||||
"#ifdef __cplusplus\n"
|
||||
"#define EXTERN_C extern \"C\"\n"
|
||||
"#else\n"
|
||||
"#define EXTERN_C\n"
|
||||
"#endif\n"
|
||||
"\n"
|
||||
"EXTERN_C static __inline__ __attribute__((regparm(2)))"
|
||||
"void*ZwRosSystemServiceThunk(long n,void*a)"
|
||||
"{"
|
||||
"void*ret;"
|
||||
"__asm__"
|
||||
"("
|
||||
"\"int $0x2E\":"
|
||||
"\"=a\"(ret):"
|
||||
"\"a\"(n),\"d\"(a)"
|
||||
");"
|
||||
"return ret;"
|
||||
"}\n",
|
||||
out
|
||||
);
|
||||
}
|
||||
|
||||
void write_syscall_stub_func(FILE* out, char* name, unsigned nr_args,
|
||||
unsigned int sys_call_idx)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
fprintf(out, "EXTERN_C void*__stdcall %s(", name);
|
||||
|
||||
if(nr_args == 0)
|
||||
fputs("void", out);
|
||||
else
|
||||
for(i = 0; i < nr_args; ++ i)
|
||||
{
|
||||
if(i > 0)
|
||||
fputs(",", out);
|
||||
|
||||
fprintf(out, "void*a%u", i);
|
||||
}
|
||||
|
||||
fputs("){", out);
|
||||
|
||||
if(nr_args > 1)
|
||||
for(i = 1; i < nr_args; ++ i)
|
||||
fprintf(out, "(void)a%u;", i);
|
||||
|
||||
fprintf(out, "return ZwRosSystemServiceThunk(%u,", sys_call_idx);
|
||||
|
||||
if(nr_args == 0)
|
||||
fputs("0", out);
|
||||
else
|
||||
fputs("&a0", out);
|
||||
|
||||
fputs(");}\n", out);
|
||||
}
|
||||
|
||||
void write_syscall_stub(FILE* out1, FILE* out2, char* name,
|
||||
unsigned nr_args, unsigned int sys_call_idx)
|
||||
{
|
||||
write_syscall_stub_func(out1, name, nr_args, sys_call_idx);
|
||||
write_syscall_stub_func(out2, name, nr_args, sys_call_idx);
|
||||
}
|
||||
|
||||
int makeSystemServiceTable(FILE *in, FILE *out)
|
||||
{
|
||||
char line [INPUT_BUFFER_SIZE];
|
||||
char *s;
|
||||
char *name;
|
||||
int sys_call_idx;
|
||||
char *snr_args;
|
||||
|
||||
/*
|
||||
* Main SSDT Header
|
||||
*/
|
||||
fprintf(out,"// Machine generated, don't edit\n");
|
||||
fprintf(out,"\n\n");
|
||||
|
||||
/*
|
||||
* First we build the Win32k SSDT
|
||||
*/
|
||||
fprintf(out,"SSDT Win32kSSDT[] = {\n");
|
||||
|
||||
/* First system call has index zero */
|
||||
sys_call_idx = 0;
|
||||
|
||||
/* Go on until EOF or read zero bytes */
|
||||
while ((!feof(in))&& (fgets(line, sizeof line, in) != NULL))
|
||||
{
|
||||
if ((s = (char *) strchr(line,'\r')) != NULL)
|
||||
{
|
||||
*s = '\0';
|
||||
}
|
||||
/*
|
||||
* Skip comments (#) and empty lines.
|
||||
*/
|
||||
s = & line[0];
|
||||
if ((*s) != '#' && (*s) != '\0')
|
||||
{
|
||||
/* Extract the NtXXX name */
|
||||
name = (char *)strtok(s," \t");
|
||||
|
||||
#ifdef VERBOSE
|
||||
printf("%3d \"%s\"\n",sys_call_idx | INDEX,name);
|
||||
#endif
|
||||
|
||||
if (sys_call_idx > 0)
|
||||
{
|
||||
fprintf(out,",\n");
|
||||
}
|
||||
/*
|
||||
* Now write the current system call's name
|
||||
* in the service table.
|
||||
*/
|
||||
fprintf(out,"\t\t(PVOID (NTAPI *)(VOID))%s",name);
|
||||
|
||||
/* Next system call index */
|
||||
sys_call_idx++;
|
||||
}
|
||||
}
|
||||
/* Close the service table (C syntax) */
|
||||
fprintf(out,"\n};\n");
|
||||
|
||||
/*
|
||||
* Now we build the Win32k SSPT
|
||||
*/
|
||||
rewind(in);
|
||||
fprintf(out,"\n\n");
|
||||
fprintf(out,"SSPT Win32kSSPT[] = {\n");
|
||||
|
||||
/* First system call has index zero */
|
||||
sys_call_idx = 0;
|
||||
|
||||
/* Go on until EOF or read zero bytes */
|
||||
while ((!feof(in))&& (fgets(line, sizeof line, in) != NULL))
|
||||
{
|
||||
if ((s = (char *) strchr(line,'\r')) != NULL)
|
||||
{
|
||||
*s = '\0';
|
||||
}
|
||||
/*
|
||||
* Skip comments (#) and empty lines.
|
||||
*/
|
||||
s = & line[0];
|
||||
if ((*s) != '#' && (*s) != '\0')
|
||||
{
|
||||
/* Extract the NtXXX name */
|
||||
name = (char *)strtok(s," \t");
|
||||
/* Extract the stack size */
|
||||
snr_args = (char *)strtok(NULL," \t");
|
||||
|
||||
#ifdef VERBOSE
|
||||
printf("%3d \"%s\"\n",sys_call_idx|INDEX,name);
|
||||
#endif
|
||||
|
||||
if (sys_call_idx > 0)
|
||||
{
|
||||
fprintf(out,",\n");
|
||||
}
|
||||
/*
|
||||
* Now write the current system call's ID
|
||||
* in the service table along with its Parameters Size.
|
||||
*/
|
||||
fprintf(out,"\t\t%lu * sizeof(void*)", strtoul(snr_args, NULL, 0));
|
||||
|
||||
/* Next system call index */
|
||||
sys_call_idx++;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Close the service table (C syntax)
|
||||
*/
|
||||
fprintf(out,"\n};\n");
|
||||
|
||||
/*
|
||||
* We write some useful defines
|
||||
*/
|
||||
fprintf(out, "\n\n#define MIN_SYSCALL_NUMBER 0\n");
|
||||
fprintf(out, "#define MAX_SYSCALL_NUMBER %d\n", sys_call_idx-1);
|
||||
fprintf(out, "#define NUMBER_OF_SYSCALLS %d\n", sys_call_idx);
|
||||
fprintf(out, "ULONG Win32kNumberOfSysCalls = %d;\n", sys_call_idx);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
process(
|
||||
FILE * in,
|
||||
FILE * out1,
|
||||
FILE * out2
|
||||
)
|
||||
{
|
||||
char line [INPUT_BUFFER_SIZE];
|
||||
char * s;
|
||||
char * name; /* NtXXX name */
|
||||
int sys_call_idx; /* NtXXX index number in the service table */
|
||||
char * snr_args; /* stack_size / machine_word_size */
|
||||
|
||||
/*
|
||||
* GDI32 stubs file header
|
||||
*/
|
||||
write_stub_header(out1);
|
||||
|
||||
/*
|
||||
* USER32 stubs file header
|
||||
*/
|
||||
write_stub_header(out2);
|
||||
|
||||
/*
|
||||
* Scan the database. DB is a text file; each line
|
||||
* is a record, which contains data for one system
|
||||
* function. Each record has three columns:
|
||||
*
|
||||
* NT_NAME (e.g. NtCreateProcess)
|
||||
* ZW_NAME (e.g. ZwCreateProcess)
|
||||
* STACK_SIZE (in machine words: for x[3456]86
|
||||
* processors a machine word is 4 bytes)
|
||||
*/
|
||||
|
||||
/* First system call has index zero */
|
||||
sys_call_idx = 0;
|
||||
while (
|
||||
/* Go on until EOF or read zero bytes */
|
||||
( (!feof(in))
|
||||
&& (fgets(line, sizeof line, in) != NULL)
|
||||
)
|
||||
)
|
||||
{
|
||||
/*
|
||||
* Remove, if present, the trailing CR.
|
||||
* (os specific?)
|
||||
*/
|
||||
if ((s = (char *) strchr(line,'\r')) != NULL)
|
||||
{
|
||||
*s = '\0';
|
||||
}
|
||||
/*
|
||||
* Skip comments (#) and empty lines.
|
||||
*/
|
||||
s = & line[0];
|
||||
if ((*s) != '#' && (*s) != '\0')
|
||||
{
|
||||
/* Extract the NtXXX name */
|
||||
name = (char *)strtok(s," \t");
|
||||
/* Extract the stack size */
|
||||
snr_args = (char *)strtok(NULL," \t");
|
||||
|
||||
#ifdef VERBOSE
|
||||
printf("%3d \"%s\"\n",sys_call_idx | INDEX,name);
|
||||
#endif
|
||||
|
||||
write_syscall_stub(out1, out2, name, strtoul(snr_args, NULL, 0), sys_call_idx | INDEX);
|
||||
|
||||
/* Next system call index */
|
||||
sys_call_idx++;
|
||||
}
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
void usage(char * argv0)
|
||||
{
|
||||
printf("Usage: %s w32ksvc.db w32k.lst ssdt.h win32k.c win32k.c\n"
|
||||
" w32ksvc.db input file(system calls database)\n"
|
||||
" w32k.lst system functions database\n"
|
||||
" ssdt.h WIN32K service table\n"
|
||||
" win32k.c GDI32 stubs\n"
|
||||
" win32k.c USER32 stubs\n",
|
||||
argv0
|
||||
);
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
FILE * in; /* System calls database */
|
||||
FILE * out1; /* SERVICE_TABLE */
|
||||
FILE * out2; /* GDI32 stubs */
|
||||
FILE * out3; /* USER32 stubs */
|
||||
int ret;
|
||||
|
||||
if (argc != 5)
|
||||
{
|
||||
usage(argv[0]);
|
||||
return(1);
|
||||
}
|
||||
|
||||
in = fopen(argv[1],"rb");
|
||||
if (in == NULL)
|
||||
{
|
||||
perror("Failed to open input file (system calls database)");
|
||||
return(1);
|
||||
}
|
||||
|
||||
out1 = fopen(argv[2],"wb");
|
||||
if (out1 == NULL)
|
||||
{
|
||||
perror("Failed to open output file (WIN32K service table)");
|
||||
return(1);
|
||||
}
|
||||
|
||||
out2 = fopen(argv[3],"wb");
|
||||
if (out2 == NULL)
|
||||
{
|
||||
perror("Failed to open output file (GDI32 stubs)");
|
||||
return(1);
|
||||
}
|
||||
|
||||
out3 = fopen(argv[4],"wb");
|
||||
if (out3 == NULL)
|
||||
{
|
||||
perror("Failed to open output file (USER32 stubs)");
|
||||
return(1);
|
||||
}
|
||||
|
||||
ret = process(in,out2,out3);
|
||||
rewind(in);
|
||||
ret = makeSystemServiceTable(in, out1);
|
||||
|
||||
fclose(in);
|
||||
fclose(out1);
|
||||
fclose(out2);
|
||||
fclose(out3);
|
||||
|
||||
return(ret);
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
# $Id$
|
||||
#
|
||||
# ReactOS Operating System
|
||||
#
|
||||
# Generate files for a kernel module that needs to add a service table.
|
||||
#
|
||||
PATH_TO_TOP = ../..
|
||||
|
||||
#TARGETNAME = mktab
|
||||
TARGETNAME = genw32k
|
||||
|
||||
# WIN32K.SYS
|
||||
SVC_DB=w32ksvc.db
|
||||
SVC_MASK=0x1000
|
||||
|
||||
# DOS and Win32 kernels handle Unix paths too.
|
||||
SVC_SERVICE_TABLE=../../subsys/win32k/main/svctab.c
|
||||
SVC_GDI_STUBS=../../lib/gdi32/misc/win32k.c
|
||||
SVC_USER_STUBS=../../lib/user32/misc/win32k.c
|
||||
|
||||
SVC_FILES = $(SVC_GDI_STUBS) $(SVC_USER_STUBS) $(SVC_SERVICE_TABLE)
|
||||
|
||||
CLEAN_FILES = $(TARGETNAME)$(EXE_POSTFIX) $(SVC_FILES)
|
||||
|
||||
BASE_CFLAGS = -I../../include
|
||||
|
||||
CFLAGS += -Wall -Werror
|
||||
|
||||
all: $(SVC_FILES)
|
||||
|
||||
$(TARGETNAME)$(EXE_POSTFIX): $(TARGETNAME).c
|
||||
$(HOST_CC) \
|
||||
$(CFLAGS) \
|
||||
-o $(TARGETNAME) \
|
||||
-O2 \
|
||||
$(TARGETNAME).c
|
||||
|
||||
$(SVC_FILES): $(SVC_DB) $(TARGETNAME)$(EXE_POSTFIX)
|
||||
@./$(TARGETNAME)$(EXE_POSTFIX) \
|
||||
$(SVC_DB) \
|
||||
$(SVC_SERVICE_TABLE) \
|
||||
$(SVC_GDI_STUBS) \
|
||||
$(SVC_USER_STUBS)
|
||||
|
||||
|
||||
clean:
|
||||
- $(RM) $(CLEAN_FILES)
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
include ../../rules.mak
|
|
@ -1,400 +0,0 @@
|
|||
/* $Id$
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS version of ntdll
|
||||
* FILE: iface/native/genntdll.c
|
||||
* PURPOSE: Generates the system call stubs in ntdll
|
||||
* CHANGE HISTORY: Added a '@xx' to deal with stdcall [ Ariadne ]
|
||||
* 19990616 (ea)
|
||||
* Four arguments now required; 4th is the file
|
||||
* for ntoskrnl ZwXXX functions (which are merely calls
|
||||
* to twin NtXXX calls, via int 0x2e (x86).
|
||||
* 19990617 (ea)
|
||||
* Fixed a bug in function numbers in kernel ZwXXX stubs.
|
||||
* 20040406 (kjkh)
|
||||
* The sysfuncs.lst file now specifies the number of parameters,
|
||||
* not their stack size, for obvious portability reastons. Also, we
|
||||
* now generate real C functions to let the compiler do the correct
|
||||
* name decoration and whatever else (this also makes this tool
|
||||
* marginally more portable).
|
||||
*
|
||||
*/
|
||||
|
||||
/* INCLUDE ******************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define PARAMETERIZED_LIBS
|
||||
|
||||
/* #define VERBOSE */
|
||||
|
||||
#define INPUT_BUFFER_SIZE 255
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
void write_stub_header(FILE * out)
|
||||
{
|
||||
fputs
|
||||
(
|
||||
"/* Machine generated, don't edit */\n"
|
||||
"\n"
|
||||
"#ifdef __cplusplus\n"
|
||||
"#define EXTERN_C extern \"C\"\n"
|
||||
"#else\n"
|
||||
"#define EXTERN_C\n"
|
||||
"#endif\n"
|
||||
"\n"
|
||||
"EXTERN_C static __inline__ __attribute__((regparm(2)))"
|
||||
"void*ZwRosSystemServiceThunk(long n,void*a)"
|
||||
"{"
|
||||
"void*ret;"
|
||||
"__asm__"
|
||||
"("
|
||||
"\"int $0x2E\":"
|
||||
"\"=a\"(ret):"
|
||||
"\"a\"(n),\"d\"(a)"
|
||||
");"
|
||||
"return ret;"
|
||||
"}\n",
|
||||
out
|
||||
);
|
||||
}
|
||||
|
||||
void write_syscall_stub_func(FILE* out, char* name, unsigned nr_args,
|
||||
unsigned int sys_call_idx)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
fprintf(out, "EXTERN_C void*__stdcall %s(", name);
|
||||
|
||||
if(nr_args == 0)
|
||||
fputs("void", out);
|
||||
else
|
||||
for(i = 0; i < nr_args; ++ i)
|
||||
{
|
||||
if(i > 0)
|
||||
fputs(",", out);
|
||||
|
||||
fprintf(out, "void*a%u", i);
|
||||
}
|
||||
|
||||
fputs("){", out);
|
||||
|
||||
if(nr_args > 1)
|
||||
for(i = 1; i < nr_args; ++ i)
|
||||
fprintf(out, "(void)a%u;", i);
|
||||
|
||||
fprintf(out, "return ZwRosSystemServiceThunk(%u,", sys_call_idx);
|
||||
|
||||
if(nr_args == 0)
|
||||
fputs("0", out);
|
||||
else
|
||||
fputs("&a0", out);
|
||||
|
||||
fputs(");}\n", out);
|
||||
}
|
||||
|
||||
void write_syscall_stub(FILE* out, FILE* out3, char* name, char* name2,
|
||||
unsigned nr_args, unsigned int sys_call_idx)
|
||||
{
|
||||
write_syscall_stub_func(out, name, nr_args, sys_call_idx);
|
||||
write_syscall_stub_func(out, name2, nr_args, sys_call_idx);
|
||||
|
||||
/*
|
||||
* Now write the NTOSKRNL stub for the
|
||||
* current system call. ZwXXX does NOT
|
||||
* alias the corresponding NtXXX call.
|
||||
*/
|
||||
write_syscall_stub_func(out3, name2, nr_args, sys_call_idx);
|
||||
}
|
||||
|
||||
int makeSystemServiceTable(FILE *in, FILE *out)
|
||||
{
|
||||
char line [INPUT_BUFFER_SIZE];
|
||||
char *s;
|
||||
char *name;
|
||||
char *name2;
|
||||
int sys_call_idx;
|
||||
char *snr_args;
|
||||
char *stmp;
|
||||
|
||||
/*
|
||||
* Main SSDT Header
|
||||
*/
|
||||
fprintf(out,"/* Machine generated, don't edit */\n");
|
||||
fprintf(out,"\n\n");
|
||||
|
||||
/*
|
||||
* First we build the Main SSDT
|
||||
*/
|
||||
fprintf(out,"\n\n\n");
|
||||
fprintf(out,"SSDT MainSSDT[] = {\n");
|
||||
|
||||
for ( /* First system call has index zero */
|
||||
sys_call_idx = 0;
|
||||
/* Go on until EOF or read zero bytes */
|
||||
( (!feof(in))
|
||||
&& (fgets(line, sizeof line, in) != NULL)
|
||||
);
|
||||
/* Next system call index */
|
||||
sys_call_idx++
|
||||
)
|
||||
{
|
||||
if ((s = (char *) strchr(line,'\r')) != NULL)
|
||||
{
|
||||
*s = '\0';
|
||||
}
|
||||
/*
|
||||
* Skip comments (#) and empty lines.
|
||||
*/
|
||||
s = & line[0];
|
||||
if ((*s) != '#' && (*s) != '\0')
|
||||
{
|
||||
/* Extract the NtXXX name */
|
||||
name = (char *)strtok(s," \t");
|
||||
/* Extract the ZwXXX name */
|
||||
name2 = (char *)strtok(NULL," \t");
|
||||
//value = strtok(NULL," \t");
|
||||
/* Extract the argument count */
|
||||
snr_args = (char *)strtok(NULL," \t");
|
||||
/*
|
||||
* Remove, if present, the trailing LF.
|
||||
*/
|
||||
if ((stmp = strchr(snr_args, '\n')) != NULL)
|
||||
{
|
||||
*stmp = '\0';
|
||||
}
|
||||
#ifdef VERBOSE
|
||||
printf("%3d \"%s\"\n",sys_call_idx,name);
|
||||
#endif
|
||||
|
||||
if (sys_call_idx > 0)
|
||||
{
|
||||
fprintf(out,",\n");
|
||||
}
|
||||
/*
|
||||
* Now write the current system call's name
|
||||
* in the service table.
|
||||
*/
|
||||
fprintf(out,"\t\t(PVOID (NTAPI *)(VOID))%s",name);
|
||||
}
|
||||
}
|
||||
/* Close the service table (C syntax) */
|
||||
fprintf(out,"\n};\n");
|
||||
|
||||
/*
|
||||
* Now we build the Main SSPT
|
||||
*/
|
||||
rewind(in);
|
||||
fprintf(out,"\n\n\n");
|
||||
fprintf(out,"SSPT MainSSPT[] = {\n");
|
||||
|
||||
for ( /* First system call has index zero */
|
||||
sys_call_idx = 0;
|
||||
/* Go on until EOF or read zero bytes */
|
||||
( (!feof(in))
|
||||
&& (fgets(line, sizeof line, in) != NULL)
|
||||
);
|
||||
/* Next system call index */
|
||||
sys_call_idx++
|
||||
)
|
||||
{
|
||||
if ((s = (char *) strchr(line,'\r')) != NULL)
|
||||
{
|
||||
*s = '\0';
|
||||
}
|
||||
/*
|
||||
* Skip comments (#) and empty lines.
|
||||
*/
|
||||
s = & line[0];
|
||||
if ((*s) != '#' && (*s) != '\0')
|
||||
{
|
||||
/* Extract the NtXXX name */
|
||||
name = (char *)strtok(s," \t");
|
||||
/* Extract the ZwXXX name */
|
||||
name2 = (char *)strtok(NULL," \t");
|
||||
//value = strtok(NULL," \t");
|
||||
/* Extract the argument count */
|
||||
snr_args = (char *)strtok(NULL," \t");
|
||||
#ifdef VERBOSE
|
||||
printf("%3d \"%s\"\n",sys_call_idx,name);
|
||||
#endif
|
||||
|
||||
if (sys_call_idx > 0)
|
||||
{
|
||||
fprintf(out,",\n");
|
||||
}
|
||||
/*
|
||||
* Now write the current system call's ID
|
||||
* in the service table along with its Parameters Size.
|
||||
*/
|
||||
fprintf(out,"\t\t%lu * sizeof(void *)",strtoul(snr_args, NULL, 0));
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Close the service table (C syntax)
|
||||
*/
|
||||
fprintf(out,"\n};\n");
|
||||
|
||||
/*
|
||||
* We write some useful defines
|
||||
*/
|
||||
fprintf(out, "\n\n#define MIN_SYSCALL_NUMBER 0\n");
|
||||
fprintf(out, "#define MAX_SYSCALL_NUMBER %d\n", sys_call_idx-1);
|
||||
fprintf(out, "#define NUMBER_OF_SYSCALLS %d\n", sys_call_idx);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
process(
|
||||
FILE * in,
|
||||
FILE * out,
|
||||
FILE * out2,
|
||||
FILE * out3
|
||||
)
|
||||
{
|
||||
char line [INPUT_BUFFER_SIZE];
|
||||
char * s;
|
||||
char * name; /* NtXXX name */
|
||||
char * name2; /* ZwXXX name */
|
||||
int sys_call_idx; /* NtXXX index number in the service table */
|
||||
char * snr_args; /* stack_size / machine_word_size */
|
||||
|
||||
/*
|
||||
* NTDLL stubs file header
|
||||
*/
|
||||
write_stub_header(out);
|
||||
|
||||
/*
|
||||
* NTOSKRNL Zw functions stubs header
|
||||
*/
|
||||
write_stub_header(out3);
|
||||
|
||||
/*
|
||||
* Scan the database. DB is a text file; each line
|
||||
* is a record, which contains data for one system
|
||||
* function. Each record has three columns:
|
||||
*
|
||||
* NT_NAME (e.g. NtCreateProcess)
|
||||
* ZW_NAME (e.g. ZwCreateProcess)
|
||||
* STACK_SIZE (in machine words: for x[3456]86
|
||||
* processors a machine word is 4 bytes)
|
||||
*/
|
||||
for ( /* First system call has index zero */
|
||||
sys_call_idx = 0;
|
||||
/* Go on until EOF or read zero bytes */
|
||||
( (!feof(in))
|
||||
&& (fgets(line, sizeof line, in) != NULL)
|
||||
);
|
||||
/* Next system call index */
|
||||
sys_call_idx++
|
||||
)
|
||||
{
|
||||
/*
|
||||
* Remove, if present, the trailing CR.
|
||||
* (os specific?)
|
||||
*/
|
||||
if ((s = (char *) strchr(line,'\r')) != NULL)
|
||||
{
|
||||
*s = '\0';
|
||||
}
|
||||
/*
|
||||
* Skip comments (#) and empty lines.
|
||||
*/
|
||||
s = & line[0];
|
||||
if ((*s) != '#' && (*s) != '\0')
|
||||
{
|
||||
unsigned nr_args;
|
||||
|
||||
/* Extract the NtXXX name */
|
||||
name = (char *)strtok(s," \t");
|
||||
/* Extract the ZwXXX name */
|
||||
name2 = (char *)strtok(NULL," \t");
|
||||
//value = strtok(NULL," \t");
|
||||
/* Extract the argument count */
|
||||
snr_args = (char *)strtok(NULL," \t");
|
||||
nr_args = strtoul(snr_args, NULL, 0);
|
||||
#ifdef VERBOSE
|
||||
printf("%3d \"%s\"\n",sys_call_idx,name);
|
||||
#endif
|
||||
/*
|
||||
* Write the NTDLL stub for the current
|
||||
* system call: NtXXX and ZwXXX symbols
|
||||
* are aliases.
|
||||
*/
|
||||
write_syscall_stub(out, out3, name, name2,
|
||||
nr_args, sys_call_idx);
|
||||
}
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
void usage(char * argv0)
|
||||
{
|
||||
printf("Usage: %s sysfuncs.lst napi.c napi.h zw.c\n"
|
||||
" sysfuncs.lst system functions database\n"
|
||||
" napi.c NTDLL stubs\n"
|
||||
" napi.h NTOSKRNL service table\n"
|
||||
" zw.c NTOSKRNL Zw stubs\n",
|
||||
argv0
|
||||
);
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
FILE * in; /* System calls database */
|
||||
FILE * out1; /* NTDLL stubs */
|
||||
FILE * out2; /* SERVICE_TABLE */
|
||||
FILE * out3; /* NTOSKRNL Zw stubs */
|
||||
int ret;
|
||||
|
||||
if (argc != 5)
|
||||
{
|
||||
usage(argv[0]);
|
||||
return(1);
|
||||
}
|
||||
|
||||
in = fopen(argv[1],"rb");
|
||||
if (in == NULL)
|
||||
{
|
||||
perror("Failed to open input file (system calls database)");
|
||||
return(1);
|
||||
}
|
||||
|
||||
out1 = fopen(argv[2],"wb");
|
||||
if (out1 == NULL)
|
||||
{
|
||||
perror("Failed to open output file (NTDLL stubs)");
|
||||
return(1);
|
||||
}
|
||||
|
||||
out2 = fopen(argv[3],"wb");
|
||||
if (out2 == NULL)
|
||||
{
|
||||
perror("Failed to open output file (NTOSKRNL service table)");
|
||||
return(1);
|
||||
}
|
||||
|
||||
out3 = fopen(argv[4],"wb");
|
||||
if (out3 == NULL)
|
||||
{
|
||||
perror("Failed to open output file (NTOSKRNL Zw stubs)");
|
||||
return(1);
|
||||
}
|
||||
|
||||
ret = process(in,out1,out2,out3);
|
||||
rewind(in);
|
||||
ret = makeSystemServiceTable(in, out2);
|
||||
|
||||
fclose(in);
|
||||
fclose(out1);
|
||||
fclose(out2);
|
||||
fclose(out3);
|
||||
|
||||
return(ret);
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
# $Id$
|
||||
#
|
||||
# ReactOS Operating System
|
||||
#
|
||||
# Generate:
|
||||
# - genntdll
|
||||
# - ntoskrnl.exe service table;
|
||||
# - ntoskrnl.exe Zw functions stubs to call Nt functions from kernel mode;
|
||||
# - ntdll.dll stubs to call system functions from user mode applications.
|
||||
#
|
||||
PATH_TO_TOP = ../..
|
||||
|
||||
TARGET = genntdll
|
||||
SYSTEM_CALLS_DB = sysfuncs.lst
|
||||
NTDLL_STUBS = ../../lib/ntdll/napi.c
|
||||
KERNEL_SERVICE_TABLE = ../../include/ntdll/napi.h
|
||||
KERNEL_ZW_CALLS = ../../ntoskrnl/ex/zw.c
|
||||
NAPI_FILES = $(NTDLL_STUBS) $(KERNEL_SERVICE_TABLE) $(KERNEL_ZW_CALLS)
|
||||
|
||||
BASE_CFLAGS = -I../../include
|
||||
|
||||
all: $(TARGET)$(EXE_POSTFIX) $(NAPI_FILES)
|
||||
|
||||
$(NAPI_FILES): $(SYSTEM_CALLS_DB) $(TARGET)$(EXE_POSTFIX)
|
||||
@./$(TARGET)$(EXE_POSTFIX) \
|
||||
$(SYSTEM_CALLS_DB) \
|
||||
$(NTDLL_STUBS) \
|
||||
$(KERNEL_SERVICE_TABLE) \
|
||||
$(KERNEL_ZW_CALLS)
|
||||
|
||||
# (rjj) i removed the following option from line below: -If:\gnu\mingw32\include
|
||||
$(TARGET)$(EXE_POSTFIX): $(TARGET).c
|
||||
$(HOST_CC) -g -Wall -Werror $(TARGET).c -o $(TARGET)$(EXE_POSTFIX)
|
||||
|
||||
clean:
|
||||
- $(RM) $(TARGET)$(EXE_POSTFIX) $(NTDLL_STUBS) $(KERNEL_SERVICE_TABLE) $(KERNEL_ZW_CALLS)
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
include ../../rules.mak
|
|
@ -1,235 +0,0 @@
|
|||
NtAcceptConnectPort ZwAcceptConnectPort 6
|
||||
NtAccessCheck ZwAccessCheck 8
|
||||
NtAccessCheckAndAuditAlarm ZwAccessCheckAndAuditAlarm 11
|
||||
NtAddAtom ZwAddAtom 3
|
||||
NtAddBootEntry ZwAddBootEntry 2
|
||||
NtAdjustGroupsToken ZwAdjustGroupsToken 6
|
||||
NtAdjustPrivilegesToken ZwAdjustPrivilegesToken 6
|
||||
NtAlertResumeThread ZwAlertResumeThread 2
|
||||
NtAlertThread ZwAlertThread 1
|
||||
NtAllocateLocallyUniqueId ZwAllocateLocallyUniqueId 1
|
||||
NtAllocateUuids ZwAllocateUuids 4
|
||||
NtAllocateVirtualMemory ZwAllocateVirtualMemory 6
|
||||
NtAssignProcessToJobObject ZwAssignProcessToJobObject 2
|
||||
NtCallbackReturn ZwCallbackReturn 3
|
||||
NtCancelIoFile ZwCancelIoFile 2
|
||||
NtCancelTimer ZwCancelTimer 2
|
||||
NtClearEvent ZwClearEvent 1
|
||||
NtClose ZwClose 1
|
||||
NtCloseObjectAuditAlarm ZwCloseObjectAuditAlarm 3
|
||||
NtCompleteConnectPort ZwCompleteConnectPort 1
|
||||
NtConnectPort ZwConnectPort 8
|
||||
NtContinue ZwContinue 2
|
||||
NtCreateDirectoryObject ZwCreateDirectoryObject 3
|
||||
NtCreateEvent ZwCreateEvent 5
|
||||
NtCreateEventPair ZwCreateEventPair 3
|
||||
NtCreateFile ZwCreateFile 11
|
||||
NtCreateIoCompletion ZwCreateIoCompletion 4
|
||||
NtCreateJobObject ZwCreateJobObject 3
|
||||
NtCreateKey ZwCreateKey 7
|
||||
NtCreateMailslotFile ZwCreateMailslotFile 8
|
||||
NtCreateMutant ZwCreateMutant 4
|
||||
NtCreateNamedPipeFile ZwCreateNamedPipeFile 14
|
||||
NtCreatePagingFile ZwCreatePagingFile 4
|
||||
NtCreatePort ZwCreatePort 5
|
||||
NtCreateProcess ZwCreateProcess 8
|
||||
NtCreateProfile ZwCreateProfile 9
|
||||
NtCreateSection ZwCreateSection 7
|
||||
NtCreateSemaphore ZwCreateSemaphore 5
|
||||
NtCreateSymbolicLinkObject ZwCreateSymbolicLinkObject 4
|
||||
NtCreateThread ZwCreateThread 8
|
||||
NtCreateTimer ZwCreateTimer 4
|
||||
NtCreateToken ZwCreateToken 13
|
||||
NtCreateWaitablePort ZwCreateWaitablePort 5
|
||||
NtDelayExecution ZwDelayExecution 2
|
||||
NtDeleteAtom ZwDeleteAtom 1
|
||||
NtDeleteBootEntry ZwDeleteBootEntry 2
|
||||
NtDeleteFile ZwDeleteFile 1
|
||||
NtDeleteKey ZwDeleteKey 1
|
||||
NtDeleteObjectAuditAlarm ZwDeleteObjectAuditAlarm 3
|
||||
NtDeleteValueKey ZwDeleteValueKey 2
|
||||
NtDeviceIoControlFile ZwDeviceIoControlFile 10
|
||||
NtDisplayString ZwDisplayString 1
|
||||
NtDuplicateObject ZwDuplicateObject 7
|
||||
NtDuplicateToken ZwDuplicateToken 6
|
||||
NtEnumerateBootEntries ZwEnumerateBootEntries 2
|
||||
NtEnumerateKey ZwEnumerateKey 6
|
||||
NtEnumerateValueKey ZwEnumerateValueKey 6
|
||||
NtExtendSection ZwExtendSection 2
|
||||
NtFindAtom ZwFindAtom 3
|
||||
NtFlushBuffersFile ZwFlushBuffersFile 2
|
||||
NtFlushInstructionCache ZwFlushInstructionCache 3
|
||||
NtFlushKey ZwFlushKey 1
|
||||
NtFlushVirtualMemory ZwFlushVirtualMemory 4
|
||||
NtFlushWriteBuffer ZwFlushWriteBuffer 0
|
||||
NtFreeVirtualMemory ZwFreeVirtualMemory 4
|
||||
NtFsControlFile ZwFsControlFile 10
|
||||
NtGetContextThread ZwGetContextThread 2
|
||||
NtGetPlugPlayEvent ZwGetPlugPlayEvent 4
|
||||
NtGetTickCount ZwGetTickCount 0
|
||||
NtImpersonateClientOfPort ZwImpersonateClientOfPort 2
|
||||
NtImpersonateThread ZwImpersonateThread 3
|
||||
NtInitializeRegistry ZwInitializeRegistry 1
|
||||
NtInitiatePowerAction ZwInitiatePowerAction 4
|
||||
NtIsProcessInJob ZwIsProcessInJob 2
|
||||
NtListenPort ZwListenPort 2
|
||||
NtLoadDriver ZwLoadDriver 1
|
||||
NtLoadKey ZwLoadKey 2
|
||||
NtLoadKey2 ZwLoadKey2 3
|
||||
NtLockFile ZwLockFile 10
|
||||
NtLockVirtualMemory ZwLockVirtualMemory 4
|
||||
NtMakePermanentObject ZwMakePermanentObject 1
|
||||
NtMakeTemporaryObject ZwMakeTemporaryObject 1
|
||||
NtMapViewOfSection ZwMapViewOfSection 10
|
||||
NtNotifyChangeDirectoryFile ZwNotifyChangeDirectoryFile 9
|
||||
NtNotifyChangeKey ZwNotifyChangeKey 10
|
||||
NtOpenDirectoryObject ZwOpenDirectoryObject 3
|
||||
NtOpenEvent ZwOpenEvent 3
|
||||
NtOpenEventPair ZwOpenEventPair 3
|
||||
NtOpenFile ZwOpenFile 6
|
||||
NtOpenIoCompletion ZwOpenIoCompletion 3
|
||||
NtOpenJobObject ZwOpenJobObject 3
|
||||
NtOpenKey ZwOpenKey 3
|
||||
NtOpenMutant ZwOpenMutant 3
|
||||
NtOpenObjectAuditAlarm ZwOpenObjectAuditAlarm 12
|
||||
NtOpenProcess ZwOpenProcess 4
|
||||
NtOpenProcessToken ZwOpenProcessToken 3
|
||||
NtOpenProcessTokenEx ZwOpenProcessTokenEx 4
|
||||
NtOpenSection ZwOpenSection 3
|
||||
NtOpenSemaphore ZwOpenSemaphore 3
|
||||
NtOpenSymbolicLinkObject ZwOpenSymbolicLinkObject 3
|
||||
NtOpenThread ZwOpenThread 4
|
||||
NtOpenThreadToken ZwOpenThreadToken 4
|
||||
NtOpenThreadTokenEx ZwOpenThreadTokenEx 5
|
||||
NtOpenTimer ZwOpenTimer 3
|
||||
NtPlugPlayControl ZwPlugPlayControl 4
|
||||
NtPowerInformation ZwPowerInformation 5
|
||||
NtPrivilegeCheck ZwPrivilegeCheck 3
|
||||
NtPrivilegedServiceAuditAlarm ZwPrivilegedServiceAuditAlarm 5
|
||||
NtPrivilegeObjectAuditAlarm ZwPrivilegeObjectAuditAlarm 6
|
||||
NtProtectVirtualMemory ZwProtectVirtualMemory 5
|
||||
NtPulseEvent ZwPulseEvent 2
|
||||
NtQueryInformationAtom ZwQueryInformationAtom 5
|
||||
NtQueryAttributesFile ZwQueryAttributesFile 2
|
||||
NtQueryBootEntryOrder ZwQueryBootEntryOrder 2
|
||||
NtQueryBootOptions ZwQueryBootOptions 2
|
||||
NtQueryDefaultLocale ZwQueryDefaultLocale 2
|
||||
NtQueryDefaultUILanguage ZwQueryDefaultUILanguage 1
|
||||
NtQueryDirectoryFile ZwQueryDirectoryFile 11
|
||||
NtQueryDirectoryObject ZwQueryDirectoryObject 7
|
||||
NtQueryEaFile ZwQueryEaFile 9
|
||||
NtQueryEvent ZwQueryEvent 5
|
||||
NtQueryFullAttributesFile ZwQueryFullAttributesFile 2
|
||||
NtQueryInformationFile ZwQueryInformationFile 5
|
||||
NtQueryInformationJobObject ZwQueryInformationJobObject 5
|
||||
NtQueryInformationPort ZwQueryInformationPort 5
|
||||
NtQueryInformationProcess ZwQueryInformationProcess 5
|
||||
NtQueryInformationThread ZwQueryInformationThread 5
|
||||
NtQueryInformationToken ZwQueryInformationToken 5
|
||||
NtQueryInstallUILanguage ZwQueryInstallUILanguage 1
|
||||
NtQueryIntervalProfile ZwQueryIntervalProfile 2
|
||||
NtQueryIoCompletion ZwQueryIoCompletion 5
|
||||
NtQueryKey ZwQueryKey 5
|
||||
NtQueryMultipleValueKey ZwQueryMultipleValueKey 6
|
||||
NtQueryMutant ZwQueryMutant 5
|
||||
NtQueryObject ZwQueryObject 5
|
||||
NtQueryOleDirectoryFile ZwQueryOleDirectoryFile 11
|
||||
NtQueryPerformanceCounter ZwQueryPerformanceCounter 2
|
||||
NtQueryQuotaInformationFile ZwQueryQuotaInformationFile 9
|
||||
NtQuerySection ZwQuerySection 5
|
||||
NtQuerySecurityObject ZwQuerySecurityObject 5
|
||||
NtQuerySemaphore ZwQuerySemaphore 5
|
||||
NtQuerySymbolicLinkObject ZwQuerySymbolicLinkObject 3
|
||||
NtQuerySystemEnvironmentValue ZwQuerySystemEnvironmentValue 4
|
||||
NtQuerySystemInformation ZwQuerySystemInformation 4
|
||||
NtQuerySystemTime ZwQuerySystemTime 1
|
||||
NtQueryTimer ZwQueryTimer 5
|
||||
NtQueryTimerResolution ZwQueryTimerResolution 3
|
||||
NtQueryValueKey ZwQueryValueKey 6
|
||||
NtQueryVirtualMemory ZwQueryVirtualMemory 6
|
||||
NtQueryVolumeInformationFile ZwQueryVolumeInformationFile 5
|
||||
NtQueueApcThread ZwQueueApcThread 5
|
||||
NtRaiseException ZwRaiseException 3
|
||||
NtRaiseHardError ZwRaiseHardError 6
|
||||
NtReadFile ZwReadFile 9
|
||||
NtReadFileScatter ZwReadFileScatter 9
|
||||
NtReadRequestData ZwReadRequestData 6
|
||||
NtReadVirtualMemory ZwReadVirtualMemory 5
|
||||
NtRegisterThreadTerminatePort ZwRegisterThreadTerminatePort 1
|
||||
NtReleaseMutant ZwReleaseMutant 2
|
||||
NtReleaseSemaphore ZwReleaseSemaphore 3
|
||||
NtRemoveIoCompletion ZwRemoveIoCompletion 5
|
||||
NtReplaceKey ZwReplaceKey 3
|
||||
NtReplyPort ZwReplyPort 2
|
||||
NtReplyWaitReceivePort ZwReplyWaitReceivePort 4
|
||||
NtReplyWaitReplyPort ZwReplyWaitReplyPort 2
|
||||
NtRequestPort ZwRequestPort 2
|
||||
NtRequestWaitReplyPort ZwRequestWaitReplyPort 3
|
||||
NtResetEvent ZwResetEvent 2
|
||||
NtRestoreKey ZwRestoreKey 3
|
||||
NtResumeThread ZwResumeThread 2
|
||||
NtSaveKey ZwSaveKey 2
|
||||
NtSaveKeyEx ZwSaveKeyEx 3
|
||||
NtSetBootEntryOrder ZwSetBootEntryOrder 2
|
||||
NtSetBootOptions ZwSetBootOptions 2
|
||||
NtSetIoCompletion ZwSetIoCompletion 5
|
||||
NtSetContextThread ZwSetContextThread 2
|
||||
NtSetDefaultHardErrorPort ZwSetDefaultHardErrorPort 1
|
||||
NtSetDefaultLocale ZwSetDefaultLocale 2
|
||||
NtSetDefaultUILanguage ZwSetDefaultUILanguage 1
|
||||
NtSetEaFile ZwSetEaFile 4
|
||||
NtSetEvent ZwSetEvent 2
|
||||
NtSetHighEventPair ZwSetHighEventPair 1
|
||||
NtSetHighWaitLowEventPair ZwSetHighWaitLowEventPair 1
|
||||
NtSetHighWaitLowThread ZwSetHighWaitLowThread 0
|
||||
NtSetInformationFile ZwSetInformationFile 5
|
||||
NtSetInformationKey ZwSetInformationKey 4
|
||||
NtSetInformationJobObject ZwSetInformationJobObject 4
|
||||
NtSetInformationObject ZwSetInformationObject 4
|
||||
NtSetInformationProcess ZwSetInformationProcess 4
|
||||
NtSetInformationThread ZwSetInformationThread 4
|
||||
NtSetInformationToken ZwSetInformationToken 4
|
||||
NtSetIntervalProfile ZwSetIntervalProfile 2
|
||||
NtSetLdtEntries ZwSetLdtEntries 6
|
||||
NtSetLowEventPair ZwSetLowEventPair 1
|
||||
NtSetLowWaitHighEventPair ZwSetLowWaitHighEventPair 1
|
||||
NtSetLowWaitHighThread ZwSetLowWaitHighThread 0
|
||||
NtSetQuotaInformationFile ZwSetQuotaInformationFile 4
|
||||
NtSetSecurityObject ZwSetSecurityObject 3
|
||||
NtSetSystemEnvironmentValue ZwSetSystemEnvironmentValue 2
|
||||
NtSetSystemInformation ZwSetSystemInformation 3
|
||||
NtSetSystemPowerState ZwSetSystemPowerState 3
|
||||
NtSetSystemTime ZwSetSystemTime 2
|
||||
NtSetTimer ZwSetTimer 7
|
||||
NtSetTimerResolution ZwSetTimerResolution 3
|
||||
NtSetUuidSeed ZwSetUuidSeed 1
|
||||
NtSetValueKey ZwSetValueKey 6
|
||||
NtSetVolumeInformationFile ZwSetVolumeInformationFile 5
|
||||
NtShutdownSystem ZwShutdownSystem 1
|
||||
NtSignalAndWaitForSingleObject ZwSignalAndWaitForSingleObject 4
|
||||
NtStartProfile ZwStartProfile 1
|
||||
NtStopProfile ZwStopProfile 1
|
||||
NtSuspendThread ZwSuspendThread 2
|
||||
NtSystemDebugControl ZwSystemDebugControl 6
|
||||
NtTerminateJobObject ZwTerminateJobObject 2
|
||||
NtTerminateProcess ZwTerminateProcess 2
|
||||
NtTerminateThread ZwTerminateThread 2
|
||||
NtTestAlert ZwTestAlert 0
|
||||
NtTraceEvent ZwTraceEvent 4
|
||||
NtTranslateFilePath ZwTranslateFilePath 3
|
||||
NtUnloadDriver ZwUnloadDriver 1
|
||||
NtUnloadKey ZwUnloadKey 1
|
||||
NtUnlockFile ZwUnlockFile 5
|
||||
NtUnlockVirtualMemory ZwUnlockVirtualMemory 4
|
||||
NtUnmapViewOfSection ZwUnmapViewOfSection 2
|
||||
NtVdmControl ZwVdmControl 2
|
||||
NtWaitForMultipleObjects ZwWaitForMultipleObjects 5
|
||||
NtWaitForSingleObject ZwWaitForSingleObject 3
|
||||
NtWaitHighEventPair ZwWaitHighEventPair 1
|
||||
NtWaitLowEventPair ZwWaitLowEventPair 1
|
||||
NtWriteFile ZwWriteFile 9
|
||||
NtWriteFileGather ZwWriteFileGather 9
|
||||
NtWriteRequestData ZwWriteRequestData 6
|
||||
NtWriteVirtualMemory ZwWriteVirtualMemory 5
|
||||
NtW32Call ZwW32Call 5
|
||||
NtYieldExecution ZwYieldExecution 0
|
|
@ -13,6 +13,8 @@
|
|||
#define PF_PAE_ENABLED 9
|
||||
#define PF_XMMI64_INSTRUCTIONS_AVAILABLE 10
|
||||
|
||||
#ifndef __ASM__
|
||||
|
||||
typedef enum _ALTERNATIVE_ARCHITECTURE_TYPE
|
||||
{
|
||||
StandardDesign,
|
||||
|
@ -62,13 +64,15 @@ typedef struct _KUSER_SHARED_DATA {
|
|||
BOOLEAN SafeBootMode;
|
||||
ULONG TraceLogging;
|
||||
ULONGLONG Fill0;
|
||||
ULONGLONG SystemCall[4];
|
||||
UCHAR SystemCall[16];
|
||||
union {
|
||||
volatile KSYSTEM_TIME TickCount;
|
||||
volatile ULONG64 TickCountQuad;
|
||||
};
|
||||
} KUSER_SHARED_DATA, *PKUSER_SHARED_DATA;
|
||||
|
||||
#endif
|
||||
|
||||
/* Values for DosDeviceDriveType */
|
||||
#define DOSDEVICE_DRIVE_UNKNOWN 0
|
||||
#define DOSDEVICE_DRIVE_CALCULATE 1
|
||||
|
@ -102,5 +106,7 @@ typedef struct _KUSER_SHARED_DATA {
|
|||
#define SharedUserData ((KUSER_SHARED_DATA * const)USER_SHARED_DATA)
|
||||
#endif
|
||||
|
||||
#define KUSER_SHARED_SYSCALL 0x7FFE0300
|
||||
#define KUSER_SHARED_SYSCALL_RET 0x7FFE0304
|
||||
|
||||
#endif /* __INCLUDE_NAPI_SHARED_DATA_H */
|
||||
|
|
|
@ -550,7 +550,7 @@ TARGET_CLEAN = \
|
|||
$(PATH_TO_TOP)/include/reactos/bugcodes.h \
|
||||
$(DEP_OBJECTS) $(DEP_FILES) MSG00409.bin bugcodes.rc
|
||||
|
||||
ex/napi.o: ex/napi.c $(PATH_TO_TOP)/include/ntdll/napi.h
|
||||
ex/napi.o: ex/zw.S $(PATH_TO_TOP)/include/ntdll/napi.h
|
||||
|
||||
ke/main.o: ke/main.c $(PATH_TO_TOP)/include/reactos/buildno.h
|
||||
|
||||
|
|
|
@ -88,6 +88,7 @@
|
|||
#define X86_FEATURE_TSC 0x00000010 /* time stamp counters are present */
|
||||
#define X86_FEATURE_PAE 0x00000040 /* physical address extension is present */
|
||||
#define X86_FEATURE_CX8 0x00000100 /* CMPXCHG8B instruction present */
|
||||
#define X86_FEATURE_SYSCALL 0x00000800 /* SYSCALL/SYSRET support present */
|
||||
#define X86_FEATURE_PGE 0x00002000 /* Page Global Enable */
|
||||
#define X86_FEATURE_MMX 0x00800000 /* MMX extension present */
|
||||
#define X86_FEATURE_FXSR 0x01000000 /* FXSAVE/FXRSTOR instructions present */
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#define KTHREAD_TEB 0x20
|
||||
#define KTHREAD_KERNEL_STACK 0x28
|
||||
#define KTHREAD_NPX_STATE 0x31
|
||||
#define KTHREAD_PENDING_USER_APC 0x34 + 0x16
|
||||
#define KTHREAD_APCSTATE_PROCESS 0x44
|
||||
#define KTHREAD_SERVICE_TABLE 0xDC
|
||||
#define KTHREAD_PREVIOUS_MODE 0x137
|
||||
|
|
|
@ -143,4 +143,4 @@ _PsBeginThreadWithContextInternal:
|
|||
|
||||
/* Load the rest of the thread's user mode context. */
|
||||
movl $0, %eax
|
||||
jmp KeReturnFromSystemCallWithHook
|
||||
jmp _KiServiceExit
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
# define ARRAY_SIZE(x) (sizeof (x) / sizeof (x[0]))
|
||||
#endif
|
||||
|
||||
extern void interrupt_handler2e(void);
|
||||
extern void KiSystemService(void);
|
||||
extern void interrupt_handler2d(void);
|
||||
|
||||
extern VOID KiTrap0(VOID);
|
||||
|
@ -850,7 +850,7 @@ KeInitExceptions(VOID)
|
|||
}
|
||||
|
||||
set_system_call_gate(0x2d,(int)interrupt_handler2d);
|
||||
set_system_call_gate(0x2e,(int)interrupt_handler2e);
|
||||
set_system_call_gate(0x2e,(int)KiSystemService);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -873,30 +873,32 @@ KeRaiseUserException(IN NTSTATUS ExceptionCode)
|
|||
return((NTSTATUS)OldEip);
|
||||
}
|
||||
|
||||
VOID
|
||||
FASTCALL
|
||||
KeRosTrapReturn ( PKTRAP_FRAME TrapFrame, PKTRAP_FRAME PrevTrapFrame );
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
NTSTATUS STDCALL
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
NtRaiseException (
|
||||
IN PEXCEPTION_RECORD ExceptionRecord,
|
||||
IN PCONTEXT Context,
|
||||
IN BOOLEAN SearchFrames)
|
||||
IN PEXCEPTION_RECORD ExceptionRecord,
|
||||
IN PCONTEXT Context,
|
||||
IN BOOLEAN SearchFrames)
|
||||
{
|
||||
PKTRAP_FRAME TrapFrame = KeGetCurrentThread()->TrapFrame;
|
||||
PKTRAP_FRAME PrevTrapFrame = (PKTRAP_FRAME)TrapFrame->Edx;
|
||||
PKTHREAD Thread = KeGetCurrentThread();
|
||||
PKTRAP_FRAME TrapFrame = Thread->TrapFrame;
|
||||
PKTRAP_FRAME PrevTrapFrame = (PKTRAP_FRAME)TrapFrame->Edx;
|
||||
|
||||
KeGetCurrentKPCR()->Tib.ExceptionList = TrapFrame->ExceptionList;
|
||||
KeGetCurrentKPCR()->Tib.ExceptionList = TrapFrame->ExceptionList;
|
||||
|
||||
KiDispatchException(ExceptionRecord,
|
||||
Context,
|
||||
PsGetCurrentThread()->Tcb.TrapFrame,
|
||||
(KPROCESSOR_MODE)ExGetPreviousMode(),
|
||||
SearchFrames);
|
||||
KiDispatchException(ExceptionRecord,
|
||||
Context,
|
||||
TrapFrame,
|
||||
KeGetPreviousMode(),
|
||||
SearchFrames);
|
||||
|
||||
KeRosTrapReturn ( TrapFrame, PrevTrapFrame );
|
||||
return(STATUS_SUCCESS);
|
||||
/* Restore the user context */
|
||||
Thread->TrapFrame = PrevTrapFrame;
|
||||
__asm__("mov %%ebx, %%esp;\n" "jmp _KiServiceExit": : "b" (TrapFrame));
|
||||
|
||||
/* We never get here */
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
|
|
@ -40,10 +40,10 @@ USHORT KiBootGdt[11 * 4] =
|
|||
0x0, 0x0, 0x0, 0x0, /* Null */
|
||||
0xffff, 0x0, 0x9a00, 0xcf, /* Kernel CS */
|
||||
0xffff, 0x0, 0x9200, 0xcf, /* Kernel DS */
|
||||
0x0, 0x0, 0xfa00, 0xcc, /* User CS */
|
||||
0x0, 0x0, 0xf200, 0xcc, /* User DS */
|
||||
0x0, 0x0, 0xfa00, 0xcf, /* User CS */
|
||||
0x0, 0x0, 0xf200, 0xcf, /* User DS */
|
||||
0x0, 0x0, 0x0, 0x0, /* TSS */
|
||||
0x1000, 0x0000, 0x9200, 0xff00, /* PCR */
|
||||
0x1000, 0x0000, 0x9200, 0xffc0, /* PCR */
|
||||
0x1000, 0x0, 0xf200, 0x0, /* TEB */
|
||||
0x0, 0x0, 0x0, 0x0, /* Reserved */
|
||||
0x0, 0x0, 0x0, 0x0, /* LDT */
|
||||
|
|
|
@ -43,6 +43,7 @@ BOOLEAN Ke386NoExecute = FALSE;
|
|||
BOOLEAN Ke386Pae = FALSE;
|
||||
BOOLEAN Ke386PaeEnabled = FALSE;
|
||||
BOOLEAN Ke386GlobalPagesEnabled = FALSE;
|
||||
ULONG KiFastSystemCallDisable = 0;
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
|
@ -323,6 +324,18 @@ KeInit1(PCHAR CommandLine, PULONG LastKernelAddress)
|
|||
MiEnablePAE((PVOID*)LastKernelAddress);
|
||||
Ke386PaeEnabled = TRUE;
|
||||
}
|
||||
|
||||
if (KPCR->PrcbData.FeatureBits & X86_FEATURE_SYSCALL)
|
||||
{
|
||||
extern void KiFastCallEntry(void);
|
||||
|
||||
/* CS Selector of the target segment. */
|
||||
Ke386Wrmsr(0x174, KERNEL_CS, 0);
|
||||
/* Target ESP. */
|
||||
Ke386Wrmsr(0x175, 0, 0);
|
||||
/* Target EIP. */
|
||||
Ke386Wrmsr(0x176, (ULONG_PTR)KiFastCallEntry, 0);
|
||||
}
|
||||
}
|
||||
|
||||
VOID INIT_FUNCTION
|
||||
|
@ -391,23 +404,89 @@ KeInit2(VOID)
|
|||
VOID INIT_FUNCTION
|
||||
Ki386SetProcessorFeatures(VOID)
|
||||
{
|
||||
PKPCR Pcr = KeGetCurrentKPCR();
|
||||
PKPCR Pcr = KeGetCurrentKPCR();
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
UNICODE_STRING KeyName;
|
||||
UNICODE_STRING ValueName;
|
||||
HANDLE KeyHandle;
|
||||
ULONG ResultLength;
|
||||
KEY_VALUE_PARTIAL_INFORMATION ValueData;
|
||||
NTSTATUS Status;
|
||||
|
||||
SharedUserData->ProcessorFeatures[PF_FLOATING_POINT_PRECISION_ERRATA] = FALSE;
|
||||
SharedUserData->ProcessorFeatures[PF_FLOATING_POINT_EMULATED] = FALSE;
|
||||
SharedUserData->ProcessorFeatures[PF_COMPARE_EXCHANGE_DOUBLE] =
|
||||
(Pcr->PrcbData.FeatureBits & X86_FEATURE_CX8);
|
||||
SharedUserData->ProcessorFeatures[PF_MMX_INSTRUCTIONS_AVAILABLE] =
|
||||
(Pcr->PrcbData.FeatureBits & X86_FEATURE_MMX);
|
||||
SharedUserData->ProcessorFeatures[PF_PPC_MOVEMEM_64BIT_OK] = FALSE;
|
||||
SharedUserData->ProcessorFeatures[PF_ALPHA_BYTE_INSTRUCTIONS] = FALSE;
|
||||
SharedUserData->ProcessorFeatures[PF_XMMI_INSTRUCTIONS_AVAILABLE] =
|
||||
(Pcr->PrcbData.FeatureBits & X86_FEATURE_SSE);
|
||||
SharedUserData->ProcessorFeatures[PF_3DNOW_INSTRUCTIONS_AVAILABLE] =
|
||||
(Ke386CpuidExFlags & X86_EXT_FEATURE_3DNOW);
|
||||
SharedUserData->ProcessorFeatures[PF_RDTSC_INSTRUCTION_AVAILABLE] =
|
||||
(Pcr->PrcbData.FeatureBits & X86_FEATURE_TSC);
|
||||
SharedUserData->ProcessorFeatures[PF_PAE_ENABLED] = Ke386PaeEnabled;
|
||||
SharedUserData->ProcessorFeatures[PF_XMMI64_INSTRUCTIONS_AVAILABLE] =
|
||||
(Pcr->PrcbData.FeatureBits & X86_FEATURE_SSE2);
|
||||
SharedUserData->ProcessorFeatures[PF_FLOATING_POINT_PRECISION_ERRATA] = FALSE;
|
||||
SharedUserData->ProcessorFeatures[PF_FLOATING_POINT_EMULATED] = FALSE;
|
||||
SharedUserData->ProcessorFeatures[PF_COMPARE_EXCHANGE_DOUBLE] =
|
||||
(Pcr->PrcbData.FeatureBits & X86_FEATURE_CX8);
|
||||
SharedUserData->ProcessorFeatures[PF_MMX_INSTRUCTIONS_AVAILABLE] =
|
||||
(Pcr->PrcbData.FeatureBits & X86_FEATURE_MMX);
|
||||
SharedUserData->ProcessorFeatures[PF_PPC_MOVEMEM_64BIT_OK] = FALSE;
|
||||
SharedUserData->ProcessorFeatures[PF_ALPHA_BYTE_INSTRUCTIONS] = FALSE;
|
||||
SharedUserData->ProcessorFeatures[PF_XMMI_INSTRUCTIONS_AVAILABLE] =
|
||||
(Pcr->PrcbData.FeatureBits & X86_FEATURE_SSE);
|
||||
SharedUserData->ProcessorFeatures[PF_3DNOW_INSTRUCTIONS_AVAILABLE] =
|
||||
(Ke386CpuidExFlags & X86_EXT_FEATURE_3DNOW);
|
||||
SharedUserData->ProcessorFeatures[PF_RDTSC_INSTRUCTION_AVAILABLE] =
|
||||
(Pcr->PrcbData.FeatureBits & X86_FEATURE_TSC);
|
||||
SharedUserData->ProcessorFeatures[PF_PAE_ENABLED] = Ke386PaeEnabled;
|
||||
SharedUserData->ProcessorFeatures[PF_XMMI64_INSTRUCTIONS_AVAILABLE] =
|
||||
(Pcr->PrcbData.FeatureBits & X86_FEATURE_SSE2);
|
||||
|
||||
/* Does the CPU Support Fast System Call? */
|
||||
if (Pcr->PrcbData.FeatureBits & X86_FEATURE_SYSCALL) {
|
||||
|
||||
/* FIXME: Check for Family == 6, Model < 3 and Stepping < 3 and disable */
|
||||
|
||||
/* Make sure it's not disabled in registry */
|
||||
RtlRosInitUnicodeStringFromLiteral(&KeyName,
|
||||
L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Session Manager\\Kernel");
|
||||
RtlRosInitUnicodeStringFromLiteral(&ValueName,
|
||||
L"FastSystemCallDisable");
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&KeyName,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
NULL,
|
||||
NULL);
|
||||
Status = NtOpenKey(&KeyHandle, KEY_ALL_ACCESS, &ObjectAttributes);
|
||||
|
||||
if (NT_SUCCESS(Status)) {
|
||||
|
||||
/* Read the Value then Close the Key */
|
||||
Status = NtQueryValueKey(KeyHandle,
|
||||
&ValueName,
|
||||
KeyValuePartialInformation,
|
||||
&ValueData,
|
||||
sizeof(ValueData),
|
||||
&ResultLength);
|
||||
RtlMoveMemory(&KiFastSystemCallDisable, ValueData.Data, sizeof(ULONG));
|
||||
|
||||
NtClose(KeyHandle);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
/* Disable SYSENTER/SYSEXIT, because the CPU doesn't support it */
|
||||
KiFastSystemCallDisable = 1;
|
||||
|
||||
}
|
||||
|
||||
if (!KiFastSystemCallDisable) {
|
||||
|
||||
/* Use SYSENTER */
|
||||
SharedUserData->SystemCall[0] = 0x8B;
|
||||
SharedUserData->SystemCall[1] = 0xD4;
|
||||
SharedUserData->SystemCall[2] = 0x0F;
|
||||
SharedUserData->SystemCall[3] = 0x34;
|
||||
SharedUserData->SystemCall[4] = 0xC3;
|
||||
|
||||
} else {
|
||||
|
||||
/* Use INT2E */
|
||||
SharedUserData->SystemCall[0] = 0x8D;
|
||||
SharedUserData->SystemCall[1] = 0x54;
|
||||
SharedUserData->SystemCall[2] = 0x24;
|
||||
SharedUserData->SystemCall[3] = 0x08;
|
||||
SharedUserData->SystemCall[4] = 0xCD;
|
||||
SharedUserData->SystemCall[5] = 0x2E;
|
||||
SharedUserData->SystemCall[6] = 0xC3;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -78,5 +78,5 @@ _KePushAndStackSwitchAndSysRet@8:
|
|||
push $0
|
||||
call _KeLowerIrql@4
|
||||
|
||||
jmp KeReturnFromSystemCall
|
||||
jmp _KiServiceExit
|
||||
|
||||
|
|
|
@ -1,324 +1,317 @@
|
|||
/*
|
||||
* ReactOS kernel
|
||||
* Copyright (C) 2000 David Welch <welch@cwcom.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/* $Id$
|
||||
*
|
||||
* FILE: ntoskrnl/ke/i386/syscall.S
|
||||
* PURPOSE: 2E trap handler
|
||||
* PROGRAMMER: David Welch (david.welch@seh.ox.ac.uk)
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PURPOSE: System Call Handler
|
||||
* PROGRAMMER: Alex Ionescu (alex@relsoft.net)
|
||||
* UPDATE HISTORY:
|
||||
* ???
|
||||
* ??-??-??: Original Version - David Welch(?)
|
||||
* 13-01-05: Complete rewrite, added support for SYSENTER, direct kmode syscalls
|
||||
* and re-wrote most of handler code. - Alex Ionescu
|
||||
*/
|
||||
|
||||
#include <ddk/status.h>
|
||||
#include <internal/i386/segment.h>
|
||||
#include <internal/ps.h>
|
||||
#include <internal/i386/ke.h>
|
||||
#include <ntos/tss.h>
|
||||
#include <napi/shared_data.h>
|
||||
#include <roscfg.h>
|
||||
|
||||
#define KernelMode (0)
|
||||
#define UserMode (1)
|
||||
#define UserMode (1)
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
.globl KeReturnFromSystemCall
|
||||
.globl KeReturnFromSystemCallWithHook
|
||||
.globl _interrupt_handler2e
|
||||
_interrupt_handler2e:
|
||||
.globl _KiServiceExit
|
||||
.globl _KiFastCallEntry
|
||||
.globl _KiSystemService
|
||||
|
||||
/* Construct a trap frame on the stack */
|
||||
_KiFastCallEntry:
|
||||
|
||||
/* Error code */
|
||||
pushl $0
|
||||
pushl %ebp
|
||||
pushl %ebx
|
||||
pushl %esi
|
||||
pushl %edi
|
||||
pushl %fs
|
||||
/* Load PCR selector into fs */
|
||||
movl $PCR_SELECTOR, %ebx
|
||||
movl %ebx, %fs
|
||||
/* Set FS to PCR */
|
||||
movl $PCR_SELECTOR, %ecx
|
||||
movw %cx, %fs
|
||||
|
||||
/* Set the current stack to Kernel Stack */
|
||||
movl %fs:KPCR_TSS, %ecx
|
||||
movl KTSS_ESP0(%ecx), %ecx
|
||||
movl %ecx, %esp
|
||||
|
||||
/* Set up a fake INT Stack. */
|
||||
pushl $USER_DS
|
||||
pushl %edx /* Ring 3 SS:ESP */
|
||||
pushfl
|
||||
orl $200, (%esp) /* Re-enable IRQs in EFLAGS, to fake INT */
|
||||
pushl $USER_CS
|
||||
pushl $KUSER_SHARED_SYSCALL_RET
|
||||
|
||||
/* User Parameter List */
|
||||
add $8, %edx
|
||||
|
||||
_KiSystemService:
|
||||
|
||||
/* Save the old exception list */
|
||||
movl %fs:KPCR_EXCEPTION_LIST, %ebx
|
||||
pushl %ebx
|
||||
/* Set the exception handler chain terminator */
|
||||
movl $0xffffffff, %fs:KPCR_EXCEPTION_LIST
|
||||
/* Get a pointer to the current thread */
|
||||
movl %fs:KPCR_CURRENT_THREAD, %esi
|
||||
/* Save the old previous mode */
|
||||
movl $0, %ebx
|
||||
movb %ss:KTHREAD_PREVIOUS_MODE(%esi), %bl
|
||||
pushl %ebx
|
||||
/* Set the new previous mode based on the saved CS selector */
|
||||
movl 0x24(%esp), %ebx
|
||||
andl $0x0000FFFF, %ebx
|
||||
cmpl $KERNEL_CS, %ebx
|
||||
jne L1
|
||||
movb $KernelMode, %ss:KTHREAD_PREVIOUS_MODE(%esi)
|
||||
jmp L3
|
||||
L1:
|
||||
movb $UserMode, %ss:KTHREAD_PREVIOUS_MODE(%esi)
|
||||
L3:
|
||||
/*
|
||||
* Construct a trap frame on the stack.
|
||||
* The following are already on the stack.
|
||||
*/
|
||||
// SS + 0x0
|
||||
// ESP + 0x4
|
||||
// EFLAGS + 0x8
|
||||
// CS + 0xC
|
||||
// EIP + 0x10
|
||||
pushl $0 // + 0x14
|
||||
pushl %ebp // + 0x18
|
||||
pushl %ebx // + 0x1C
|
||||
pushl %esi // + 0x20
|
||||
pushl %edi // + 0x24
|
||||
pushl %fs // + 0x28
|
||||
|
||||
/* Load PCR Selector into fs */
|
||||
movw $PCR_SELECTOR, %bx
|
||||
movw %bx, %fs
|
||||
|
||||
/* Save the previous exception list */
|
||||
pushl %fs:KPCR_EXCEPTION_LIST // + 0x2C
|
||||
|
||||
/* Save other registers */
|
||||
pushl %eax
|
||||
pushl %ecx
|
||||
pushl %edx
|
||||
pushl %ds
|
||||
pushl %es
|
||||
pushl %gs
|
||||
pushl $0 /* DR7 */
|
||||
pushl $0 /* DR6 */
|
||||
pushl $0 /* DR3 */
|
||||
pushl $0 /* DR2 */
|
||||
pushl $0 /* DR1 */
|
||||
pushl $0 /* DR0 */
|
||||
pushl $0 /* XXX: TempESP */
|
||||
pushl $0 /* XXX: TempCS */
|
||||
pushl $0 /* XXX: DebugPointer */
|
||||
pushl $0 /* XXX: DebugArgMark */
|
||||
/* Set the exception handler chain terminator */
|
||||
movl $0xffffffff, %fs:KPCR_EXCEPTION_LIST
|
||||
|
||||
/* Get a pointer to the current thread */
|
||||
movl %fs:KPCR_CURRENT_THREAD, %esi
|
||||
|
||||
/* Save the old previous mode */
|
||||
pushl %ss:KTHREAD_PREVIOUS_MODE(%esi) // + 0x30
|
||||
|
||||
/* Set the new previous mode based on the saved CS selector */
|
||||
movl 0x24(%esp), %ebx
|
||||
and $1, %ebx
|
||||
movb %bl, %ss:KTHREAD_PREVIOUS_MODE(%esi)
|
||||
|
||||
/* Save other registers */
|
||||
pushl %eax // + 0x34
|
||||
pushl %ecx // + 0x38
|
||||
pushl %edx // + 0x3C
|
||||
pushl %ds // + 0x40
|
||||
pushl %es // + 0x44
|
||||
pushl %gs // + 0x48
|
||||
sub $0x28, %esp // + 0x70
|
||||
|
||||
#ifdef DBG
|
||||
/* Trick gdb 6 into backtracing over the system call */
|
||||
movl 4(%ebp), %ebx
|
||||
pushl %ebx /* DebugEIP */
|
||||
movl (%ebp), %ebx
|
||||
pushl %ebx /* DebugEBP */
|
||||
/* Trick gdb 6 into backtracing over the system call */
|
||||
pushl 4(%ebp) /* DebugEIP */ // + 0x74
|
||||
pushl (%ebp) /* DebugEBP */ // + 0x78
|
||||
#else
|
||||
movl 0x60(%esp), %ebx
|
||||
pushl %ebx /* DebugEIP */
|
||||
pushl %ebp /* DebugEBP */
|
||||
pushl 0x60(%esp) /* DebugEIP */ // + 0x74
|
||||
pushl %ebp /* DebugEBP */ // + 0x78
|
||||
#endif
|
||||
|
||||
/* Load the segment registers */
|
||||
movl $KERNEL_DS, %ebx
|
||||
movl %ebx, %ds
|
||||
movl %ebx, %es
|
||||
movl %ebx, %gs
|
||||
/* Load the segment registers */
|
||||
movw $KERNEL_DS, %bx
|
||||
movw %bx, %ds
|
||||
movw %bx, %es
|
||||
movw %bx, %gs
|
||||
|
||||
/*
|
||||
* Save the old trap frame pointer over where we would save the EDX
|
||||
* register.
|
||||
*/
|
||||
movl KTHREAD_TRAP_FRAME(%esi), %ebx
|
||||
movl %ebx, KTRAP_FRAME_EDX(%esp)
|
||||
/* Save the old trap frame pointer where EDX would be saved */
|
||||
movl KTHREAD_TRAP_FRAME(%esi), %ebx
|
||||
movl %ebx, KTRAP_FRAME_EDX(%esp)
|
||||
|
||||
/* Allocate new Kernel stack frame */
|
||||
movl %esp,%ebp
|
||||
/* Allocate new Kernel stack frame */
|
||||
movl %esp,%ebp
|
||||
|
||||
/* Save a pointer to the trap frame in the TCB */
|
||||
movl %ebp, KTHREAD_TRAP_FRAME(%esi)
|
||||
/* Save a pointer to the trap frame in the TCB */
|
||||
movl %ebp, KTHREAD_TRAP_FRAME(%esi)
|
||||
|
||||
/* Set ES to kernel segment */
|
||||
movw $KERNEL_DS,%bx
|
||||
movw %bx,%es
|
||||
|
||||
/* Users's current stack frame pointer is source */
|
||||
movl %edx,%esi
|
||||
|
||||
/* Determine system service table to use */
|
||||
cmpl $0x0fff, %eax
|
||||
ja new_useShadowTable
|
||||
|
||||
/* Check to see if EAX is valid/inrange */
|
||||
cmpl %es:_KeServiceDescriptorTable + 8, %eax
|
||||
jbe new_serviceInRange
|
||||
movl $STATUS_INVALID_SYSTEM_SERVICE, %eax
|
||||
movl %eax, KTRAP_FRAME_EAX(%ebp) /* save our return value in PKTRAP_FRAME->Eax */
|
||||
jmp KeReturnFromSystemCall
|
||||
|
||||
new_serviceInRange:
|
||||
CheckValidCall:
|
||||
|
||||
/*
|
||||
* Find out which table offset to use. Converts 0x1124 into 0x10.
|
||||
* The offset is related to the Table Index as such: Offset = TableIndex x 10
|
||||
*/
|
||||
movl %eax, %edi
|
||||
shrl $8, %edi
|
||||
andl $0x10, %edi
|
||||
movl %edi, %ecx
|
||||
|
||||
/* Now add the thread's base system table to the offset */
|
||||
addl KTHREAD_SERVICE_TABLE(%esi), %edi
|
||||
|
||||
/* Get the true syscall ID and check it */
|
||||
movl %eax, %ebx
|
||||
andl $0x0FFF, %eax
|
||||
cmpl 8(%edi), %eax
|
||||
|
||||
/* Invalid ID, try to load Win32K Table */
|
||||
jnb KiBBTUnexpectedRange
|
||||
|
||||
#ifdef DBG
|
||||
/* GDB thinks the function starts here and
|
||||
wants a standard prolog, so let's give it */
|
||||
pushl %ebp
|
||||
movl %esp,%ebp
|
||||
popl %ebp
|
||||
/*
|
||||
* GDB thinks the function starts here and
|
||||
* wants a standard prolog, so let's give it
|
||||
*/
|
||||
pushl %ebp
|
||||
movl %esp,%ebp
|
||||
popl %ebp
|
||||
#endif
|
||||
|
||||
/* Allocate room for argument list from kernel stack */
|
||||
movl %es:_KeServiceDescriptorTable + 12, %ecx
|
||||
movb %es:(%ecx, %eax), %cl
|
||||
movzx %cl, %ecx
|
||||
subl %ecx, %esp
|
||||
/* Users's current stack frame pointer is source */
|
||||
movl %edx, %esi
|
||||
|
||||
/* Allocate room for argument list from kernel stack */
|
||||
movl 12(%edi), %ecx
|
||||
movb (%ecx, %eax), %cl
|
||||
movzx %cl, %ecx
|
||||
|
||||
/* Allocate space on our stack */
|
||||
subl %ecx, %esp
|
||||
|
||||
/* Get pointer to function */
|
||||
movl (%edi), %edi
|
||||
movl (%edi, %eax, 4), %eax
|
||||
|
||||
/* Copy the arguments from the user stack to the kernel stack */
|
||||
movl %esp,%edi
|
||||
cld
|
||||
rep movsb
|
||||
/* Copy the arguments from the user stack to our stack */
|
||||
shr $2, %ecx
|
||||
movl %esp, %edi
|
||||
cld
|
||||
rep movsd
|
||||
|
||||
/* DS is now also kernel segment */
|
||||
movw %bx, %ds
|
||||
/* Do the System Call */
|
||||
call *%eax
|
||||
movl %eax, KTRAP_FRAME_EAX(%ebp)
|
||||
|
||||
/* Call system call hook */
|
||||
pushl %eax
|
||||
call _KiSystemCallHook
|
||||
popl %eax
|
||||
|
||||
/* Make the system service call */
|
||||
movl %es:_KeServiceDescriptorTable, %ecx
|
||||
movl %es:(%ecx, %eax, 4), %eax
|
||||
call *%eax
|
||||
movl %eax, KTRAP_FRAME_EAX(%ebp) /* save our return value in PKTRAP_FRAME->Eax */
|
||||
|
||||
#if CHECKED
|
||||
/* Bump Service Counter */
|
||||
#endif
|
||||
|
||||
jmp KeDeallocateStackAndReturnFromSystemCallWithHook
|
||||
|
||||
new_useShadowTable:
|
||||
|
||||
subl $0x1000, %eax
|
||||
|
||||
/* Check to see if EAX is valid/inrange */
|
||||
cmpl %es:_KeServiceDescriptorTableShadow + 24, %eax
|
||||
jbe new_shadowServiceInRange
|
||||
movl $STATUS_INVALID_SYSTEM_SERVICE, %eax
|
||||
movl %eax, KTRAP_FRAME_EAX(%ebp) /* save our return value in PKTRAP_FRAME->Eax */
|
||||
jmp KeReturnFromSystemCall
|
||||
|
||||
new_shadowServiceInRange:
|
||||
|
||||
#ifdef DBG
|
||||
/*
|
||||
* GDB thinks the function starts here and
|
||||
* wants a standard prolog, so let's give it
|
||||
*/
|
||||
pushl %ebp
|
||||
movl %esp,%ebp
|
||||
popl %ebp
|
||||
#endif
|
||||
|
||||
/* Allocate room for argument list from kernel stack */
|
||||
movl %es:_KeServiceDescriptorTableShadow + 28, %ecx
|
||||
movb %es:(%ecx, %eax), %cl
|
||||
movzx %cl, %ecx
|
||||
subl %ecx, %esp
|
||||
|
||||
/* Copy the arguments from the user stack to the kernel stack */
|
||||
movl %esp,%edi
|
||||
cld
|
||||
rep movsb
|
||||
|
||||
/* DS is now also kernel segment */
|
||||
movw %bx,%ds
|
||||
|
||||
/* Call system call hook */
|
||||
// pushl %eax
|
||||
// call _KiSystemCallHook
|
||||
// popl %eax
|
||||
|
||||
/* Call service check routine */
|
||||
pushl %eax
|
||||
call _KiServiceCheck
|
||||
popl %eax
|
||||
|
||||
/* Make the system service call */
|
||||
movl %es:_KeServiceDescriptorTableShadow + 16, %ecx
|
||||
movl %es:(%ecx, %eax, 4), %eax
|
||||
call *%eax
|
||||
movl %eax, KTRAP_FRAME_EAX(%ebp) /* save our return value in PKTRAP_FRAME->Eax */
|
||||
|
||||
#if CHECKED
|
||||
/* Bump Service Counter */
|
||||
#endif
|
||||
|
||||
KeDeallocateStackAndReturnFromSystemCallWithHook:
|
||||
/* Deallocate the kernel stack frame */
|
||||
movl %ebp,%esp
|
||||
|
||||
KeReturnFromSystemCallWithHook:
|
||||
/* Call the post system call hook and deliver any pending APCs */
|
||||
pushl %esp
|
||||
call _KiAfterSystemCallHook
|
||||
addl $4,%esp
|
||||
/* Deallocate the kernel stack frame */
|
||||
movl %ebp, %esp
|
||||
|
||||
KeReturnFromSystemCall:
|
||||
|
||||
/* Restore the user context */
|
||||
/* Get a pointer to the current thread */
|
||||
movl %fs:0x124, %esi
|
||||
/* Get the Current Thread */
|
||||
movl %fs:KPCR_CURRENT_THREAD, %esi
|
||||
|
||||
/* Restore the old trap frame pointer */
|
||||
movl KTRAP_FRAME_EDX(%esp), %ebx
|
||||
movl %ebx, KTHREAD_TRAP_FRAME(%esi)
|
||||
/* Restore the old trap frame pointer */
|
||||
movl KTRAP_FRAME_EDX(%esp), %ebx
|
||||
movl %ebx, KTHREAD_TRAP_FRAME(%esi)
|
||||
|
||||
_KiServiceExit:
|
||||
|
||||
/* Get the Current Thread */
|
||||
movl %fs:KPCR_CURRENT_THREAD, %esi
|
||||
|
||||
/* Deliver APCs only if we were called from user mode */
|
||||
testb $1, KTRAP_FRAME_CS(%esp)
|
||||
je KiRosTrapReturn
|
||||
|
||||
/* And only if any are actually pending */
|
||||
cmpb $0, KTHREAD_PENDING_USER_APC(%esi)
|
||||
je KiRosTrapReturn
|
||||
|
||||
/* Save pointer to Trap Frame */
|
||||
movl %esp, %ebx
|
||||
|
||||
/* Raise IRQL to HIGH_LEVEL */
|
||||
movl $1, %ecx
|
||||
call @KfRaiseIrql@4
|
||||
|
||||
/* Save old IRQL */
|
||||
pushl %eax
|
||||
|
||||
/* Deliver APCs */
|
||||
pushl %ebx
|
||||
pushl $0
|
||||
pushl $UserMode
|
||||
call _KiDeliverApc@12
|
||||
|
||||
/* Return to old IRQL */
|
||||
popl %ecx
|
||||
call @KfLowerIrql@4
|
||||
|
||||
KiRosTrapReturn:
|
||||
|
||||
/* Skip debug information and unsaved registers */
|
||||
addl $0x30, %esp // + 0x48
|
||||
popl %gs // + 0x44
|
||||
popl %es // + 0x40
|
||||
popl %ds // + 0x3C
|
||||
popl %edx // + 0x38
|
||||
popl %ecx // + 0x34
|
||||
popl %eax // + 0x30
|
||||
|
||||
#if 0
|
||||
mov KTRAP_FRAME_RESERVED1(%ebp), %ax
|
||||
cmp %ax, SSIDX_NTCONTINUE
|
||||
jnz KeNoEpilogPrint
|
||||
movl KTRAP_FRAME_ESP(%ebp), %ecx
|
||||
movl KTRAP_FRAME_EBP(%ebp), %edx
|
||||
call @KeRosPrintEspEbp@8
|
||||
KeNoEpilogPrint:
|
||||
#endif
|
||||
/* Restore the old previous mode */
|
||||
popl %ebx // + 0x2C
|
||||
movb %bl, %ss:KTHREAD_PREVIOUS_MODE(%esi)
|
||||
|
||||
/* Skip debug information and unsaved registers */
|
||||
addl $0x30, %esp
|
||||
popl %gs
|
||||
popl %es
|
||||
popl %ds
|
||||
popl %edx
|
||||
popl %ecx
|
||||
popl %eax
|
||||
/* Restore the old exception handler list */
|
||||
popl %fs:KPCR_EXCEPTION_LIST // + 0x28
|
||||
|
||||
/* Restore the old previous mode */
|
||||
popl %ebx
|
||||
movb %bl, %ss:KTHREAD_PREVIOUS_MODE(%esi)
|
||||
/* Restore final registers from trap frame */
|
||||
popl %fs // + 0x24
|
||||
popl %edi // + 0x20
|
||||
popl %esi // + 0x1C
|
||||
popl %ebx // + 0x18
|
||||
popl %ebp // + 0x14
|
||||
add $4, %esp // + 0x10
|
||||
|
||||
/* Restore the old exception handler list */
|
||||
popl %ebx
|
||||
movl %ebx, %fs:KPCR_EXCEPTION_LIST
|
||||
/* Check if previous CS is from user-mode */
|
||||
testl $1, 4(%esp)
|
||||
|
||||
/* It is, so use Fast Exit */
|
||||
jnz FastRet
|
||||
|
||||
/*
|
||||
* Restore what the stub pushed, and return back to it.
|
||||
* Note that we were CALLed, so the first thing on our stack is the ret EIP!
|
||||
*/
|
||||
pop %edx // + 0x0C
|
||||
pop %ecx // + 0x08
|
||||
popf // + 0x04
|
||||
jmp *%edx
|
||||
|
||||
IntRet:
|
||||
|
||||
iret
|
||||
|
||||
popl %fs
|
||||
popl %edi
|
||||
popl %esi
|
||||
popl %ebx
|
||||
popl %ebp
|
||||
addl $0x4, %esp /* Ignore error code */
|
||||
FastRet:
|
||||
|
||||
iret
|
||||
/* Is SYSEXIT Supported/Wanted? */
|
||||
cmpl $1, _KiFastSystemCallDisable
|
||||
je IntRet
|
||||
|
||||
/* R3: NOTE: This is part of my in-progress attempt at correcting NtContinue
|
||||
* It is not being called, yet...
|
||||
*/
|
||||
.globl @KeRosTrapReturn@8
|
||||
@KeRosTrapReturn@8:
|
||||
/* Restore FS to TIB */
|
||||
mov $TEB_SELECTOR, %ecx
|
||||
mov %ecx, %fs
|
||||
|
||||
/* We will be cleaning up the stack ourselves */
|
||||
popl %edx /* New Ring 3 EIP */
|
||||
add $0x4, %esp /* Skip Ring 3 DS */
|
||||
andl $0xFD, 9(%esp) /* Remove IRQ hack from EFLAGS */
|
||||
popfl /* Restore old EFLAGS */
|
||||
popl %ecx /* Old Ring 3 SS:ESP */
|
||||
|
||||
/*
|
||||
* At this point:
|
||||
* ECX points to the old User Stack.
|
||||
* EDX points to the instruction to execute in usermode after the sysenter
|
||||
*/
|
||||
sti
|
||||
sysexit
|
||||
|
||||
/* point %esp to the trap frame to restore */
|
||||
movl %ecx, %esp
|
||||
movl %esp, %ebp
|
||||
KiBBTUnexpectedRange:
|
||||
|
||||
/* Call the post system call hook and deliver any pending APCs */
|
||||
pushl %esp
|
||||
call _KiAfterSystemCallHook
|
||||
addl $4,%esp
|
||||
/* If this isn't a Win32K call, fail */
|
||||
cmp $0x10, %ecx
|
||||
jne InvalidCall
|
||||
|
||||
/* Restore the user context */
|
||||
/* Get a pointer to the current thread */
|
||||
movl %fs:0x124, %esi
|
||||
/* Restore the old trap frame pointer */
|
||||
movl %edx, KTHREAD_TRAP_FRAME(%esi)
|
||||
/* Set up Win32K Table */
|
||||
pushl %edx
|
||||
pushl %ebx
|
||||
call _KiServiceCheck
|
||||
popl %eax
|
||||
popl %edx
|
||||
|
||||
/* Try the Call again */
|
||||
jmp CheckValidCall
|
||||
|
||||
InvalidCall:
|
||||
|
||||
jmp KiRosTrapReturn;
|
||||
/* Invalid System Call */
|
||||
int $3
|
||||
movl $STATUS_INVALID_SYSTEM_SERVICE, %eax
|
||||
movl %eax, KTRAP_FRAME_EAX(%ebp)
|
||||
jmp _KiServiceExit
|
||||
|
|
|
@ -17,127 +17,6 @@
|
|||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
VOID
|
||||
KiSystemCallHook(ULONG Nr, ...)
|
||||
{
|
||||
#if 0
|
||||
va_list ap;
|
||||
ULONG i;
|
||||
|
||||
va_start(ap, Nr);
|
||||
|
||||
DbgPrint("%x/%d ", KeServiceDescriptorTable[0].SSDT[Nr].SysCallPtr, Nr);
|
||||
DbgPrint("%x (", KeServiceDescriptorTable[0].SSPT[Nr].ParamBytes);
|
||||
for (i = 0; i < KeServiceDescriptorTable[0].SSPT[Nr].ParamBytes / 4; i++)
|
||||
{
|
||||
DbgPrint("%x, ", va_arg(ap, ULONG));
|
||||
}
|
||||
DbgPrint(")\n");
|
||||
ASSERT_IRQL(PASSIVE_LEVEL);
|
||||
va_end(ap);
|
||||
#endif
|
||||
}
|
||||
|
||||
VOID
|
||||
KiAfterSystemCallHook(PKTRAP_FRAME TrapFrame)
|
||||
{
|
||||
KIRQL oldIrql;
|
||||
|
||||
/* If we are returning to umode, deliver one pending umode apc.
|
||||
* Note that kmode apcs are also delivered, even if deliverymode is UserMode.
|
||||
* This is because we can't return to umode with pending kmode apcs!
|
||||
* FIXME: Should we deliver pending kmode apcs when returning from a
|
||||
* kmode-to-kmode syscall (ZwXxx calls)?????
|
||||
* -Gunnar
|
||||
*/
|
||||
if (TrapFrame->Cs != KERNEL_CS)
|
||||
{
|
||||
KeRaiseIrql(APC_LEVEL, &oldIrql);
|
||||
KiDeliverApc(UserMode, NULL, TrapFrame);
|
||||
KeLowerIrql(oldIrql);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
KiServiceCheck (ULONG Nr)
|
||||
{
|
||||
PETHREAD Thread;
|
||||
|
||||
Thread = PsGetCurrentThread();
|
||||
|
||||
#if 0
|
||||
DbgPrint ("KiServiceCheck(%p) called\n", Thread);
|
||||
DbgPrint ("Service %d (%p)\n", Nr, KeServiceDescriptorTableShadow[1].SSDT[Nr].SysCallPtr);
|
||||
#endif
|
||||
|
||||
if (Thread->Tcb.ServiceTable != KeServiceDescriptorTableShadow)
|
||||
{
|
||||
#if 0
|
||||
DbgPrint ("Initialize Win32 thread\n");
|
||||
#endif
|
||||
|
||||
PsInitWin32Thread (Thread);
|
||||
|
||||
Thread->Tcb.ServiceTable = KeServiceDescriptorTableShadow;
|
||||
}
|
||||
}
|
||||
|
||||
// This function should be used by win32k.sys to add its own user32/gdi32 services
|
||||
// TableIndex is 0 based
|
||||
// ServiceCountTable its not used at the moment
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOLEAN STDCALL
|
||||
KeAddSystemServiceTable (
|
||||
PSSDT SSDT,
|
||||
PULONG ServiceCounterTable,
|
||||
ULONG NumberOfServices,
|
||||
PSSPT SSPT,
|
||||
ULONG TableIndex
|
||||
)
|
||||
{
|
||||
if (TableIndex > SSDT_MAX_ENTRIES - 1)
|
||||
return FALSE;
|
||||
|
||||
/* check if descriptor table entry is free */
|
||||
if ((KeServiceDescriptorTable[TableIndex].SSDT != NULL) ||
|
||||
(KeServiceDescriptorTableShadow[TableIndex].SSDT != NULL))
|
||||
return FALSE;
|
||||
|
||||
/* initialize the shadow service descriptor table */
|
||||
KeServiceDescriptorTableShadow[TableIndex].SSDT = SSDT;
|
||||
KeServiceDescriptorTableShadow[TableIndex].SSPT = SSPT;
|
||||
KeServiceDescriptorTableShadow[TableIndex].NumberOfServices = NumberOfServices;
|
||||
KeServiceDescriptorTableShadow[TableIndex].ServiceCounterTable = ServiceCounterTable;
|
||||
|
||||
/* initialize the service descriptor table (not for win32k services) */
|
||||
if (TableIndex != 1)
|
||||
{
|
||||
KeServiceDescriptorTable[TableIndex].SSDT = SSDT;
|
||||
KeServiceDescriptorTable[TableIndex].SSPT = SSPT;
|
||||
KeServiceDescriptorTable[TableIndex].NumberOfServices = NumberOfServices;
|
||||
KeServiceDescriptorTable[TableIndex].ServiceCounterTable = ServiceCounterTable;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
BOOLEAN
|
||||
STDCALL
|
||||
KeRemoveSystemServiceTable(
|
||||
IN PUCHAR Number
|
||||
)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
|
|
|
@ -33,6 +33,21 @@
|
|||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
VOID
|
||||
KiServiceCheck (VOID)
|
||||
{
|
||||
PETHREAD Thread;
|
||||
|
||||
Thread = PsGetCurrentThread();
|
||||
|
||||
if (Thread->Tcb.ServiceTable != KeServiceDescriptorTableShadow)
|
||||
{
|
||||
PsInitWin32Thread (Thread);
|
||||
|
||||
Thread->Tcb.ServiceTable = KeServiceDescriptorTableShadow;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
|
|
|
@ -270,4 +270,46 @@ KeUnstackDetachProcess (
|
|||
KeReleaseDispatcherDatabaseLock(OldIrql);
|
||||
}
|
||||
|
||||
// This function should be used by win32k.sys to add its own user32/gdi32 services
|
||||
// TableIndex is 0 based
|
||||
// ServiceCountTable its not used at the moment
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOLEAN STDCALL
|
||||
KeAddSystemServiceTable (
|
||||
PSSDT SSDT,
|
||||
PULONG ServiceCounterTable,
|
||||
ULONG NumberOfServices,
|
||||
PSSPT SSPT,
|
||||
ULONG TableIndex
|
||||
)
|
||||
{
|
||||
/* check if descriptor table entry is free */
|
||||
if ((TableIndex > SSDT_MAX_ENTRIES - 1) ||
|
||||
(KeServiceDescriptorTable[TableIndex].SSDT != NULL) ||
|
||||
(KeServiceDescriptorTableShadow[TableIndex].SSDT != NULL))
|
||||
return FALSE;
|
||||
|
||||
/* initialize the shadow service descriptor table */
|
||||
KeServiceDescriptorTableShadow[TableIndex].SSDT = SSDT;
|
||||
KeServiceDescriptorTableShadow[TableIndex].SSPT = SSPT;
|
||||
KeServiceDescriptorTableShadow[TableIndex].NumberOfServices = NumberOfServices;
|
||||
KeServiceDescriptorTableShadow[TableIndex].ServiceCounterTable = ServiceCounterTable;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
BOOLEAN
|
||||
STDCALL
|
||||
KeRemoveSystemServiceTable(
|
||||
IN PUCHAR Number
|
||||
)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return FALSE;
|
||||
}
|
||||
/* EOF */
|
||||
|
|
|
@ -15,10 +15,6 @@
|
|||
#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
||||
VOID
|
||||
FASTCALL
|
||||
KeRosTrapReturn ( PKTRAP_FRAME TrapFrame, PKTRAP_FRAME PrevTrapFrame );
|
||||
|
||||
VOID STDCALL
|
||||
KeRosDumpStackFrames ( PULONG Frame, ULONG FrameCount );
|
||||
|
||||
|
@ -30,8 +26,9 @@ NtContinue (
|
|||
IN PCONTEXT Context,
|
||||
IN BOOLEAN TestAlert)
|
||||
{
|
||||
PKTRAP_FRAME TrapFrame = KeGetCurrentThread()->TrapFrame;
|
||||
PKTRAP_FRAME PrevTrapFrame = (PKTRAP_FRAME)TrapFrame->Edx;
|
||||
PKTHREAD Thread = KeGetCurrentThread();
|
||||
PKTRAP_FRAME TrapFrame = Thread->TrapFrame;
|
||||
PKTRAP_FRAME PrevTrapFrame = (PKTRAP_FRAME)TrapFrame->Edx;
|
||||
PFX_SAVE_AREA FxSaveArea;
|
||||
KIRQL oldIrql;
|
||||
|
||||
|
@ -65,12 +62,12 @@ NtContinue (
|
|||
/* Put the floating point context into the thread's FX_SAVE_AREA
|
||||
* and make sure it is reloaded when needed.
|
||||
*/
|
||||
FxSaveArea = (PFX_SAVE_AREA)((ULONG_PTR)KeGetCurrentThread()->InitialStack - sizeof(FX_SAVE_AREA));
|
||||
FxSaveArea = (PFX_SAVE_AREA)((ULONG_PTR)Thread->InitialStack - sizeof(FX_SAVE_AREA));
|
||||
if (KiContextToFxSaveArea(FxSaveArea, Context))
|
||||
{
|
||||
KeGetCurrentThread()->NpxState = NPX_STATE_VALID;
|
||||
Thread->NpxState = NPX_STATE_VALID;
|
||||
KeRaiseIrql(DISPATCH_LEVEL, &oldIrql);
|
||||
if (KeGetCurrentKPCR()->PrcbData.NpxThread == KeGetCurrentThread())
|
||||
if (KeGetCurrentKPCR()->PrcbData.NpxThread == Thread)
|
||||
{
|
||||
KeGetCurrentKPCR()->PrcbData.NpxThread = NULL;
|
||||
Ke386SetCr0(Ke386GetCr0() | X86_CR0_TS);
|
||||
|
@ -82,7 +79,9 @@ NtContinue (
|
|||
KeLowerIrql(oldIrql);
|
||||
}
|
||||
|
||||
KeRosTrapReturn ( TrapFrame, PrevTrapFrame );
|
||||
/* Restore the user context */
|
||||
Thread->TrapFrame = PrevTrapFrame;
|
||||
__asm__("mov %%ebx, %%esp;\n" "jmp _KiServiceExit": : "b" (TrapFrame));
|
||||
|
||||
return STATUS_SUCCESS; /* this doesn't actually happen b/c KeRosTrapReturn() won't return */
|
||||
}
|
||||
|
|
|
@ -280,6 +280,8 @@ IsVmwSVGAEnabled(VOID)
|
|||
return (Value == 1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
BOOL
|
||||
SaveResolutionSettings(DWORD ResX, DWORD ResY, DWORD ColDepth)
|
||||
{
|
||||
|
@ -313,6 +315,43 @@ SaveResolutionSettings(DWORD ResX, DWORD ResY, DWORD ColDepth)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL
|
||||
DisableFastSystemCall(VOID)
|
||||
{
|
||||
DWORD Value = 1;
|
||||
HKEY hReg;
|
||||
|
||||
/* Open or Create the Kernel Settings Key */
|
||||
if(RegCreateKeyEx(HKEY_LOCAL_MACHINE,
|
||||
L"SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Kernel",
|
||||
0,
|
||||
NULL,
|
||||
REG_OPTION_NON_VOLATILE,
|
||||
KEY_SET_VALUE,
|
||||
NULL,
|
||||
&hReg,
|
||||
NULL) != ERROR_SUCCESS) {
|
||||
DbgPrint("Failed to Disable Sysenter\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Disable Fast System Call */
|
||||
if(RegSetValueEx(hReg,
|
||||
L"FastSystemCallDisable",
|
||||
0,
|
||||
REG_DWORD,
|
||||
(BYTE*)&Value,
|
||||
sizeof(DWORD)) != ERROR_SUCCESS) {
|
||||
RegCloseKey(hReg);
|
||||
DbgPrint("Failed to Disable Sysenter\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Return Success */
|
||||
RegCloseKey(hReg);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL
|
||||
EnableDriver(WCHAR *Key, BOOL Enable)
|
||||
{
|
||||
|
@ -1022,6 +1061,9 @@ WinMain(HINSTANCE hInstance,
|
|||
/* restore the exception handler */
|
||||
SetUnhandledExceptionFilter(OldHandler);
|
||||
|
||||
/* Disable Fast System Call no matter what */
|
||||
DisableFastSystemCall();
|
||||
|
||||
lc = DestinationPath;
|
||||
lc += GetSystemDirectory(DestinationPath, MAX_PATH) - 1;
|
||||
if(lc >= DestinationPath && *lc != L'\\')
|
||||
|
|
56
reactos/tools/nci/makefile
Normal file
56
reactos/tools/nci/makefile
Normal file
|
@ -0,0 +1,56 @@
|
|||
# $Id: makefile 12852 2005-01-06 13:58:04Z mf $
|
||||
#
|
||||
# ReactOS Operating System
|
||||
#
|
||||
# Generate files for a kernel module that needs to add a service table.
|
||||
#
|
||||
PATH_TO_TOP = ../..
|
||||
|
||||
TARGETNAME = ncitool
|
||||
|
||||
# WIN32K.SYS
|
||||
WIN32K_SVC_DB = w32ksvc.db
|
||||
WIN32K_SERVICE_TABLE=../../subsys/win32k/main/svctab.c
|
||||
WIN32K_GDI_STUBS=../../lib/gdi32/misc/win32k.S
|
||||
WIN32K_USER_STUBS=../../lib/user32/misc/win32k.S
|
||||
|
||||
# NTOSKRNL.EXE
|
||||
KERNEL_SVC_DB = sysfuncs.lst
|
||||
KERNEL_SERVICE_TABLE = ../../include/ntdll/napi.h
|
||||
NTDLL_STUBS = ../../lib/ntdll/napi.S
|
||||
KERNEL_STUBS = ../../ntoskrnl/ex/zw.S
|
||||
|
||||
SVC_FILES = $(KERNEL_SERVICE_TABLE) $(WIN32K_SERVICE_TABLE) $(NTDLL_STUBS) $(KERNEL_STUBS) $(WIN32K_GDI_STUBS) $(WIN32K_USER_STUBS)
|
||||
|
||||
CLEAN_FILES = $(TARGETNAME)$(EXE_POSTFIX) $(SVC_FILES)
|
||||
|
||||
BASE_CFLAGS = -I../../include
|
||||
|
||||
CFLAGS += -Wall -Werror
|
||||
|
||||
all: $(SVC_FILES)
|
||||
|
||||
$(TARGETNAME)$(EXE_POSTFIX): $(TARGETNAME).c
|
||||
$(HOST_CC) \
|
||||
$(CFLAGS) \
|
||||
-o $(TARGETNAME) \
|
||||
-O2 \
|
||||
$(TARGETNAME).c
|
||||
|
||||
$(SVC_FILES): $(TARGETNAME)$(EXE_POSTFIX)
|
||||
@./$(TARGETNAME)$(EXE_POSTFIX) \
|
||||
$(KERNEL_SVC_DB) \
|
||||
$(WIN32K_SVC_DB) \
|
||||
$(KERNEL_SERVICE_TABLE) \
|
||||
$(WIN32K_SERVICE_TABLE) \
|
||||
$(NTDLL_STUBS) \
|
||||
$(KERNEL_STUBS) \
|
||||
$(WIN32K_GDI_STUBS) \
|
||||
$(WIN32K_USER_STUBS)
|
||||
|
||||
clean:
|
||||
- $(RM) $(CLEAN_FILES)
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
include ../../rules.mak
|
556
reactos/tools/nci/ncitool.c
Normal file
556
reactos/tools/nci/ncitool.c
Normal file
|
@ -0,0 +1,556 @@
|
|||
/*
|
||||
* FILE: tools/nci/ncitool.c
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: Native Call Interface Support Tool
|
||||
* PURPOSE: Generates NCI Tables and Stubs.
|
||||
* PROGRAMMER; Alex Ionescu (alex@relsoft.net)
|
||||
* CHANGE HISTORY: 14/01/05 - Created. Based on original code by
|
||||
* KJK::Hyperion and Emanuelle Aliberti.
|
||||
*
|
||||
*/
|
||||
|
||||
/* INCLUDE ******************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/* DEFINES ****************************************************************/
|
||||
|
||||
#define INPUT_BUFFER_SIZE 255
|
||||
#define Arguments 8
|
||||
|
||||
/******* Table Indexes ************/
|
||||
#define MAIN_INDEX 0x0
|
||||
#define WIN32K_INDEX 0x1000
|
||||
|
||||
/******* Argument List ************/
|
||||
/* First, define the Databases */
|
||||
#define NativeSystemDb 0
|
||||
#define NativeGuiDb 1
|
||||
|
||||
/* Now the Service Tables */
|
||||
#define NtosServiceTable 2
|
||||
#define Win32kServiceTable 3
|
||||
|
||||
/* And finally, the stub files. */
|
||||
#define NtosUserStubs 4
|
||||
#define NtosKernelStubs 5
|
||||
#define Win32kGdiStubs 6
|
||||
#define Win32kUserStubs 7
|
||||
|
||||
/********** Stub Code ************/
|
||||
|
||||
/*
|
||||
* This stubs calls into KUSER_SHARED_DATA where either a
|
||||
* sysenter or interrupt is performed, depending on CPU support.
|
||||
*/
|
||||
#define UserModeStub_x86 " movl $0x%x, %%eax\n" \
|
||||
" movl $KUSER_SHARED_SYSCALL, %%ecx\n" \
|
||||
" call *%%ecx\n" \
|
||||
" ret $0x%x\n\n"
|
||||
|
||||
/*
|
||||
* This stub calls KiSystemService directly with a fake INT2E stack.
|
||||
* Because EIP is pushed during the call, the handler will return here.
|
||||
*/
|
||||
#define KernelModeStub_x86 " movl $0x%x, %%eax\n" \
|
||||
" leal 4(%%esp), %%edx\n" \
|
||||
" pushfl\n" \
|
||||
" pushl $KERNEL_CS\n" \
|
||||
" call _KiSystemService\n" \
|
||||
" ret $0x%x\n\n"
|
||||
|
||||
/***** Arch Dependent Stuff ******/
|
||||
//#ifdef _M_IX86
|
||||
#define ARGS_TO_BYTES(x) x*4
|
||||
#define UserModeStub UserModeStub_x86
|
||||
#define KernelModeStub KernelModeStub_x86
|
||||
|
||||
//#elseif
|
||||
//#error Unsupported Architecture
|
||||
//#endif
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
/*++
|
||||
* WriteFileHeader
|
||||
*
|
||||
* Prints out the File Header for a Stub File.
|
||||
*
|
||||
* Params:
|
||||
* StubFile - Stub File to which to write the header.
|
||||
*
|
||||
* FileDescription - Description of the Stub file to which to write the header.
|
||||
*
|
||||
* FileLocation - Name of the Stub file to which to write the header.
|
||||
*
|
||||
* Returns:
|
||||
* None.
|
||||
*
|
||||
* Remarks:
|
||||
* FileLocation is only used for printing the header.
|
||||
*
|
||||
*--*/
|
||||
void
|
||||
WriteFileHeader(FILE * StubFile,
|
||||
char* FileDescription,
|
||||
char* FileLocation)
|
||||
{
|
||||
/* This prints out the file header */
|
||||
fprintf(StubFile,
|
||||
"/* FILE: %s\n"
|
||||
" * COPYRIGHT: See COPYING in the top level directory\n"
|
||||
" * PURPOSE: %s\n"
|
||||
" * PROGRAMMER: Computer Generated File. See tools/nci/ncitool.c\n"
|
||||
" * REMARK: DO NOT EDIT OR COMMIT MODIFICATIONS TO THIS FILE\n"
|
||||
" */\n\n\n"
|
||||
"#include <napi/shared_data.h>\n\n",
|
||||
FileDescription,
|
||||
FileLocation);
|
||||
}
|
||||
|
||||
/*++
|
||||
* WriteFileHeader
|
||||
*
|
||||
* Prints out the File Header for a Stub File.
|
||||
*
|
||||
* Params:
|
||||
* StubFile - Stub File to which to write the header.
|
||||
*
|
||||
* FileDescription - Description of the Stub file to which to write the header.
|
||||
*
|
||||
* FileLocation - Name of the Stub file to which to write the header.
|
||||
*
|
||||
* Returns:
|
||||
* None.
|
||||
*
|
||||
* Remarks:
|
||||
* FileLocation is only used for printing the header.
|
||||
*
|
||||
*--*/
|
||||
void
|
||||
WriteStubHeader(FILE* StubFile,
|
||||
char* SyscallName,
|
||||
unsigned StackBytes)
|
||||
{
|
||||
/* Export the function */
|
||||
fprintf(StubFile, ".global _%s@%d\n", SyscallName, StackBytes);
|
||||
|
||||
/* Define it */
|
||||
fprintf(StubFile, "_%s@%d:\n\n", SyscallName, StackBytes);
|
||||
}
|
||||
|
||||
|
||||
/*++
|
||||
* WriteKernelModeStub
|
||||
*
|
||||
* Prints out the Kernel Mode Stub for a System Call.
|
||||
*
|
||||
* Params:
|
||||
* StubFile - Stub File to which to write the header.
|
||||
*
|
||||
* SyscallName - Name of System Call for which to add the stub.
|
||||
*
|
||||
* StackBytes - Number of bytes on the stack to return after doing the system call.
|
||||
*
|
||||
* SyscallId - Service Descriptor Table ID for this System Call.
|
||||
*
|
||||
* Returns:
|
||||
* None.
|
||||
*
|
||||
* Remarks:
|
||||
* On i386, StackBytes is the number of arguments x 4.
|
||||
*
|
||||
*--*/
|
||||
void
|
||||
WriteKernelModeStub(FILE* StubFile,
|
||||
char* SyscallName,
|
||||
unsigned StackBytes,
|
||||
unsigned int SyscallId)
|
||||
{
|
||||
/* Write the Stub Header and export the Function */
|
||||
WriteStubHeader(StubFile, SyscallName, StackBytes);
|
||||
|
||||
/* Write the Stub Code */
|
||||
fprintf(StubFile, KernelModeStub, SyscallId, StackBytes);
|
||||
}
|
||||
|
||||
/*++
|
||||
* WriteUserModeStub
|
||||
*
|
||||
* Prints out the User Mode Stub for a System Call.
|
||||
*
|
||||
* Params:
|
||||
* StubFile - Stub File to which to write the header.
|
||||
*
|
||||
* SyscallName - Name of System Call for which to add the stub.
|
||||
*
|
||||
* StackBytes - Number of bytes on the stack to return after doing the system call.
|
||||
*
|
||||
* SyscallId - Service Descriptor Table ID for this System Call.
|
||||
*
|
||||
* Returns:
|
||||
* None.
|
||||
*
|
||||
* Remarks:
|
||||
* On i386, StackBytes is the number of arguments x 4.
|
||||
*
|
||||
*--*/
|
||||
void
|
||||
WriteUserModeStub(FILE* StubFile,
|
||||
char* SyscallName,
|
||||
unsigned StackBytes,
|
||||
unsigned int SyscallId)
|
||||
{
|
||||
/* Write the Stub Header and export the Function */
|
||||
WriteStubHeader(StubFile, SyscallName, StackBytes);
|
||||
|
||||
/* Write the Stub Code */
|
||||
fprintf(StubFile, UserModeStub, SyscallId, StackBytes);
|
||||
}
|
||||
|
||||
/*++
|
||||
* GetNameAndArgumentsFromDb
|
||||
*
|
||||
* Parses an entry from a System Call Database, extracting
|
||||
* the function's name and arguments that it takes.
|
||||
*
|
||||
* Params:
|
||||
* Line - Entry from the Database to parse.
|
||||
*
|
||||
* NtSyscallName - Output string to which to save the Function Name
|
||||
*
|
||||
* SyscallArguments - Output string to which to save the number of
|
||||
* arguments that the function takes.
|
||||
*
|
||||
* Returns:
|
||||
* None.
|
||||
*
|
||||
* Remarks:
|
||||
* On i386, StackBytes is the number of arguments x 4.
|
||||
*
|
||||
*--*/
|
||||
void
|
||||
GetNameAndArgumentsFromDb(char Line[],
|
||||
char ** NtSyscallName,
|
||||
char ** SyscallArguments)
|
||||
{
|
||||
char *s;
|
||||
char *stmp;
|
||||
|
||||
/* Remove new line */
|
||||
if ((s = (char *) strchr(Line,'\r')) != NULL) {
|
||||
*s = '\0';
|
||||
}
|
||||
|
||||
/* Skip comments (#) and empty lines */
|
||||
s = &Line[0];
|
||||
if ((*s) != '#' && (*s) != '\0') {
|
||||
|
||||
/* Extract the NtXXX name */
|
||||
*NtSyscallName = (char *)strtok(s," \t");
|
||||
|
||||
/* Extract the argument count */
|
||||
*SyscallArguments = (char *)strtok(NULL," \t");
|
||||
|
||||
/* Remove, if present, the trailing LF */
|
||||
if ((stmp = strchr(*SyscallArguments, '\n')) != NULL) {
|
||||
*stmp = '\0';
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
/* Skip this entry */
|
||||
*NtSyscallName = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*++
|
||||
* CreateStubs
|
||||
*
|
||||
* Parses a System Call Database and creates stubs for all the entries.
|
||||
*
|
||||
* Params:
|
||||
* SyscallDb - System Call Database to parse.
|
||||
*
|
||||
* UserModeFiles - Array of Usermode Stub Files to which to write the stubs.
|
||||
*
|
||||
* KernelModeFile - Kernelmode Stub Files to which to write the stubs.
|
||||
*
|
||||
* Index - Name of System Call for which to add the stub.
|
||||
*
|
||||
* UserFiles - Number of bytes on the stack to return after doing the system call.
|
||||
*
|
||||
* NeedsZw - Service Descriptor Table ID for this System Call.
|
||||
*
|
||||
* Returns:
|
||||
* None.
|
||||
*
|
||||
* Remarks:
|
||||
* None.
|
||||
*
|
||||
*--*/
|
||||
void
|
||||
CreateStubs(FILE * SyscallDb,
|
||||
FILE * UserModeFiles[],
|
||||
FILE * KernelModeFile,
|
||||
unsigned Index,
|
||||
unsigned UserFiles,
|
||||
unsigned NeedsZw)
|
||||
{
|
||||
char Line[INPUT_BUFFER_SIZE];
|
||||
char *NtSyscallName;
|
||||
char *ZwSyscallName = NULL;
|
||||
char *SyscallArguments;
|
||||
int SyscallId;
|
||||
unsigned StackBytes;
|
||||
|
||||
/* We loop, incrementing the System Call Index, until the end of the file */
|
||||
for (SyscallId = 0; ((!feof(SyscallDb)) && (fgets(Line, sizeof(Line), SyscallDb) != NULL));) {
|
||||
|
||||
/* Extract the Name and Arguments */
|
||||
GetNameAndArgumentsFromDb(Line, &NtSyscallName, &SyscallArguments);
|
||||
StackBytes = ARGS_TO_BYTES(strtoul(SyscallArguments, NULL, 0));
|
||||
|
||||
/* Make sure we really extracted something */
|
||||
if (NtSyscallName) {
|
||||
|
||||
/* Create the ZwXXX name, if requested */
|
||||
if (NeedsZw) {
|
||||
ZwSyscallName = alloca(strlen(NtSyscallName));
|
||||
strcpy(ZwSyscallName, NtSyscallName);
|
||||
ZwSyscallName[0] = 'Z';
|
||||
ZwSyscallName[1] = 'w';
|
||||
}
|
||||
|
||||
/* Create Usermode Stubs for Nt/Zw syscalls in each Usermode file */
|
||||
int i;
|
||||
for (i= 0; i < UserFiles; i++) {
|
||||
|
||||
/* Write the Nt Version */
|
||||
WriteUserModeStub(UserModeFiles[i],
|
||||
NtSyscallName,
|
||||
StackBytes,
|
||||
SyscallId | Index);
|
||||
|
||||
/* If a Zw Version is needed (was specified), write it too */
|
||||
if (ZwSyscallName) WriteUserModeStub(UserModeFiles[i],
|
||||
ZwSyscallName,
|
||||
StackBytes,
|
||||
SyscallId | Index);
|
||||
|
||||
}
|
||||
|
||||
/* Create the Kernel coutnerparts (only Zw*, Nt* are the real functions!) */
|
||||
if (KernelModeFile) WriteKernelModeStub(KernelModeFile,
|
||||
ZwSyscallName,
|
||||
StackBytes,
|
||||
SyscallId | Index);
|
||||
|
||||
/* Only increase if we actually added something */
|
||||
SyscallId++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*++
|
||||
* CreateSystemServiceTable
|
||||
*
|
||||
* Parses a System Call Database and creates a System Call Service Table for it.
|
||||
*
|
||||
* Params:
|
||||
* SyscallDb - System Call Database to parse.
|
||||
*
|
||||
* SyscallTable - File in where to create System Call Service Table.
|
||||
*
|
||||
* Name - Name of the Service Table.
|
||||
*
|
||||
* FileLocation - Filename containing the Table.
|
||||
*
|
||||
* Returns:
|
||||
* None.
|
||||
*
|
||||
* Remarks:
|
||||
* FileLocation is only used for the header generation.
|
||||
*
|
||||
*--*/
|
||||
void
|
||||
CreateSystemServiceTable(FILE *SyscallDb,
|
||||
FILE *SyscallTable,
|
||||
char * Name,
|
||||
char * FileLocation)
|
||||
{
|
||||
char Line[INPUT_BUFFER_SIZE];
|
||||
char *NtSyscallName;
|
||||
char *SyscallArguments;
|
||||
int SyscallId;
|
||||
|
||||
/* Print the Header */
|
||||
WriteFileHeader(SyscallTable, "System Call Table for Native API", FileLocation);
|
||||
|
||||
/* First we build the SSDT */
|
||||
fprintf(SyscallTable,"\n\n\n");
|
||||
fprintf(SyscallTable,"SSDT %sSSDT[] = {\n", Name);
|
||||
|
||||
/* We loop, incrementing the System Call Index, until the end of the file */
|
||||
for (SyscallId = 0; ((!feof(SyscallDb)) && (fgets(Line, sizeof(Line), SyscallDb) != NULL));) {
|
||||
|
||||
/* Extract the Name and Arguments */
|
||||
GetNameAndArgumentsFromDb(Line, &NtSyscallName, &SyscallArguments);
|
||||
|
||||
/* Make sure we really extracted something */
|
||||
if (NtSyscallName) {
|
||||
|
||||
/* Add a new line */
|
||||
if (SyscallId > 0) fprintf(SyscallTable,",\n");
|
||||
|
||||
/* Write the syscall name in the service table. */
|
||||
fprintf(SyscallTable,"\t\t(PVOID (NTAPI *)(VOID))%s", NtSyscallName);
|
||||
|
||||
/* Only increase if we actually added something */
|
||||
SyscallId++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Close the service table (C syntax) */
|
||||
fprintf(SyscallTable,"\n};\n");
|
||||
|
||||
/* Now we build the SSPT */
|
||||
rewind(SyscallDb);
|
||||
fprintf(SyscallTable,"\n\n\n");
|
||||
fprintf(SyscallTable,"SSPT %sSSPT[] = {\n", Name);
|
||||
|
||||
for (SyscallId = 0; ((!feof(SyscallDb)) && (fgets(Line, sizeof(Line), SyscallDb) != NULL));) {
|
||||
|
||||
/* Extract the Name and Arguments */
|
||||
GetNameAndArgumentsFromDb(Line, &NtSyscallName, &SyscallArguments);
|
||||
|
||||
/* Make sure we really extracted something */
|
||||
if (NtSyscallName) {
|
||||
|
||||
/* Add a new line */
|
||||
if (SyscallId > 0) fprintf(SyscallTable,",\n");
|
||||
|
||||
/* Write the syscall arguments in the argument table. */
|
||||
fprintf(SyscallTable,"\t\t%lu * sizeof(void *)",strtoul(SyscallArguments, NULL, 0));
|
||||
|
||||
/* Only increase if we actually added something */
|
||||
SyscallId++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Close the service table (C syntax) */
|
||||
fprintf(SyscallTable,"\n};\n");
|
||||
|
||||
/*
|
||||
* We write some useful defines
|
||||
*/
|
||||
fprintf(SyscallTable, "\n\n#define MIN_SYSCALL_NUMBER 0\n");
|
||||
fprintf(SyscallTable, "#define MAX_SYSCALL_NUMBER %d\n", SyscallId - 1);
|
||||
fprintf(SyscallTable, "#define NUMBER_OF_SYSCALLS %d\n", SyscallId);
|
||||
fprintf(SyscallTable, "ULONG %sNumberOfSysCalls = %d;\n", Name, SyscallId);
|
||||
}
|
||||
|
||||
void usage(char * argv0)
|
||||
{
|
||||
printf("Usage: %s sysfuncs.lst w32ksvc.db napi.h ssdt.h napi.S zw.S win32k.S win32k.S\n"
|
||||
" sysfuncs.lst native system functions database\n"
|
||||
" w32ksvc.db native graphic functions database\n"
|
||||
" napi.h NTOSKRNL service table\n"
|
||||
" ssdt.h WIN32K service table\n"
|
||||
" napi.S NTDLL stubs\n"
|
||||
" zw.S NTOSKRNL Zw stubs\n"
|
||||
" win32k.S GDI32 stubs\n"
|
||||
" win32k.S USER32 stubs\n",
|
||||
argv0
|
||||
);
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
FILE * Files[Arguments];
|
||||
int FileNumber;
|
||||
char * OpenType = "r";
|
||||
|
||||
/* Make sure all arguments all there */
|
||||
if (argc != Arguments + 1) {
|
||||
usage(argv[0]);
|
||||
return(1);
|
||||
}
|
||||
|
||||
/* Open all Output and bail out if any fail */
|
||||
for (FileNumber = 0; FileNumber < Arguments; FileNumber++) {
|
||||
|
||||
/* Open the File */
|
||||
if (FileNumber == 2) OpenType = "wb";
|
||||
Files[FileNumber] = fopen(argv[FileNumber + 1], OpenType);
|
||||
|
||||
/* Check for failure and error out if so */
|
||||
if (!Files[FileNumber]) {
|
||||
perror(argv[FileNumber + 1]);
|
||||
return (1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Write the File Headers */
|
||||
WriteFileHeader(Files[NtosUserStubs],
|
||||
"System Call Stubs for Native API",
|
||||
argv[NtosUserStubs + 1]);
|
||||
|
||||
WriteFileHeader(Files[NtosKernelStubs],
|
||||
"System Call Stubs for Native API",
|
||||
argv[NtosKernelStubs + 1]);
|
||||
fputs("#include <internal/i386/segment.h>\n\n", Files[NtosKernelStubs]);
|
||||
|
||||
WriteFileHeader(Files[Win32kGdiStubs],
|
||||
"System Call Stubs for Native API",
|
||||
argv[Win32kGdiStubs + 1]);
|
||||
|
||||
WriteFileHeader(Files[Win32kUserStubs],
|
||||
"System Call Stubs for Native API",
|
||||
argv[Win32kUserStubs + 1]);
|
||||
|
||||
|
||||
/* Create the System Stubs */
|
||||
CreateStubs(Files[NativeSystemDb],
|
||||
&Files[NtosUserStubs],
|
||||
Files[NtosKernelStubs],
|
||||
MAIN_INDEX,
|
||||
1,
|
||||
1);
|
||||
|
||||
/* Create the Graphics Stubs */
|
||||
CreateStubs(Files[NativeGuiDb],
|
||||
&Files[Win32kGdiStubs],
|
||||
NULL,
|
||||
WIN32K_INDEX,
|
||||
2,
|
||||
0);
|
||||
|
||||
/* Rewind the databases */
|
||||
rewind(Files[NativeSystemDb]);
|
||||
rewind(Files[NativeGuiDb]);
|
||||
|
||||
/* Create the Service Tables */
|
||||
CreateSystemServiceTable(Files[NativeSystemDb],
|
||||
Files[NtosServiceTable],
|
||||
"Main",
|
||||
argv[NtosServiceTable + 1]);
|
||||
|
||||
CreateSystemServiceTable(Files[NativeGuiDb],
|
||||
Files[Win32kServiceTable],
|
||||
"Win32k",
|
||||
argv[Win32kServiceTable + 1]);
|
||||
|
||||
/* Close all files */
|
||||
for (FileNumber = 0; FileNumber < Arguments; FileNumber++) {
|
||||
|
||||
/* Close the File */
|
||||
fclose(Files[FileNumber]);
|
||||
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
235
reactos/tools/nci/sysfuncs.lst
Normal file
235
reactos/tools/nci/sysfuncs.lst
Normal file
|
@ -0,0 +1,235 @@
|
|||
NtAcceptConnectPort 6
|
||||
NtAccessCheck 8
|
||||
NtAccessCheckAndAuditAlarm 11
|
||||
NtAddAtom 3
|
||||
NtAddBootEntry 2
|
||||
NtAdjustGroupsToken 6
|
||||
NtAdjustPrivilegesToken 6
|
||||
NtAlertResumeThread 2
|
||||
NtAlertThread 1
|
||||
NtAllocateLocallyUniqueId 1
|
||||
NtAllocateUuids 4
|
||||
NtAllocateVirtualMemory 6
|
||||
NtAssignProcessToJobObject 2
|
||||
NtCallbackReturn 3
|
||||
NtCancelIoFile 2
|
||||
NtCancelTimer 2
|
||||
NtClearEvent 1
|
||||
NtClose 1
|
||||
NtCloseObjectAuditAlarm 3
|
||||
NtCompleteConnectPort 1
|
||||
NtConnectPort 8
|
||||
NtContinue 2
|
||||
NtCreateDirectoryObject 3
|
||||
NtCreateEvent 5
|
||||
NtCreateEventPair 3
|
||||
NtCreateFile 11
|
||||
NtCreateIoCompletion 4
|
||||
NtCreateJobObject 3
|
||||
NtCreateKey 7
|
||||
NtCreateMailslotFile 8
|
||||
NtCreateMutant 4
|
||||
NtCreateNamedPipeFile 14
|
||||
NtCreatePagingFile 4
|
||||
NtCreatePort 5
|
||||
NtCreateProcess 8
|
||||
NtCreateProfile 9
|
||||
NtCreateSection 7
|
||||
NtCreateSemaphore 5
|
||||
NtCreateSymbolicLinkObject 4
|
||||
NtCreateThread 8
|
||||
NtCreateTimer 4
|
||||
NtCreateToken 13
|
||||
NtCreateWaitablePort 5
|
||||
NtDelayExecution 2
|
||||
NtDeleteAtom 1
|
||||
NtDeleteBootEntry 2
|
||||
NtDeleteFile 1
|
||||
NtDeleteKey 1
|
||||
NtDeleteObjectAuditAlarm 3
|
||||
NtDeleteValueKey 2
|
||||
NtDeviceIoControlFile 10
|
||||
NtDisplayString 1
|
||||
NtDuplicateObject 7
|
||||
NtDuplicateToken 6
|
||||
NtEnumerateBootEntries 2
|
||||
NtEnumerateKey 6
|
||||
NtEnumerateValueKey 6
|
||||
NtExtendSection 2
|
||||
NtFindAtom 3
|
||||
NtFlushBuffersFile 2
|
||||
NtFlushInstructionCache 3
|
||||
NtFlushKey 1
|
||||
NtFlushVirtualMemory 4
|
||||
NtFlushWriteBuffer 0
|
||||
NtFreeVirtualMemory 4
|
||||
NtFsControlFile 10
|
||||
NtGetContextThread 2
|
||||
NtGetPlugPlayEvent 4
|
||||
NtGetTickCount 0
|
||||
NtImpersonateClientOfPort 2
|
||||
NtImpersonateThread 3
|
||||
NtInitializeRegistry 1
|
||||
NtInitiatePowerAction 4
|
||||
NtIsProcessInJob 2
|
||||
NtListenPort 2
|
||||
NtLoadDriver 1
|
||||
NtLoadKey 2
|
||||
NtLoadKey2 3
|
||||
NtLockFile 10
|
||||
NtLockVirtualMemory 4
|
||||
NtMakePermanentObject 1
|
||||
NtMakeTemporaryObject 1
|
||||
NtMapViewOfSection 10
|
||||
NtNotifyChangeDirectoryFile 9
|
||||
NtNotifyChangeKey 10
|
||||
NtOpenDirectoryObject 3
|
||||
NtOpenEvent 3
|
||||
NtOpenEventPair 3
|
||||
NtOpenFile 6
|
||||
NtOpenIoCompletion 3
|
||||
NtOpenJobObject 3
|
||||
NtOpenKey 3
|
||||
NtOpenMutant 3
|
||||
NtOpenObjectAuditAlarm 12
|
||||
NtOpenProcess 4
|
||||
NtOpenProcessToken 3
|
||||
NtOpenProcessTokenEx 4
|
||||
NtOpenSection 3
|
||||
NtOpenSemaphore 3
|
||||
NtOpenSymbolicLinkObject 3
|
||||
NtOpenThread 4
|
||||
NtOpenThreadToken 4
|
||||
NtOpenThreadTokenEx 5
|
||||
NtOpenTimer 3
|
||||
NtPlugPlayControl 4
|
||||
NtPowerInformation 5
|
||||
NtPrivilegeCheck 3
|
||||
NtPrivilegedServiceAuditAlarm 5
|
||||
NtPrivilegeObjectAuditAlarm 6
|
||||
NtProtectVirtualMemory 5
|
||||
NtPulseEvent 2
|
||||
NtQueryInformationAtom 5
|
||||
NtQueryAttributesFile 2
|
||||
NtQueryBootEntryOrder 2
|
||||
NtQueryBootOptions 2
|
||||
NtQueryDefaultLocale 2
|
||||
NtQueryDefaultUILanguage 1
|
||||
NtQueryDirectoryFile 11
|
||||
NtQueryDirectoryObject 7
|
||||
NtQueryEaFile 9
|
||||
NtQueryEvent 5
|
||||
NtQueryFullAttributesFile 2
|
||||
NtQueryInformationFile 5
|
||||
NtQueryInformationJobObject 5
|
||||
NtQueryInformationPort 5
|
||||
NtQueryInformationProcess 5
|
||||
NtQueryInformationThread 5
|
||||
NtQueryInformationToken 5
|
||||
NtQueryInstallUILanguage 1
|
||||
NtQueryIntervalProfile 2
|
||||
NtQueryIoCompletion 5
|
||||
NtQueryKey 5
|
||||
NtQueryMultipleValueKey 6
|
||||
NtQueryMutant 5
|
||||
NtQueryObject 5
|
||||
NtQueryOleDirectoryFile 11
|
||||
NtQueryPerformanceCounter 2
|
||||
NtQueryQuotaInformationFile 9
|
||||
NtQuerySection 5
|
||||
NtQuerySecurityObject 5
|
||||
NtQuerySemaphore 5
|
||||
NtQuerySymbolicLinkObject 3
|
||||
NtQuerySystemEnvironmentValue 4
|
||||
NtQuerySystemInformation 4
|
||||
NtQuerySystemTime 1
|
||||
NtQueryTimer 5
|
||||
NtQueryTimerResolution 3
|
||||
NtQueryValueKey 6
|
||||
NtQueryVirtualMemory 6
|
||||
NtQueryVolumeInformationFile 5
|
||||
NtQueueApcThread 5
|
||||
NtRaiseException 3
|
||||
NtRaiseHardError 6
|
||||
NtReadFile 9
|
||||
NtReadFileScatter 9
|
||||
NtReadRequestData 6
|
||||
NtReadVirtualMemory 5
|
||||
NtRegisterThreadTerminatePort 1
|
||||
NtReleaseMutant 2
|
||||
NtReleaseSemaphore 3
|
||||
NtRemoveIoCompletion 5
|
||||
NtReplaceKey 3
|
||||
NtReplyPort 2
|
||||
NtReplyWaitReceivePort 4
|
||||
NtReplyWaitReplyPort 2
|
||||
NtRequestPort 2
|
||||
NtRequestWaitReplyPort 3
|
||||
NtResetEvent 2
|
||||
NtRestoreKey 3
|
||||
NtResumeThread 2
|
||||
NtSaveKey 2
|
||||
NtSaveKeyEx 3
|
||||
NtSetBootEntryOrder 2
|
||||
NtSetBootOptions 2
|
||||
NtSetIoCompletion 5
|
||||
NtSetContextThread 2
|
||||
NtSetDefaultHardErrorPort 1
|
||||
NtSetDefaultLocale 2
|
||||
NtSetDefaultUILanguage 1
|
||||
NtSetEaFile 4
|
||||
NtSetEvent 2
|
||||
NtSetHighEventPair 1
|
||||
NtSetHighWaitLowEventPair 1
|
||||
NtSetHighWaitLowThread 0
|
||||
NtSetInformationFile 5
|
||||
NtSetInformationKey 4
|
||||
NtSetInformationJobObject 4
|
||||
NtSetInformationObject 4
|
||||
NtSetInformationProcess 4
|
||||
NtSetInformationThread 4
|
||||
NtSetInformationToken 4
|
||||
NtSetIntervalProfile 2
|
||||
NtSetLdtEntries 6
|
||||
NtSetLowEventPair 1
|
||||
NtSetLowWaitHighEventPair 1
|
||||
NtSetLowWaitHighThread 0
|
||||
NtSetQuotaInformationFile 4
|
||||
NtSetSecurityObject 3
|
||||
NtSetSystemEnvironmentValue 2
|
||||
NtSetSystemInformation 3
|
||||
NtSetSystemPowerState 3
|
||||
NtSetSystemTime 2
|
||||
NtSetTimer 7
|
||||
NtSetTimerResolution 3
|
||||
NtSetUuidSeed 1
|
||||
NtSetValueKey 6
|
||||
NtSetVolumeInformationFile 5
|
||||
NtShutdownSystem 1
|
||||
NtSignalAndWaitForSingleObject 4
|
||||
NtStartProfile 1
|
||||
NtStopProfile 1
|
||||
NtSuspendThread 2
|
||||
NtSystemDebugControl 6
|
||||
NtTerminateJobObject 2
|
||||
NtTerminateProcess 2
|
||||
NtTerminateThread 2
|
||||
NtTestAlert 0
|
||||
NtTraceEvent 4
|
||||
NtTranslateFilePath 3
|
||||
NtUnloadDriver 1
|
||||
NtUnloadKey 1
|
||||
NtUnlockFile 5
|
||||
NtUnlockVirtualMemory 4
|
||||
NtUnmapViewOfSection 2
|
||||
NtVdmControl 2
|
||||
NtWaitForMultipleObjects 5
|
||||
NtWaitForSingleObject 3
|
||||
NtWaitHighEventPair 1
|
||||
NtWaitLowEventPair 1
|
||||
NtWriteFile 9
|
||||
NtWriteFileGather 9
|
||||
NtWriteRequestData 6
|
||||
NtWriteVirtualMemory 5
|
||||
NtW32Call 5
|
||||
NtYieldExecution 0
|
Loading…
Reference in a new issue