mirror of
https://github.com/reactos/reactos.git
synced 2025-04-28 01:11:35 +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) \
|
all: bootstrap $(BOOT_LOADERS) $(COMPONENTS) $(REGTESTS) $(HALS) $(BUS) $(LIB_FSLIB) \
|
||||||
$(DLLS) $(SUBSYS) $(KERNEL_DRIVERS) $(SYS_APPS) $(SYS_SVC) $(APPS) $(EXT_MODULES)
|
$(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) \
|
depends: $(LIB_STATIC:%=%_depends) $(LIB_FSLIB:%=%_depends) msvcrt_depends $(DLLS:%=%_depends) \
|
||||||
$(SUBSYS:%=%_depends) $(SYS_SVC:%=%_depends) \
|
$(SUBSYS:%=%_depends) $(SYS_SVC:%=%_depends) \
|
||||||
|
@ -147,7 +147,7 @@ test: $(BOOT_LOADERS:%=%_test) $(COMPONENTS:%=%_test) $(HALS:%=%_test) $(BUS:%=%
|
||||||
$(KERNEL_DRIVERS:%=%_test) $(SUBSYS:%=%_test) \
|
$(KERNEL_DRIVERS:%=%_test) $(SUBSYS:%=%_test) \
|
||||||
$(SYS_SVC:%=%_test) $(EXT_MODULES:%=%_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) \
|
$(BOOT_LOADERS:%=%_clean) $(HALS:%=%_clean) $(COMPONENTS:%=%_clean) \
|
||||||
$(BUS:%=%_clean) $(LIB_STATIC:%=%_clean) $(LIB_FSLIB:%=%_clean) \
|
$(BUS:%=%_clean) $(LIB_STATIC:%=%_clean) $(LIB_FSLIB:%=%_clean) \
|
||||||
msvcrt_clean $(DLLS:%=%_clean) $(KERNEL_DRIVERS:%=%_clean) \
|
msvcrt_clean $(DLLS:%=%_clean) $(KERNEL_DRIVERS:%=%_clean) \
|
||||||
|
@ -462,37 +462,21 @@ dk_install:
|
||||||
# Interfaces
|
# Interfaces
|
||||||
#
|
#
|
||||||
iface_native:
|
iface_native:
|
||||||
$(MAKE) --silent -C iface/native
|
$(MAKE) --silent -C tools/nci
|
||||||
|
|
||||||
iface_native_implib:
|
iface_native_implib:
|
||||||
|
|
||||||
iface_native_test:
|
iface_native_test:
|
||||||
|
|
||||||
iface_native_clean:
|
iface_native_clean:
|
||||||
$(MAKE) --silent -C iface/native clean
|
$(MAKE) --silent -C tools/nci clean
|
||||||
|
|
||||||
iface_native_install:
|
iface_native_install:
|
||||||
|
|
||||||
iface_native_bootcd:
|
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 \
|
.PHONY: iface_native iface_native_implib iface_native_test iface_native_clean \
|
||||||
iface_native_install iface_native_bootcd iface_additional \
|
iface_native_install iface_native_bootcd
|
||||||
iface_additional_implib iface_additional_test iface_additional_clean \
|
|
||||||
iface_additional_install iface_additional_bootcd
|
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|
|
@ -25,7 +25,7 @@ KDBG := 0
|
||||||
#
|
#
|
||||||
# Whether to compile for debugging
|
# Whether to compile for debugging
|
||||||
#
|
#
|
||||||
DBG := 0
|
DBG := 0
|
||||||
|
|
||||||
#
|
#
|
||||||
# Whether to compile with optimizations
|
# 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_PAE_ENABLED 9
|
||||||
#define PF_XMMI64_INSTRUCTIONS_AVAILABLE 10
|
#define PF_XMMI64_INSTRUCTIONS_AVAILABLE 10
|
||||||
|
|
||||||
|
#ifndef __ASM__
|
||||||
|
|
||||||
typedef enum _ALTERNATIVE_ARCHITECTURE_TYPE
|
typedef enum _ALTERNATIVE_ARCHITECTURE_TYPE
|
||||||
{
|
{
|
||||||
StandardDesign,
|
StandardDesign,
|
||||||
|
@ -62,13 +64,15 @@ typedef struct _KUSER_SHARED_DATA {
|
||||||
BOOLEAN SafeBootMode;
|
BOOLEAN SafeBootMode;
|
||||||
ULONG TraceLogging;
|
ULONG TraceLogging;
|
||||||
ULONGLONG Fill0;
|
ULONGLONG Fill0;
|
||||||
ULONGLONG SystemCall[4];
|
UCHAR SystemCall[16];
|
||||||
union {
|
union {
|
||||||
volatile KSYSTEM_TIME TickCount;
|
volatile KSYSTEM_TIME TickCount;
|
||||||
volatile ULONG64 TickCountQuad;
|
volatile ULONG64 TickCountQuad;
|
||||||
};
|
};
|
||||||
} KUSER_SHARED_DATA, *PKUSER_SHARED_DATA;
|
} KUSER_SHARED_DATA, *PKUSER_SHARED_DATA;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Values for DosDeviceDriveType */
|
/* Values for DosDeviceDriveType */
|
||||||
#define DOSDEVICE_DRIVE_UNKNOWN 0
|
#define DOSDEVICE_DRIVE_UNKNOWN 0
|
||||||
#define DOSDEVICE_DRIVE_CALCULATE 1
|
#define DOSDEVICE_DRIVE_CALCULATE 1
|
||||||
|
@ -102,5 +106,7 @@ typedef struct _KUSER_SHARED_DATA {
|
||||||
#define SharedUserData ((KUSER_SHARED_DATA * const)USER_SHARED_DATA)
|
#define SharedUserData ((KUSER_SHARED_DATA * const)USER_SHARED_DATA)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define KUSER_SHARED_SYSCALL 0x7FFE0300
|
||||||
|
#define KUSER_SHARED_SYSCALL_RET 0x7FFE0304
|
||||||
|
|
||||||
#endif /* __INCLUDE_NAPI_SHARED_DATA_H */
|
#endif /* __INCLUDE_NAPI_SHARED_DATA_H */
|
||||||
|
|
|
@ -550,7 +550,7 @@ TARGET_CLEAN = \
|
||||||
$(PATH_TO_TOP)/include/reactos/bugcodes.h \
|
$(PATH_TO_TOP)/include/reactos/bugcodes.h \
|
||||||
$(DEP_OBJECTS) $(DEP_FILES) MSG00409.bin bugcodes.rc
|
$(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
|
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_TSC 0x00000010 /* time stamp counters are present */
|
||||||
#define X86_FEATURE_PAE 0x00000040 /* physical address extension is present */
|
#define X86_FEATURE_PAE 0x00000040 /* physical address extension is present */
|
||||||
#define X86_FEATURE_CX8 0x00000100 /* CMPXCHG8B instruction 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_PGE 0x00002000 /* Page Global Enable */
|
||||||
#define X86_FEATURE_MMX 0x00800000 /* MMX extension present */
|
#define X86_FEATURE_MMX 0x00800000 /* MMX extension present */
|
||||||
#define X86_FEATURE_FXSR 0x01000000 /* FXSAVE/FXRSTOR instructions present */
|
#define X86_FEATURE_FXSR 0x01000000 /* FXSAVE/FXRSTOR instructions present */
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#define KTHREAD_TEB 0x20
|
#define KTHREAD_TEB 0x20
|
||||||
#define KTHREAD_KERNEL_STACK 0x28
|
#define KTHREAD_KERNEL_STACK 0x28
|
||||||
#define KTHREAD_NPX_STATE 0x31
|
#define KTHREAD_NPX_STATE 0x31
|
||||||
|
#define KTHREAD_PENDING_USER_APC 0x34 + 0x16
|
||||||
#define KTHREAD_APCSTATE_PROCESS 0x44
|
#define KTHREAD_APCSTATE_PROCESS 0x44
|
||||||
#define KTHREAD_SERVICE_TABLE 0xDC
|
#define KTHREAD_SERVICE_TABLE 0xDC
|
||||||
#define KTHREAD_PREVIOUS_MODE 0x137
|
#define KTHREAD_PREVIOUS_MODE 0x137
|
||||||
|
|
|
@ -143,4 +143,4 @@ _PsBeginThreadWithContextInternal:
|
||||||
|
|
||||||
/* Load the rest of the thread's user mode context. */
|
/* Load the rest of the thread's user mode context. */
|
||||||
movl $0, %eax
|
movl $0, %eax
|
||||||
jmp KeReturnFromSystemCallWithHook
|
jmp _KiServiceExit
|
||||||
|
|
|
@ -45,7 +45,7 @@
|
||||||
# define ARRAY_SIZE(x) (sizeof (x) / sizeof (x[0]))
|
# define ARRAY_SIZE(x) (sizeof (x) / sizeof (x[0]))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern void interrupt_handler2e(void);
|
extern void KiSystemService(void);
|
||||||
extern void interrupt_handler2d(void);
|
extern void interrupt_handler2d(void);
|
||||||
|
|
||||||
extern VOID KiTrap0(VOID);
|
extern VOID KiTrap0(VOID);
|
||||||
|
@ -850,7 +850,7 @@ KeInitExceptions(VOID)
|
||||||
}
|
}
|
||||||
|
|
||||||
set_system_call_gate(0x2d,(int)interrupt_handler2d);
|
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);
|
return((NTSTATUS)OldEip);
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
|
||||||
FASTCALL
|
|
||||||
KeRosTrapReturn ( PKTRAP_FRAME TrapFrame, PKTRAP_FRAME PrevTrapFrame );
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
NTSTATUS STDCALL
|
NTSTATUS
|
||||||
|
STDCALL
|
||||||
NtRaiseException (
|
NtRaiseException (
|
||||||
IN PEXCEPTION_RECORD ExceptionRecord,
|
IN PEXCEPTION_RECORD ExceptionRecord,
|
||||||
IN PCONTEXT Context,
|
IN PCONTEXT Context,
|
||||||
IN BOOLEAN SearchFrames)
|
IN BOOLEAN SearchFrames)
|
||||||
{
|
{
|
||||||
PKTRAP_FRAME TrapFrame = KeGetCurrentThread()->TrapFrame;
|
PKTHREAD Thread = KeGetCurrentThread();
|
||||||
PKTRAP_FRAME PrevTrapFrame = (PKTRAP_FRAME)TrapFrame->Edx;
|
PKTRAP_FRAME TrapFrame = Thread->TrapFrame;
|
||||||
|
PKTRAP_FRAME PrevTrapFrame = (PKTRAP_FRAME)TrapFrame->Edx;
|
||||||
|
|
||||||
KeGetCurrentKPCR()->Tib.ExceptionList = TrapFrame->ExceptionList;
|
KeGetCurrentKPCR()->Tib.ExceptionList = TrapFrame->ExceptionList;
|
||||||
|
|
||||||
KiDispatchException(ExceptionRecord,
|
KiDispatchException(ExceptionRecord,
|
||||||
Context,
|
Context,
|
||||||
PsGetCurrentThread()->Tcb.TrapFrame,
|
TrapFrame,
|
||||||
(KPROCESSOR_MODE)ExGetPreviousMode(),
|
KeGetPreviousMode(),
|
||||||
SearchFrames);
|
SearchFrames);
|
||||||
|
|
||||||
KeRosTrapReturn ( TrapFrame, PrevTrapFrame );
|
/* Restore the user context */
|
||||||
return(STATUS_SUCCESS);
|
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 */
|
0x0, 0x0, 0x0, 0x0, /* Null */
|
||||||
0xffff, 0x0, 0x9a00, 0xcf, /* Kernel CS */
|
0xffff, 0x0, 0x9a00, 0xcf, /* Kernel CS */
|
||||||
0xffff, 0x0, 0x9200, 0xcf, /* Kernel DS */
|
0xffff, 0x0, 0x9200, 0xcf, /* Kernel DS */
|
||||||
0x0, 0x0, 0xfa00, 0xcc, /* User CS */
|
0x0, 0x0, 0xfa00, 0xcf, /* User CS */
|
||||||
0x0, 0x0, 0xf200, 0xcc, /* User DS */
|
0x0, 0x0, 0xf200, 0xcf, /* User DS */
|
||||||
0x0, 0x0, 0x0, 0x0, /* TSS */
|
0x0, 0x0, 0x0, 0x0, /* TSS */
|
||||||
0x1000, 0x0000, 0x9200, 0xff00, /* PCR */
|
0x1000, 0x0000, 0x9200, 0xffc0, /* PCR */
|
||||||
0x1000, 0x0, 0xf200, 0x0, /* TEB */
|
0x1000, 0x0, 0xf200, 0x0, /* TEB */
|
||||||
0x0, 0x0, 0x0, 0x0, /* Reserved */
|
0x0, 0x0, 0x0, 0x0, /* Reserved */
|
||||||
0x0, 0x0, 0x0, 0x0, /* LDT */
|
0x0, 0x0, 0x0, 0x0, /* LDT */
|
||||||
|
|
|
@ -43,6 +43,7 @@ BOOLEAN Ke386NoExecute = FALSE;
|
||||||
BOOLEAN Ke386Pae = FALSE;
|
BOOLEAN Ke386Pae = FALSE;
|
||||||
BOOLEAN Ke386PaeEnabled = FALSE;
|
BOOLEAN Ke386PaeEnabled = FALSE;
|
||||||
BOOLEAN Ke386GlobalPagesEnabled = FALSE;
|
BOOLEAN Ke386GlobalPagesEnabled = FALSE;
|
||||||
|
ULONG KiFastSystemCallDisable = 0;
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
|
@ -323,6 +324,18 @@ KeInit1(PCHAR CommandLine, PULONG LastKernelAddress)
|
||||||
MiEnablePAE((PVOID*)LastKernelAddress);
|
MiEnablePAE((PVOID*)LastKernelAddress);
|
||||||
Ke386PaeEnabled = TRUE;
|
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
|
VOID INIT_FUNCTION
|
||||||
|
@ -391,23 +404,89 @@ KeInit2(VOID)
|
||||||
VOID INIT_FUNCTION
|
VOID INIT_FUNCTION
|
||||||
Ki386SetProcessorFeatures(VOID)
|
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_PRECISION_ERRATA] = FALSE;
|
||||||
SharedUserData->ProcessorFeatures[PF_FLOATING_POINT_EMULATED] = FALSE;
|
SharedUserData->ProcessorFeatures[PF_FLOATING_POINT_EMULATED] = FALSE;
|
||||||
SharedUserData->ProcessorFeatures[PF_COMPARE_EXCHANGE_DOUBLE] =
|
SharedUserData->ProcessorFeatures[PF_COMPARE_EXCHANGE_DOUBLE] =
|
||||||
(Pcr->PrcbData.FeatureBits & X86_FEATURE_CX8);
|
(Pcr->PrcbData.FeatureBits & X86_FEATURE_CX8);
|
||||||
SharedUserData->ProcessorFeatures[PF_MMX_INSTRUCTIONS_AVAILABLE] =
|
SharedUserData->ProcessorFeatures[PF_MMX_INSTRUCTIONS_AVAILABLE] =
|
||||||
(Pcr->PrcbData.FeatureBits & X86_FEATURE_MMX);
|
(Pcr->PrcbData.FeatureBits & X86_FEATURE_MMX);
|
||||||
SharedUserData->ProcessorFeatures[PF_PPC_MOVEMEM_64BIT_OK] = FALSE;
|
SharedUserData->ProcessorFeatures[PF_PPC_MOVEMEM_64BIT_OK] = FALSE;
|
||||||
SharedUserData->ProcessorFeatures[PF_ALPHA_BYTE_INSTRUCTIONS] = FALSE;
|
SharedUserData->ProcessorFeatures[PF_ALPHA_BYTE_INSTRUCTIONS] = FALSE;
|
||||||
SharedUserData->ProcessorFeatures[PF_XMMI_INSTRUCTIONS_AVAILABLE] =
|
SharedUserData->ProcessorFeatures[PF_XMMI_INSTRUCTIONS_AVAILABLE] =
|
||||||
(Pcr->PrcbData.FeatureBits & X86_FEATURE_SSE);
|
(Pcr->PrcbData.FeatureBits & X86_FEATURE_SSE);
|
||||||
SharedUserData->ProcessorFeatures[PF_3DNOW_INSTRUCTIONS_AVAILABLE] =
|
SharedUserData->ProcessorFeatures[PF_3DNOW_INSTRUCTIONS_AVAILABLE] =
|
||||||
(Ke386CpuidExFlags & X86_EXT_FEATURE_3DNOW);
|
(Ke386CpuidExFlags & X86_EXT_FEATURE_3DNOW);
|
||||||
SharedUserData->ProcessorFeatures[PF_RDTSC_INSTRUCTION_AVAILABLE] =
|
SharedUserData->ProcessorFeatures[PF_RDTSC_INSTRUCTION_AVAILABLE] =
|
||||||
(Pcr->PrcbData.FeatureBits & X86_FEATURE_TSC);
|
(Pcr->PrcbData.FeatureBits & X86_FEATURE_TSC);
|
||||||
SharedUserData->ProcessorFeatures[PF_PAE_ENABLED] = Ke386PaeEnabled;
|
SharedUserData->ProcessorFeatures[PF_PAE_ENABLED] = Ke386PaeEnabled;
|
||||||
SharedUserData->ProcessorFeatures[PF_XMMI64_INSTRUCTIONS_AVAILABLE] =
|
SharedUserData->ProcessorFeatures[PF_XMMI64_INSTRUCTIONS_AVAILABLE] =
|
||||||
(Pcr->PrcbData.FeatureBits & X86_FEATURE_SSE2);
|
(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
|
push $0
|
||||||
call _KeLowerIrql@4
|
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$
|
/* $Id$
|
||||||
*
|
*
|
||||||
* FILE: ntoskrnl/ke/i386/syscall.S
|
* FILE: ntoskrnl/ke/i386/syscall.S
|
||||||
* PURPOSE: 2E trap handler
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROGRAMMER: David Welch (david.welch@seh.ox.ac.uk)
|
* PURPOSE: System Call Handler
|
||||||
|
* PROGRAMMER: Alex Ionescu (alex@relsoft.net)
|
||||||
* UPDATE HISTORY:
|
* 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 <ddk/status.h>
|
||||||
#include <internal/i386/segment.h>
|
#include <internal/i386/segment.h>
|
||||||
#include <internal/ps.h>
|
#include <internal/ps.h>
|
||||||
#include <internal/i386/ke.h>
|
#include <internal/i386/ke.h>
|
||||||
|
#include <ntos/tss.h>
|
||||||
|
#include <napi/shared_data.h>
|
||||||
#include <roscfg.h>
|
#include <roscfg.h>
|
||||||
|
|
||||||
#define KernelMode (0)
|
#define UserMode (1)
|
||||||
#define UserMode (1)
|
|
||||||
|
|
||||||
/*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
.globl KeReturnFromSystemCall
|
|
||||||
.globl KeReturnFromSystemCallWithHook
|
.globl KeReturnFromSystemCallWithHook
|
||||||
.globl _interrupt_handler2e
|
.globl _KiServiceExit
|
||||||
_interrupt_handler2e:
|
.globl _KiFastCallEntry
|
||||||
|
.globl _KiSystemService
|
||||||
|
|
||||||
/* Construct a trap frame on the stack */
|
_KiFastCallEntry:
|
||||||
|
|
||||||
/* Error code */
|
/* Set FS to PCR */
|
||||||
pushl $0
|
movl $PCR_SELECTOR, %ecx
|
||||||
pushl %ebp
|
movw %cx, %fs
|
||||||
pushl %ebx
|
|
||||||
pushl %esi
|
/* Set the current stack to Kernel Stack */
|
||||||
pushl %edi
|
movl %fs:KPCR_TSS, %ecx
|
||||||
pushl %fs
|
movl KTSS_ESP0(%ecx), %ecx
|
||||||
/* Load PCR selector into fs */
|
movl %ecx, %esp
|
||||||
movl $PCR_SELECTOR, %ebx
|
|
||||||
movl %ebx, %fs
|
/* 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
|
* Construct a trap frame on the stack.
|
||||||
pushl %ebx
|
* The following are already on the stack.
|
||||||
/* Set the exception handler chain terminator */
|
*/
|
||||||
movl $0xffffffff, %fs:KPCR_EXCEPTION_LIST
|
// SS + 0x0
|
||||||
/* Get a pointer to the current thread */
|
// ESP + 0x4
|
||||||
movl %fs:KPCR_CURRENT_THREAD, %esi
|
// EFLAGS + 0x8
|
||||||
/* Save the old previous mode */
|
// CS + 0xC
|
||||||
movl $0, %ebx
|
// EIP + 0x10
|
||||||
movb %ss:KTHREAD_PREVIOUS_MODE(%esi), %bl
|
pushl $0 // + 0x14
|
||||||
pushl %ebx
|
pushl %ebp // + 0x18
|
||||||
/* Set the new previous mode based on the saved CS selector */
|
pushl %ebx // + 0x1C
|
||||||
movl 0x24(%esp), %ebx
|
pushl %esi // + 0x20
|
||||||
andl $0x0000FFFF, %ebx
|
pushl %edi // + 0x24
|
||||||
cmpl $KERNEL_CS, %ebx
|
pushl %fs // + 0x28
|
||||||
jne L1
|
|
||||||
movb $KernelMode, %ss:KTHREAD_PREVIOUS_MODE(%esi)
|
/* Load PCR Selector into fs */
|
||||||
jmp L3
|
movw $PCR_SELECTOR, %bx
|
||||||
L1:
|
movw %bx, %fs
|
||||||
movb $UserMode, %ss:KTHREAD_PREVIOUS_MODE(%esi)
|
|
||||||
L3:
|
/* Save the previous exception list */
|
||||||
|
pushl %fs:KPCR_EXCEPTION_LIST // + 0x2C
|
||||||
|
|
||||||
/* Save other registers */
|
/* Set the exception handler chain terminator */
|
||||||
pushl %eax
|
movl $0xffffffff, %fs:KPCR_EXCEPTION_LIST
|
||||||
pushl %ecx
|
|
||||||
pushl %edx
|
/* Get a pointer to the current thread */
|
||||||
pushl %ds
|
movl %fs:KPCR_CURRENT_THREAD, %esi
|
||||||
pushl %es
|
|
||||||
pushl %gs
|
/* Save the old previous mode */
|
||||||
pushl $0 /* DR7 */
|
pushl %ss:KTHREAD_PREVIOUS_MODE(%esi) // + 0x30
|
||||||
pushl $0 /* DR6 */
|
|
||||||
pushl $0 /* DR3 */
|
/* Set the new previous mode based on the saved CS selector */
|
||||||
pushl $0 /* DR2 */
|
movl 0x24(%esp), %ebx
|
||||||
pushl $0 /* DR1 */
|
and $1, %ebx
|
||||||
pushl $0 /* DR0 */
|
movb %bl, %ss:KTHREAD_PREVIOUS_MODE(%esi)
|
||||||
pushl $0 /* XXX: TempESP */
|
|
||||||
pushl $0 /* XXX: TempCS */
|
/* Save other registers */
|
||||||
pushl $0 /* XXX: DebugPointer */
|
pushl %eax // + 0x34
|
||||||
pushl $0 /* XXX: DebugArgMark */
|
pushl %ecx // + 0x38
|
||||||
|
pushl %edx // + 0x3C
|
||||||
|
pushl %ds // + 0x40
|
||||||
|
pushl %es // + 0x44
|
||||||
|
pushl %gs // + 0x48
|
||||||
|
sub $0x28, %esp // + 0x70
|
||||||
|
|
||||||
#ifdef DBG
|
#ifdef DBG
|
||||||
/* Trick gdb 6 into backtracing over the system call */
|
/* Trick gdb 6 into backtracing over the system call */
|
||||||
movl 4(%ebp), %ebx
|
pushl 4(%ebp) /* DebugEIP */ // + 0x74
|
||||||
pushl %ebx /* DebugEIP */
|
pushl (%ebp) /* DebugEBP */ // + 0x78
|
||||||
movl (%ebp), %ebx
|
|
||||||
pushl %ebx /* DebugEBP */
|
|
||||||
#else
|
#else
|
||||||
movl 0x60(%esp), %ebx
|
pushl 0x60(%esp) /* DebugEIP */ // + 0x74
|
||||||
pushl %ebx /* DebugEIP */
|
pushl %ebp /* DebugEBP */ // + 0x78
|
||||||
pushl %ebp /* DebugEBP */
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Load the segment registers */
|
/* Load the segment registers */
|
||||||
movl $KERNEL_DS, %ebx
|
movw $KERNEL_DS, %bx
|
||||||
movl %ebx, %ds
|
movw %bx, %ds
|
||||||
movl %ebx, %es
|
movw %bx, %es
|
||||||
movl %ebx, %gs
|
movw %bx, %gs
|
||||||
|
|
||||||
/*
|
/* Save the old trap frame pointer where EDX would be saved */
|
||||||
* Save the old trap frame pointer over where we would save the EDX
|
movl KTHREAD_TRAP_FRAME(%esi), %ebx
|
||||||
* register.
|
movl %ebx, KTRAP_FRAME_EDX(%esp)
|
||||||
*/
|
|
||||||
movl KTHREAD_TRAP_FRAME(%esi), %ebx
|
|
||||||
movl %ebx, KTRAP_FRAME_EDX(%esp)
|
|
||||||
|
|
||||||
/* Allocate new Kernel stack frame */
|
/* Allocate new Kernel stack frame */
|
||||||
movl %esp,%ebp
|
movl %esp,%ebp
|
||||||
|
|
||||||
/* Save a pointer to the trap frame in the TCB */
|
/* Save a pointer to the trap frame in the TCB */
|
||||||
movl %ebp, KTHREAD_TRAP_FRAME(%esi)
|
movl %ebp, KTHREAD_TRAP_FRAME(%esi)
|
||||||
|
|
||||||
/* Set ES to kernel segment */
|
CheckValidCall:
|
||||||
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:
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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
|
#ifdef DBG
|
||||||
/* GDB thinks the function starts here and
|
/*
|
||||||
wants a standard prolog, so let's give it */
|
* GDB thinks the function starts here and
|
||||||
pushl %ebp
|
* wants a standard prolog, so let's give it
|
||||||
movl %esp,%ebp
|
*/
|
||||||
popl %ebp
|
pushl %ebp
|
||||||
|
movl %esp,%ebp
|
||||||
|
popl %ebp
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Allocate room for argument list from kernel stack */
|
/* Users's current stack frame pointer is source */
|
||||||
movl %es:_KeServiceDescriptorTable + 12, %ecx
|
movl %edx, %esi
|
||||||
movb %es:(%ecx, %eax), %cl
|
|
||||||
movzx %cl, %ecx
|
/* Allocate room for argument list from kernel stack */
|
||||||
subl %ecx, %esp
|
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 */
|
/* Copy the arguments from the user stack to our stack */
|
||||||
movl %esp,%edi
|
shr $2, %ecx
|
||||||
cld
|
movl %esp, %edi
|
||||||
rep movsb
|
cld
|
||||||
|
rep movsd
|
||||||
|
|
||||||
/* DS is now also kernel segment */
|
/* Do the System Call */
|
||||||
movw %bx, %ds
|
call *%eax
|
||||||
|
movl %eax, KTRAP_FRAME_EAX(%ebp)
|
||||||
|
|
||||||
/* Call system call hook */
|
/* Deallocate the kernel stack frame */
|
||||||
pushl %eax
|
movl %ebp, %esp
|
||||||
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
|
|
||||||
|
|
||||||
KeReturnFromSystemCall:
|
KeReturnFromSystemCall:
|
||||||
|
|
||||||
/* Restore the user context */
|
/* Get the Current Thread */
|
||||||
/* Get a pointer to the current thread */
|
movl %fs:KPCR_CURRENT_THREAD, %esi
|
||||||
movl %fs:0x124, %esi
|
|
||||||
|
|
||||||
/* Restore the old trap frame pointer */
|
/* Restore the old trap frame pointer */
|
||||||
movl KTRAP_FRAME_EDX(%esp), %ebx
|
movl KTRAP_FRAME_EDX(%esp), %ebx
|
||||||
movl %ebx, KTHREAD_TRAP_FRAME(%esi)
|
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:
|
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
|
/* Restore the old previous mode */
|
||||||
mov KTRAP_FRAME_RESERVED1(%ebp), %ax
|
popl %ebx // + 0x2C
|
||||||
cmp %ax, SSIDX_NTCONTINUE
|
movb %bl, %ss:KTHREAD_PREVIOUS_MODE(%esi)
|
||||||
jnz KeNoEpilogPrint
|
|
||||||
movl KTRAP_FRAME_ESP(%ebp), %ecx
|
|
||||||
movl KTRAP_FRAME_EBP(%ebp), %edx
|
|
||||||
call @KeRosPrintEspEbp@8
|
|
||||||
KeNoEpilogPrint:
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Skip debug information and unsaved registers */
|
/* Restore the old exception handler list */
|
||||||
addl $0x30, %esp
|
popl %fs:KPCR_EXCEPTION_LIST // + 0x28
|
||||||
popl %gs
|
|
||||||
popl %es
|
|
||||||
popl %ds
|
|
||||||
popl %edx
|
|
||||||
popl %ecx
|
|
||||||
popl %eax
|
|
||||||
|
|
||||||
/* Restore the old previous mode */
|
/* Restore final registers from trap frame */
|
||||||
popl %ebx
|
popl %fs // + 0x24
|
||||||
movb %bl, %ss:KTHREAD_PREVIOUS_MODE(%esi)
|
popl %edi // + 0x20
|
||||||
|
popl %esi // + 0x1C
|
||||||
|
popl %ebx // + 0x18
|
||||||
|
popl %ebp // + 0x14
|
||||||
|
add $4, %esp // + 0x10
|
||||||
|
|
||||||
/* Restore the old exception handler list */
|
/* Check if previous CS is from user-mode */
|
||||||
popl %ebx
|
testl $1, 4(%esp)
|
||||||
movl %ebx, %fs:KPCR_EXCEPTION_LIST
|
|
||||||
|
/* 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
|
FastRet:
|
||||||
popl %edi
|
|
||||||
popl %esi
|
|
||||||
popl %ebx
|
|
||||||
popl %ebp
|
|
||||||
addl $0x4, %esp /* Ignore error code */
|
|
||||||
|
|
||||||
iret
|
/* Is SYSEXIT Supported/Wanted? */
|
||||||
|
cmpl $1, _KiFastSystemCallDisable
|
||||||
|
je IntRet
|
||||||
|
|
||||||
/* R3: NOTE: This is part of my in-progress attempt at correcting NtContinue
|
/* Restore FS to TIB */
|
||||||
* It is not being called, yet...
|
mov $TEB_SELECTOR, %ecx
|
||||||
*/
|
mov %ecx, %fs
|
||||||
.globl @KeRosTrapReturn@8
|
|
||||||
@KeRosTrapReturn@8:
|
/* 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 */
|
KiBBTUnexpectedRange:
|
||||||
movl %ecx, %esp
|
|
||||||
movl %esp, %ebp
|
|
||||||
|
|
||||||
/* Call the post system call hook and deliver any pending APCs */
|
/* If this isn't a Win32K call, fail */
|
||||||
pushl %esp
|
cmp $0x10, %ecx
|
||||||
call _KiAfterSystemCallHook
|
jne InvalidCall
|
||||||
addl $4,%esp
|
|
||||||
|
|
||||||
/* Restore the user context */
|
/* Set up Win32K Table */
|
||||||
/* Get a pointer to the current thread */
|
pushl %edx
|
||||||
movl %fs:0x124, %esi
|
pushl %ebx
|
||||||
/* Restore the old trap frame pointer */
|
call _KiServiceCheck
|
||||||
movl %edx, KTHREAD_TRAP_FRAME(%esi)
|
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 *****************************************************************/
|
/* 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
|
* @unimplemented
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -33,6 +33,21 @@
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
|
VOID
|
||||||
|
KiServiceCheck (VOID)
|
||||||
|
{
|
||||||
|
PETHREAD Thread;
|
||||||
|
|
||||||
|
Thread = PsGetCurrentThread();
|
||||||
|
|
||||||
|
if (Thread->Tcb.ServiceTable != KeServiceDescriptorTableShadow)
|
||||||
|
{
|
||||||
|
PsInitWin32Thread (Thread);
|
||||||
|
|
||||||
|
Thread->Tcb.ServiceTable = KeServiceDescriptorTableShadow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @unimplemented
|
* @unimplemented
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -270,4 +270,46 @@ KeUnstackDetachProcess (
|
||||||
KeReleaseDispatcherDatabaseLock(OldIrql);
|
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 */
|
/* EOF */
|
||||||
|
|
|
@ -15,10 +15,6 @@
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <internal/debug.h>
|
#include <internal/debug.h>
|
||||||
|
|
||||||
VOID
|
|
||||||
FASTCALL
|
|
||||||
KeRosTrapReturn ( PKTRAP_FRAME TrapFrame, PKTRAP_FRAME PrevTrapFrame );
|
|
||||||
|
|
||||||
VOID STDCALL
|
VOID STDCALL
|
||||||
KeRosDumpStackFrames ( PULONG Frame, ULONG FrameCount );
|
KeRosDumpStackFrames ( PULONG Frame, ULONG FrameCount );
|
||||||
|
|
||||||
|
@ -30,8 +26,9 @@ NtContinue (
|
||||||
IN PCONTEXT Context,
|
IN PCONTEXT Context,
|
||||||
IN BOOLEAN TestAlert)
|
IN BOOLEAN TestAlert)
|
||||||
{
|
{
|
||||||
PKTRAP_FRAME TrapFrame = KeGetCurrentThread()->TrapFrame;
|
PKTHREAD Thread = KeGetCurrentThread();
|
||||||
PKTRAP_FRAME PrevTrapFrame = (PKTRAP_FRAME)TrapFrame->Edx;
|
PKTRAP_FRAME TrapFrame = Thread->TrapFrame;
|
||||||
|
PKTRAP_FRAME PrevTrapFrame = (PKTRAP_FRAME)TrapFrame->Edx;
|
||||||
PFX_SAVE_AREA FxSaveArea;
|
PFX_SAVE_AREA FxSaveArea;
|
||||||
KIRQL oldIrql;
|
KIRQL oldIrql;
|
||||||
|
|
||||||
|
@ -65,12 +62,12 @@ NtContinue (
|
||||||
/* Put the floating point context into the thread's FX_SAVE_AREA
|
/* Put the floating point context into the thread's FX_SAVE_AREA
|
||||||
* and make sure it is reloaded when needed.
|
* 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))
|
if (KiContextToFxSaveArea(FxSaveArea, Context))
|
||||||
{
|
{
|
||||||
KeGetCurrentThread()->NpxState = NPX_STATE_VALID;
|
Thread->NpxState = NPX_STATE_VALID;
|
||||||
KeRaiseIrql(DISPATCH_LEVEL, &oldIrql);
|
KeRaiseIrql(DISPATCH_LEVEL, &oldIrql);
|
||||||
if (KeGetCurrentKPCR()->PrcbData.NpxThread == KeGetCurrentThread())
|
if (KeGetCurrentKPCR()->PrcbData.NpxThread == Thread)
|
||||||
{
|
{
|
||||||
KeGetCurrentKPCR()->PrcbData.NpxThread = NULL;
|
KeGetCurrentKPCR()->PrcbData.NpxThread = NULL;
|
||||||
Ke386SetCr0(Ke386GetCr0() | X86_CR0_TS);
|
Ke386SetCr0(Ke386GetCr0() | X86_CR0_TS);
|
||||||
|
@ -82,7 +79,9 @@ NtContinue (
|
||||||
KeLowerIrql(oldIrql);
|
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 */
|
return STATUS_SUCCESS; /* this doesn't actually happen b/c KeRosTrapReturn() won't return */
|
||||||
}
|
}
|
||||||
|
|
|
@ -280,6 +280,8 @@ IsVmwSVGAEnabled(VOID)
|
||||||
return (Value == 1);
|
return (Value == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
SaveResolutionSettings(DWORD ResX, DWORD ResY, DWORD ColDepth)
|
SaveResolutionSettings(DWORD ResX, DWORD ResY, DWORD ColDepth)
|
||||||
{
|
{
|
||||||
|
@ -313,6 +315,43 @@ SaveResolutionSettings(DWORD ResX, DWORD ResY, DWORD ColDepth)
|
||||||
return TRUE;
|
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
|
BOOL
|
||||||
EnableDriver(WCHAR *Key, BOOL Enable)
|
EnableDriver(WCHAR *Key, BOOL Enable)
|
||||||
{
|
{
|
||||||
|
@ -1022,6 +1061,9 @@ WinMain(HINSTANCE hInstance,
|
||||||
/* restore the exception handler */
|
/* restore the exception handler */
|
||||||
SetUnhandledExceptionFilter(OldHandler);
|
SetUnhandledExceptionFilter(OldHandler);
|
||||||
|
|
||||||
|
/* Disable Fast System Call no matter what */
|
||||||
|
DisableFastSystemCall();
|
||||||
|
|
||||||
lc = DestinationPath;
|
lc = DestinationPath;
|
||||||
lc += GetSystemDirectory(DestinationPath, MAX_PATH) - 1;
|
lc += GetSystemDirectory(DestinationPath, MAX_PATH) - 1;
|
||||||
if(lc >= DestinationPath && *lc != L'\\')
|
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