Ignore:
Timestamp:
Feb 19, 2000, 9:40:31 AM (26 years ago)
Author:
bird
Message:

g_tkExecPgm is overloaded, so we may change paramerters for a process later.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/win32k/ldr/myldrOpen.cpp

    r2501 r2827  
    1 /* $Id: myldrOpen.cpp,v 1.6 2000-01-22 18:21:02 bird Exp $
     1/* $Id: myldrOpen.cpp,v 1.7 2000-02-19 08:40:30 bird Exp $
    22 *
    33 * myldrOpen - ldrOpen.
     
    1616#define INCL_NOPMAPI
    1717
     18#define INCL_OS2KRNL_IO
     19
    1820/*******************************************************************************
    1921*   Header Files                                                               *
     
    2123#include <os2.h>
    2224
     25#include "rmalloc.h"
    2326#include "malloc.h"
    2427#include <memory.h>
    2528#include <stdlib.h>
     29#include <string.h>
    2630
    2731#include "log.h"
     
    2933#include <exe386.h>
    3034#include "OS2Krnl.h"
     35#include "dev32.h"
    3136#include "ModuleBase.h"
    3237#include "pe2lx.h"
     
    3641#include "ldrCalls.h"
    3742#include "options.h"
     43#include "myExecPgm.h"
     44
     45
     46/*******************************************************************************
     47*   Internal Functions                                                         *
     48*******************************************************************************/
     49static unsigned getArgsLength(const char *pachArgs);
    3850
    3951
     
    4961    ULONG rc;
    5062
     63    /*
     64     * Try open the file (thats why this function is called anyway)
     65     */
    5166    rc = ldrOpen(phFile, pszFilename, param3);
    5267
     68    /* log sucesses */
    5369    if (rc == NO_ERROR)
    5470        kprintf(("ldrOpen:  phFile=%#.4x, flags=%#.8x, pszFn=%s\n", *phFile, param3, pszFilename));
    5571
     72    /*
     73     * Are we to intercept the loading?
     74     * - Only if open were succesful and one of the loaders are enabled.
     75     */
    5676    if (rc == NO_ERROR && (options.fElf || options.fPE != FLAGS_PE_NOT || options.fScript))
    5777    {
    58         static char achBuffer[sizeof(IMAGE_DOS_HEADER)];
    59         PIMAGE_DOS_HEADER   pMzHdr = (PIMAGE_DOS_HEADER)&achBuffer[0];
    60         PIMAGE_NT_HEADERS   pNtHdrs = (PIMAGE_NT_HEADERS)&achBuffer[0]; /* oops. Last accessible field is OptionalHeader.FileAlignment */
    61         char               *pach = &achBuffer[0];
    62 
    63         /**
     78        char               *pszBuffer = (char*)rmalloc(640);        /* Read buffer. */
     79        PIMAGE_DOS_HEADER   pMzHdr = (PIMAGE_DOS_HEADER)pszBuffer;  /* Pointer to the buffer as it were a dosheader. */
     80        PIMAGE_NT_HEADERS   pNtHdrs = (PIMAGE_NT_HEADERS)pszBuffer; /* Pointer to the buffer as if it were an NT header. */
     81        char               *pach = pszBuffer;                       /* Finally an pointer to the buffer as if it were chars.. (which it is!) */
     82        PEXECPGMBUFFER      pBuffer;                                /* Pointer to a buffer containing the programname and arguments. */
     83                                                                    /* For scripts and PE.EXE this has to be changed to have correct */
     84                                                                    /* parameters sendt in to the program. */
     85        unsigned            cchRead = sizeof(IMAGE_DOS_HEADER);     /* Amount of the buffer which contains valid data. */
     86        unsigned            cbFile;                                 /* Filesize (0xffffffff if call to SftFileSize failed - should _never_ happen though)  */
     87
     88        /*
     89         * Verify that rmalloc completed successfully.
     90         */
     91        if (pszBuffer == NULL)
     92        {
     93            kprintf(("ldrOpen: rmalloc(1024) failed\n"));
     94            return NO_ERROR;
     95        }
     96
     97        /*
     98         * Try get the filesize
     99         */
     100        /*
     101        rc = SftFileSize(*phFile, (PULONG)SSToDS(&cbFile));
     102        if (rc != NO_ERROR)
     103        {
     104            kprintf(("ldrOpen: SftFileSize failed with rc=%d\n", rc));
     105        */
     106            cbFile = (unsigned)~0;
     107        /*
     108        } */
     109
     110        /*
    64111         * See if this is an recognizable module format.
    65112         * This costs up to two disk reads!
    66113         */
    67         rc = ldrRead(*phFile, 0UL, pMzHdr, 0UL, sizeof(IMAGE_DOS_HEADER), NULL);
     114        rc = ldrRead(*phFile, 0UL, pMzHdr, 0UL, cchRead, NULL);
    68115        if (rc == NO_ERROR)
    69116        {
     117            /*
     118             * PE header?
     119             *  - If DOS Magic is found AND a valid e_lfanew (offset of NE/LX/LE/PE header) is found
     120             *  - OR if PE siganture is found.
     121             */
    70122            if ((pMzHdr->e_magic == IMAGE_DOS_SIGNATURE &&
    71123                 pMzHdr->e_lfanew > sizeof(IMAGE_DOS_HEADER) && pMzHdr->e_lfanew < 0x04000000UL) /* Larger than 64 bytes and less that 64MB. */
    72124                || *(PULONG)pach == IMAGE_NT_SIGNATURE)
    73             {   /* MZ or PE header found */
     125            {   /*
     126                 * MZ or PE header found
     127                 */
     128
     129                /* if PE loading is diable return to the caller */
    74130                if (options.fPE == FLAGS_PE_NOT)
     131                {
     132                    free(pszBuffer);
    75133                    return NO_ERROR;
    76 
     134                }
     135
     136                /*
     137                 * Read the PE header if it isn't what we allready have!
     138                 */
     139                cchRead = sizeof(IMAGE_NT_HEADERS);
    77140                if (*(PULONG)pach != IMAGE_NT_SIGNATURE)
    78                     rc = ldrRead(*phFile, pMzHdr->e_lfanew, pach, 0UL, sizeof(achBuffer), NULL);
    79 
     141                    rc = ldrRead(*phFile, pMzHdr->e_lfanew, pach, 0UL, cchRead, NULL);
     142                else
     143                    rc = ldrRead(*phFile, 0UL, pach, 0UL, cchRead, NULL);
     144
     145                /*
     146                 * If successfully read, and a PE signature is present the continue and try load it!
     147                 * Else don't do anything, simply return NO_ERROR to the caller. (probably NE or LX exec)
     148                 */
    80149                if (rc == NO_ERROR && *(PULONG)pach == IMAGE_NT_SIGNATURE)
    81                 {   /* PE signature found */
     150                {   /*
     151                     * PE signature found.
     152                     */
    82153                    kprintf(("ldrOpen: PE executable...\n"));
     154
     155                    /*
     156                     * PE2LX?
     157                     *  - When PE2LX flag is set
     158                     *  - OR when the MIXED flag is set and the image is with the first 64MB of memory.
     159                     */
    83160                    if (options.fPE == FLAGS_PE_PE2LX
    84161                        || (options.fPE == FLAGS_PE_MIXED
     
    88165                            )
    89166                        )
    90                     {   /* pe2lx */
     167                    {   /*
     168                         * Pe2Lx (Ring0 of course)
     169                         * - Create a Pe2Lx class,
     170                         * - initiate it
     171                         * - Add the module to the module tree so we may find it later...
     172                         * - Set the handle state to 'our'.
     173                         */
    91174                        Pe2Lx * pPe2Lx = new Pe2Lx(*phFile);
    92175                        if (pPe2Lx != NULL)
     
    113196                    }
    114197                    else
     198                    {
     199                        /*
     200                         * Starting of PE.EXE enable?
     201                         */
    115202                        if (options.fPE == FLAGS_PE_PE || options.fPE == FLAGS_PE_MIXED)
    116                         {   /* pe.exe */
     203                        {   /*
     204                             * pe.exe - need the path!
     205                             */
    117206                            kprintf(("ldrOpen: pe.exe - opening\n"));
    118207                            ldrClose(*phFile);
    119208                            rc = ldrOpen(phFile, "pe.exe", param3);  /* path....! problems! */
    120209                            kprintf(("ldrOpen: pe.exe - open returned with rc = %d\n", rc));
     210                            free(pszBuffer);
    121211                            return rc;
    122212                        }
     213                    }
    123214                }
    124                 rc = NO_ERROR;
     215                free(pszBuffer);
     216                return NO_ERROR;
    125217            }
    126218            else
    127219            {
     220                /*
     221                 * ELF image?
     222                 */
    128223                if (pach[0] == ELFMAG0 && pach[1] == ELFMAG1 && pach[2] == ELFMAG2 && pach[3] == ELFMAG3)
    129224                {
    130                     /* ELF signature found */
     225                    /*
     226                     * ELF signature found.
     227                     */
    131228                    kprintf(("ldrOpen: ELF executable! - not implemented yet!\n"));
     229
     230                    /*
     231                     * Do nothing more yet. NEED AN ELF LOADER!!!
     232                     */
     233                    free(pszBuffer);
     234                    return NO_ERROR;
    132235                }
    133                 else
    134                     if (*pach == '#' && pach[1] == '!')
     236            }
     237
     238            /*
     239             * Only unreconized files and readerror passes this point!
     240             *
     241             * * Fileformats with lower priority should reside here. *
     242             *
     243             */
     244
     245            /*
     246             * If the initial readoperation failed try to read a smaller amount, in case it is a small script...
     247             * 4 bytes is a small amount isn't it?
     248             */
     249            if (rc != NO_ERROR)
     250            {
     251                kprintf(("ldrOpen: first ldrread failed with rc=%d. tries to read 4 byte.\n", rc));
     252                cchRead = 4;
     253                if ((rc = ldrRead(*phFile, 0UL, pach, 0UL, cchRead, NULL)) != NO_ERROR)
     254                    kprintf(("ldrOpen: second ldrread failed with rc=%d.\n ", rc));
     255            }
     256
     257            /*
     258             * Now we'll try again, UNIX styled script?
     259             */
     260            if (rc == NO_ERROR && *pach == '#' && pach[1] == '!')
     261            {
     262                /*
     263                 * UNIX styled script?
     264                 * FIXME! Must be more than 64 bytes long?
     265                 *        No options!
     266                 *        Firstline < 64 bytes!
     267                 */
     268                kprintf(("ldrOpen: unix script?\n"));
     269
     270                cchRead = min(cbFile, 256);
     271                rc = ldrRead(*phFile, 0UL, pach, 0UL, cchRead, NULL);
     272                if (rc != NO_ERROR)
     273                {
     274                    char *pszStart = pach+2;
     275
     276                    /* Make sure we don't read to much... */
     277                    pszBuffer[cchRead] = '\0';
     278
     279                    /*
     280                     * Skip blanks
     281                     */
     282                    pszStart = pszBuffer + 2; /* skips the "#!" stuff. */
     283                    while (*pszStart != '\0' && (*pszStart == ' ' || *pszStart == '\t'))
     284                        pszStart++;
     285
     286                    /* anything left on the line? */
     287                    if (*pszStart != '\0' && *pszStart != '\r' && *pszStart != '\n')
    135288                    {
    136                         /* unix styled script...? Must be more than 64 bytes long? No options. firstline < 64 bytes. */
    137                         char *pszStart = pach+2;
    138                         char *pszEnd;
    139                         kprintf(("ldrOpen: unix script?\n"));
    140 
    141                         achBuffer[sizeof(achBuffer)-1] = '\0'; /* just to make sure we don't read to much... */
    142 
    143                         /* skip blanks */
    144                         while (*pszStart != '\0' && (*pszStart == ' ' || *pszStart == '\t'))
    145                             pszStart++;
    146                         if (*pszStart != '\0' && *pszStart != '\r' && *pszStart != '\n')
    147                         {   /* find end-of-word */
    148                             pszEnd = pszStart + 1;
    149                             while (*pszEnd != '\0' && *pszEnd != '\n' && *pszEnd != '\r'
    150                                    && *pszEnd != '\t' && *pszEnd != ' ')
    151                                 pszEnd++;
    152                             if (*pszEnd != '\0')
     289                        char *      pszEnd;         /* Pointer to the end of the string(s) when the next step is finished. */
     290                        //char *      pszFirstArg;    /* Pointer to the first argument, the one after the interpreter name. */
     291                        unsigned    cchToAdd = 1;   /* Chars to add */
     292                        int         f = TRUE;       /* flag which tells me if I have just closed the last argument.  */
     293                        /*
     294                         * find linesize and make parameters ready for copying
     295                         */
     296                        pszEnd = pszStart;
     297                        //pszFirstArg = NULL;
     298                        while (*pszEnd != '\0' && *pszEnd != '\r' && *pszEnd != '\n')
     299                        {
     300                            if (f)
    153301                            {
    154                                 *pszEnd = '\0';
    155                                 kprintf(("ldrOpen: unix script - opening %s\n", pszStart));
    156                                 ldrClose(*phFile);
    157                                 rc = ldrOpen(phFile, pszStart, param3);
    158                                 kprintf(("ldrOpen: unix script - open returned with rc = %d\n", rc));
     302                                f = FALSE;
     303                                //if (pszFirstArg != NULL) pszFirstArg = pszEnd + 1;
     304                            }
     305                            else if (!f && (*pszEnd == ' ' || *pszEnd == '\t'))
     306                            {
     307                                 *pszEnd = '\0';
     308                                 f = TRUE;
     309                            }
     310
     311                            /* next */
     312                            pszEnd++;
     313                            cchToAdd++;
     314                        }
     315                        *pszEnd = '\0';
     316
     317                        /*
     318                         * Find the ExecPgm buffer.
     319                         */
     320                        pBuffer = QueryBufferPointerFromFilename(pszFilename);
     321                        if (pBuffer != NULL)
     322                        {
     323                            unsigned cchArguments = getArgsLength(pBuffer->achArgs);
     324                            kprintf(("ldrOpen: debug1\n"));
     325
     326                            /*
     327                             * Is there enough space in the struct?
     328                             */
     329                            if (cchArguments + cchToAdd < sizeof(pBuffer->achArgs))
     330                            {
     331                                kprintf(("ldrOpen: debug2\n"));
     332                                /*
     333                                 * Open the interpreter.
     334                                 */
     335                                rc = ldrClose(*phFile);
     336                                rc = ldrOpen(phFile, pszStart, param3); /* FIXME, recusion! check that name not equal! Use flags to prevent race? */
     337                                if (rc == NO_ERROR)
     338                                {
     339                                    kprintf(("ldrOpen: debug3\n"));
     340                                    /* Make space for the addition arguments. */
     341                                    memmove(&pBuffer->achArgs[cchToAdd], &pBuffer->achArgs[0], cchArguments);
     342                                    memcpy(&pBuffer->achArgs[0], pszBuffer, cchToAdd);
     343                                    kprintf(("ldrOpen: debug4\n"));
     344                                }
     345                                else
     346                                    kprintf(("ldrOpen: failed to open interpreter (%s), rc=%d\n", pszStart, rc));
     347                            }
     348                            else
     349                            {
     350                                kprintf(("ldrOpen: Argument buffer too small, %d\n", cchArguments + cchToAdd));
     351                                rc = ERROR_BAD_EXE_FORMAT;
    159352                            }
    160353                        }
    161354                        else
    162                             kprintf(("ldrOpen: unix script - unexpected end of line/file. (line: %.10s\n", pach));
     355                        {
     356                            kprintf(("ldrOpen: QueryBufferPointerFromFilename failed.\n"));
     357                            rc = ERROR_BAD_EXE_FORMAT; /*?*/
     358                        }
    163359                    }
    164             }
     360                    else
     361                    {
     362                        kprintf(("ldrOpen: no interpereter on the first line.\n"));
     363                        rc = ERROR_BAD_EXE_FORMAT; /*?*/
     364                    }
     365                }
     366                else
     367                {
     368                    kprintf(("ldrOpen: read of min(cbFile, 256) = %d failed, rc = %d\n", cchRead, rc));
     369                }
     370            } /* else inn other formats here. */
    165371        }
    166372        else
     
    169375            rc = NO_ERROR;
    170376        }
     377        free(pszBuffer);
    171378    }
    172379    return rc;
    173380}
     381
     382
     383/**
     384 * Get the lenght of the arguments.
     385 * @returns   Lenght in char, includes the two '\0's.
     386 * @param     pachArgs  Pointer to the ASCIIZs which makes up the arguments.
     387 * @status    completely implemented.
     388 * @author    knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
     389 */
     390static unsigned getArgsLength(const char *pachArgs)
     391{
     392    unsigned    cch = 1;
     393    const char *psz = pachArgs;
     394
     395    while (*psz != '\0')
     396    {
     397        register unsigned cch2 = strlen(psz);
     398        cch += cch2;
     399        psz += cch2 + 1;
     400    }
     401
     402    return cch;
     403}
Note: See TracChangeset for help on using the changeset viewer.