Index: trunk/src/win32k/dev16/probkrnl.c
===================================================================
--- trunk/src/win32k/dev16/probkrnl.c	(revision 2826)
+++ trunk/src/win32k/dev16/probkrnl.c	(revision 2827)
@@ -1,3 +1,3 @@
-/* $Id: probkrnl.c,v 1.9 2000-02-18 19:27:29 bird Exp $
+/* $Id: probkrnl.c,v 1.10 2000-02-19 08:40:29 bird Exp $
  *
  * Description:   Autoprobes the os2krnl file and os2krnl[*].sym files.
@@ -94,5 +94,5 @@
     {FALSE, -1,  8, "_ldrOpen",             -1,  -1, EPT_PROC},        /* 1 */
     {FALSE, -1,  9, "_ldrClose",            -1,  -1, EPT_PROC},        /* 2 */
-    {FALSE, -1, 12, "_LDRQAppType",         -1,  -1, EPT_PROC},        /* 3 */
+    {FALSE, -1, 12, "_LDRQAppType",         -1,  -1, EPT_PROCIMPORT},  /* 3 */ /* to be removed? */
     {FALSE, -1, 20, "_ldrEnum32bitRelRecs", -1,  -1, EPT_PROC},        /* 4 */
     {FALSE, -1, 10, "_IOSftOpen",           -1,  -1, EPT_PROCIMPORT},  /* 5 */
@@ -101,7 +101,8 @@
     {FALSE, -1, 12, "_IOSftReadAt",         -1,  -1, EPT_PROCIMPORT},  /* 8 */
     {FALSE, -1, 13, "_IOSftWriteAt",        -1,  -1, EPT_PROCIMPORT},  /* 9 */
-    {FALSE, -1, 11, "_VMAllocMem",          -1,  -1, EPT_PROCIMPORT},  /* 10 */
-    {FALSE, -1, 11, "_VMGetOwner",          -1,  -1, EPT_PROCIMPORT},  /* 11 */
-    {FALSE, -1, 11, "g_tkExecPgm",          -1,  -1, EPT_PROC}         /* 12 */
+    {FALSE, -1, 12, "_SftFileSize",         -1,  -1, EPT_PROCIMPORT},  /* 10 */
+    {FALSE, -1, 11, "_VMAllocMem",          -1,  -1, EPT_PROCIMPORT},  /* 11 */
+    {FALSE, -1, 11, "_VMGetOwner",          -1,  -1, EPT_PROCIMPORT},  /* 12 */
+    {FALSE, -1, 11, "g_tkExecPgm",          -1,  -1, EPT_PROC}         /* 13 */
 };
 
Index: trunk/src/win32k/dev32/d32init.c
===================================================================
--- trunk/src/win32k/dev32/d32init.c	(revision 2826)
+++ trunk/src/win32k/dev32/d32init.c	(revision 2827)
@@ -1,3 +1,3 @@
-/* $Id: d32init.c,v 1.9 2000-02-18 19:27:29 bird Exp $
+/* $Id: d32init.c,v 1.10 2000-02-19 08:40:29 bird Exp $
  *
  * d32init.c - 32-bits init routines.
@@ -566,6 +566,7 @@
                         (unsigned)myldrOpen,
                         (unsigned)myldrClose,
-                        (unsigned)myLDRQAppType,
+                        0,//(unsigned)myLDRQAppType,
                         (unsigned)myldrEnum32bitRelRecs,
+                        0,
                         0,
                         0,
Index: trunk/src/win32k/include/OS2KIO.h
===================================================================
--- trunk/src/win32k/include/OS2KIO.h	(revision 2826)
+++ trunk/src/win32k/include/OS2KIO.h	(revision 2827)
@@ -1,3 +1,3 @@
-/* $Id: OS2KIO.h,v 1.3 2000-01-22 18:20:58 bird Exp $
+/* $Id: OS2KIO.h,v 1.4 2000-02-19 08:40:30 bird Exp $
  *
  * OS/2 kernel IO: prototypes, typedefs and macros.
@@ -13,5 +13,5 @@
 /**
  * Opens a given file.
- * @returns  NO_ERROR on success. other on error.
+ * @returns  NO_ERROR on success. OS/2 error code on error.
  * @param    pszFilename   Pointer to filename.
  * @param    flOpenFlags   Open flags. (similar to DosOpen)
@@ -31,5 +31,5 @@
 /**
  * Closes the specified file.
- * @returns  NO_ERROR on success. other on error.
+ * @returns  NO_ERROR on success. OS/2 error code on error.
  * @param    hFile      File handle - System File Number.
  */
@@ -41,5 +41,5 @@
 /**
  * Probably this function will expand a relative path to a full path.
- * @returns  NO_ERROR on success. other on error. (?)
+ * @returns  NO_ERROR on success. OS/2 error code on error.
  * @param    pszPath  Pointer to path to expand. Contains the full path upon return. (?)
  *                    This buffer should probably be of CCHMAXPATH length.
@@ -52,5 +52,5 @@
 /**
  * Read at a given offset in the a file.
- * @returns  NO_ERROR on success. other on error.
+ * @returns  NO_ERROR on success. OS/2 error code on error.
  * @param    hFile      File handle - System File Number.
  * @param    pcbActual  Pointer to variable which upon input holds the number
@@ -71,5 +71,5 @@
 /**
  * Write at a given offset in the a file.
- * @returns  NO_ERROR on success. other on error.
+ * @returns  NO_ERROR on success. OS/2 error code on error.
  * @param    hFile      File handle - System File Number.
  * @param    pcbActual  Pointer to variable which upon input holds the number
@@ -87,3 +87,15 @@
     );
 
+
+/**
+ * Gets the filesize.
+ * @returns   NO_ERROR on success; OS/2 error code on error.
+ * @param     hFile    File handle - System File Number.
+ * @param     pcbFile  Pointer to ULONG which will hold the file size upon return.
+ */
+APIRET KRNLCALL SftFileSize(
+    SFN hFile,
+    PULONG pcbFile
+    );
+
 #endif
Index: trunk/src/win32k/include/probkrnl.h
===================================================================
--- trunk/src/win32k/include/probkrnl.h	(revision 2826)
+++ trunk/src/win32k/include/probkrnl.h	(revision 2827)
@@ -1,3 +1,3 @@
-/* $Id: probkrnl.h,v 1.6 2000-02-18 19:27:29 bird Exp $
+/* $Id: probkrnl.h,v 1.7 2000-02-19 08:40:30 bird Exp $
  *
  * Include file for ProbKrnl.
@@ -16,5 +16,5 @@
 *   Defined Constants And Macros                                               *
 *******************************************************************************/
-#define NUMBER_OF_PROCS      13
+#define NUMBER_OF_PROCS      14
 #define MAX_LENGTH_NAME      32
 
Index: trunk/src/win32k/ldr/calltab.asm
===================================================================
--- trunk/src/win32k/ldr/calltab.asm	(revision 2826)
+++ trunk/src/win32k/ldr/calltab.asm	(revision 2827)
@@ -1,3 +1,3 @@
-; $Id: calltab.asm,v 1.5 2000-02-18 19:27:30 bird Exp $
+; $Id: calltab.asm,v 1.6 2000-02-19 08:40:30 bird Exp $
 ;
 ; callTab - Call back again table - table with entry for each function which is overrided.
@@ -30,4 +30,5 @@
     public _IOSftReadAt@20
     public _IOSftWriteAt@20
+    public _SftFileSize@8
 
     public _VMAllocMem@36
@@ -94,4 +95,8 @@
 _IOSftWriteAt@20 ENDP
 
+_SftFileSize@8 PROC NEAR
+    db MAXSIZE_PROLOG dup(0cch)
+_SftFileSize@8 ENDP
+
 
 _VMAllocMem@36 PROC NEAR
Index: trunk/src/win32k/ldr/myldrOpen.cpp
===================================================================
--- trunk/src/win32k/ldr/myldrOpen.cpp	(revision 2826)
+++ trunk/src/win32k/ldr/myldrOpen.cpp	(revision 2827)
@@ -1,3 +1,3 @@
-/* $Id: myldrOpen.cpp,v 1.6 2000-01-22 18:21:02 bird Exp $
+/* $Id: myldrOpen.cpp,v 1.7 2000-02-19 08:40:30 bird Exp $
  *
  * myldrOpen - ldrOpen.
@@ -16,4 +16,6 @@
 #define INCL_NOPMAPI
 
+#define INCL_OS2KRNL_IO
+
 /*******************************************************************************
 *   Header Files                                                               *
@@ -21,7 +23,9 @@
 #include <os2.h>
 
+#include "rmalloc.h"
 #include "malloc.h"
 #include <memory.h>
 #include <stdlib.h>
+#include <string.h>
 
 #include "log.h"
@@ -29,4 +33,5 @@
 #include <exe386.h>
 #include "OS2Krnl.h"
+#include "dev32.h"
 #include "ModuleBase.h"
 #include "pe2lx.h"
@@ -36,4 +41,11 @@
 #include "ldrCalls.h"
 #include "options.h"
+#include "myExecPgm.h"
+
+
+/*******************************************************************************
+*   Internal Functions                                                         *
+*******************************************************************************/
+static unsigned getArgsLength(const char *pachArgs);
 
 
@@ -49,36 +61,101 @@
     ULONG rc;
 
+    /*
+     * Try open the file (thats why this function is called anyway)
+     */
     rc = ldrOpen(phFile, pszFilename, param3);
 
+    /* log sucesses */
     if (rc == NO_ERROR)
         kprintf(("ldrOpen:  phFile=%#.4x, flags=%#.8x, pszFn=%s\n", *phFile, param3, pszFilename));
 
+    /*
+     * Are we to intercept the loading?
+     * - Only if open were succesful and one of the loaders are enabled.
+     */
     if (rc == NO_ERROR && (options.fElf || options.fPE != FLAGS_PE_NOT || options.fScript))
     {
-        static char achBuffer[sizeof(IMAGE_DOS_HEADER)];
-        PIMAGE_DOS_HEADER   pMzHdr = (PIMAGE_DOS_HEADER)&achBuffer[0];
-        PIMAGE_NT_HEADERS   pNtHdrs = (PIMAGE_NT_HEADERS)&achBuffer[0]; /* oops. Last accessible field is OptionalHeader.FileAlignment */
-        char               *pach = &achBuffer[0];
-
-        /**
+        char               *pszBuffer = (char*)rmalloc(640);        /* Read buffer. */
+        PIMAGE_DOS_HEADER   pMzHdr = (PIMAGE_DOS_HEADER)pszBuffer;  /* Pointer to the buffer as it were a dosheader. */
+        PIMAGE_NT_HEADERS   pNtHdrs = (PIMAGE_NT_HEADERS)pszBuffer; /* Pointer to the buffer as if it were an NT header. */
+        char               *pach = pszBuffer;                       /* Finally an pointer to the buffer as if it were chars.. (which it is!) */
+        PEXECPGMBUFFER      pBuffer;                                /* Pointer to a buffer containing the programname and arguments. */
+                                                                    /* For scripts and PE.EXE this has to be changed to have correct */
+                                                                    /* parameters sendt in to the program. */
+        unsigned            cchRead = sizeof(IMAGE_DOS_HEADER);     /* Amount of the buffer which contains valid data. */
+        unsigned            cbFile;                                 /* Filesize (0xffffffff if call to SftFileSize failed - should _never_ happen though)  */
+
+        /*
+         * Verify that rmalloc completed successfully.
+         */
+        if (pszBuffer == NULL)
+        {
+            kprintf(("ldrOpen: rmalloc(1024) failed\n"));
+            return NO_ERROR;
+        }
+
+        /*
+         * Try get the filesize
+         */
+        /*
+        rc = SftFileSize(*phFile, (PULONG)SSToDS(&cbFile));
+        if (rc != NO_ERROR)
+        {
+            kprintf(("ldrOpen: SftFileSize failed with rc=%d\n", rc));
+        */
+            cbFile = (unsigned)~0;
+        /*
+        } */
+
+        /*
          * See if this is an recognizable module format.
          * This costs up to two disk reads!
          */
-        rc = ldrRead(*phFile, 0UL, pMzHdr, 0UL, sizeof(IMAGE_DOS_HEADER), NULL);
+        rc = ldrRead(*phFile, 0UL, pMzHdr, 0UL, cchRead, NULL);
         if (rc == NO_ERROR)
         {
+            /*
+             * PE header?
+             *  - If DOS Magic is found AND a valid e_lfanew (offset of NE/LX/LE/PE header) is found
+             *  - OR if PE siganture is found.
+             */
             if ((pMzHdr->e_magic == IMAGE_DOS_SIGNATURE &&
                  pMzHdr->e_lfanew > sizeof(IMAGE_DOS_HEADER) && pMzHdr->e_lfanew < 0x04000000UL) /* Larger than 64 bytes and less that 64MB. */
                 || *(PULONG)pach == IMAGE_NT_SIGNATURE)
-            {   /* MZ or PE header found */
+            {   /*
+                 * MZ or PE header found
+                 */
+
+                /* if PE loading is diable return to the caller */
                 if (options.fPE == FLAGS_PE_NOT)
+                {
+                    free(pszBuffer);
                     return NO_ERROR;
-
+                }
+
+                /*
+                 * Read the PE header if it isn't what we allready have!
+                 */
+                cchRead = sizeof(IMAGE_NT_HEADERS);
                 if (*(PULONG)pach != IMAGE_NT_SIGNATURE)
-                    rc = ldrRead(*phFile, pMzHdr->e_lfanew, pach, 0UL, sizeof(achBuffer), NULL);
-
+                    rc = ldrRead(*phFile, pMzHdr->e_lfanew, pach, 0UL, cchRead, NULL);
+                else
+                    rc = ldrRead(*phFile, 0UL, pach, 0UL, cchRead, NULL);
+
+                /*
+                 * If successfully read, and a PE signature is present the continue and try load it!
+                 * Else don't do anything, simply return NO_ERROR to the caller. (probably NE or LX exec)
+                 */
                 if (rc == NO_ERROR && *(PULONG)pach == IMAGE_NT_SIGNATURE)
-                {   /* PE signature found */
+                {   /*
+                     * PE signature found.
+                     */
                     kprintf(("ldrOpen: PE executable...\n"));
+
+                    /*
+                     * PE2LX?
+                     *  - When PE2LX flag is set
+                     *  - OR when the MIXED flag is set and the image is with the first 64MB of memory.
+                     */
                     if (options.fPE == FLAGS_PE_PE2LX
                         || (options.fPE == FLAGS_PE_MIXED
@@ -88,5 +165,11 @@
                             )
                         )
-                    {   /* pe2lx */
+                    {   /*
+                         * Pe2Lx (Ring0 of course)
+                         * - Create a Pe2Lx class,
+                         * - initiate it
+                         * - Add the module to the module tree so we may find it later...
+                         * - Set the handle state to 'our'.
+                         */
                         Pe2Lx * pPe2Lx = new Pe2Lx(*phFile);
                         if (pPe2Lx != NULL)
@@ -113,54 +196,177 @@
                     }
                     else
+                    {
+                        /*
+                         * Starting of PE.EXE enable?
+                         */
                         if (options.fPE == FLAGS_PE_PE || options.fPE == FLAGS_PE_MIXED)
-                        {   /* pe.exe */
+                        {   /*
+                             * pe.exe - need the path!
+                             */
                             kprintf(("ldrOpen: pe.exe - opening\n"));
                             ldrClose(*phFile);
                             rc = ldrOpen(phFile, "pe.exe", param3);  /* path....! problems! */
                             kprintf(("ldrOpen: pe.exe - open returned with rc = %d\n", rc));
+                            free(pszBuffer);
                             return rc;
                         }
+                    }
                 }
-                rc = NO_ERROR;
+                free(pszBuffer);
+                return NO_ERROR;
             }
             else
             {
+                /*
+                 * ELF image?
+                 */
                 if (pach[0] == ELFMAG0 && pach[1] == ELFMAG1 && pach[2] == ELFMAG2 && pach[3] == ELFMAG3)
                 {
-                    /* ELF signature found */
+                    /*
+                     * ELF signature found.
+                     */
                     kprintf(("ldrOpen: ELF executable! - not implemented yet!\n"));
+
+                    /*
+                     * Do nothing more yet. NEED AN ELF LOADER!!!
+                     */
+                    free(pszBuffer);
+                    return NO_ERROR;
                 }
-                else
-                    if (*pach == '#' && pach[1] == '!')
+            }
+
+            /*
+             * Only unreconized files and readerror passes this point!
+             *
+             * * Fileformats with lower priority should reside here. *
+             *
+             */
+
+            /*
+             * If the initial readoperation failed try to read a smaller amount, in case it is a small script...
+             * 4 bytes is a small amount isn't it?
+             */
+            if (rc != NO_ERROR)
+            {
+                kprintf(("ldrOpen: first ldrread failed with rc=%d. tries to read 4 byte.\n", rc));
+                cchRead = 4;
+                if ((rc = ldrRead(*phFile, 0UL, pach, 0UL, cchRead, NULL)) != NO_ERROR)
+                    kprintf(("ldrOpen: second ldrread failed with rc=%d.\n ", rc));
+            }
+
+            /*
+             * Now we'll try again, UNIX styled script?
+             */
+            if (rc == NO_ERROR && *pach == '#' && pach[1] == '!')
+            {
+                /*
+                 * UNIX styled script?
+                 * FIXME! Must be more than 64 bytes long?
+                 *        No options!
+                 *        Firstline < 64 bytes!
+                 */
+                kprintf(("ldrOpen: unix script?\n"));
+
+                cchRead = min(cbFile, 256);
+                rc = ldrRead(*phFile, 0UL, pach, 0UL, cchRead, NULL);
+                if (rc != NO_ERROR)
+                {
+                    char *pszStart = pach+2;
+
+                    /* Make sure we don't read to much... */
+                    pszBuffer[cchRead] = '\0';
+
+                    /*
+                     * Skip blanks
+                     */
+                    pszStart = pszBuffer + 2; /* skips the "#!" stuff. */
+                    while (*pszStart != '\0' && (*pszStart == ' ' || *pszStart == '\t'))
+                        pszStart++;
+
+                    /* anything left on the line? */
+                    if (*pszStart != '\0' && *pszStart != '\r' && *pszStart != '\n')
                     {
-                        /* unix styled script...? Must be more than 64 bytes long? No options. firstline < 64 bytes. */
-                        char *pszStart = pach+2;
-                        char *pszEnd;
-                        kprintf(("ldrOpen: unix script?\n"));
-
-                        achBuffer[sizeof(achBuffer)-1] = '\0'; /* just to make sure we don't read to much... */
-
-                        /* skip blanks */
-                        while (*pszStart != '\0' && (*pszStart == ' ' || *pszStart == '\t'))
-                            pszStart++;
-                        if (*pszStart != '\0' && *pszStart != '\r' && *pszStart != '\n')
-                        {   /* find end-of-word */
-                            pszEnd = pszStart + 1;
-                            while (*pszEnd != '\0' && *pszEnd != '\n' && *pszEnd != '\r'
-                                   && *pszEnd != '\t' && *pszEnd != ' ')
-                                pszEnd++;
-                            if (*pszEnd != '\0')
+                        char *      pszEnd;         /* Pointer to the end of the string(s) when the next step is finished. */
+                        //char *      pszFirstArg;    /* Pointer to the first argument, the one after the interpreter name. */
+                        unsigned    cchToAdd = 1;   /* Chars to add */
+                        int         f = TRUE;       /* flag which tells me if I have just closed the last argument.  */
+                        /*
+                         * find linesize and make parameters ready for copying
+                         */
+                        pszEnd = pszStart;
+                        //pszFirstArg = NULL;
+                        while (*pszEnd != '\0' && *pszEnd != '\r' && *pszEnd != '\n')
+                        {
+                            if (f)
                             {
-                                *pszEnd = '\0';
-                                kprintf(("ldrOpen: unix script - opening %s\n", pszStart));
-                                ldrClose(*phFile);
-                                rc = ldrOpen(phFile, pszStart, param3);
-                                kprintf(("ldrOpen: unix script - open returned with rc = %d\n", rc));
+                                f = FALSE;
+                                //if (pszFirstArg != NULL) pszFirstArg = pszEnd + 1;
+                            }
+                            else if (!f && (*pszEnd == ' ' || *pszEnd == '\t'))
+                            {
+                                 *pszEnd = '\0';
+                                 f = TRUE;
+                            }
+
+                            /* next */
+                            pszEnd++;
+                            cchToAdd++;
+                        }
+                        *pszEnd = '\0';
+
+                        /*
+                         * Find the ExecPgm buffer.
+                         */
+                        pBuffer = QueryBufferPointerFromFilename(pszFilename);
+                        if (pBuffer != NULL)
+                        {
+                            unsigned cchArguments = getArgsLength(pBuffer->achArgs);
+                            kprintf(("ldrOpen: debug1\n"));
+
+                            /*
+                             * Is there enough space in the struct?
+                             */
+                            if (cchArguments + cchToAdd < sizeof(pBuffer->achArgs))
+                            {
+                                kprintf(("ldrOpen: debug2\n"));
+                                /*
+                                 * Open the interpreter.
+                                 */
+                                rc = ldrClose(*phFile);
+                                rc = ldrOpen(phFile, pszStart, param3); /* FIXME, recusion! check that name not equal! Use flags to prevent race? */
+                                if (rc == NO_ERROR)
+                                {
+                                    kprintf(("ldrOpen: debug3\n"));
+                                    /* Make space for the addition arguments. */
+                                    memmove(&pBuffer->achArgs[cchToAdd], &pBuffer->achArgs[0], cchArguments);
+                                    memcpy(&pBuffer->achArgs[0], pszBuffer, cchToAdd);
+                                    kprintf(("ldrOpen: debug4\n"));
+                                }
+                                else
+                                    kprintf(("ldrOpen: failed to open interpreter (%s), rc=%d\n", pszStart, rc));
+                            }
+                            else
+                            {
+                                kprintf(("ldrOpen: Argument buffer too small, %d\n", cchArguments + cchToAdd));
+                                rc = ERROR_BAD_EXE_FORMAT;
                             }
                         }
                         else
-                            kprintf(("ldrOpen: unix script - unexpected end of line/file. (line: %.10s\n", pach));
+                        {
+                            kprintf(("ldrOpen: QueryBufferPointerFromFilename failed.\n"));
+                            rc = ERROR_BAD_EXE_FORMAT; /*?*/
+                        }
                     }
-            }
+                    else
+                    {
+                        kprintf(("ldrOpen: no interpereter on the first line.\n"));
+                        rc = ERROR_BAD_EXE_FORMAT; /*?*/
+                    }
+                }
+                else
+                {
+                    kprintf(("ldrOpen: read of min(cbFile, 256) = %d failed, rc = %d\n", cchRead, rc));
+                }
+            } /* else inn other formats here. */
         }
         else
@@ -169,5 +375,29 @@
             rc = NO_ERROR;
         }
+        free(pszBuffer);
     }
     return rc;
 }
+
+
+/**
+ * Get the lenght of the arguments.
+ * @returns   Lenght in char, includes the two '\0's.
+ * @param     pachArgs  Pointer to the ASCIIZs which makes up the arguments.
+ * @status    completely implemented.
+ * @author    knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
+ */
+static unsigned getArgsLength(const char *pachArgs)
+{
+    unsigned    cch = 1;
+    const char *psz = pachArgs;
+
+    while (*psz != '\0')
+    {
+        register unsigned cch2 = strlen(psz);
+        cch += cch2;
+        psz += cch2 + 1;
+    }
+
+    return cch;
+}
Index: trunk/src/win32k/ldr/mytkExecPgm.asm
===================================================================
--- trunk/src/win32k/ldr/mytkExecPgm.asm	(revision 2826)
+++ trunk/src/win32k/ldr/mytkExecPgm.asm	(revision 2827)
@@ -1,3 +1,3 @@
-; $Id: mytkExecPgm.asm,v 1.2 2000-02-18 19:54:19 bird Exp $
+; $Id: mytkExecPgm.asm,v 1.3 2000-02-19 08:40:31 bird Exp $
 ;
 ; mytkExecPgm - tkExecPgm overload
@@ -17,5 +17,7 @@
 ;   Imported Functions
 ;
+DATA32 SEGMENT
     extrn  g_tkExecPgm:PROC
+DATA32 ENDS
     extrn  AcquireBuffer:PROC
     extrn  ReleaseBuffer:PROC
@@ -54,6 +56,6 @@
 ;   struct Buffer
 ;   {
-;       char szFilename[261]; /* offset 0   */
-;       char szArg[4096-261]; /* offset 261 */
+;       char szFilename[261];  /* offset 0   */
+;       char achArg[1536-261]; /* offset 261 */
 ;   };
 ;
@@ -77,6 +79,18 @@
     push    edi
 
-    ; init local variables
-    mov     [ebp+pBuffer], 0
+IF 0
+;    ; Check if this overloading has anything too say, after all it is using some stack space!
+;    jmp     mytkExecPgm_CalltkExecPgm_X1
+ENDIF
+
+    ; parameter validations
+    mov     ax, ds                      ; pointer to filename
+    cmp     ax, 4
+    jb      mytkExecPgm_CalltkExecPgm_X1
+
+    ; This test is currently disabled. We'll pass on an empty string if the argument pointer is NULL.
+    ; Hopefully an empty string is treated equally to an NULL pointer.
+;    cmp     di, 4
+;    jl      mytkExecPgm_CalltkExecPgm_X1
 
     ; filename length
@@ -86,4 +100,5 @@
     movzx   edi, dx                     ; es:di is now filename address (ds:dx).
     mov     ecx, 0ffffffffh
+    cld
     repne scasb
     not     ecx
@@ -98,18 +113,28 @@
     ;
     ; args length
-    ;
-    pop     edi
-    push    edi
+    ; Note: the arguments are a series of ASCIIZs ended by an empty string (ie. '\0').
+    ;
+    pop     edi
+    push    edi
+    xor     ecx, ecx
+    cmp     di, 4                       ; The argument might me a invalid pointer...
+    jb      mytkExecPgm_CalltkExecPgm_1
     mov     es, di
-    movzx   edi, si                     ; es:di is now args address (di:si), eax is still 0
-    mov     ecx, 0ffffffffh
-    repne scasb
+    movzx   edi, si                     ; es:edi is now args address (di:si), eax is still 0
+    dec     ecx
+    cld
+mytkExecPgm_CalltkExecPgm_loop:         ; loop true all ASCIIZ strings
+    repne scasb                         ; scans forwards until '\0' is read. es:edi is pointing at the char after the '\0'.
+    cmp     byte ptr es:[edi], 0        ; is this char '\0' ? stop looping : loop once more;
+    jnz     mytkExecPgm_CalltkExecPgm_loop
+    dec     ecx                         ; update count - count terminating zero too
     not     ecx
 
+mytkExecPgm_CalltkExecPgm_1:
     mov     [ebp+cchArgs], ecx
     add     ecx, [ebp+cchFilename]      ; filename
     add     ecx, 3 + 260                ;  260 = new argument from a scrip file or something.
                                         ;    3 = two '\0's and a space after added argument.
-    cmp     ecx, 4096                   ; 4096 = Buffersize.  FIXME! Define this!!!
+    cmp     ecx, 1536                   ; 1536 = Buffersize.  FIXME! Define this!!!
     jae     mytkExecPgm_CalltkExecPgm_X1; jmp if argument + file + new file > buffer size
 
@@ -139,5 +164,6 @@
     movzx   esi, dx                     ; ds:si  Filename pointer (input ds:dx)
     mov     ecx, [ebp+cchFilename]
-    repnz movsb
+    cld
+    rep movsb
 
     ;
@@ -149,13 +175,22 @@
     push    edi
     push    esi
+    add     eax, 261                    ; we'll use eax in the branch
+    cmp     di, 4
+    jb      mytkExecPgm_CalltkExecPgm_2
+    and     esi, 00000ffffh             ; remove high part of the register
     mov     ds, di                      ; ds:si -> arguments
-    mov     edi, eax
-    add     edi, 261                    ; es:di -> pBuffer + 261
+    mov     edi, eax                    ; es:di -> pBuffer + 261
     mov     ecx, [ebp+cchArgs]
-    repnz movsb
+    cld
+    rep movsb
+    jmp     mytkExecPgm_CalltkExecPgm_3
+
+mytkExecPgm_CalltkExecPgm_2:
+    mov     byte ptr es:[eax], 0        ; Terminate the empty string!
 
     ;
     ; Set Pointers, pszFilename and pszArguments
     ;
+mytkExecPgm_CalltkExecPgm_3:
     mov     ax, seg FLAT:DATA32
     mov     ds, ax
@@ -197,5 +232,6 @@
     ; Call g_tkExecPgm
     ;
-    call far ptr FLAT:g_tkExecPgm;WARNING far call!!!
+    push    cs
+    call    near ptr FLAT:g_tkExecPgm
     pushfd
 
@@ -235,9 +271,18 @@
 
 mytkExecPgm_CalltkExecPgm:
-    call    far ptr FLAT:g_tkExecPgm
+    call    far ptr FLAT:g_tkExecPgmStub
     leave
     retf
 mytkExecPgm ENDP
 
+
+;;
+; Stub which jumps to g_tkExecPgmStub.
+; (This way I will hopefully get the right selector.)
+g_tkExecPgmStub PROC FAR
+    jmp     near ptr FLAT:g_tkExecPgm
+g_tkExecPgmStub ENDP
+
+
 CODE32 ENDS
 END
Index: trunk/src/win32k/misc/asmutils.asm
===================================================================
--- trunk/src/win32k/misc/asmutils.asm	(revision 2826)
+++ trunk/src/win32k/misc/asmutils.asm	(revision 2827)
@@ -1,3 +1,3 @@
-; $Id: asmutils.asm,v 1.3 1999-10-27 02:02:59 bird Exp $
+; $Id: asmutils.asm,v 1.4 2000-02-19 08:40:31 bird Exp $
 ;
 ; asmutils - assembly utility functions
@@ -24,6 +24,6 @@
     public GetSS
     public Int3
-    public _memrevmov@12
-    public _memmov@12
+;    public _memrevmov@12
+;    public _memmov@12
 ;    public DisableInterrupts
 ;    public EnableInterrupts
@@ -94,5 +94,5 @@
 ;EnableInterrupts ENDP
 
-
+if 0
 ;void __stdcall memrevmov(void *pTo, void* pFrom, unsigned int Len);
 pTo     EQU dword ptr [ebp+08]
@@ -193,5 +193,5 @@
     jmp memmov_end
 _memmov@12 ENDP
-
+endif
 
 CODE32 ends
Index: trunk/src/win32k/misc/buffer.asm
===================================================================
--- trunk/src/win32k/misc/buffer.asm	(revision 2826)
+++ trunk/src/win32k/misc/buffer.asm	(revision 2827)
@@ -1,3 +1,3 @@
-; $Id: buffer.asm,v 1.2 2000-02-18 19:27:31 bird Exp $
+; $Id: buffer.asm,v 1.3 2000-02-19 08:40:31 bird Exp $
 ;
 ; Simple resident buffer for use when overloading tkExecPgm.
@@ -8,4 +8,11 @@
 ;
     .486p
+
+
+;
+;   Defined Constants And Macros
+;
+NBR_BUFFERS     EQU 20
+BUFFER_SIZE     EQU 1536
 
 ;
@@ -20,5 +27,11 @@
     public ReleaseBuffer
     public QueryBufferSegmentOffset
-;    public cbBuffer
+    public QueryBufferPointerFromFilename
+
+
+;
+;   Imported Functions
+;
+    extrn stricmp:PROC
 
 
@@ -27,12 +40,11 @@
 ;
 DATA16 SEGMENT
-;DATA32 SEGMENT
-achBuffer   db 4096 dup(?)
+aachBuffer  db BUFFER_SIZE*NBR_BUFFERS dup(?) ; The buffer
 DATA16 ENDS
-;DATA32 ENDS
-
-;DATA16 SEGMENT
+
 DATA32 SEGMENT
-fBuffer     db 0            ;Access "semaphore"
+afBuffer    db NBR_BUFFERS dup(0)       ; Access "semaphore"
+                                        ; 0 - not in use
+                                        ; 1 - in use
 DATA32 ENDS
 
@@ -46,5 +58,5 @@
 ; @returns   Pointer to buffer
 ; @uses      eax
-; @sketch    if fBuffer == 0 then
+; @sketch    if AfBuffer == 0 then
 ;               ok!
 ;               fBuffer <- 1
@@ -59,19 +71,38 @@
 AcquireBuffer PROC NEAR
     push    ds
-    ;mov     ax,
-;    push    FLAT
-    pop     ds
-    ;mov     ds, ax
+    push    ecx
+    push    edx
+
+    ; make ds flat
+    mov     ax, seg FLAT:DATA32
+    mov     ds, ax
     ASSUME  DS:FLAT
-    mov     al, 0
-    mov     ah, 1
-    lock cmpxchg fBuffer, ah
-    jnz     AcquireBuffer_nok
-AcquireBuffer_ok:
-    mov     eax, offset achBuffer
-    pop     ds
-    ret
+
+    ; loop thru all buffers and try reserve one
+    mov     ah, 1                       ; afBuffer[ecx] is set to this value (if equal to al)
+    mov     ecx, NBR_BUFFERS            ; interations.
+    mov     edx, offset FLAT:afBuffer
+    add     edx, ecx
+AcquireBuffer_loop:
+    dec     edx
+    mov     al, 0                       ; afBuffer[ecx] should have this value
+    lock cmpxchg [edx], ah
+    je      AcquireBuffer_ok
+    loop    AcquireBuffer_loop
+
+    ; failure
 AcquireBuffer_nok:
     xor     eax,eax
+    jmp     AcquireBuffer_ret
+
+    ;success - calc buffer pointer
+AcquireBuffer_ok:
+    mov     eax, BUFFER_SIZE
+    dec     ecx
+    imul    eax, ecx                    ; ecx has the buffer number
+    add     eax, offset FLAT:aachBuffer
+AcquireBuffer_ret:
+    pop     edx
+    pop     ecx
     pop     ds
     ret
@@ -85,10 +116,4 @@
 ; @uses      eax
 ; @equiv
-; @sketch    if eax == achBuffer then
-;                set fBuffer to 0 if 1.
-;                if fBuffer was not 1 then fail with rc = 87!
-;            else
-;                fail with rc = 87
-;            endif
 ; @status
 ; @author    knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
@@ -97,21 +122,60 @@
     ASSUME  DS:NOTHING
     push    ds
-;    mov     ax, DATA16
-;    mov     ds, ax
-;    push    FLAT
-    pop     ds
+    push    ecx
+    push    edx
+
+    ; make ds flat
+    push    eax
+    mov     ax, seg FLAT:DATA32
+    mov     ds, ax
     ASSUME  DS:FLAT
-    cmp     eax, offset achBuffer
-    jne     ReleaseBuffer_nok
+    pop     eax
+    push    eax
+
+    ; validate input and calc buffer number
+    cmp     eax, offset FLAT:aachBuffer
+    jl      ReleaseBuffer_nok           ; if eax (buffer pointer) is less than the first buffer, then fail.
+    sub     eax, offset FLAT:aachBuffer ; eax <- offset to buffer from aachBuffer
+    xor     edx, edx
+    mov     ecx, BUFFER_SIZE
+    div     ecx                         ; eax <- buffer number, edx <- offset into buffer (should be NULL)
+    or      edx, edx
+    jnz     ReleaseBuffer_nok           ; if offset into buffer not 0 the fail.
+    cmp     eax, NBR_BUFFERS
+    jge     ReleaseBuffer_nok           ; if buffernumber >= number of buffers then fail.
+
+    ; unlock buffer - if locked
+    mov     edx, eax
+    add     edx, offset FLAT:afBuffer   ; ds:edx  points at buffer "semaphore"
     mov     al, 1
     mov     ah, 0
-    lock cmpxchg fBuffer, ah
-    jnz     ReleaseBuffer_nok
+    lock cmpxchg [edx], ah
+    jne     ReleaseBuffer_nok           ; fail if buffer was not locked
+
 ReleaseBuffer_ok:
-    xor     eax, eax
-    pop     ds
-    ret
+    ;swipe out buffer
+    pop     eax
+    push    edi
+    push    es
+    mov     edi, eax
+    mov     ax, ds
+    mov     es, ax
+    ASSUME  es:FLAT
+    xor     eax, eax                    ; ecx is allready BUFFER_SIZE
+    rep     stosb
+    pop     es
+    pop     edi
+
+    ;return successfully
+    jmp     ReleaseBuffer_ret
+
 ReleaseBuffer_nok:
+    ;failure
+    pop     eax
     mov     eax, 87 ;some error
+
+ReleaseBuffer_ret:
+    pop     edx
+    pop     ecx
     pop     ds
     ret
@@ -132,16 +196,20 @@
     ASSUME  DS:NOTHING
     push    ds
-;    mov     ax, DATA16
-;    mov     ds, ax
-;    push    FLAT
-    pop     ds
+
+    ; make ds FLAT
+    push    eax
+    mov     ax, seg FLAT:DATA32
+    mov     ds, ax
     ASSUME  DS:FLAT
-    cmp     eax, offset achBuffer
-    jne     QueryBufferSegmentOffset_nok
-    cmp     fBuffer, 1
-    jne     QueryBufferSegmentOffset_nok
+    pop     eax
+
+    ; validate parameter and calc offset relative to aachBuffer
+    cmp     eax, offset FLAT:aachBuffer
+    jl      QueryBufferSegmentOffset_nok
+    sub     eax, offset FLAT:aachBuffer
+    cmp     eax, NBR_BUFFERS * BUFFER_SIZE
+    jge     QueryBufferSegmentOffset_nok
 
 QueryBufferSegmentOffset_ok:
-    xor     eax, eax
     jmp     far ptr CODE16:GetBufferSegmentOffset16
 QueryBufferSegmentOffset_Back::
@@ -156,16 +224,84 @@
 
 
+;;
+; Special function which checks all used buffers for the string passed in in eax.
+; @cproto    PCHAR _Optlink QueryBufferPointerFromFilename(const char *pszFilename)
+; @returns   Pointer to Buffer. NULL on error/notfound.
+; @param     ds:eax   Pointer to filename. The filename will later be compared to the string at buffer start.
+;                     Currently this parameter is not used, since there is only one buffer.
+; @uses      eax.
+; @sketch
+; @status    completely implemented
+; @author    knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
+; @remark    assumes ds flat on call.
+QueryBufferPointerFromFilename PROC NEAR
+    ASSUME  cs:CODE32, ds:FLAT
+    push    ecx
+    push    edx
+    push    ebx
+
+    ; loop thru all buffers until found or non left
+    mov     ecx, NBR_BUFFERS
+    mov     edx, BUFFER_SIZE
+    imul    edx, ecx                    ; edx <- sizeof(aachBuffer)
+    add     edx, offset FLAT:aachBuffer ; edx points at the first byte after the buffers.
+    mov     ebx, offset FLAT:afBuffer
+    add     ebx, ecx                    ; edx points at the first byte after the "semaphore" array (afBuffer).
+QueryBufferPointerFromFilename_loop:
+    sub     edx, BUFFER_SIZE            ; edx points at the buffer being concidered.
+    dec     ebx                         ; ebx points at the "semaphore" for the buffer being concidered.
+    cmp     byte ptr [edx], 1           ; Is buffer in use?
+    jne     QueryBufferPointerFromFilename_next
+
+    ; buffer is active - lets compare
+    push    eax
+    push    ecx
+    push    edx
+    call    stricmp
+    pop     edx
+    pop     ecx
+    or      eax, eax
+    jz      QueryBufferPointerFromFilename_found
+    pop     eax
+
+QueryBufferPointerFromFilename_next:
+    loop QueryBufferPointerFromFilename_loop
+    ; when we exit this loop we have failed!
+
+QueryBufferPointerFromFilename_nok:
+    ; The buffer was not found, return NULL pointer.
+    xor     eax, eax
+    pop     edx
+    pop     ecx
+    ret
+
+QueryBufferPointerFromFilename_found:
+    ; The buffer was found, return the pointer to it!
+    pop     eax
+    mov     eax, edx
+    pop     edx
+    pop     ecx
+    ret
+
+QueryBufferPointerFromFilename ENDP
+
+
+
+
 CODE32 ENDS
 
+
 CODE16 SEGMENT
-
-;;
-; Gets the segment(->es) and offset(->ax) of the achBuffer.
+;;
+; Gets the segment(->es) and offset(+ax -> ax) of the achBuffer.
+; @param    ax  offset to buffer relative to aachBuffer
 ; Jumps back to GetBufferOffset32
 GetBufferSegmentOffset16:
     ASSUME CS:CODE16, DS:NOTHING
-    mov     ax, seg achBuffer
+    push    ax
+    mov     ax, seg aachBuffer
     mov     es, ax
-    mov     ax, offset achBuffer
+    pop     ax
+    add     ax, offset aachBuffer
     jmp     far ptr FLAT:QueryBufferSegmentOffset_Back
 CODE16 ENDS
Index: trunk/src/win32k/win32k.def
===================================================================
--- trunk/src/win32k/win32k.def	(revision 2826)
+++ trunk/src/win32k/win32k.def	(revision 2827)
@@ -17,4 +17,5 @@
     CODE32          class 'CODE'
     CALLTAB         class 'DATA'
+;    CALLTAB         class 'CODE' WRITABLE
     DATA32          class 'DATA'
     c_common        class 'DATA'
