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:
Alex Ionescu 2005-01-17 07:10:34 +00:00
parent 0eab4e1544
commit f6559e22c4
26 changed files with 1361 additions and 1560 deletions

View file

@ -130,7 +130,7 @@ REGTESTS = regtests
all: bootstrap $(BOOT_LOADERS) $(COMPONENTS) $(REGTESTS) $(HALS) $(BUS) $(LIB_FSLIB) \
$(DLLS) $(SUBSYS) $(KERNEL_DRIVERS) $(SYS_APPS) $(SYS_SVC) $(APPS) $(EXT_MODULES)
bootstrap: dk implib iface_native iface_additional
bootstrap: dk implib iface_native
depends: $(LIB_STATIC:%=%_depends) $(LIB_FSLIB:%=%_depends) msvcrt_depends $(DLLS:%=%_depends) \
$(SUBSYS:%=%_depends) $(SYS_SVC:%=%_depends) \
@ -147,7 +147,7 @@ test: $(BOOT_LOADERS:%=%_test) $(COMPONENTS:%=%_test) $(HALS:%=%_test) $(BUS:%=%
$(KERNEL_DRIVERS:%=%_test) $(SUBSYS:%=%_test) \
$(SYS_SVC:%=%_test) $(EXT_MODULES:%=%_test)
clean: tools dk_clean iface_native_clean iface_additional_clean hallib_clean \
clean: tools dk_clean iface_native_clean hallib_clean \
$(BOOT_LOADERS:%=%_clean) $(HALS:%=%_clean) $(COMPONENTS:%=%_clean) \
$(BUS:%=%_clean) $(LIB_STATIC:%=%_clean) $(LIB_FSLIB:%=%_clean) \
msvcrt_clean $(DLLS:%=%_clean) $(KERNEL_DRIVERS:%=%_clean) \
@ -462,37 +462,21 @@ dk_install:
# Interfaces
#
iface_native:
$(MAKE) --silent -C iface/native
$(MAKE) --silent -C tools/nci
iface_native_implib:
iface_native_test:
iface_native_clean:
$(MAKE) --silent -C iface/native clean
$(MAKE) --silent -C tools/nci clean
iface_native_install:
iface_native_bootcd:
iface_additional:
$(MAKE) --silent -C iface/addsys
iface_additional_implib:
iface_additional_test:
iface_additional_clean:
$(MAKE) --silent -C iface/addsys clean
iface_additional_install:
iface_additional_bootcd:
.PHONY: iface_native iface_native_implib iface_native_test iface_native_clean \
iface_native_install iface_native_bootcd iface_additional \
iface_additional_implib iface_additional_test iface_additional_clean \
iface_additional_install iface_additional_bootcd
iface_native_install iface_native_bootcd
#

View file

@ -25,7 +25,7 @@ KDBG := 0
#
# Whether to compile for debugging
#
DBG := 0
DBG := 0
#
# Whether to compile with optimizations

View file

@ -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);
}

View file

@ -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

View file

@ -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);
}

View file

@ -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

View file

@ -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

View file

@ -13,6 +13,8 @@
#define PF_PAE_ENABLED 9
#define PF_XMMI64_INSTRUCTIONS_AVAILABLE 10
#ifndef __ASM__
typedef enum _ALTERNATIVE_ARCHITECTURE_TYPE
{
StandardDesign,
@ -62,13 +64,15 @@ typedef struct _KUSER_SHARED_DATA {
BOOLEAN SafeBootMode;
ULONG TraceLogging;
ULONGLONG Fill0;
ULONGLONG SystemCall[4];
UCHAR SystemCall[16];
union {
volatile KSYSTEM_TIME TickCount;
volatile ULONG64 TickCountQuad;
};
} KUSER_SHARED_DATA, *PKUSER_SHARED_DATA;
#endif
/* Values for DosDeviceDriveType */
#define DOSDEVICE_DRIVE_UNKNOWN 0
#define DOSDEVICE_DRIVE_CALCULATE 1
@ -102,5 +106,7 @@ typedef struct _KUSER_SHARED_DATA {
#define SharedUserData ((KUSER_SHARED_DATA * const)USER_SHARED_DATA)
#endif
#define KUSER_SHARED_SYSCALL 0x7FFE0300
#define KUSER_SHARED_SYSCALL_RET 0x7FFE0304
#endif /* __INCLUDE_NAPI_SHARED_DATA_H */

View file

@ -550,7 +550,7 @@ TARGET_CLEAN = \
$(PATH_TO_TOP)/include/reactos/bugcodes.h \
$(DEP_OBJECTS) $(DEP_FILES) MSG00409.bin bugcodes.rc
ex/napi.o: ex/napi.c $(PATH_TO_TOP)/include/ntdll/napi.h
ex/napi.o: ex/zw.S $(PATH_TO_TOP)/include/ntdll/napi.h
ke/main.o: ke/main.c $(PATH_TO_TOP)/include/reactos/buildno.h

View file

@ -88,6 +88,7 @@
#define X86_FEATURE_TSC 0x00000010 /* time stamp counters are present */
#define X86_FEATURE_PAE 0x00000040 /* physical address extension is present */
#define X86_FEATURE_CX8 0x00000100 /* CMPXCHG8B instruction present */
#define X86_FEATURE_SYSCALL 0x00000800 /* SYSCALL/SYSRET support present */
#define X86_FEATURE_PGE 0x00002000 /* Page Global Enable */
#define X86_FEATURE_MMX 0x00800000 /* MMX extension present */
#define X86_FEATURE_FXSR 0x01000000 /* FXSAVE/FXRSTOR instructions present */

View file

@ -27,6 +27,7 @@
#define KTHREAD_TEB 0x20
#define KTHREAD_KERNEL_STACK 0x28
#define KTHREAD_NPX_STATE 0x31
#define KTHREAD_PENDING_USER_APC 0x34 + 0x16
#define KTHREAD_APCSTATE_PROCESS 0x44
#define KTHREAD_SERVICE_TABLE 0xDC
#define KTHREAD_PREVIOUS_MODE 0x137

View file

@ -143,4 +143,4 @@ _PsBeginThreadWithContextInternal:
/* Load the rest of the thread's user mode context. */
movl $0, %eax
jmp KeReturnFromSystemCallWithHook
jmp _KiServiceExit

View file

@ -45,7 +45,7 @@
# define ARRAY_SIZE(x) (sizeof (x) / sizeof (x[0]))
#endif
extern void interrupt_handler2e(void);
extern void KiSystemService(void);
extern void interrupt_handler2d(void);
extern VOID KiTrap0(VOID);
@ -850,7 +850,7 @@ KeInitExceptions(VOID)
}
set_system_call_gate(0x2d,(int)interrupt_handler2d);
set_system_call_gate(0x2e,(int)interrupt_handler2e);
set_system_call_gate(0x2e,(int)KiSystemService);
}
/*
@ -873,30 +873,32 @@ KeRaiseUserException(IN NTSTATUS ExceptionCode)
return((NTSTATUS)OldEip);
}
VOID
FASTCALL
KeRosTrapReturn ( PKTRAP_FRAME TrapFrame, PKTRAP_FRAME PrevTrapFrame );
/*
* @implemented
*/
NTSTATUS STDCALL
NTSTATUS
STDCALL
NtRaiseException (
IN PEXCEPTION_RECORD ExceptionRecord,
IN PCONTEXT Context,
IN BOOLEAN SearchFrames)
IN PEXCEPTION_RECORD ExceptionRecord,
IN PCONTEXT Context,
IN BOOLEAN SearchFrames)
{
PKTRAP_FRAME TrapFrame = KeGetCurrentThread()->TrapFrame;
PKTRAP_FRAME PrevTrapFrame = (PKTRAP_FRAME)TrapFrame->Edx;
PKTHREAD Thread = KeGetCurrentThread();
PKTRAP_FRAME TrapFrame = Thread->TrapFrame;
PKTRAP_FRAME PrevTrapFrame = (PKTRAP_FRAME)TrapFrame->Edx;
KeGetCurrentKPCR()->Tib.ExceptionList = TrapFrame->ExceptionList;
KeGetCurrentKPCR()->Tib.ExceptionList = TrapFrame->ExceptionList;
KiDispatchException(ExceptionRecord,
Context,
PsGetCurrentThread()->Tcb.TrapFrame,
(KPROCESSOR_MODE)ExGetPreviousMode(),
SearchFrames);
KiDispatchException(ExceptionRecord,
Context,
TrapFrame,
KeGetPreviousMode(),
SearchFrames);
KeRosTrapReturn ( TrapFrame, PrevTrapFrame );
return(STATUS_SUCCESS);
/* Restore the user context */
Thread->TrapFrame = PrevTrapFrame;
__asm__("mov %%ebx, %%esp;\n" "jmp _KiServiceExit": : "b" (TrapFrame));
/* We never get here */
return(STATUS_SUCCESS);
}

View file

@ -40,10 +40,10 @@ USHORT KiBootGdt[11 * 4] =
0x0, 0x0, 0x0, 0x0, /* Null */
0xffff, 0x0, 0x9a00, 0xcf, /* Kernel CS */
0xffff, 0x0, 0x9200, 0xcf, /* Kernel DS */
0x0, 0x0, 0xfa00, 0xcc, /* User CS */
0x0, 0x0, 0xf200, 0xcc, /* User DS */
0x0, 0x0, 0xfa00, 0xcf, /* User CS */
0x0, 0x0, 0xf200, 0xcf, /* User DS */
0x0, 0x0, 0x0, 0x0, /* TSS */
0x1000, 0x0000, 0x9200, 0xff00, /* PCR */
0x1000, 0x0000, 0x9200, 0xffc0, /* PCR */
0x1000, 0x0, 0xf200, 0x0, /* TEB */
0x0, 0x0, 0x0, 0x0, /* Reserved */
0x0, 0x0, 0x0, 0x0, /* LDT */

View file

@ -43,6 +43,7 @@ BOOLEAN Ke386NoExecute = FALSE;
BOOLEAN Ke386Pae = FALSE;
BOOLEAN Ke386PaeEnabled = FALSE;
BOOLEAN Ke386GlobalPagesEnabled = FALSE;
ULONG KiFastSystemCallDisable = 0;
/* FUNCTIONS *****************************************************************/
@ -323,6 +324,18 @@ KeInit1(PCHAR CommandLine, PULONG LastKernelAddress)
MiEnablePAE((PVOID*)LastKernelAddress);
Ke386PaeEnabled = TRUE;
}
if (KPCR->PrcbData.FeatureBits & X86_FEATURE_SYSCALL)
{
extern void KiFastCallEntry(void);
/* CS Selector of the target segment. */
Ke386Wrmsr(0x174, KERNEL_CS, 0);
/* Target ESP. */
Ke386Wrmsr(0x175, 0, 0);
/* Target EIP. */
Ke386Wrmsr(0x176, (ULONG_PTR)KiFastCallEntry, 0);
}
}
VOID INIT_FUNCTION
@ -391,23 +404,89 @@ KeInit2(VOID)
VOID INIT_FUNCTION
Ki386SetProcessorFeatures(VOID)
{
PKPCR Pcr = KeGetCurrentKPCR();
PKPCR Pcr = KeGetCurrentKPCR();
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING KeyName;
UNICODE_STRING ValueName;
HANDLE KeyHandle;
ULONG ResultLength;
KEY_VALUE_PARTIAL_INFORMATION ValueData;
NTSTATUS Status;
SharedUserData->ProcessorFeatures[PF_FLOATING_POINT_PRECISION_ERRATA] = FALSE;
SharedUserData->ProcessorFeatures[PF_FLOATING_POINT_EMULATED] = FALSE;
SharedUserData->ProcessorFeatures[PF_COMPARE_EXCHANGE_DOUBLE] =
(Pcr->PrcbData.FeatureBits & X86_FEATURE_CX8);
SharedUserData->ProcessorFeatures[PF_MMX_INSTRUCTIONS_AVAILABLE] =
(Pcr->PrcbData.FeatureBits & X86_FEATURE_MMX);
SharedUserData->ProcessorFeatures[PF_PPC_MOVEMEM_64BIT_OK] = FALSE;
SharedUserData->ProcessorFeatures[PF_ALPHA_BYTE_INSTRUCTIONS] = FALSE;
SharedUserData->ProcessorFeatures[PF_XMMI_INSTRUCTIONS_AVAILABLE] =
(Pcr->PrcbData.FeatureBits & X86_FEATURE_SSE);
SharedUserData->ProcessorFeatures[PF_3DNOW_INSTRUCTIONS_AVAILABLE] =
(Ke386CpuidExFlags & X86_EXT_FEATURE_3DNOW);
SharedUserData->ProcessorFeatures[PF_RDTSC_INSTRUCTION_AVAILABLE] =
(Pcr->PrcbData.FeatureBits & X86_FEATURE_TSC);
SharedUserData->ProcessorFeatures[PF_PAE_ENABLED] = Ke386PaeEnabled;
SharedUserData->ProcessorFeatures[PF_XMMI64_INSTRUCTIONS_AVAILABLE] =
(Pcr->PrcbData.FeatureBits & X86_FEATURE_SSE2);
SharedUserData->ProcessorFeatures[PF_FLOATING_POINT_PRECISION_ERRATA] = FALSE;
SharedUserData->ProcessorFeatures[PF_FLOATING_POINT_EMULATED] = FALSE;
SharedUserData->ProcessorFeatures[PF_COMPARE_EXCHANGE_DOUBLE] =
(Pcr->PrcbData.FeatureBits & X86_FEATURE_CX8);
SharedUserData->ProcessorFeatures[PF_MMX_INSTRUCTIONS_AVAILABLE] =
(Pcr->PrcbData.FeatureBits & X86_FEATURE_MMX);
SharedUserData->ProcessorFeatures[PF_PPC_MOVEMEM_64BIT_OK] = FALSE;
SharedUserData->ProcessorFeatures[PF_ALPHA_BYTE_INSTRUCTIONS] = FALSE;
SharedUserData->ProcessorFeatures[PF_XMMI_INSTRUCTIONS_AVAILABLE] =
(Pcr->PrcbData.FeatureBits & X86_FEATURE_SSE);
SharedUserData->ProcessorFeatures[PF_3DNOW_INSTRUCTIONS_AVAILABLE] =
(Ke386CpuidExFlags & X86_EXT_FEATURE_3DNOW);
SharedUserData->ProcessorFeatures[PF_RDTSC_INSTRUCTION_AVAILABLE] =
(Pcr->PrcbData.FeatureBits & X86_FEATURE_TSC);
SharedUserData->ProcessorFeatures[PF_PAE_ENABLED] = Ke386PaeEnabled;
SharedUserData->ProcessorFeatures[PF_XMMI64_INSTRUCTIONS_AVAILABLE] =
(Pcr->PrcbData.FeatureBits & X86_FEATURE_SSE2);
/* Does the CPU Support Fast System Call? */
if (Pcr->PrcbData.FeatureBits & X86_FEATURE_SYSCALL) {
/* FIXME: Check for Family == 6, Model < 3 and Stepping < 3 and disable */
/* Make sure it's not disabled in registry */
RtlRosInitUnicodeStringFromLiteral(&KeyName,
L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Session Manager\\Kernel");
RtlRosInitUnicodeStringFromLiteral(&ValueName,
L"FastSystemCallDisable");
InitializeObjectAttributes(&ObjectAttributes,
&KeyName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
Status = NtOpenKey(&KeyHandle, KEY_ALL_ACCESS, &ObjectAttributes);
if (NT_SUCCESS(Status)) {
/* Read the Value then Close the Key */
Status = NtQueryValueKey(KeyHandle,
&ValueName,
KeyValuePartialInformation,
&ValueData,
sizeof(ValueData),
&ResultLength);
RtlMoveMemory(&KiFastSystemCallDisable, ValueData.Data, sizeof(ULONG));
NtClose(KeyHandle);
}
} else {
/* Disable SYSENTER/SYSEXIT, because the CPU doesn't support it */
KiFastSystemCallDisable = 1;
}
if (!KiFastSystemCallDisable) {
/* Use SYSENTER */
SharedUserData->SystemCall[0] = 0x8B;
SharedUserData->SystemCall[1] = 0xD4;
SharedUserData->SystemCall[2] = 0x0F;
SharedUserData->SystemCall[3] = 0x34;
SharedUserData->SystemCall[4] = 0xC3;
} else {
/* Use INT2E */
SharedUserData->SystemCall[0] = 0x8D;
SharedUserData->SystemCall[1] = 0x54;
SharedUserData->SystemCall[2] = 0x24;
SharedUserData->SystemCall[3] = 0x08;
SharedUserData->SystemCall[4] = 0xCD;
SharedUserData->SystemCall[5] = 0x2E;
SharedUserData->SystemCall[6] = 0xC3;
}
}

View file

@ -78,5 +78,5 @@ _KePushAndStackSwitchAndSysRet@8:
push $0
call _KeLowerIrql@4
jmp KeReturnFromSystemCall
jmp _KiServiceExit

View file

@ -1,324 +1,317 @@
/*
* ReactOS kernel
* Copyright (C) 2000 David Welch <welch@cwcom.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id$
*
* FILE: ntoskrnl/ke/i386/syscall.S
* PURPOSE: 2E trap handler
* PROGRAMMER: David Welch (david.welch@seh.ox.ac.uk)
* COPYRIGHT: See COPYING in the top level directory
* PURPOSE: System Call Handler
* PROGRAMMER: Alex Ionescu (alex@relsoft.net)
* UPDATE HISTORY:
* ???
* ??-??-??: Original Version - David Welch(?)
* 13-01-05: Complete rewrite, added support for SYSENTER, direct kmode syscalls
* and re-wrote most of handler code. - Alex Ionescu
*/
#include <ddk/status.h>
#include <internal/i386/segment.h>
#include <internal/ps.h>
#include <internal/i386/ke.h>
#include <ntos/tss.h>
#include <napi/shared_data.h>
#include <roscfg.h>
#define KernelMode (0)
#define UserMode (1)
#define UserMode (1)
/*
*
*/
.globl KeReturnFromSystemCall
.globl KeReturnFromSystemCallWithHook
.globl _interrupt_handler2e
_interrupt_handler2e:
.globl _KiServiceExit
.globl _KiFastCallEntry
.globl _KiSystemService
/* Construct a trap frame on the stack */
_KiFastCallEntry:
/* Error code */
pushl $0
pushl %ebp
pushl %ebx
pushl %esi
pushl %edi
pushl %fs
/* Load PCR selector into fs */
movl $PCR_SELECTOR, %ebx
movl %ebx, %fs
/* Set FS to PCR */
movl $PCR_SELECTOR, %ecx
movw %cx, %fs
/* Set the current stack to Kernel Stack */
movl %fs:KPCR_TSS, %ecx
movl KTSS_ESP0(%ecx), %ecx
movl %ecx, %esp
/* Set up a fake INT Stack. */
pushl $USER_DS
pushl %edx /* Ring 3 SS:ESP */
pushfl
orl $200, (%esp) /* Re-enable IRQs in EFLAGS, to fake INT */
pushl $USER_CS
pushl $KUSER_SHARED_SYSCALL_RET
/* User Parameter List */
add $8, %edx
_KiSystemService:
/* Save the old exception list */
movl %fs:KPCR_EXCEPTION_LIST, %ebx
pushl %ebx
/* Set the exception handler chain terminator */
movl $0xffffffff, %fs:KPCR_EXCEPTION_LIST
/* Get a pointer to the current thread */
movl %fs:KPCR_CURRENT_THREAD, %esi
/* Save the old previous mode */
movl $0, %ebx
movb %ss:KTHREAD_PREVIOUS_MODE(%esi), %bl
pushl %ebx
/* Set the new previous mode based on the saved CS selector */
movl 0x24(%esp), %ebx
andl $0x0000FFFF, %ebx
cmpl $KERNEL_CS, %ebx
jne L1
movb $KernelMode, %ss:KTHREAD_PREVIOUS_MODE(%esi)
jmp L3
L1:
movb $UserMode, %ss:KTHREAD_PREVIOUS_MODE(%esi)
L3:
/*
* Construct a trap frame on the stack.
* The following are already on the stack.
*/
// SS + 0x0
// ESP + 0x4
// EFLAGS + 0x8
// CS + 0xC
// EIP + 0x10
pushl $0 // + 0x14
pushl %ebp // + 0x18
pushl %ebx // + 0x1C
pushl %esi // + 0x20
pushl %edi // + 0x24
pushl %fs // + 0x28
/* Load PCR Selector into fs */
movw $PCR_SELECTOR, %bx
movw %bx, %fs
/* Save the previous exception list */
pushl %fs:KPCR_EXCEPTION_LIST // + 0x2C
/* Save other registers */
pushl %eax
pushl %ecx
pushl %edx
pushl %ds
pushl %es
pushl %gs
pushl $0 /* DR7 */
pushl $0 /* DR6 */
pushl $0 /* DR3 */
pushl $0 /* DR2 */
pushl $0 /* DR1 */
pushl $0 /* DR0 */
pushl $0 /* XXX: TempESP */
pushl $0 /* XXX: TempCS */
pushl $0 /* XXX: DebugPointer */
pushl $0 /* XXX: DebugArgMark */
/* Set the exception handler chain terminator */
movl $0xffffffff, %fs:KPCR_EXCEPTION_LIST
/* Get a pointer to the current thread */
movl %fs:KPCR_CURRENT_THREAD, %esi
/* Save the old previous mode */
pushl %ss:KTHREAD_PREVIOUS_MODE(%esi) // + 0x30
/* Set the new previous mode based on the saved CS selector */
movl 0x24(%esp), %ebx
and $1, %ebx
movb %bl, %ss:KTHREAD_PREVIOUS_MODE(%esi)
/* Save other registers */
pushl %eax // + 0x34
pushl %ecx // + 0x38
pushl %edx // + 0x3C
pushl %ds // + 0x40
pushl %es // + 0x44
pushl %gs // + 0x48
sub $0x28, %esp // + 0x70
#ifdef DBG
/* Trick gdb 6 into backtracing over the system call */
movl 4(%ebp), %ebx
pushl %ebx /* DebugEIP */
movl (%ebp), %ebx
pushl %ebx /* DebugEBP */
/* Trick gdb 6 into backtracing over the system call */
pushl 4(%ebp) /* DebugEIP */ // + 0x74
pushl (%ebp) /* DebugEBP */ // + 0x78
#else
movl 0x60(%esp), %ebx
pushl %ebx /* DebugEIP */
pushl %ebp /* DebugEBP */
pushl 0x60(%esp) /* DebugEIP */ // + 0x74
pushl %ebp /* DebugEBP */ // + 0x78
#endif
/* Load the segment registers */
movl $KERNEL_DS, %ebx
movl %ebx, %ds
movl %ebx, %es
movl %ebx, %gs
/* Load the segment registers */
movw $KERNEL_DS, %bx
movw %bx, %ds
movw %bx, %es
movw %bx, %gs
/*
* Save the old trap frame pointer over where we would save the EDX
* register.
*/
movl KTHREAD_TRAP_FRAME(%esi), %ebx
movl %ebx, KTRAP_FRAME_EDX(%esp)
/* Save the old trap frame pointer where EDX would be saved */
movl KTHREAD_TRAP_FRAME(%esi), %ebx
movl %ebx, KTRAP_FRAME_EDX(%esp)
/* Allocate new Kernel stack frame */
movl %esp,%ebp
/* Allocate new Kernel stack frame */
movl %esp,%ebp
/* Save a pointer to the trap frame in the TCB */
movl %ebp, KTHREAD_TRAP_FRAME(%esi)
/* Save a pointer to the trap frame in the TCB */
movl %ebp, KTHREAD_TRAP_FRAME(%esi)
/* Set ES to kernel segment */
movw $KERNEL_DS,%bx
movw %bx,%es
/* Users's current stack frame pointer is source */
movl %edx,%esi
/* Determine system service table to use */
cmpl $0x0fff, %eax
ja new_useShadowTable
/* Check to see if EAX is valid/inrange */
cmpl %es:_KeServiceDescriptorTable + 8, %eax
jbe new_serviceInRange
movl $STATUS_INVALID_SYSTEM_SERVICE, %eax
movl %eax, KTRAP_FRAME_EAX(%ebp) /* save our return value in PKTRAP_FRAME->Eax */
jmp KeReturnFromSystemCall
new_serviceInRange:
CheckValidCall:
/*
* Find out which table offset to use. Converts 0x1124 into 0x10.
* The offset is related to the Table Index as such: Offset = TableIndex x 10
*/
movl %eax, %edi
shrl $8, %edi
andl $0x10, %edi
movl %edi, %ecx
/* Now add the thread's base system table to the offset */
addl KTHREAD_SERVICE_TABLE(%esi), %edi
/* Get the true syscall ID and check it */
movl %eax, %ebx
andl $0x0FFF, %eax
cmpl 8(%edi), %eax
/* Invalid ID, try to load Win32K Table */
jnb KiBBTUnexpectedRange
#ifdef DBG
/* GDB thinks the function starts here and
wants a standard prolog, so let's give it */
pushl %ebp
movl %esp,%ebp
popl %ebp
/*
* GDB thinks the function starts here and
* wants a standard prolog, so let's give it
*/
pushl %ebp
movl %esp,%ebp
popl %ebp
#endif
/* Allocate room for argument list from kernel stack */
movl %es:_KeServiceDescriptorTable + 12, %ecx
movb %es:(%ecx, %eax), %cl
movzx %cl, %ecx
subl %ecx, %esp
/* Users's current stack frame pointer is source */
movl %edx, %esi
/* Allocate room for argument list from kernel stack */
movl 12(%edi), %ecx
movb (%ecx, %eax), %cl
movzx %cl, %ecx
/* Allocate space on our stack */
subl %ecx, %esp
/* Get pointer to function */
movl (%edi), %edi
movl (%edi, %eax, 4), %eax
/* Copy the arguments from the user stack to the kernel stack */
movl %esp,%edi
cld
rep movsb
/* Copy the arguments from the user stack to our stack */
shr $2, %ecx
movl %esp, %edi
cld
rep movsd
/* DS is now also kernel segment */
movw %bx, %ds
/* Do the System Call */
call *%eax
movl %eax, KTRAP_FRAME_EAX(%ebp)
/* Call system call hook */
pushl %eax
call _KiSystemCallHook
popl %eax
/* Make the system service call */
movl %es:_KeServiceDescriptorTable, %ecx
movl %es:(%ecx, %eax, 4), %eax
call *%eax
movl %eax, KTRAP_FRAME_EAX(%ebp) /* save our return value in PKTRAP_FRAME->Eax */
#if CHECKED
/* Bump Service Counter */
#endif
jmp KeDeallocateStackAndReturnFromSystemCallWithHook
new_useShadowTable:
subl $0x1000, %eax
/* Check to see if EAX is valid/inrange */
cmpl %es:_KeServiceDescriptorTableShadow + 24, %eax
jbe new_shadowServiceInRange
movl $STATUS_INVALID_SYSTEM_SERVICE, %eax
movl %eax, KTRAP_FRAME_EAX(%ebp) /* save our return value in PKTRAP_FRAME->Eax */
jmp KeReturnFromSystemCall
new_shadowServiceInRange:
#ifdef DBG
/*
* GDB thinks the function starts here and
* wants a standard prolog, so let's give it
*/
pushl %ebp
movl %esp,%ebp
popl %ebp
#endif
/* Allocate room for argument list from kernel stack */
movl %es:_KeServiceDescriptorTableShadow + 28, %ecx
movb %es:(%ecx, %eax), %cl
movzx %cl, %ecx
subl %ecx, %esp
/* Copy the arguments from the user stack to the kernel stack */
movl %esp,%edi
cld
rep movsb
/* DS is now also kernel segment */
movw %bx,%ds
/* Call system call hook */
// pushl %eax
// call _KiSystemCallHook
// popl %eax
/* Call service check routine */
pushl %eax
call _KiServiceCheck
popl %eax
/* Make the system service call */
movl %es:_KeServiceDescriptorTableShadow + 16, %ecx
movl %es:(%ecx, %eax, 4), %eax
call *%eax
movl %eax, KTRAP_FRAME_EAX(%ebp) /* save our return value in PKTRAP_FRAME->Eax */
#if CHECKED
/* Bump Service Counter */
#endif
KeDeallocateStackAndReturnFromSystemCallWithHook:
/* Deallocate the kernel stack frame */
movl %ebp,%esp
KeReturnFromSystemCallWithHook:
/* Call the post system call hook and deliver any pending APCs */
pushl %esp
call _KiAfterSystemCallHook
addl $4,%esp
/* Deallocate the kernel stack frame */
movl %ebp, %esp
KeReturnFromSystemCall:
/* Restore the user context */
/* Get a pointer to the current thread */
movl %fs:0x124, %esi
/* Get the Current Thread */
movl %fs:KPCR_CURRENT_THREAD, %esi
/* Restore the old trap frame pointer */
movl KTRAP_FRAME_EDX(%esp), %ebx
movl %ebx, KTHREAD_TRAP_FRAME(%esi)
/* Restore the old trap frame pointer */
movl KTRAP_FRAME_EDX(%esp), %ebx
movl %ebx, KTHREAD_TRAP_FRAME(%esi)
_KiServiceExit:
/* Get the Current Thread */
movl %fs:KPCR_CURRENT_THREAD, %esi
/* Deliver APCs only if we were called from user mode */
testb $1, KTRAP_FRAME_CS(%esp)
je KiRosTrapReturn
/* And only if any are actually pending */
cmpb $0, KTHREAD_PENDING_USER_APC(%esi)
je KiRosTrapReturn
/* Save pointer to Trap Frame */
movl %esp, %ebx
/* Raise IRQL to HIGH_LEVEL */
movl $1, %ecx
call @KfRaiseIrql@4
/* Save old IRQL */
pushl %eax
/* Deliver APCs */
pushl %ebx
pushl $0
pushl $UserMode
call _KiDeliverApc@12
/* Return to old IRQL */
popl %ecx
call @KfLowerIrql@4
KiRosTrapReturn:
/* Skip debug information and unsaved registers */
addl $0x30, %esp // + 0x48
popl %gs // + 0x44
popl %es // + 0x40
popl %ds // + 0x3C
popl %edx // + 0x38
popl %ecx // + 0x34
popl %eax // + 0x30
#if 0
mov KTRAP_FRAME_RESERVED1(%ebp), %ax
cmp %ax, SSIDX_NTCONTINUE
jnz KeNoEpilogPrint
movl KTRAP_FRAME_ESP(%ebp), %ecx
movl KTRAP_FRAME_EBP(%ebp), %edx
call @KeRosPrintEspEbp@8
KeNoEpilogPrint:
#endif
/* Restore the old previous mode */
popl %ebx // + 0x2C
movb %bl, %ss:KTHREAD_PREVIOUS_MODE(%esi)
/* Skip debug information and unsaved registers */
addl $0x30, %esp
popl %gs
popl %es
popl %ds
popl %edx
popl %ecx
popl %eax
/* Restore the old exception handler list */
popl %fs:KPCR_EXCEPTION_LIST // + 0x28
/* Restore the old previous mode */
popl %ebx
movb %bl, %ss:KTHREAD_PREVIOUS_MODE(%esi)
/* Restore final registers from trap frame */
popl %fs // + 0x24
popl %edi // + 0x20
popl %esi // + 0x1C
popl %ebx // + 0x18
popl %ebp // + 0x14
add $4, %esp // + 0x10
/* Restore the old exception handler list */
popl %ebx
movl %ebx, %fs:KPCR_EXCEPTION_LIST
/* Check if previous CS is from user-mode */
testl $1, 4(%esp)
/* It is, so use Fast Exit */
jnz FastRet
/*
* Restore what the stub pushed, and return back to it.
* Note that we were CALLed, so the first thing on our stack is the ret EIP!
*/
pop %edx // + 0x0C
pop %ecx // + 0x08
popf // + 0x04
jmp *%edx
IntRet:
iret
popl %fs
popl %edi
popl %esi
popl %ebx
popl %ebp
addl $0x4, %esp /* Ignore error code */
FastRet:
iret
/* Is SYSEXIT Supported/Wanted? */
cmpl $1, _KiFastSystemCallDisable
je IntRet
/* R3: NOTE: This is part of my in-progress attempt at correcting NtContinue
* It is not being called, yet...
*/
.globl @KeRosTrapReturn@8
@KeRosTrapReturn@8:
/* Restore FS to TIB */
mov $TEB_SELECTOR, %ecx
mov %ecx, %fs
/* We will be cleaning up the stack ourselves */
popl %edx /* New Ring 3 EIP */
add $0x4, %esp /* Skip Ring 3 DS */
andl $0xFD, 9(%esp) /* Remove IRQ hack from EFLAGS */
popfl /* Restore old EFLAGS */
popl %ecx /* Old Ring 3 SS:ESP */
/*
* At this point:
* ECX points to the old User Stack.
* EDX points to the instruction to execute in usermode after the sysenter
*/
sti
sysexit
/* point %esp to the trap frame to restore */
movl %ecx, %esp
movl %esp, %ebp
KiBBTUnexpectedRange:
/* Call the post system call hook and deliver any pending APCs */
pushl %esp
call _KiAfterSystemCallHook
addl $4,%esp
/* If this isn't a Win32K call, fail */
cmp $0x10, %ecx
jne InvalidCall
/* Restore the user context */
/* Get a pointer to the current thread */
movl %fs:0x124, %esi
/* Restore the old trap frame pointer */
movl %edx, KTHREAD_TRAP_FRAME(%esi)
/* Set up Win32K Table */
pushl %edx
pushl %ebx
call _KiServiceCheck
popl %eax
popl %edx
/* Try the Call again */
jmp CheckValidCall
InvalidCall:
jmp KiRosTrapReturn;
/* Invalid System Call */
int $3
movl $STATUS_INVALID_SYSTEM_SERVICE, %eax
movl %eax, KTRAP_FRAME_EAX(%ebp)
jmp _KiServiceExit

View file

@ -17,127 +17,6 @@
/* FUNCTIONS *****************************************************************/
VOID
KiSystemCallHook(ULONG Nr, ...)
{
#if 0
va_list ap;
ULONG i;
va_start(ap, Nr);
DbgPrint("%x/%d ", KeServiceDescriptorTable[0].SSDT[Nr].SysCallPtr, Nr);
DbgPrint("%x (", KeServiceDescriptorTable[0].SSPT[Nr].ParamBytes);
for (i = 0; i < KeServiceDescriptorTable[0].SSPT[Nr].ParamBytes / 4; i++)
{
DbgPrint("%x, ", va_arg(ap, ULONG));
}
DbgPrint(")\n");
ASSERT_IRQL(PASSIVE_LEVEL);
va_end(ap);
#endif
}
VOID
KiAfterSystemCallHook(PKTRAP_FRAME TrapFrame)
{
KIRQL oldIrql;
/* If we are returning to umode, deliver one pending umode apc.
* Note that kmode apcs are also delivered, even if deliverymode is UserMode.
* This is because we can't return to umode with pending kmode apcs!
* FIXME: Should we deliver pending kmode apcs when returning from a
* kmode-to-kmode syscall (ZwXxx calls)?????
* -Gunnar
*/
if (TrapFrame->Cs != KERNEL_CS)
{
KeRaiseIrql(APC_LEVEL, &oldIrql);
KiDeliverApc(UserMode, NULL, TrapFrame);
KeLowerIrql(oldIrql);
}
}
VOID
KiServiceCheck (ULONG Nr)
{
PETHREAD Thread;
Thread = PsGetCurrentThread();
#if 0
DbgPrint ("KiServiceCheck(%p) called\n", Thread);
DbgPrint ("Service %d (%p)\n", Nr, KeServiceDescriptorTableShadow[1].SSDT[Nr].SysCallPtr);
#endif
if (Thread->Tcb.ServiceTable != KeServiceDescriptorTableShadow)
{
#if 0
DbgPrint ("Initialize Win32 thread\n");
#endif
PsInitWin32Thread (Thread);
Thread->Tcb.ServiceTable = KeServiceDescriptorTableShadow;
}
}
// This function should be used by win32k.sys to add its own user32/gdi32 services
// TableIndex is 0 based
// ServiceCountTable its not used at the moment
/*
* @implemented
*/
BOOLEAN STDCALL
KeAddSystemServiceTable (
PSSDT SSDT,
PULONG ServiceCounterTable,
ULONG NumberOfServices,
PSSPT SSPT,
ULONG TableIndex
)
{
if (TableIndex > SSDT_MAX_ENTRIES - 1)
return FALSE;
/* check if descriptor table entry is free */
if ((KeServiceDescriptorTable[TableIndex].SSDT != NULL) ||
(KeServiceDescriptorTableShadow[TableIndex].SSDT != NULL))
return FALSE;
/* initialize the shadow service descriptor table */
KeServiceDescriptorTableShadow[TableIndex].SSDT = SSDT;
KeServiceDescriptorTableShadow[TableIndex].SSPT = SSPT;
KeServiceDescriptorTableShadow[TableIndex].NumberOfServices = NumberOfServices;
KeServiceDescriptorTableShadow[TableIndex].ServiceCounterTable = ServiceCounterTable;
/* initialize the service descriptor table (not for win32k services) */
if (TableIndex != 1)
{
KeServiceDescriptorTable[TableIndex].SSDT = SSDT;
KeServiceDescriptorTable[TableIndex].SSPT = SSPT;
KeServiceDescriptorTable[TableIndex].NumberOfServices = NumberOfServices;
KeServiceDescriptorTable[TableIndex].ServiceCounterTable = ServiceCounterTable;
}
return TRUE;
}
/*
* @unimplemented
*/
BOOLEAN
STDCALL
KeRemoveSystemServiceTable(
IN PUCHAR Number
)
{
UNIMPLEMENTED;
return FALSE;
}
/*
* @unimplemented
*/

View file

@ -33,6 +33,21 @@
/* FUNCTIONS *****************************************************************/
VOID
KiServiceCheck (VOID)
{
PETHREAD Thread;
Thread = PsGetCurrentThread();
if (Thread->Tcb.ServiceTable != KeServiceDescriptorTableShadow)
{
PsInitWin32Thread (Thread);
Thread->Tcb.ServiceTable = KeServiceDescriptorTableShadow;
}
}
/*
* @unimplemented
*/

View file

@ -270,4 +270,46 @@ KeUnstackDetachProcess (
KeReleaseDispatcherDatabaseLock(OldIrql);
}
// This function should be used by win32k.sys to add its own user32/gdi32 services
// TableIndex is 0 based
// ServiceCountTable its not used at the moment
/*
* @implemented
*/
BOOLEAN STDCALL
KeAddSystemServiceTable (
PSSDT SSDT,
PULONG ServiceCounterTable,
ULONG NumberOfServices,
PSSPT SSPT,
ULONG TableIndex
)
{
/* check if descriptor table entry is free */
if ((TableIndex > SSDT_MAX_ENTRIES - 1) ||
(KeServiceDescriptorTable[TableIndex].SSDT != NULL) ||
(KeServiceDescriptorTableShadow[TableIndex].SSDT != NULL))
return FALSE;
/* initialize the shadow service descriptor table */
KeServiceDescriptorTableShadow[TableIndex].SSDT = SSDT;
KeServiceDescriptorTableShadow[TableIndex].SSPT = SSPT;
KeServiceDescriptorTableShadow[TableIndex].NumberOfServices = NumberOfServices;
KeServiceDescriptorTableShadow[TableIndex].ServiceCounterTable = ServiceCounterTable;
return TRUE;
}
/*
* @unimplemented
*/
BOOLEAN
STDCALL
KeRemoveSystemServiceTable(
IN PUCHAR Number
)
{
UNIMPLEMENTED;
return FALSE;
}
/* EOF */

View file

@ -15,10 +15,6 @@
#define NDEBUG
#include <internal/debug.h>
VOID
FASTCALL
KeRosTrapReturn ( PKTRAP_FRAME TrapFrame, PKTRAP_FRAME PrevTrapFrame );
VOID STDCALL
KeRosDumpStackFrames ( PULONG Frame, ULONG FrameCount );
@ -30,8 +26,9 @@ NtContinue (
IN PCONTEXT Context,
IN BOOLEAN TestAlert)
{
PKTRAP_FRAME TrapFrame = KeGetCurrentThread()->TrapFrame;
PKTRAP_FRAME PrevTrapFrame = (PKTRAP_FRAME)TrapFrame->Edx;
PKTHREAD Thread = KeGetCurrentThread();
PKTRAP_FRAME TrapFrame = Thread->TrapFrame;
PKTRAP_FRAME PrevTrapFrame = (PKTRAP_FRAME)TrapFrame->Edx;
PFX_SAVE_AREA FxSaveArea;
KIRQL oldIrql;
@ -65,12 +62,12 @@ NtContinue (
/* Put the floating point context into the thread's FX_SAVE_AREA
* and make sure it is reloaded when needed.
*/
FxSaveArea = (PFX_SAVE_AREA)((ULONG_PTR)KeGetCurrentThread()->InitialStack - sizeof(FX_SAVE_AREA));
FxSaveArea = (PFX_SAVE_AREA)((ULONG_PTR)Thread->InitialStack - sizeof(FX_SAVE_AREA));
if (KiContextToFxSaveArea(FxSaveArea, Context))
{
KeGetCurrentThread()->NpxState = NPX_STATE_VALID;
Thread->NpxState = NPX_STATE_VALID;
KeRaiseIrql(DISPATCH_LEVEL, &oldIrql);
if (KeGetCurrentKPCR()->PrcbData.NpxThread == KeGetCurrentThread())
if (KeGetCurrentKPCR()->PrcbData.NpxThread == Thread)
{
KeGetCurrentKPCR()->PrcbData.NpxThread = NULL;
Ke386SetCr0(Ke386GetCr0() | X86_CR0_TS);
@ -82,7 +79,9 @@ NtContinue (
KeLowerIrql(oldIrql);
}
KeRosTrapReturn ( TrapFrame, PrevTrapFrame );
/* Restore the user context */
Thread->TrapFrame = PrevTrapFrame;
__asm__("mov %%ebx, %%esp;\n" "jmp _KiServiceExit": : "b" (TrapFrame));
return STATUS_SUCCESS; /* this doesn't actually happen b/c KeRosTrapReturn() won't return */
}

View file

@ -280,6 +280,8 @@ IsVmwSVGAEnabled(VOID)
return (Value == 1);
}
BOOL
SaveResolutionSettings(DWORD ResX, DWORD ResY, DWORD ColDepth)
{
@ -313,6 +315,43 @@ SaveResolutionSettings(DWORD ResX, DWORD ResY, DWORD ColDepth)
return TRUE;
}
BOOL
DisableFastSystemCall(VOID)
{
DWORD Value = 1;
HKEY hReg;
/* Open or Create the Kernel Settings Key */
if(RegCreateKeyEx(HKEY_LOCAL_MACHINE,
L"SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Kernel",
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_SET_VALUE,
NULL,
&hReg,
NULL) != ERROR_SUCCESS) {
DbgPrint("Failed to Disable Sysenter\n");
return FALSE;
}
/* Disable Fast System Call */
if(RegSetValueEx(hReg,
L"FastSystemCallDisable",
0,
REG_DWORD,
(BYTE*)&Value,
sizeof(DWORD)) != ERROR_SUCCESS) {
RegCloseKey(hReg);
DbgPrint("Failed to Disable Sysenter\n");
return FALSE;
}
/* Return Success */
RegCloseKey(hReg);
return TRUE;
}
BOOL
EnableDriver(WCHAR *Key, BOOL Enable)
{
@ -1022,6 +1061,9 @@ WinMain(HINSTANCE hInstance,
/* restore the exception handler */
SetUnhandledExceptionFilter(OldHandler);
/* Disable Fast System Call no matter what */
DisableFastSystemCall();
lc = DestinationPath;
lc += GetSystemDirectory(DestinationPath, MAX_PATH) - 1;
if(lc >= DestinationPath && *lc != L'\\')

View 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
View 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);
}

View 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