[ros-diffs] [tkreuzer] 28060: fix nci tool to only generate one stub file for our win32ksys lib to silence the warning. Fix some comments.

tkreuzer at svn.reactos.org tkreuzer at svn.reactos.org
Wed Aug 1 01:00:31 CEST 2007


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=28060&r1=28059&r2=28060&view=diff
==============================================================================
--- 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=28060&r1=28059&r2=28060&view=diff
==============================================================================
--- 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 at 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 at 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);
+}




More information about the Ros-diffs mailing list