Author: tkreuzer
Date: Wed Aug 1 03:00:31 2007
New Revision: 28060
URL:
http://svn.reactos.org/svn/reactos?rev=28060&view=rev
Log:
fix nci tool to only generate one stub file for our win32ksys lib to silence the warning.
Fix some comments.
Modified:
trunk/reactos/tools/nci/nci.mak
trunk/reactos/tools/nci/ncitool.c
Modified: trunk/reactos/tools/nci/nci.mak
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/tools/nci/nci.mak?rev=2806…
==============================================================================
--- trunk/reactos/tools/nci/nci.mak (original)
+++ trunk/reactos/tools/nci/nci.mak Wed Aug 1 03:00:31 2007
@@ -44,8 +44,7 @@
# WIN32K.SYS
WIN32K_SVC_DB = subsystems$(SEP)win32$(SEP)win32k$(SEP)w32ksvc.db
WIN32K_SERVICE_TABLE = subsystems$(SEP)win32$(SEP)win32k$(SEP)include$(SEP)napi.h
-WIN32K_GDI_STUBS = lib$(SEP)win32ksys$(SEP)$(ARCH)$(SEP)win32k.S
-WIN32K_USER_STUBS = lib$(SEP)win32ksys$(SEP)$(ARCH)$(SEP)win32k.S
+WIN32K_STUBS = lib$(SEP)win32ksys$(SEP)$(ARCH)$(SEP)win32k.S
@@ -78,8 +77,7 @@
$(WIN32K_SERVICE_TABLE) \
$(NTDLL_STUBS) \
$(KERNEL_STUBS) \
- $(WIN32K_GDI_STUBS) \
- $(WIN32K_USER_STUBS)
+ $(WIN32K_STUBS)
.PHONY: nci_service_files_clean
nci_service_files_clean:
Modified: trunk/reactos/tools/nci/ncitool.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/tools/nci/ncitool.c?rev=28…
==============================================================================
--- trunk/reactos/tools/nci/ncitool.c (original)
+++ trunk/reactos/tools/nci/ncitool.c Wed Aug 1 03:00:31 2007
@@ -1,631 +1,625 @@
-/*
- * 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(a)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>
-#ifndef __FreeBSD__
-# include <malloc.h>
-#endif // __FreeBSD__
-
-/* 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.
- */
-#if defined(__GNUC__)
-#define UserModeStub_x86 " movl $0x%x, %%eax\n" \
- " movl $KUSER_SHARED_SYSCALL, %%ecx\n" \
- " call *(%%ecx)\n" \
- " ret $0x%x\n\n"
-
-#define UserModeStub_ppc " mflr 0\n" \
- " addi 1,1,-16\n" \
- " li 0,%x\n" \
- " stw 0,1(0)\n" \
- " sc\n" \
- " lwz 0,1(0)\n" \
- " mtlr 0\n" \
- " addi 1,1,16\n" \
- " blr\n"
-#elif defined(_MSC_VER)
-#define UserModeStub_x86 " asm { \n" \
- " mov eax, %xh\n" \
- " mov ecx, KUSER_SHARED_SYSCALL\n" \
- " call [ecx]\n" \
- " ret %xh\n" \
- " }\n"
-#else
-#error Unknown compiler for inline assembler
-#endif
-
-/*
- * This stub calls KiSystemService directly with a fake INT2E stack.
- * Because EIP is pushed during the call, the handler will return here.
- */
-#if defined(__GNUC__)
-#define KernelModeStub_x86 " movl $0x%x, %%eax\n" \
- " leal 4(%%esp), %%edx\n" \
- " pushfl\n" \
- " pushl $KGDT_R0_CODE\n" \
- " call _KiSystemService\n" \
- " ret $0x%x\n\n"
-
-#define KernelModeStub_ppc " bl KiSystemService\n" \
- " rfi\n"
-#elif defined(_MSC_VER)
-#define KernelModeStub_x86 " asm { \n" \
- " mov eax, %xh\n" \
- " lea edx, [esp+4]\n" \
- " pushf\n" \
- " push KGDT_R0_CODE\n" \
- " call _KiSystemService\n" \
- " ret %xh\n" \
- " }\n"
-#else
-#error Unknown compiler for inline assembler
-#endif
-
-/***** Arch Dependent Stuff ******/
-struct ncitool_data_t {
- const char *arch;
- int args_to_bytes;
- const char *km_stub;
- const char *um_stub;
- const char *global_header;
- const char *declaration;
-};
-
-struct ncitool_data_t ncitool_data[] = {
- { "i386", 4, KernelModeStub_x86, UserModeStub_x86,
- ".global _%s@%d\n", "_%s@%d:\n" },
- { "powerpc", 4, KernelModeStub_ppc, UserModeStub_ppc,
- "\t.globl %s\n", "%s:\n" },
- { 0, }
-};
-int arch_sel = 0;
-#define ARGS_TO_BYTES(x) (x)*(ncitool_data[arch_sel].args_to_bytes)
-#define UserModeStub ncitool_data[arch_sel].um_stub
-#define KernelModeStub ncitool_data[arch_sel].km_stub
-#define GlobalHeader ncitool_data[arch_sel].global_header
-#define Declaration ncitool_data[arch_sel].declaration
-
-/* 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 <ndk/asm.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, GlobalHeader, SyscallName, StackBytes);
-
- /* Define it */
- fprintf(StubFile, Declaration, 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;
- *SyscallArguments = 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 *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);
- if (SyscallArguments != NULL)
- StackBytes = ARGS_TO_BYTES(strtoul(SyscallArguments, NULL, 0));
- else
- StackBytes = 0;
-
- /* Make sure we really extracted something */
- if (NtSyscallName) {
-
- /* 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 (NeedsZw) {
-
- NtSyscallName[0] = 'Z';
- NtSyscallName[1] = 'w';
- WriteUserModeStub(UserModeFiles[i],
- NtSyscallName,
- StackBytes,
- SyscallId | Index);
- }
-
- }
-
- /* Create the Kernel coutnerparts (only Zw*, Nt* are the real functions!) */
- if (KernelModeFile) {
-
- NtSyscallName[0] = 'Z';
- NtSyscallName[1] = 'w';
- WriteKernelModeStub(KernelModeFile,
- NtSyscallName,
- 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,"ULONG_PTR %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(ULONG_PTR)%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,"UCHAR %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. */
- if (SyscallArguments != NULL)
- fprintf(SyscallTable,"\t\t%lu * sizeof(void
*)",strtoul(SyscallArguments, NULL, 0));
- else
- fprintf(SyscallTable,"\t\t0");
-
- /* 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 [-arch <arch>] 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"
- " -arch is optional, default is %s\n",
- argv0,
- ncitool_data[0].arch
- );
-}
-
-int main(int argc, char* argv[])
-{
- FILE * Files[Arguments] = { };
- int FileNumber, ArgOffset = 1;
- char * OpenType = "r";
-
- /* Catch architecture argument */
- if (argc > 3 && !strcmp(argv[1],"-arch")) {
- for( arch_sel = 0; ncitool_data[arch_sel].arch; arch_sel++ )
- if (strcmp(argv[2],ncitool_data[arch_sel].arch) == 0)
- break;
- if (!ncitool_data[arch_sel].arch) {
- printf("Invalid arch '%s'\n", argv[2]);
- usage(argv[0]);
- return 1;
- }
- ArgOffset = 3;
- }
- /* Make sure all arguments all there */
- if (argc != Arguments + ArgOffset) {
- 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 + ArgOffset], OpenType);
-
- /* Check for failure and error out if so */
- if (!Files[FileNumber]) {
- perror(argv[FileNumber + ArgOffset]);
- return (1);
- }
- }
-
- /* Write the File Headers */
- WriteFileHeader(Files[NtosUserStubs],
- "System Call Stubs for Native API",
- argv[NtosUserStubs + ArgOffset]);
-
- WriteFileHeader(Files[NtosKernelStubs],
- "System Call Stubs for Native API",
- argv[NtosKernelStubs + ArgOffset]);
- fputs("#include <ndk/asm.h>\n\n", Files[NtosKernelStubs]);
-
- WriteFileHeader(Files[Win32kGdiStubs],
- "System Call Stubs for Native API",
- argv[Win32kGdiStubs + ArgOffset]);
-
- WriteFileHeader(Files[Win32kUserStubs],
- "System Call Stubs for Native API",
- argv[Win32kUserStubs + ArgOffset]);
-
-
- /* 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 + ArgOffset]);
-
- CreateSystemServiceTable(Files[NativeGuiDb],
- Files[Win32kServiceTable],
- "Win32k",
- argv[Win32kServiceTable + ArgOffset]);
-
- /* Close all files */
- for (FileNumber = 0; FileNumber < Arguments-ArgOffset; FileNumber++) {
-
- /* Close the File */
- fclose(Files[FileNumber]);
-
- }
-
- return(0);
-}
+/*
+ * 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(a)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>
+#ifndef __FreeBSD__
+# include <malloc.h>
+#endif // __FreeBSD__
+
+/* DEFINES ****************************************************************/
+
+#define INPUT_BUFFER_SIZE 255
+#define Arguments 7
+
+/******* 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 Win32kStubs 6
+
+/********** Stub Code ************/
+
+/*
+ * This stubs calls into KUSER_SHARED_DATA where either a
+ * sysenter or interrupt is performed, depending on CPU support.
+ */
+#if defined(__GNUC__)
+#define UserModeStub_x86 " movl $0x%x, %%eax\n" \
+ " movl $KUSER_SHARED_SYSCALL, %%ecx\n" \
+ " call *(%%ecx)\n" \
+ " ret $0x%x\n\n"
+
+#define UserModeStub_ppc " mflr 0\n" \
+ " addi 1,1,-16\n" \
+ " li 0,%x\n" \
+ " stw 0,1(0)\n" \
+ " sc\n" \
+ " lwz 0,1(0)\n" \
+ " mtlr 0\n" \
+ " addi 1,1,16\n" \
+ " blr\n"
+#elif defined(_MSC_VER)
+#define UserModeStub_x86 " asm { \n" \
+ " mov eax, %xh\n" \
+ " mov ecx, KUSER_SHARED_SYSCALL\n" \
+ " call [ecx]\n" \
+ " ret %xh\n" \
+ " }\n"
+#else
+#error Unknown compiler for inline assembler
+#endif
+
+/*
+ * This stub calls KiSystemService directly with a fake INT2E stack.
+ * Because EIP is pushed during the call, the handler will return here.
+ */
+#if defined(__GNUC__)
+#define KernelModeStub_x86 " movl $0x%x, %%eax\n" \
+ " leal 4(%%esp), %%edx\n" \
+ " pushfl\n" \
+ " pushl $KGDT_R0_CODE\n" \
+ " call _KiSystemService\n" \
+ " ret $0x%x\n\n"
+
+#define KernelModeStub_ppc " bl KiSystemService\n" \
+ " rfi\n"
+#elif defined(_MSC_VER)
+#define KernelModeStub_x86 " asm { \n" \
+ " mov eax, %xh\n" \
+ " lea edx, [esp+4]\n" \
+ " pushf\n" \
+ " push KGDT_R0_CODE\n" \
+ " call _KiSystemService\n" \
+ " ret %xh\n" \
+ " }\n"
+#else
+#error Unknown compiler for inline assembler
+#endif
+
+/***** Arch Dependent Stuff ******/
+struct ncitool_data_t {
+ const char *arch;
+ int args_to_bytes;
+ const char *km_stub;
+ const char *um_stub;
+ const char *global_header;
+ const char *declaration;
+};
+
+struct ncitool_data_t ncitool_data[] = {
+ { "i386", 4, KernelModeStub_x86, UserModeStub_x86,
+ ".global _%s@%d\n", "_%s@%d:\n" },
+ { "powerpc", 4, KernelModeStub_ppc, UserModeStub_ppc,
+ "\t.globl %s\n", "%s:\n" },
+ { 0, }
+};
+int arch_sel = 0;
+#define ARGS_TO_BYTES(x) (x)*(ncitool_data[arch_sel].args_to_bytes)
+#define UserModeStub ncitool_data[arch_sel].um_stub
+#define KernelModeStub ncitool_data[arch_sel].km_stub
+#define GlobalHeader ncitool_data[arch_sel].global_header
+#define Declaration ncitool_data[arch_sel].declaration
+
+/* 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 <ndk/asm.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, GlobalHeader, SyscallName, StackBytes);
+
+ /* Define it */
+ fprintf(StubFile, Declaration, 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;
+ *SyscallArguments = 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 - Number of first syscall
+ *
+ * UserFiles - Number of Usermode Stub Files to create
+ *
+ * NeedsZw - Write Zw prefix?
+ *
+ * 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 *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);
+ if (SyscallArguments != NULL)
+ StackBytes = ARGS_TO_BYTES(strtoul(SyscallArguments, NULL, 0));
+ else
+ StackBytes = 0;
+
+ /* Make sure we really extracted something */
+ if (NtSyscallName) {
+
+ /* 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 (NeedsZw) {
+
+ NtSyscallName[0] = 'Z';
+ NtSyscallName[1] = 'w';
+ WriteUserModeStub(UserModeFiles[i],
+ NtSyscallName,
+ StackBytes,
+ SyscallId | Index);
+ }
+
+ }
+
+ /* Create the Kernel coutnerparts (only Zw*, Nt* are the real functions!) */
+ if (KernelModeFile) {
+
+ NtSyscallName[0] = 'Z';
+ NtSyscallName[1] = 'w';
+ WriteKernelModeStub(KernelModeFile,
+ NtSyscallName,
+ 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,"ULONG_PTR %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(ULONG_PTR)%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,"UCHAR %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. */
+ if (SyscallArguments != NULL)
+ fprintf(SyscallTable,"\t\t%lu * sizeof(void
*)",strtoul(SyscallArguments, NULL, 0));
+ else
+ fprintf(SyscallTable,"\t\t0");
+
+ /* 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 [-arch <arch>] 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"
+ " -arch is optional, default is %s\n",
+ argv0,
+ ncitool_data[0].arch
+ );
+}
+
+int main(int argc, char* argv[])
+{
+ FILE * Files[Arguments] = { };
+ int FileNumber, ArgOffset = 1;
+ char * OpenType = "r";
+
+ /* Catch architecture argument */
+ if (argc > 3 && !strcmp(argv[1],"-arch")) {
+ for( arch_sel = 0; ncitool_data[arch_sel].arch; arch_sel++ )
+ if (strcmp(argv[2],ncitool_data[arch_sel].arch) == 0)
+ break;
+ if (!ncitool_data[arch_sel].arch) {
+ printf("Invalid arch '%s'\n", argv[2]);
+ usage(argv[0]);
+ return 1;
+ }
+ ArgOffset = 3;
+ }
+ /* Make sure all arguments all there */
+ if (argc != Arguments + ArgOffset) {
+ 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 + ArgOffset], OpenType);
+
+ /* Check for failure and error out if so */
+ if (!Files[FileNumber]) {
+ perror(argv[FileNumber + ArgOffset]);
+ return (1);
+ }
+ }
+
+ /* Write the File Headers */
+ WriteFileHeader(Files[NtosUserStubs],
+ "System Call Stubs for Native API",
+ argv[NtosUserStubs + ArgOffset]);
+
+ WriteFileHeader(Files[NtosKernelStubs],
+ "System Call Stubs for Native API",
+ argv[NtosKernelStubs + ArgOffset]);
+ fputs("#include <ndk/asm.h>\n\n", Files[NtosKernelStubs]);
+
+ WriteFileHeader(Files[Win32kStubs],
+ "System Call Stubs for Native API",
+ argv[Win32kStubs + ArgOffset]);
+
+ /* Create the System Stubs */
+ CreateStubs(Files[NativeSystemDb],
+ &Files[NtosUserStubs],
+ Files[NtosKernelStubs],
+ MAIN_INDEX,
+ 1,
+ 1);
+
+ /* Create the Graphics Stubs */
+ CreateStubs(Files[NativeGuiDb],
+ &Files[Win32kStubs],
+ NULL,
+ WIN32K_INDEX,
+ 1,
+ 0);
+
+ /* Rewind the databases */
+ rewind(Files[NativeSystemDb]);
+ rewind(Files[NativeGuiDb]);
+
+ /* Create the Service Tables */
+ CreateSystemServiceTable(Files[NativeSystemDb],
+ Files[NtosServiceTable],
+ "Main",
+ argv[NtosServiceTable + ArgOffset]);
+
+ CreateSystemServiceTable(Files[NativeGuiDb],
+ Files[Win32kServiceTable],
+ "Win32k",
+ argv[Win32kServiceTable + ArgOffset]);
+
+ /* Close all files */
+ for (FileNumber = 0; FileNumber < Arguments-ArgOffset; FileNumber++) {
+
+ /* Close the File */
+ fclose(Files[FileNumber]);
+
+ }
+
+ return(0);
+}