Changeset 4164 for trunk/src/win32k/ldr


Ignore:
Timestamp:
Sep 2, 2000, 11:08:23 PM (25 years ago)
Author:
bird
Message:

Merged in the Grace branch. New Win32k!

Location:
trunk/src/win32k/ldr
Files:
1 added
5 deleted
10 edited

Legend:

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

    r2926 r4164  
    1 /* $Id: ModuleBase.cpp,v 1.3 2000-02-27 02:17:06 bird Exp $
     1/* $Id: ModuleBase.cpp,v 1.4 2000-09-02 21:08:06 bird Exp $
    22 *
    33 * ModuleBase - Implementetation.
     
    1212*   Defined Constants And Macros                                               *
    1313*******************************************************************************/
    14 #define INCL_DOSERRORS                      /* DOS Error codes. */
     14#define INCL_DOSERRORS                  /* DOS Error codes. */
    1515#ifdef RING0
    16     #define INCL_NOAPI                      /* RING0: No apis. */
     16    #define INCL_NOAPI                  /* RING0: No apis. */
    1717#else /*RING3*/
    18     #define INCL_DOSFILEMGR                 /* RING3: DOS File api. */
     18    #define INCL_DOSFILEMGR             /* RING3: DOS File api. */
    1919#endif
    2020
     
    2323*   Header Files                                                               *
    2424*******************************************************************************/
    25 #include <os2.h>                            /* OS/2 header file. */
    26 
    27 #include "malloc.h"                         /* win32k malloc. Not C library! */
    28 
    29 #include <string.h>                         /* C library string.h. */
    30 #include <stdarg.h>                         /* C library stdarg.h. */
    31 
    32 #include "vprintf.h"                        /* win32k printf and vprintf. Not C library! */
    33 #include "dev32.h"                          /* 32-Bit part of the device driver. (SSToDS) */
    34 #include "OS2Krnl.h"                        /* kernel structs.  (SFN) */
    35 #include "modulebase.h"                     /* ModuleBase class definitions, ++. */
     25#include <os2.h>                        /* OS/2 header file. */
     26
     27#include "devSegDf.h"                   /* Win32k segment definitions. */
     28#include "malloc.h"                     /* Win32k malloc. Not C library! */
     29
     30#include <string.h>                     /* C library string.h. */
     31#include <stdarg.h>                     /* C library stdarg.h. */
     32
     33#include "vprintf.h"                    /* win32k printf and vprintf. Not C library! */
     34#include "dev32.h"                      /* 32-Bit part of the device driver. (SSToDS) */
     35#include "OS2Krnl.h"                    /* kernel structs.  (SFN) */
     36#include "ldrCalls.h"                   /* ldrOpenPath and ldrlv_t. */
     37#include "modulebase.h"                 /* ModuleBase class definitions, ++. */
    3638
    3739
     
    159161}
    160162
     163
     164/**
     165 * openPath - opens file eventually searching loader specific paths.
     166 *
     167 * This base implementation simply calls ldrOpenPath.
     168 * This method is only called for DLLs. DosLoadModule and Imports.
     169 *
     170 * @returns   OS2 return code.
     171 *            pLdrLv->lv_sfn  is set to filename handle.
     172 * @param     pachFilename  Pointer to filename. Not zero terminated!
     173 * @param     cchFilename   Filename length.
     174 * @param     pLdrLv        Loader local variables? (Struct from KERNEL.SDF)
     175 * @param     pful          Pointer to flags which are passed on to ldrOpen.
     176 * @sketch
     177 * This is roughly what the original ldrOpenPath does:
     178 *      if !CLASS_GLOBAL or miniifs then
     179 *          ldrOpen(pachModName)
     180 *      else
     181 *          loop until no more libpath elements
     182 *              get next libpath element and add it to the modname.
     183 *              try open the modname
     184 *              if successfull then break the loop.
     185 *          endloop
     186 *      endif
     187 */
     188ULONG  ModuleBase::openPath(PCHAR pachFilename, USHORT cchFilename, ldrlv_t *pLdrLv, PULONG pful) /* (ldrOpenPath) */
     189{
     190    #ifdef RING0
     191    printf("ModuleBase::openPath:\n");
     192    return ldrOpenPath(pachFilename, cchFilename, pLdrLv, pful);
     193    #else
     194    NOREF(pachFilename);
     195    NOREF(cchFilename);
     196    NOREF(pLdrLv);
     197    NOREF(pful);
     198    return ERROR_NOT_SUPPORTED;
     199    #endif
     200}
    161201
    162202
     
    232272
    233273/**
     274 * Gets the fullpath filename.
     275 * @returns     Const ("Readonly") pointer to the filename.
     276 * @author      knut st. osmundsen (knut.stange.osmundsen@mynd.no)
     277 */
     278PCSZ ModuleBase::getFilename()
     279{
     280    return pszFilename;
     281}
     282
     283
     284/**
     285 * Gets the modulename.
     286 * @returns     Const ("Readonly") pointer to the module name.
     287 * @author      knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
     288 * @remark      Modulename is filename without path and extention.
     289 */
     290PCSZ ModuleBase::getModuleName()
     291{
     292    return pszModuleName;
     293}
     294
     295
     296/**
    234297 * Output function for Modules.
    235298 * @param     pszFormat    Pointer to format string.
     
    273336        rc = DosRead(hFile, pvBuffer, cbToRead, &cbRead);
    274337    else
    275         printErr(("DosSetFilePtr(hfile, %#8x(%d),..) failed with rc = %d.",
     338        printErr(("DosSetFilePtr(hfile, %#8x(%d),..) failed with rc = %d.\n",
    276339                  ulOffset, ulOffset, rc));
    277340
  • trunk/src/win32k/ldr/calltab.asm

    r3411 r4164  
    1 ; $Id: calltab.asm,v 1.12 2000-04-17 01:56:49 bird Exp $
    2 ;
    3 ; callTab - Call back again table - table with entry for each function which is overrided.
    4 ;           It holds the part of the prolog which was replaced by a jmp instruction.
    5 ;
    6 ; Copyright (c) 1998-1999 knut st. osmundsen
     1; $Id: calltab.asm,v 1.13 2000-09-02 21:08:06 bird Exp $
     2;
     3; callTab - Call back again table - table with entry for each function or
     4;           variable which is overrided.
     5;           It holds the part of the prolog which was replaced by the jmp
     6;           instruction (overridden functions).
     7;
     8; Copyright (c) 1998-2000 knut st. osmundsen
    79;
    810; Project Odin Software License can be found in LICENSE.TXT
     
    3537    public _VMGetOwner@8
    3638    public _g_tkExecPgm
     39    public _tkStartProcess
    3740    public _f_FuStrLenZ
    3841    public _f_FuBuff
    3942
     43    public _VMObjHandleInfo@12
     44    public _ldrASMpMTEFromHandle@4
     45    public _ldrOpenPath@16
     46    public _LDRClearSem@0
     47    public _ldrFindModule@16
     48    public _KSEMRequestMutex@8
     49    public _KSEMReleaseMutex@4
     50    public _KSEMQueryMutex@8
     51    public _KSEMInit@12
     52
     53    public pLDRSem
     54    public LDRSem_offObject
     55    public _fpLDRSem
     56    public LDRSem_sel
     57
     58    public pLDRLibPath
     59    public LDRLibPath_offObject
     60    public _fpLDRLibPath
     61    public LDRLibPath_sel
     62
     63    public _TKSuBuff@16
     64    public _TKFuBuff@16
     65    public _TKFuBufLen@20
     66    public _ldrValidateMteHandle@4
     67
     68    public ppTCBCur
     69    public pTCBCur_offObject
     70    public _fppTCBCur
     71    public pTCBCur_sel
     72
     73    public ppPTDACur
     74    public pPTDACur_offObject
     75    public _fppPTDACur
     76    public pPTDACur_sel
     77
     78    public pptda_start
     79    public ptda_start_offObject
     80    public _fpptda_start
     81    public ptda_start_sel
     82
     83    public pptda_environ
     84    public ptda_environ_offObject
     85    public _fpptda_environ
     86    public ptda_environ_sel
     87
     88    public pptda_ptdasem
     89    public ptda_ptdasem_offObject
     90    public _fpptda_ptdasem
     91    public ptda_ptdasem_sel
     92
     93    public pptda_module
     94    public ptda_module_offObject
     95    public _fpptda_module
     96    public ptda_module_sel
     97
     98    public pptda_pBeginLIBPATH
     99    public ptda_pBeginLIBPATH_offObject
     100    public _fpptda_pBeginLIBPATH
     101    public pptda_pBeginLIBPATH_sel
     102
     103    public pldrpFileNameBuf
     104    public pldrpFileNameBuf_offObject
     105    public _fpldrpFileNameBuf
     106    public pldrpFileNameBuf_sel
     107
     108    public SecPathFromSFN
     109
    40110
    41111;
     
    47117
    48118CALLTAB segment
    49     assume cs:CALLTAB, ds:flat, ss:nothing
     119    ;assume cs:CALLTAB, ds:flat, ss:nothing
     120    assume ds:flat, ss:nothing
    50121;
    51122; callTab is an array of evt. function prologs with a jump to the real function.
     
    56127;
    57128callTab:
     129
     130; 0
    58131_ldrRead@24 PROC NEAR
    59132    db MAXSIZE_PROLOG dup(0cch)
    60133_ldrRead@24 ENDP
    61134
     135; 1
    62136_ldrOpen@12 PROC NEAR
    63137    db MAXSIZE_PROLOG dup(0cch)
    64138_ldrOpen@12 ENDP
    65139
     140; 2
    66141_ldrClose@4 PROC NEAR
    67142    db MAXSIZE_PROLOG dup(0cch)
    68143_ldrClose@4 ENDP
    69144
     145; 3
    70146_LDRQAppType@8 PROC NEAR
    71147    db MAXSIZE_PROLOG dup(0cch)
    72148_LDRQAppType@8 ENDP
    73149
     150; 4
    74151_ldrEnum32bitRelRecs@24 PROC NEAR
    75152    db MAXSIZE_PROLOG dup(0cch)
    76153_ldrEnum32bitRelRecs@24 ENDP
    77154
    78 
     155; 5
    79156_IOSftOpen@20 PROC NEAR
    80157    db MAXSIZE_PROLOG dup(0cch)
    81158_IOSftOpen@20 ENDP
    82159
     160; 6
    83161_IOSftClose@4 PROC NEAR
    84162    db MAXSIZE_PROLOG dup(0cch)
    85163_IOSftClose@4 ENDP
    86164
     165; 7
    87166_IOSftTransPath@4 PROC NEAR
    88167    db MAXSIZE_PROLOG dup(0cch)
    89168_IOSftTransPath@4 ENDP
    90169
     170; 8
    91171_IOSftReadAt@20 PROC NEAR
    92172    db MAXSIZE_PROLOG dup(0cch)
    93173_IOSftReadAt@20 ENDP
    94174
     175; 9
    95176_IOSftWriteAt@20 PROC NEAR
    96177    db MAXSIZE_PROLOG dup(0cch)
    97178_IOSftWriteAt@20 ENDP
    98179
     180; 10
    99181_SftFileSize@8 PROC NEAR
    100182    db MAXSIZE_PROLOG dup(0cch)
    101183_SftFileSize@8 ENDP
    102184
    103 
     185; 11
    104186_VMAllocMem@36 PROC NEAR
    105187    db MAXSIZE_PROLOG dup(0cch)
    106188_VMAllocMem@36 ENDP
    107189
     190; 12
    108191_VMGetOwner@8 PROC NEAR
    109192    db MAXSIZE_PROLOG dup(0cch)
    110193_VMGetOwner@8 ENDP
    111194
     195; 13
    112196_g_tkExecPgm PROC NEAR
    113197    db MAXSIZE_PROLOG dup(0cch)
    114198_g_tkExecPgm ENDP
    115199
    116 
     200; 14
     201_tkStartProcess PROC NEAR
     202    db MAXSIZE_PROLOG dup(0cch)
     203_tkStartProcess ENDP
     204
     205; 15
    117206_f_FuStrLenZ PROC FAR
    118207    db MAXSIZE_PROLOG dup(0cch)
    119208_f_FuStrLenZ ENDP
    120209
     210; 16
    121211_f_FuStrLen PROC FAR
    122212    db MAXSIZE_PROLOG dup(0cch)
    123213_f_FuStrLen ENDP
    124214
     215; 17
    125216_f_FuBuff PROC FAR
    126217    db MAXSIZE_PROLOG dup(0cch)
    127218_f_FuBuff ENDP
    128219
     220; 18
    129221_VMObjHandleInfo@12 PROC NEAR
    130222    db MAXSIZE_PROLOG dup(0cch)
    131223_VMObjHandleInfo@12 ENDP
    132224
     225; 19
     226_ldrASMpMTEFromHandle@4 PROC NEAR
     227    db MAXSIZE_PROLOG dup(0cch)
     228_ldrASMpMTEFromHandle@4 ENDP
     229
     230; 20
     231_ldrOpenPath@16 PROC NEAR
     232    db MAXSIZE_PROLOG dup(0cch)
     233_ldrOpenPath@16 ENDP
     234
     235; 21
     236_LDRClearSem@0 PROC NEAR
     237    db MAXSIZE_PROLOG dup(0cch)
     238_LDRClearSem@0 ENDP
     239
     240; 22
     241_ldrFindModule@16 PROC NEAR
     242    db MAXSIZE_PROLOG dup(0cch)
     243_ldrFindModule@16 ENDP
     244
     245; 23
     246_KSEMRequestMutex@8 PROC NEAR
     247    db MAXSIZE_PROLOG dup(0cch)
     248_KSEMRequestMutex@8 ENDP
     249
     250; 24
     251_KSEMReleaseMutex@4 PROC NEAR
     252    db MAXSIZE_PROLOG dup(0cch)
     253_KSEMReleaseMutex@4 ENDP
     254
     255; 25
     256_KSEMQueryMutex@8 PROC NEAR
     257    db MAXSIZE_PROLOG dup(0cch)
     258_KSEMQueryMutex@8 ENDP
     259
     260; 26
     261_KSEMInit@12 PROC NEAR
     262    db MAXSIZE_PROLOG dup(0cch)
     263_KSEMInit@12 ENDP
     264
     265; 27
     266pLDRSem          dd  0
     267LDRSem_offObject dd  0
     268_fpLDRSem        dd  0
     269LDRSem_sel       dw  0
     270    db (MAXSIZE_PROLOG - 14) dup(0cch)
     271
     272
     273; 28
     274pLDRLibPath          dd  0
     275LDRLibPath_offObject dd  0
     276_fpLDRLibPath        dd  0
     277LDRLibPath_sel       dw  0
     278    db (MAXSIZE_PROLOG - 14) dup(0cch)
     279
     280; 29
     281_TKSuBuff@16 PROC NEAR
     282    db MAXSIZE_PROLOG dup(0cch)
     283_TKSuBuff@16 ENDP
     284
     285; 30
     286_TKFuBuff@16 PROC NEAR
     287    db MAXSIZE_PROLOG dup(0cch)
     288_TKFuBuff@16 ENDP
     289
     290; 31
     291_TKFuBufLen@20 PROC NEAR
     292    db MAXSIZE_PROLOG dup(0cch)
     293_TKFuBufLen@20 ENDP
     294
     295; 32
     296_ldrValidateMteHandle@4 PROC NEAR
     297    db MAXSIZE_PROLOG dup(0cch)
     298_ldrValidateMteHandle@4 ENDP
     299
     300; 33
     301ppTCBCur           dd  0
     302pTCBCur_offObject  dd  0
     303_fppTCBCur         dd  0
     304pTCBCur_sel        dw  0
     305    db (MAXSIZE_PROLOG - 14) dup(0cch)
     306
     307; 34
     308ppPTDACur          dd  0
     309pPTDACur_offObject dd  0
     310_fppPTDACur        dd  0
     311pPTDACur_sel       dw  0
     312    db (MAXSIZE_PROLOG - 14) dup(0cch)
     313
     314; 35
     315pptda_start          dd  0
     316ptda_start_offObject dd  0
     317_fpptda_start        dd  0
     318ptda_start_sel       dw  0
     319    db (MAXSIZE_PROLOG - 14) dup(0cch)
     320
     321; 36
     322pptda_environ          dd  0
     323ptda_environ_offObject dd  0
     324_fpptda_environ        dd  0
     325ptda_environ_sel       dw  0
     326    db (MAXSIZE_PROLOG - 14) dup(0cch)
     327
     328; 37
     329pptda_ptdasem          dd  0
     330ptda_ptdasem_offObject dd  0
     331_fpptda_ptdasem        dd  0
     332ptda_ptdasem_sel       dw  0
     333    db (MAXSIZE_PROLOG - 14) dup(0cch)
     334
     335; 38
     336pptda_module          dd  0
     337ptda_module_offObject dd  0
     338_fpptda_module        dd  0
     339ptda_module_sel       dw  0
     340    db (MAXSIZE_PROLOG - 14) dup(0cch)
     341
     342; 39
     343pptda_pBeginLIBPATH           dd  0
     344ptda_pBeginLIBPATH_offObject  dd  0
     345_fpptda_pBeginLIBPATH         dd  0
     346pptda_pBeginLIBPATH_sel       dw  0
     347    db (MAXSIZE_PROLOG - 14) dup(0cch)
     348
     349; 40
     350pldrpFileNameBuf              dd  0
     351pldrpFileNameBuf_offObject    dd  0
     352_fpldrpFileNameBuf            dd  0
     353pldrpFileNameBuf_sel          dw  0
     354    db (MAXSIZE_PROLOG - 14) dup(0cch)
     355
     356; 41
     357SecPathFromSFN PROC NEAR
     358    db MAXSIZE_PROLOG dup(0cch)
     359SecPathFromSFN ENDP
     360
     361
    133362CALLTAB ENDS
    134363
  • trunk/src/win32k/ldr/ldr.cpp

    r2501 r4164  
    1 /* $Id: ldr.cpp,v 1.7 2000-01-22 18:21:01 bird Exp $
     1/* $Id: ldr.cpp,v 1.8 2000-09-02 21:08:06 bird Exp $
    22 *
    33 * ldr.cpp - Loader helpers.
     
    1414#define INCL_DOSERRORS
    1515#define INCL_NOPMAPI
    16 
     16#define INCL_OS2KRNL_SEM
     17#define INCL_OS2KRNL_PTDA
    1718
    1819/*******************************************************************************
     
    2122#include <os2.h>
    2223
     24#include "devSegDf.h"
    2325#include "malloc.h"
    2426#include "new.h"
     
    2628#include <stdlib.h>
    2729#include <stddef.h>
     30#include <string.h>
    2831
    2932#include "log.h"
     33#include "avl.h"
    3034#include <peexe.h>
    3135#include <exe386.h>
    3236#include "OS2Krnl.h"
     37#include "ldr.h"
     38#include "ldrCalls.h"
    3339#include "ModuleBase.h"
    3440#include "pe2lx.h"
    35 #include "avl.h"
    36 #include "ldr.h"
    3741#include "options.h"
    3842
     
    4145*   Global Variables                                                           *
    4246*******************************************************************************/
    43 PAVLNODECORE    pSFNRoot = NULL;
    44 PAVLNODECORE    pMTERoot = NULL;
    45 
     47static PAVLNODECORE    pSFNRoot = NULL;
     48static PAVLNODECORE    pMTERoot = NULL;
     49
     50
     51/*
     52 * Loader State. (See ldr.h for more info.)
     53 */
     54ULONG          ulLdrState = LDRSTATE_UNKNOWN;
     55
     56
     57/*
     58 * Pointer to the executable module being loaded.
     59 * This pointer is set by ldrOpen and cleared by tkExecPgm.
     60 * It's hence only valid at tkExecPgm time. (isLdrStateExecPgm() == TRUE).
     61 */
     62PMODULE         pExeModule = NULL;
     63
     64
     65/*
     66 * Filehandle bitmap.
     67 */
    4668unsigned char   achHandleStates[MAX_FILE_HANDLES/8];
     69
     70
    4771
    4872
     
    6488 * Gets a module by the MTE.
    6589 * @returns   Pointer to module node. If not found NULL.
    66  * @param     pMTE  Pointer an Module Table Entry.
     90 * @param     pMTE  Pointer a Module Table Entry.
    6791 * @sketch    Try find it in the MTE tree.
    6892 *            IF not found THEN
     
    124148
    125149/**
     150 * Gets a module by the hMTE.
     151 * @returns   Pointer to module node. If not found NULL.
     152 * @param     hMTE  Handle to a Module Table Entry.
     153 * @sketch    Convert hMte to an pMTE (pointer to MTE).
     154 *            Call getModuleByMTE with MTE pointer.
     155 * @status    completely implemented.
     156 * @author    knut st. osmundsen
     157 */
     158PMODULE     getModuleByhMTE(HMTE hMTE)
     159{
     160    PMTE pMTE;
     161
     162    pMTE = ldrValidateMteHandle(hMTE);
     163    if (pMTE != NULL)
     164        return getModuleByMTE(pMTE);
     165
     166    return NULL;
     167}
     168
     169
     170/**
    126171 * Get a module by filename.
    127172 * @returns   Pointer to module node. If not found NULL.
     
    236281            delete pMod->Data.pPe2Lx;
    237282            break;
    238 
     283/*
    239284        case MOD_TYPE_ELF2LX:
    240         case MOD_TYPE_SCRIPT:
    241         case MOD_TYPE_PE:
     285            break;
     286*/
     287#ifdef DEBUG
    242288        default:
    243289            kprintf(("removeModule: Unknown type, %#x\n", pMod->fFlags & MOD_TYPE_MASK));
     290#endif
    244291    }
    245292
     
    248295
    249296    return NO_ERROR;
     297}
     298
     299
     300/**
     301 * Gets the path of the executable being executed.
     302 * @returns     Pointer to pszPath on success. Path has _NOT_ a trailing slash.
     303 *              NULL pointer on error.
     304 * @param       pszPath     Pointer to path buffer. Expects CCHMAXPATH length.
     305 * @param       fExecChild  Use hMTE of the PTDAExecChild if present.
     306 * @sketch
     307 * @status      completely implemented.
     308 * @author      knut st. osmundsen (knut.stange.osmundsen@mynd.no)
     309 * @remark      The path from the pExeModule might not be fully qualified.
     310 */
     311PSZ ldrGetExePath(PSZ pszPath, BOOL fExecChild)
     312{
     313    PCSZ    pszFilename;
     314    PCSZ    psz;
     315
     316    #if 0 /* getFilename not implemented */
     317    if (pExeModule != NULL)
     318        /*
     319         * We have the executable object pointer. Let's use it!
     320         */
     321        pszFilename = pExeModule->Data.pModule->getFilename();
     322    else
     323    #endif
     324    {
     325        /*
     326         * Get the hMTE for the executable using the pPTDAExecChild
     327         * Then get the pMTE, and access the smte_path to get a pointer to the executable path.
     328         */
     329        PPTDA   pPTDACur;               /* Pointer to the current (system context) PTDA */
     330        PPTDA   pPTDA;                  /* PTDA in question. */
     331        HMTE    hMTE = NULLHANDLE;      /* Modulehandle of the executable module. */
     332        PMTE    pMTE;                   /* Pointer to ModuleTableEntry of the executable module. */
     333
     334        /*
     335         *  Get the current PTDA. (Fail if this call failes.)
     336         *  IF pPTDAExecChild isn't NULL THEN get hMTE for that.
     337         *  IF no pPTDAExecChild THEN  get hMte for the current PTDA.
     338         */
     339        pPTDACur = ptdaGetCur();
     340        if (pPTDACur != NULL)
     341        {
     342            pPTDA = ptdaGet_pPTDAExecChild(pPTDACur);
     343            if (pPTDA != NULL && fExecChild)
     344                hMTE = ptdaGet_ptda_module(pPTDA);
     345            if (hMTE == NULLHANDLE)
     346                hMTE = ptdaGet_ptda_module(pPTDACur);
     347        }
     348        else
     349        {   /* Not called at task time? No current task! */
     350            kprintf(("ldrGetExePath: Failed to get current PTDA.\n"));
     351            return NULL;
     352        }
     353
     354        /* fail if hMTE is NULLHANDLE ie. not found / invalid */
     355        if (hMTE == NULLHANDLE)
     356        {
     357            kprintf(("ldrGetExePath: Failed to get hMTE from the PTDAs.\n"));
     358            return NULL;
     359        }
     360
     361        /* get the pMTE for this hMTE */
     362        pMTE = ldrASMpMTEFromHandle(hMTE);
     363        if (pMTE == NULL)
     364        {
     365            kprintf(("ldrGetExePath: ldrASMpMTEFromHandle failed for hMTE=0x%04.\n", hMTE));
     366            return NULL;
     367        }
     368        if (pMTE->mte_swapmte == NULL) /* paranoia */
     369        {
     370            kprintf(("ldrGetExePath: mte_swapmte is NULL.\n"));
     371            return NULL;
     372        }
     373
     374        /* take the filename from the swappable MTE */
     375        pszFilename = pMTE->mte_swapmte->smte_path;
     376        if (pszFilename == NULL)
     377        {
     378            kprintf(("ldrGetExePath: smte_path is NULL.\n"));
     379            return NULL;
     380        }
     381    }
     382
     383    /* paranoia... */
     384    if (*pszFilename == '\0')
     385    {
     386        kprintf(("ldrGetExePath: pszFilename is empty!\n"));
     387        return NULL;
     388    }
     389
     390    /*
     391     * Skip back over the filename. (stops pointing at the slash or ':')
     392     */
     393    psz = pszFilename + strlen(pszFilename)-1;
     394    while (psz >= pszFilename && *psz != '\\' && *psz != '/' && *psz != ':')
     395        psz--;
     396
     397    /*
     398     * If no path the fail.
     399     */
     400    if (psz <= pszFilename)
     401    {
     402        kprintf(("ldrGetExePath: Exepath is empty.\n"));
     403        return NULL;
     404    }
     405
     406    /*
     407     * Copy path and return.
     408     */
     409    memcpy(pszPath, pszFilename, psz - pszFilename);
     410    pszPath[psz - pszFilename] = '\0';
     411    return pszPath;
    250412}
    251413
  • trunk/src/win32k/ldr/myLDRQAppType.cpp

    r2501 r4164  
    1 /* $Id: myLDRQAppType.cpp,v 1.3 2000-01-22 18:21:02 bird Exp $
     1/* $Id: myLDRQAppType.cpp,v 1.4 2000-09-02 21:08:07 bird Exp $
    22 *
    33 * _myLDRQAppType - _LDRQAppType overload.
     
    1515#define INCL_NOPMAPI
    1616
     17#define INCL_OS2KRNL_PTDA
     18#define INCL_OS2KRNL_SEM
     19
    1720/*******************************************************************************
    1821*   Header Files                                                               *
     
    2023#include <os2.h>
    2124
     25#include "devSegDf.h"                   /* Win32k segment definitions. */
    2226#include "OS2Krnl.h"
     27#include "avl.h"
     28#include "ldr.h"
    2329#include "ldrCalls.h"
    2430#include "log.h"
    2531
    26 BOOL fQAppType = FALSE;
    2732
    2833/**
    29  * LDRQAppType - Loader Query Application Type.
    30  * We set a flag while we're executing this function. Just to speed up processing.
    31  * If a PE file is queried, a dummy LX header is presented.
     34 * LDRQAppType - Loader Query Application Type - DosQueryAppType worker.
     35 *
     36 * We overrides this be able to determin if a convertion is only for a
     37 * LDRQAppType call.
     38 *
     39 * isLdrStateQAppType() returns TRUE when this procedure is on the stack.
     40 *
    3241 * @returns   return code.
    3342 * @param     p1
     
    3847    APIRET rc;
    3948
    40     kprintf(("_LDRQAppType: entry\n"));
    41     fQAppType = 1;
     49    kprintf(("myLDRQAppType: entry\n"));
     50    rc = KSEMRequestMutex(ptda_ptda_ptdasem(ptdaGetCur()), KSEM_INDEFINITE_WAIT);
     51    if (rc != NO_ERROR)
     52    {
     53        kprintf(("myLDRQAppType: failed to get intra-process semaphore.\n"));
     54        return rc;
     55    }
     56    rc = LDRRequestSem();
     57    if (rc != NO_ERROR)
     58    {
     59        kprintf(("myLDRQAppType: failed to get loader semaphore.\n"));
     60        return rc;
     61    }
     62
     63    ASSERT_LdrStateUnknown("myLDRQAppType")
     64    setLdrStateQAppType();
    4265
    4366    rc = LDRQAppType(p1, p2);
    4467
    45     fQAppType = 0;
    46     kprintf(("_LDRQAppType: exit\n"));
     68    ASSERT_LdrStateQAppType("myLDRQAppType")
     69    setLdrStateUnknown();
     70
     71    LDRClearSem();
     72    KSEMReleaseMutex(ptda_ptda_ptdasem(ptdaGetCur()));
     73    kprintf(("myLDRQAppType: exit\n"));
    4774
    4875    return rc;
  • trunk/src/win32k/ldr/myldrClose.cpp

    r2501 r4164  
    1 /* $Id: myldrClose.cpp,v 1.5 2000-01-22 18:21:02 bird Exp $
     1/* $Id: myldrClose.cpp,v 1.6 2000-09-02 21:08:07 bird Exp $
    22 *
    33 * myldrClose - ldrClose
     
    2323#include <stdlib.h>
    2424
     25#include "devSegDf.h"                   /* Win32k segment definitions. */
    2526#include "log.h"
     27#include "avl.h"
    2628#include <peexe.h>
    2729#include <exe386.h>
    2830#include "OS2Krnl.h"
    29 #include "avl.h"
    30 #include "ModuleBase.h"
    3131#include "ldr.h"
    3232#include "ldrCalls.h"
     33#include "ModuleBase.h"
     34#include "Pe2Lx.h"
    3335
    3436
     
    4244{
    4345    /* closes handle */
    44     kprintf(("ldrClose: hFile = %.4x\n", hFile));
     46    kprintf(("myldrClose: hFile = %.4x\n", hFile));
    4547    if (GetState(hFile) == HSTATE_OUR)
    4648    {
     
    5254            pMod->Data.pModule->dumpVirtualLxFile();
    5355        else
    54             kprintf(("ldrClose: getModuleBySFN failed!!!"));
     56            kprintf(("myldrClose: getModuleBySFN failed!!!"));
    5557        #endif
    5658
    5759        rc = removeModule(hFile);
    5860        if (rc != NO_ERROR)
    59             kprintf(("ldrClose: removeModule retured rc=%d\n", rc));
     61            kprintf(("myldrClose: removeModule retured rc=%d\n", rc));
    6062
    6163        #pragma info(notrd)
     
    6365        #pragma info(restore)
    6466    }
     67    /*
     68     * Invalidate the odin32path if kernel32 is closed.
     69     *  (Might possible not be needed as Pe2Lx does invalides
     70     *   the odin32path on object destruction.)
     71     */
     72    else if (Pe2Lx::getKernel32SFN() == hFile)
     73        Pe2Lx::invalidateOdin32Path();
    6574
     75    /*
     76     * Finally call the real close function.
     77     */
    6678    return ldrClose(hFile);
    6779}
  • trunk/src/win32k/ldr/myldrEnum32bitRelRecs.cpp

    r2537 r4164  
    1 /* $Id: myldrEnum32bitRelRecs.cpp,v 1.2 2000-01-27 23:43:07 bird Exp $
     1/* $Id: myldrEnum32bitRelRecs.cpp,v 1.3 2000-09-02 21:08:08 bird Exp $
    22 *
    33 * myldrEnum32bitRelRecs - ldrEnum32bitRelRecs
     
    2424#include <stdlib.h>
    2525
     26#include "devSegDf.h"                   /* Win32k segment definitions. */
     27#include "avl.h"
    2628#include "log.h"
    2729#include <peexe.h>
    2830#include <exe386.h>
    2931#include "OS2Krnl.h"
    30 #include "avl.h"
    31 #include "ModuleBase.h"
    3232#include "ldr.h"
    3333#include "ldrCalls.h"
     34#include "ModuleBase.h"
    3435
    3536
     
    6364        APIRET rc;
    6465        #if 1
    65         kprintf(("ldrEnum32BitRelRecs: pMTE=0x%08x iObject=0x%02x iPageTable=0x%03x pvPage=0x%08x\n"
     66        kprintf(("myldrEnum32BitRelRecs: pMTE=0x%08x iObject=0x%02x iPageTable=0x%03x pvPage=0x%08x\n"
    6667                 "                     ulPageAddress=0x%08x pvPTDA=0x%08x\n",
    6768                 pMTE, iObject, iPageTable, pvPage, ulPageAddress, pvPTDA
  • trunk/src/win32k/ldr/myldrOpen.cpp

    r2838 r4164  
    1 /* $Id: myldrOpen.cpp,v 1.10 2000-02-21 09:24:01 bird Exp $
     1/* $Id: myldrOpen.cpp,v 1.11 2000-09-02 21:08:09 bird Exp $
    22 *
    33 * myldrOpen - ldrOpen.
    44 *
    5  * Copyright (c) 1998-1999 knut st. osmundsen
     5 * Copyright (c) 1998-2000 knut st. osmundsen
    66 *
    77 * Project Odin Software License can be found in LICENSE.TXT
     
    1717
    1818#define INCL_OS2KRNL_IO
     19#define INCL_OS2KRNL_TCB
     20#define INCL_OS2KRNL_SEM
     21#define INCL_OS2KRNL_SEC
    1922
    2023/*******************************************************************************
     
    2326#include <os2.h>
    2427
     28#include "devSegDf.h"                   /* Win32k segment definitions. */
    2529#include "rmalloc.h"
    2630#include "malloc.h"
     
    2832#include <stdlib.h>
    2933#include <string.h>
     34#include <stdarg.h>
    3035
    3136#include "log.h"
     37#include "avl.h"
     38#include "options.h"
    3239#include <peexe.h>
    3340#include <exe386.h>
     41#include "elf.h"
    3442#include "OS2Krnl.h"
    3543#include "dev32.h"
     44#include "ldr.h"
     45#include "ldrCalls.h"
    3646#include "ModuleBase.h"
    3747#include "pe2lx.h"
    38 #include "elf.h"
    39 #include "avl.h"
    40 #include "ldr.h"
    41 #include "ldrCalls.h"
    42 #include "options.h"
    4348#include "myExecPgm.h"
    44 
    45 /*******************************************************************************
    46 *   Global Variables                                                           *
    47 *******************************************************************************/
    48 extern BOOL fQAppType;                  /* From LDRQAppType */
     49#include "env.h"
     50#include "vprintf.h"                    /* Make 100% sure we have va_start.  */
     51
     52
    4953
    5054/*******************************************************************************
    5155*   Internal Functions                                                         *
    5256*******************************************************************************/
    53 static unsigned getArgsLength(const char *pachArgs);
     57/* static */ APIRET     AddArgsToFront(int cArgs,  ...);
     58/* static */ APIRET     SetExecName(const char *pszExeName);
     59/* static */ APIRET     OpenPATH(PSFN phFile, char *pszFilename, PULONG pfl);
    5460
    5561
     
    5965 * @param     phFile       Pointer to file handler. Holds filehandle on output.
    6066 * @param     pszFilename  Pointer to filename.
    61  * @parma     param3       Probably some flags.
     67 * @parma     pfl          Pointer to some flags.
    6268 */
    63 ULONG LDRCALL myldrOpen(PSFN phFile, char *pszFilename, ULONG param3)
     69ULONG LDRCALL myldrOpen(PSFN phFile, PSZ pszFilename, PULONG pfl)
    6470{
    65     ULONG rc;
    66 
    67     /*
    68      * Try open the file (thats why this function is called anyway)
     71    static  int cNesting = 0;           /* This is an variable which hold the nesting */
     72                                        /* level of this function. This is useful     */
     73                                        /* when we call it recurcively.               */
     74                                        /* The maximum nesting level is currently 3.  */
     75                                        /* When the maximum depth has been reached    */
     76                                        /* we'll not intercept loading any longer!    */
     77    ULONG rc;                           /* Return value. */
     78
     79    /** @sketch
     80     * Try open the file (that's why this function is called anyway)
    6981     */
    70     rc = ldrOpen(phFile, pszFilename, param3);
    71 
    72     /* log sucesses */
     82    rc = ldrOpen(phFile, pszFilename, pfl);
    7383    if (rc == NO_ERROR)
    74         kprintf(("ldrOpen:  phFile=%#.4x, flags=%#.8x, pszFn=%s\n", *phFile, param3, pszFilename));
    75 
    76     /*
     84        kprintf(("myldrOpen-%d:  phFile=%#.4x, flags=%#.8x, pszFn=%s\n", cNesting, *phFile, pfl, pszFilename));
     85
     86
     87    /** @sketch
    7788     * Are we to intercept the loading?
    78      * - Only if open were succesful and one of the loaders are enabled.
     89     * - If open were successful.
     90     * - And Not too deep nesting.
     91     * - And that this isn't an unsupported load.
     92     * - And one of the loaders are enabled.
    7993     */
    80     if (rc == NO_ERROR && (options.fElf || options.fPE != FLAGS_PE_NOT || options.fScript))
    81     {
    82         char               *pszBuffer = (char*)rmalloc(640);        /* Read buffer. */
    83         PIMAGE_DOS_HEADER   pMzHdr = (PIMAGE_DOS_HEADER)pszBuffer;  /* Pointer to the buffer as it were a dosheader. */
    84         PIMAGE_NT_HEADERS   pNtHdrs = (PIMAGE_NT_HEADERS)pszBuffer; /* Pointer to the buffer as if it were an NT header. */
    85         char               *pach = pszBuffer;                       /* Finally an pointer to the buffer as if it were chars.. (which it is!) */
    86         PEXECPGMBUFFER      pBuffer;                                /* Pointer to a buffer containing the programname and arguments. */
    87                                                                     /* For scripts and PE.EXE this has to be changed to have correct */
    88                                                                     /* parameters sendt in to the program. */
    89         unsigned            cchRead = sizeof(IMAGE_DOS_HEADER);     /* Amount of the buffer which contains valid data. */
    90         unsigned            cbFile;                                 /* Filesize (0xffffffff if call to SftFileSize failed - should _never_ happen though)  */
    91 
    92         /*
    93          * Verify that rmalloc completed successfully.
    94          */
    95         if (pszBuffer == NULL)
     94    if (rc == NO_ERROR
     95        && cNesting < 3
     96        && !isLdrStateLoadingUnsupported()
     97        && isAnyLoaderEnabled()
     98        )
     99    {
     100        union _u_ReadBufferPointers         /* Read buffer pointer(s). */
    96101        {
    97             kprintf(("ldrOpen: rmalloc(1024) failed\n"));
    98             return NO_ERROR;
     102            char               *pach;       /* Pointer to the buffer as char. */
     103            unsigned long      *pul;        /* Pointer to the buffer as unsigned long. */
     104            PIMAGE_DOS_HEADER   pMzHdr;     /* Use the buffer as a dosheader. */
     105            PIMAGE_NT_HEADERS   pNtHdrs;    /* Use the buffer as a NT header. */
     106        } u1;
     107        unsigned            cbFile;         /* Filesize (0xffffffff if call to SftFileSize failed - should _never_ happen though) */
     108        unsigned            cbRead;         /* Amount of the buffer which contains valid data. */
     109        char *              psz;            /* Multipurpose string pointer no.1. */
     110        char *              psz2;           /* Multipurpose string pointer no.2. */
     111        char *              psz3;           /* Multipurpose string pointer no.3. */
     112
     113        /** @sketch
     114         * Allocate read buffer from resident heap.
     115         * IF this fails THEN we'll simply return NO_ERROR.
     116         */
     117        u1.pach = (char*)rmalloc(640);
     118        if (u1.pach == NULL)
     119        {
     120            kprintf(("myldrOpen-%d: rmalloc(640) failed\n", cNesting));
     121            goto ret;
    99122        }
    100123
    101         /*
    102          * Try get the filesize
     124
     125        /** @sketch
     126         * Increment nesting level.
     127         */
     128        cNesting++;
     129
     130
     131        /** @sketch
     132         * Get the filesize. On failure filesize is set to ~0.
    103133         */
    104134        rc = SftFileSize(*phFile, (PULONG)SSToDS(&cbFile));
    105135        if (rc != NO_ERROR)
    106136        {
    107             kprintf(("ldrOpen: SftFileSize failed with rc=%d\n", rc));
     137            kprintf(("myldrOpen-%d: SftFileSize failed with rc=%d\n", cNesting, rc));
    108138            cbFile = (unsigned)~0;
    109139        }
    110140
    111         /*
    112          * See if this is an recognizable module format.
    113          * This costs up to two disk reads!
    114          */
    115         rc = ldrRead(*phFile, 0UL, pMzHdr, 0UL, cchRead, NULL);
    116         if (rc == NO_ERROR)
     141
     142        /** @sketch
     143         *  Read the size of a DOS (ie. MZ) header.
     144         *  IF successful and more stuff in file THEN
     145         *      See if this is an recognizable module binary format:
     146         */
     147        cbRead = min(sizeof(IMAGE_DOS_HEADER), cbFile);
     148        rc = ldrRead(*phFile, 0UL, u1.pMzHdr, 0UL, cbRead, NULL);
     149        if (rc == NO_ERROR && cbRead < cbFile)
    117150        {
    118             /*
    119              * PE header?
    120              *  - If DOS Magic is found AND a valid e_lfanew (offset of NE/LX/LE/PE header) is found
    121              *  - OR if PE siganture is found.
     151            /** @sketch
     152             * If LX header just give up at once.
    122153             */
    123             if ((pMzHdr->e_magic == IMAGE_DOS_SIGNATURE &&
    124                  pMzHdr->e_lfanew > sizeof(IMAGE_DOS_HEADER) && pMzHdr->e_lfanew < 0x04000000UL) /* Larger than 64 bytes and less that 64MB. */
    125                 || *(PULONG)pach == IMAGE_NT_SIGNATURE)
    126             {   /*
    127                  * MZ or PE header found
     154            if (u1.pMzHdr->e_magic == E32MAGIC)
     155                goto cleanup;
     156
     157            /** @sketch
     158             * IF PE or MZ header THEN
     159             */
     160            if (u1.pMzHdr->e_magic == IMAGE_DOS_SIGNATURE
     161                || u1.pNtHdrs->Signature == IMAGE_NT_SIGNATURE)
     162            {
     163                ULONG   offPe;          /* Offset to PE header. */
     164
     165                /** @sketch
     166                 * ---
     167                 * We now known that this is file has a MZ or a PE header. If it's
     168                 * a MZ header, we might end up with no "New" header or the "New"
     169                 * header might turn out to be a NE, LE, or LX header. I any of
     170                 * these non PE headers occur OS/2 will take care of it, we'll do nothing.
     171                 * ---
     172                 * IF PE loading is disable or MZ header and e_lfanew is invalid THEN
     173                 *     return (successfully) to the caller.
     174                 * ENDIF
     175                 * (Find the offset of the PE header while testing (offPe).)
    128176                 */
    129 
    130                 /* if PE loading is diable return to the caller */
    131                 if (options.fPE == FLAGS_PE_NOT)
     177                if (isPELoaderDisabled())
     178                    goto cleanup;
     179                if (u1.pMzHdr->e_magic == IMAGE_DOS_SIGNATURE)
    132180                {
    133                     rfree(pszBuffer);
    134                     return NO_ERROR;
     181                    offPe = u1.pMzHdr->e_lfanew;
     182                    if (offPe < sizeof(IMAGE_DOS_HEADER) || offPe > 0x04000000UL)
     183                        goto cleanup;
    135184                }
    136 
    137                 /*
    138                  * Read the PE header if it isn't what we allready have!
     185                else
     186                    offPe = 0;
     187
     188
     189                /** @sketch
     190                 * Read the PE header.
     191                 * If the read failes or not PE signature, there isn't anything for us to do.
    139192                 */
    140                 cchRead = sizeof(IMAGE_NT_HEADERS);
    141                 if (*(PULONG)pach != IMAGE_NT_SIGNATURE)
    142                     rc = ldrRead(*phFile, pMzHdr->e_lfanew, pach, 0UL, cchRead, NULL);
    143                 else
    144                     rc = ldrRead(*phFile, 0UL, pach, 0UL, cchRead, NULL);
    145 
    146                 /*
    147                  * If successfully read, and a PE signature is present the continue and try load it!
    148                  * Else don't do anything, simply return NO_ERROR to the caller. (probably NE or LX exec)
     193                rc = ldrRead(*phFile, offPe, u1.pach, 0UL, sizeof(IMAGE_NT_HEADERS), NULL);
     194                if (rc != NO_ERROR || u1.pNtHdrs->Signature != IMAGE_NT_SIGNATURE)
     195                    goto cleanup_noerror;
     196
     197
     198                /** @sketch
     199                 * PE signature found!
    149200                 */
    150                 if (rc == NO_ERROR && *(PULONG)pach == IMAGE_NT_SIGNATURE)
    151                 {   /*
    152                      * PE signature found.
    153                      */
    154                     kprintf(("ldrOpen: PE executable...\n"));
    155 
    156                     /*
    157                      * PE2LX?
    158                      *  - When PE2LX flag is set
    159                      *  - OR when the MIXED flag is set and the image is with the first 64MB of memory.
    160                      */
    161                     if (options.fPE == FLAGS_PE_PE2LX
    162                         || (options.fPE == FLAGS_PE_MIXED
    163                             && !((pNtHdrs->FileHeader.Characteristics & IMAGE_FILE_DLL == 0UL)
    164                                  && pNtHdrs->OptionalHeader.ImageBase >= 0x04000000UL /* 64MB */
    165                                  )
     201                kprintf(("myldrOpen-%d: PE executable...\n", cNesting));
     202
     203
     204                /** @sketch
     205                 * Use Pe2Lx?
     206                 *  - When Pe2Lx flag is set
     207                 *  - When the MIXED flag is set and the image isn't an executable
     208                 *    above the first 64MB private limit without relocations
     209                 */
     210                if (isPe2LxLoaderEnabled()
     211                    || (isMixedPeLoaderEnabled()
     212                        && ((u1.pNtHdrs->FileHeader.Characteristics & IMAGE_FILE_DLL)
     213                            || !(u1.pNtHdrs->FileHeader.Characteristics & IMAGE_FILE_RELOCS_STRIPPED)
     214                            || u1.pNtHdrs->OptionalHeader.ImageBase < 0x04000000UL /* 64MB */
    166215                            )
    167216                        )
    168                     {   /*
    169                          * Pe2Lx (Ring0 of course)
    170                          * - Create a Pe2Lx class,
    171                          * - initiate it
    172                          * - Add the module to the module tree so we may find it later...
    173                          * - Set the handle state to 'our'.
    174                          */
    175                         Pe2Lx * pPe2Lx = new Pe2Lx(*phFile);
    176                         if (pPe2Lx != NULL)
     217                    )
     218                {   /** @sketch
     219                     *  Pe2Lx (Ring0 of course)
     220                     *      - Create a Pe2Lx class,
     221                     *      - initiate it
     222                     *      - Add the module to the module tree so we may find it later...
     223                     *      - Set the (file)handle state to 'our'.
     224                     *      - Set pExeModule to module pointer and loaderstate to our exe.
     225                     */
     226                    Pe2Lx * pPe2Lx = new Pe2Lx(*phFile);
     227                    if (pPe2Lx != NULL)
     228                    {
     229                        rc = pPe2Lx->init(pszFilename);
     230                        if (rc == NO_ERROR)
    177231                        {
    178                             rc = pPe2Lx->init(pszFilename);
     232                            kprintf(("myldrOpen-%d: Successfully init of Pe2Lx object.\n", cNesting));
     233                            rc = addModule(*phFile, NULL, MOD_TYPE_PE2LX, pPe2Lx);
    179234                            if (rc == NO_ERROR)
    180235                            {
    181                                 kprintf(("ldrOpen: Successfully init of Pe2Lx object.\n"));
    182                                 rc = addModule(*phFile, NULL, MOD_TYPE_PE2LX, pPe2Lx);
    183                                 if (rc == NO_ERROR)
    184                                     #pragma info(notrd)
    185                                     SetState(*phFile, HSTATE_OUR);
    186                                     #pragma info(restore)
    187                                 else
    188                                     kprintf(("ldrOpen: Failed to add the module. rc=%d\n"));
     236                                #pragma info(notrd)
     237                                SetState(*phFile, HSTATE_OUR);
     238                                #pragma info(restore)
     239                                if (pPe2Lx->isExe())
     240                                {
     241                                    setLdrStateLoadingOurEXE();
     242                                    pExeModule = getModuleBySFN(*phFile);
     243                                    #ifdef DEBUG
     244                                    if (pExeModule == NULL)
     245                                        kprintf(("myldrOpen-%d: getModuleBySFN failed when setting pExeModule! FATAL!\n", cNesting));
     246                                    #endif
     247                                }
    189248                            }
    190249                            else
    191                                 kprintf(("ldrOpen: Failed to init Pe2Lx object. rc=%d\n"));
    192                             if (rc != NO_ERROR)
    193                                 delete pPe2Lx;
     250                                kprintf(("myldrOpen-%d: Failed to add the module. rc=%d\n", cNesting));
    194251                        }
    195252                        else
    196                             kprintf(("ldrOpen: Failed to allocate Pe2Lx object.\n"));
     253                            kprintf(("myldrOpen-%d: Failed to init Pe2Lx object. rc=%d\n", cNesting));
     254                        if (rc != NO_ERROR)
     255                            delete pPe2Lx;
    197256                    }
    198257                    else
    199258                    {
    200                         /*
    201                          * Starting of PE.EXE enable?
     259                        kprintf(("myldrOpen-%d: Failed to allocate Pe2Lx object.\n", cNesting));
     260                        rc = ERROR_NOT_ENOUGH_MEMORY;
     261                    }
     262
     263                    goto cleanup;
     264                }
     265
     266
     267                /** @sketch
     268                 *  Using PE.EXE to start EXE?
     269                 *      - When the file is an EXE file and PE.EXE is enabled.
     270                 */
     271                if ((u1.pNtHdrs->FileHeader.Characteristics & IMAGE_FILE_DLL) == 0UL
     272                    && (options.fPE == FLAGS_PE_PE || options.fPE == FLAGS_PE_MIXED)
     273                    && (isLdrStateExecPgm() || isLdrStateQAppType())
     274                    )
     275                {
     276                    /** @sketch
     277                     * PE.EXE:
     278                     * Find pe.exe - look in current directory and thru the PATH.
     279                     * Note! We use the read buffer (u1.p*) as a storage for the
     280                     * pe.exe filename and path.
     281                     */
     282                    kprintf(("myldrOpen-%d: pe.exe - opening\n", cNesting));
     283                    ldrClose(*phFile);
     284                    strcpy(u1.pach, "PE.EXE");
     285                    rc = ldrOpen(phFile, u1.pach, pfl); /* This isn't recusive! */
     286                    if (rc != NO_ERROR)
     287                        rc = OpenPATH(phFile, u1.pach, pfl);
     288                    if (rc == NO_ERROR)
     289                    {
     290                        /** @sketch
     291                         * If we're in tkExecPgm state we'll have to shuffle the parameters
     292                         * and executable filename tkExecPgm were called with.
     293                         * If not tkExecPgm we can't do anything about parameters (and there is
     294                         * probably nothing to do either).
    202295                         */
    203                         if (options.fPE == FLAGS_PE_PE || options.fPE == FLAGS_PE_MIXED)
    204                         {   /*
    205                              * pe.exe - need the path!
    206                              */
    207                             kprintf(("ldrOpen: pe.exe - opening\n"));
    208                             ldrClose(*phFile);
    209                             rc = ldrOpen(phFile, "pe.exe", param3);  /* path....! problems! */
    210                             kprintf(("ldrOpen: pe.exe - open returned with rc = %d\n", rc));
    211                             rfree(pszBuffer);
    212                             return rc;
     296                        kprintf(("myldrOpen-%d: pe.exe - %s\n", cNesting, u1.pach));
     297                        if (isLdrStateExecPgm() && fTkExecPgm)
     298                        {
     299                            rc = AddArgsToFront(2, ldrpFileNameBuf, achTkExecPgmFilename);
     300                            if (rc == NO_ERROR)
     301                            {
     302                                rc = SetExecName(ldrpFileNameBuf);
     303                                if (rc != NO_ERROR)
     304                                    kprintf(("myldrOpen-%d: pe.exe - failed to set pe.exe as execname. rc=%d\n", cNesting));
     305                            }
     306                            else
     307                                kprintf(("myldrOpen-%d: pe.exe - failed to add programname as argument. rc=%d\n", cNesting, rc));
     308                            goto cleanup_noerror;
    213309                        }
    214310                    }
     311                    else
     312                        kprintf(("myldrOpen-%d: pe.exe - couldn't find/open pe.exe\n", cNesting));
    215313                }
    216                 rfree(pszBuffer);
    217                 return NO_ERROR;
     314                goto cleanup;
    218315            }
    219             else
     316            /** @sketch End of PE Loading. */
     317
     318
     319            /** @sketch
     320             * ELF image?
     321             */
     322            if (*u1.pul == ELFMAGICLSB)
    220323            {
     324                if (isELFDisabled())
     325                    goto cleanup_noerror;
     326
    221327                /*
    222                  * ELF image?
     328                 * ELF signature found.
    223329                 */
    224                 if (pach[0] == ELFMAG0 && pach[1] == ELFMAG1 && pach[2] == ELFMAG2 && pach[3] == ELFMAG3)
     330                kprintf(("myldrOpen-%d: ELF image! - not implemented yet!\n", cNesting));
     331
     332                /*
     333                 * Do nothing more yet. NEED AN ELF LOADER!!!
     334                 */
     335                goto cleanup;
     336            }
     337
     338
     339            /** @sketch
     340             * Java image?
     341             */
     342            if (*u1.pul == 0xBEBAFECAUL) //CAh FEh BAh BEh
     343            {
     344                char *pszName = NULL;
     345                int   cchName;
     346
     347                if (isJAVADisabled())
     348                    goto cleanup_noerror;
     349
     350                /** @sketch
     351                 * Java signature found.
     352                 * Copy the name to a temporary buffer. (only if necessary)
     353                 * Remove the extention (.class) and insert a space between the name and the path.
     354                 *  (This is the needed processing of the class filename to make it a classpath
     355                 *   entry (path) and a class name (filename).)
     356                 * Try find the java executor in current dir or PATH: java.exe
     357                 */
     358                kprintf(("myldrOpen-%d: Jave image!\n", cNesting));
     359
     360                if (isLdrStateExecPgm() && fTkExecPgm)
    225361                {
    226                     /*
    227                      * ELF signature found.
     362                    /* Ooops we had to get the file name from the MFT. ldrpFileNameBuf is allways uppercased... */
     363                    /* MFT seems to hold uppercased filenames! ARG! But (by pure luck?) achTkExecPgmArguments is
     364                     * not uppercased (yet). Nothing could be simpler!
    228365                     */
    229                     kprintf(("ldrOpen: ELF executable! - not implemented yet!\n"));
    230 
    231                     /*
    232                      * Do nothing more yet. NEED AN ELF LOADER!!!
     366                    #if 1
     367                    psz3 = achTkExecPgmArguments;
     368                    #elif 0
     369                    psz3 = SecPathFromSFN(*phFile);
     370                    if (psz3 == NULL)
     371                        psz3 = ldrpFileNameBuf;
     372                    #else
     373                    psz3 = ldrpFileNameBuf;
     374                    #endif
     375                    cchName = strlen(psz3);
     376                    pszName = (char*)rmalloc(cchName + 2);
     377                    if (pszName == NULL)
     378                    {
     379                        rc = ERROR_NOT_ENOUGH_MEMORY;
     380                        goto cleanup;
     381                    }
     382                    memcpy(pszName, psz3, cchName+1);
     383
     384                    psz = pszName + strlen(pszName) - 1;
     385                    while (psz > pszName && *psz != '.' && *psz != '\\' && *psz != '/')
     386                        psz--;
     387                    if (*psz == '.')
     388                    {
     389                        cchName = psz - pszName;
     390                        *psz-- = '\0';
     391                        while (psz > pszName && *psz != '\\' && *psz != '/')
     392                            psz--;
     393
     394                        /* check for root and evt. make room for an extra slash. */
     395                        if (psz - pszName == 2)
     396                        {
     397                            memmove(psz + 1, psz, cchName - 1);
     398                            *psz++ = '\\';
     399                        }
     400                    }
     401                    /* check if no path */
     402                    if (psz == pszName)
     403                        memmove(pszName + 1, pszName, cchName + 1);
     404                    *psz = ' ';
     405                }
     406
     407                ldrClose(*phFile);
     408                rc = ldrOpen(phFile, ".\\JAVA.EXE", pfl);
     409                if (rc != NO_ERROR)
     410                    rc = OpenPATH(phFile, "JAVA.EXE", pfl);
     411                if (rc == NO_ERROR)
     412                {
     413                    kprintf(("myldrOpen-%d: java - %s\n", cNesting, ldrpFileNameBuf));
     414
     415                    /** @sketch
     416                     * To be able to execute any given class name we'll have to pass in the
     417                     * directory as -classpath. But -classpath seems to override the default
     418                     * and environmental CLASSPATHs. So, we'll have to pass in the value of
     419                     * the CLASSPATH env.var. or generate the default class path (what ever that is).
     420                     *
    233421                     */
    234                     rfree(pszBuffer);
    235                     return NO_ERROR;
     422                    if (isLdrStateExecPgm() && fTkExecPgm)
     423                    {
     424                        psz = u1.pach;
     425
     426                        /*
     427                         * Get classpath and add it as a parameter
     428                         */
     429                        strcpy(u1.pach, "-classpath ");
     430                        psz = u1.pach + strlen(u1.pach);
     431
     432                        psz3 = (char*)ScanEnv(GetEnv(TRUE), "CLASSPATH");
     433                        if (psz3 != NULL)
     434                        {   /* environment variable set */
     435                            if (strlen(psz3) > 640 - 11 - 1 - cchName) //check for overflow
     436                            {   // TODO? should reallocate...
     437                                memcpy(psz, psz3, 640 - 11 - 1 - cchName);
     438                                psz[640 - 11 - 1 - cchName] = '\0';
     439                            }
     440                            else
     441                                strcpy(psz, psz3);
     442                            psz += strlen(psz);
     443                        }
     444                        else
     445                        {
     446                            /* Make default classpath by taking the java.exe path + '..\lib\classes.zip' */
     447                            strcpy(psz, ldrpFileNameBuf);
     448                            psz3 = psz + strlen(psz) - 1;
     449                            while (psz3 > psz && *psz3 != '\\' && *psz3 != '/')
     450                                psz3--;
     451                            strcpy(++psz3, "..\\lib\\classes.zip");
     452                            psz = psz3 + strlen(psz3);
     453                        }
     454
     455                        /*
     456                         * Add the class directory (as the last classpath entry) and the class name.
     457                         * (Note. I may happen that there is no directory, but that don't matter
     458                         *        a space is allways preceding the class name.)
     459                         */
     460                        *psz++ = ';';
     461                        strcpy(psz, pszName);
     462                        if (pszName != NULL)
     463                            rfree(pszName);
     464
     465                        /*
     466                         * Setup JAVA.EXE as executable with the parameters we've build.
     467                         */
     468                        rc = AddArgsToFront(2, ldrpFileNameBuf, u1.pach);
     469                        kprintf(("myldrOpen-%d: java - Exe: %s  Args: %s\n", cNesting, ldrpFileNameBuf, u1.pach));
     470                        if (rc == NO_ERROR)
     471                        {
     472                            rc = SetExecName(ldrpFileNameBuf);
     473                            if (rc != NO_ERROR)
     474                                kprintf(("myldrOpen-%d: java - failed to set java.exe as execname. rc=%d\n", cNesting, rc));
     475                        }
     476                        else
     477                            kprintf(("myldrOpen-%d: java - failed to setup the parameters. rc=%d\n", cNesting, rc));
     478
     479                        goto cleanup_noerror;
     480                    }
    236481                }
     482                else
     483                    kprintf(("myldrOpen-%d: java - couldn't find/open java.exe\n", cNesting));
     484
     485
     486                /** @sketch
     487                 *  End of Java loading. (return)
     488                 */
     489                if (pszName != NULL)
     490                    rfree(pszName);
     491                goto cleanup;
    237492            }
     493
    238494        }
     495        else
     496        {
     497            /** @sketch
     498             *  ELSE - the reading size of a DOS header failed or file is smaller than the dos header.
     499             *      IF read failed or filesize is less than 4 bytes THEN
     500             *          return no_error to the caller.
     501             *      ENDIF
     502             */
     503            #ifdef DEBUG
     504            if (rc != NO_ERROR)
     505            {
     506                kprintf(("myldrOpen-%d: ldrRead failed cbRead=%d, cbFile=%d,  rc=%d\n", cNesting, cbRead, cbFile, rc));
     507                goto cleanup_noerror;
     508            }
     509            if (cbRead < 4)
     510            {
     511                kprintf(("myldrOpen-%d: File too small! cbFile=%d\n", cNesting, cbFile));
     512                goto cleanup_noerror;
     513            }
     514            #else
     515            if (rc != NO_ERROR || cbRead < 4) //just forget files less than 4 bytes!
     516                goto cleanup_noerror;
     517            #endif
     518        }
     519        /** @sketch ENDIF (dos header read) */
     520
     521
    239522
    240523        /*
    241          * Only unreconized files and readerror passes this point!
     524         * Only unreconized files passes this point!
    242525         *
    243526         * * Fileformats with lower priority should reside here. *
     
    245528         */
    246529
    247         /*
    248          * If the initial readoperation failed try to read a smaller amount, in case it is a small script...
    249          * 4 bytes is a small amount isn't it?
    250          */
    251         if (rc != NO_ERROR)
     530        /** @sketch
     531         *  UNIX styled script?
     532         *      - Starts with a hash (#)
     533         *      - And we're loading an EXE
     534         *      - And we're either in QAppType or ExecPgm state.
     535         *      - And that a bang (!) is the first char after the hash (ignoring blanks).
     536         */
     537        if (*u1.pach == '#'
     538            && isLdrStateLoadingEXE()
     539            && (isLdrStateQAppType() || isLdrStateExecPgm())
     540            )
    252541        {
    253             kprintf(("ldrOpen: first ldrread failed with rc=%d. tries to read 4 byte.\n", rc));
    254             cchRead = 4;
    255             if ((rc = ldrRead(*phFile, 0UL, pach, 0UL, cchRead, NULL)) != NO_ERROR)
    256                 kprintf(("ldrOpen: second ldrread failed with rc=%d.\n ", rc));
    257         }
    258 
    259         /*
    260          * Now we'll try again, UNIX styled script?
    261          */
    262         if (rc == NO_ERROR && *pach == '#' && pach[1] == '!')
    263         {
     542            if (isUNIXScriptDisabled())
     543                goto cleanup_noerror;
    264544            /*
    265              * UNIX styled script?
    266              * FIXME! Must be more than 64 bytes long?
    267              *        No options!
    268              *        Firstline < 64 bytes!
     545             * Look for a bang (!). Tabs and spaces are skipped, anything else result in error.
    269546             */
    270             kprintf(("ldrOpen: unix script?\n"));
    271             cchRead = min(cbFile, 256);
    272             rc = ldrRead(*phFile, 0UL, pach, 0UL, cchRead, NULL);
    273             if (rc == NO_ERROR)
     547            psz = u1.pach + 1;
     548            while ((*psz == ' ' || *psz == '\t') && psz - u1.pach < cbRead)
     549                psz++;
     550            if (*psz == '!')
    274551            {
    275                 char *pszStart = pach+2;
    276                 kprintf(("ldrOpen: script debug 1\n"));
    277 
    278                 /* Make sure we don't read to much... */
    279                 pszBuffer[cchRead] = '\0';
    280 
    281                 /*
    282                  * Skip blanks
     552                /** @sketch Found UNIX styled script! */
     553
     554                /** @sketch
     555                 * Read more of the script if necessary. (max is 256 chars (- Linux max is 127))
     556                 * Terminate the string read from the file to make sure with stop somewhere!
    283557                 */
    284                 pszStart = pszBuffer + 2; /* skips the "#!" stuff. */
    285                 while (*pszStart != '\0' && (*pszStart == ' ' || *pszStart == '\t'))
    286                     pszStart++;
    287                 kprintf(("ldrOpen: script debug 2\n"));
    288 
    289                 /* anything left on the line? */
    290                 if (*pszStart != '\0' && *pszStart != '\r' && *pszStart != '\n')
     558                if (cbRead < cbFile /*&& cbRead != 256*/)
    291559                {
    292                     char *      pszEnd;         /* Pointer to the end of the string(s) when the next step is finished. */
    293                     unsigned    cchToAdd = 1;   /* Chars to add */
    294                     BOOL        fFirst = TRUE;  /* Set if a '\0' has not been set yet.
    295                                                  * If this is clear, there are one or more parameters after the interpreter name. */
    296 
    297                     /*
    298                      * find linesize and make parameters ready for copying
     560                    cbRead = min(256, cbFile);
     561                    rc = ldrRead(*phFile, 0UL, u1.pach, 0UL, cbRead, NULL);
     562                }
     563                u1.pach[cbRead] = '\0';
     564
     565                if (rc == NO_ERROR)
     566                {
     567                    /** @sketch
     568                     * Parse out filename and optional arguments (if any).
     569                     * The result of the parsing is that:
     570                     *      psz will point at the executable name.
     571                     *      psz2 will point at the arguments.
     572                     *  Both strings are trimmed.
    299573                     */
    300                     pszEnd = pszStart;
    301                     kprintf(("ldrOpen: script debug 3\n"));
    302                     while (*pszEnd != '\0' && *pszEnd != '\r' && *pszEnd != '\n')
     574                    psz++;                                                  /* psz points to the bang, skip it. */
     575                    while (*psz == ' ' || *psz == '\t')                     /* skip blanks after bang */
     576                        psz++;
     577                    if (*psz == '\r' || *psz == '\n' || *psz == '\0')       /* End-of-line? */
    303578                    {
    304                         if (fFirst && (*pszEnd == ' ' || *pszEnd == '\t'))
     579                        kprintf(("myldrOpen-%d: script no executable name.\n", cNesting));
     580                        goto cleanup_noerror; /* other error code? */
     581                    }
     582                    psz2 = psz + 1;                                         /* Not end-of-line, so add 1 before searching for args. */
     583                    while (*psz2 != '\0' && *psz2 != '\n' && *psz2 != '\r'  /* skip executable name. */
     584                           && *psz2 != ' ' && *psz2 != '\t')
     585                        psz2++;
     586                    while (*psz2 == ' ' || *psz2 == '\t')                    /* skip blanks after executable - pad them with '\0'! */
     587                        *psz2++ = '\0';
     588
     589                    psz3 = psz2;
     590                    while (*psz3 != '\n' && *psz3 != '\r' && *psz3 != '\0') /* find end of parameters and terminate the string. */
     591                        psz3++;
     592                    *psz3 = '\0';
     593                    while (psz3 >= psz2 && (*psz3 == '\0' || *psz3 == ' ' || *psz3 == '\t')) /* trim args */
     594                        *psz3-- = '\0';
     595
     596
     597                    /** @sketch
     598                     *  IF tkExecPgm THEN
     599                     *      Correct parameters - ie. add exec name (as argv[0]),
     600                     *        arguments (psz2) as argv[1+], old exec name, and finally
     601                     *        the existing parameters (current argv[1+]).
     602                     *      Set the executable name.
     603                     *  ENDIF
     604                     *  Open the new executable file recursively. (psz)
     605                     */
     606                    if (isLdrStateExecPgm())
     607                    {
     608                        if (*psz2)
     609                           rc = AddArgsToFront(3, psz, psz2, achTkExecPgmFilename);
     610                        else
     611                           rc = AddArgsToFront(2, psz, achTkExecPgmFilename);
     612                        if (rc != NO_ERROR)
    305613                        {
    306                             *pszEnd = '\0';
    307                             fFirst = FALSE;
    308                             if (pszEnd[1] == '\0' || pszEnd[1] == '\r' || pszEnd[1] == '\n')
    309                                 fFirst = TRUE;
     614                            kprintf(("myldrOpen-%d: AddArgsToFront failed with rc=%d\n", cNesting));
     615                            goto cleanup_noerror;
    310616                        }
    311 
    312                         /* next */
    313                         pszEnd++;
    314                         cchToAdd++;
     617                        rc = SetExecName(psz);
     618                        if (rc != NO_ERROR)
     619                            kprintf(("myldrOpen-%d: SetExecName failed with rc=%d\n", cNesting));
    315620                    }
    316                     *pszEnd = '\0';
    317                     kprintf(("ldrOpen: script debug 4\n"));
    318 
    319                     /*
    320                      * If ldrQueryApp type we don't have any ExecPgm buffer we need to mess with.
    321                      * We'll simply try open the the interpreter.
    322                      */
    323                     if (fQAppType)
     621                    ldrClose(*phFile);
     622                    rc = myldrOpen(phFile, psz, pfl);
     623                    if (rc != NO_ERROR)
    324624                    {
    325                         rc = ldrClose(*phFile);
    326                         rc = ldrOpen(phFile, pszStart, param3); /* FIXME, recusion! check that name not equal! Use flags to prevent race? */
    327                     }
    328                     else
    329                     {
    330                         /*
    331                          * Find the ExecPgm buffer.
    332                          */
    333                         pBuffer = QueryBufferPointerFromFilename(pszFilename);
    334                         kprintf(("ldrOpen: script debug 5\n"));
    335                         if (pBuffer != NULL)
     625                        psz2 = psz + strlen(psz);
     626                        if (psz + 4 >= psz2 || strcmp(psz2 - 4, ".EXE") != 0)
    336627                        {
    337                             unsigned cchArguments = getArgsLength(pBuffer->achArgs); /* minus the first argument. */
    338                             unsigned cchScriptnameDelta = strlen(pBuffer->szFilename) - strlen(pBuffer->achArgs); /* scriptname size difference. */
    339 
    340                             kprintf(("ldrOpen: script debug 6\n"));
    341 
    342                             /*
    343                              * Is there enough space in the struct?
    344                              */
    345                             if (cchArguments + cchToAdd + cchScriptnameDelta < sizeof(pBuffer->achArgs))
    346                             {
    347                                 kprintf(("ldrOpen: script debug 7\n"));
    348                                 /*
    349                                  * Open the interpreter.
    350                                  */
    351                                 rc = ldrClose(*phFile);
    352                                 rc = ldrOpen(phFile, pszStart, param3); /* FIXME, recusion! check that name not equal! Use flags to prevent race? */
    353                                 if (rc == NO_ERROR)
    354                                 {
    355                                     kprintf(("ldrOpen: script debug 8\n"));
    356                                     /* Make space for the addition arguments. */
    357                                     #ifdef DEBUG
    358                                     char *psz = &pBuffer->achArgs[0];
    359                                     int   i = 0;
    360                                     while (*psz != '\0')
    361                                     {
    362                                         kprintf(("Arg %d: %s\n", i++, psz));
    363                                         psz += 1 + strlen(psz);
    364                                     }
    365                                     #endif
    366                                     memmove(&pBuffer->achArgs[cchToAdd + cchScriptnameDelta],
    367                                             &pBuffer->achArgs[0], cchArguments);
    368 
    369                                     /*
    370                                      * Copy the arguments.
    371                                      */
    372                                     kprintf(("ldrOpen: script debug 8\n"));
    373                                     memcpy(&pBuffer->achArgs[0], pszStart, cchToAdd); /* Interpreter with arguments */
    374                                     if (!fFirst)
    375                                         pBuffer->achArgs[cchToAdd - 1] = ' ';
    376                                     strcpy(&pBuffer->achArgs[cchToAdd], pszFilename); /* Scriptname */
    377                                     kprintf(("ldrOpen: script debug a\n"));
    378 
    379                                     #ifdef DEBUG
    380                                     psz = &pBuffer->achArgs[0];
    381                                     i = 0;
    382                                     while (*psz != '\0')
    383                                     {
    384                                         kprintf(("Arg %d: %s\n", i++, psz));
    385                                         psz += 1 + strlen(psz);
    386                                     }
    387                                     #endif
    388                                 }
    389                                 else
    390                                     kprintf(("ldrOpen: failed to open interpreter (%s), rc=%d\n", pszStart, rc));
    391                             }
    392                             else
    393                             {
    394                                 kprintf(("ldrOpen: Argument buffer too small, %d\n", cchArguments + cchToAdd));
    395                                 rc = ERROR_BAD_EXE_FORMAT;
    396                             }
     628                            strcpy(psz2, ".EXE");
     629                            rc = myldrOpen(phFile, psz, pfl);
     630                            *psz2 = '\0';
    397631                        }
    398632                        else
     633                            psz2 = NULL;
     634
     635                        //should we search the PATH??? For a starting, we'll do it.
     636                        if (rc != NO_ERROR
     637                            && (rc = OpenPATH(phFile, psz, pfl)) != NO_ERROR
     638                            && psz2 != NULL)
    399639                        {
    400                             kprintf(("ldrOpen: QueryBufferPointerFromFilename failed.\n"));
    401                             rc = ERROR_BAD_EXE_FORMAT; /*?*/
     640                            *psz2 = '.';
     641                            rc = OpenPATH(phFile, psz, pfl);
    402642                        }
    403643                    }
     
    405645                else
    406646                {
    407                     kprintf(("ldrOpen: no interpereter on the first line.\n"));
    408                     rc = ERROR_BAD_EXE_FORMAT; /*?*/
     647                    kprintf(("myldrOpen-%d: script - failed to read more of the script!, rc=%d cbRead=%d cbFile=%d.\n",
     648                             cNesting, rc, cbRead, cbFile));
    409649                }
     650
     651                goto cleanup;
    410652            }
    411653            else
    412654            {
    413                 kprintf(("ldrOpen: read of min(cbFile, 256) = %d failed, rc = %d\n", cchRead, rc));
     655                kprintf(("myldrOpen-%d: script - hash found but no bang (!).\n", cNesting));
    414656            }
    415         } /* else inn other formats here. */
    416         rfree(pszBuffer);
    417     }
     657        } /**@sketch ENDIF - UNIX styled script. */
     658
     659
     660
     661        /** @sketch
     662         *  REXX script?
     663         *      - Starts with a REXX start comment ('/','*')
     664         *      - And we're loading an EXE
     665         *      - And we're either in QAppType or ExecPgm state.
     666         *      - Extention:
     667         *          .RX and .REX are known to be pure REXX scripts.
     668         *          While .CMD has to invoked used the commandline OS2_SHELL or COMSPEC variable.
     669         */
     670        psz2 = pszFilename + strlen(pszFilename) - 1;
     671        while (psz2 > pszFilename && *psz2 != '.')
     672            psz2--;
     673        if (*psz2 == '.'
     674            && *u1.pach == '/' && u1.pach[1] == '*'
     675            && isLdrStateLoadingEXE()
     676            && (isLdrStateQAppType() || isLdrStateExecPgm())
     677            && (stricmp(psz2, ".RX") == 0 || stricmp(psz2, ".REX") == 0)
     678            )
     679        {
     680            if (isREXXScriptDisabled())
     681                goto cleanup_noerror;
     682
     683            /** @sketch
     684             * Found REXX styled script!
     685             * Find the REXX interpreter. We'll use kRx.exe to execute the REXX scripts.
     686             * (This interpreter could be embedded as a child of ModuleBase as it turned out
     687             * to be quite small about 700 bytes.)
     688             */
     689            kprintf(("myldrOpen-%d: Found REXX script\n", cNesting));
     690            ldrClose(*phFile);
     691            psz = "KRX.EXE";
     692            rc = ldrOpen(phFile, psz, pfl);
     693            if (rc != NO_ERROR)
     694                rc = OpenPATH(phFile, psz, pfl);
     695
     696            /** @sketch
     697             *  IF tkExecPgm THEN
     698             *      Correct parameters - ie. add exec name (as argv[0]), old exec name,
     699             *        and finally the existing parameters (current argv[1+]).
     700             *      Set the executable name.
     701             *  ENDIF
     702             */
     703             if (rc == NO_ERROR && isLdrStateExecPgm())
     704             {
     705                 rc = AddArgsToFront(2, ldrpFileNameBuf, achTkExecPgmFilename);
     706                 if (rc != NO_ERROR)
     707                 {
     708                     kprintf(("myldrOpen-%d: AddArgsToFront failed with rc=%d\n", cNesting));
     709                     goto cleanup_noerror;
     710                 }
     711                 rc = SetExecName(ldrpFileNameBuf);
     712                 if (rc != NO_ERROR)
     713                     kprintf(("myldrOpen-%d: SetExecName failed with rc=%d\n", cNesting));
     714
     715                 goto cleanup_noerror;
     716             }
     717             goto cleanup;
     718        } /**@sketch ENDIF - REXX styled script. */
     719
     720
     721        /*
     722         * Cleanup with rc set to NO_ERROR.
     723         */
     724    cleanup_noerror:
     725        rc = NO_ERROR;
     726
     727        /*
     728         * Cleanup without having rc set to NO_ERROR.
     729         * Decrement the nesting count.
     730         */
     731    cleanup:
     732        rfree(u1.pach);
     733        cNesting--;
     734    }
     735    #ifdef DEBUG
     736    else if (cNesting >= 3)
     737        kprintf(("myldrOpen-%d: cNesting = %d, which is too deep!\n", cNesting, cNesting));
     738    #endif
     739
     740ret:
     741    /** @sketch
     742     *  Return rc.
     743     */
    418744    return rc;
    419745}
     
    421747
    422748/**
    423  * Get the lenght of the arguments.
    424  * @returns   Lenght in char, includes the two '\0's.
    425  * @param     pachArgs  Pointer to the ASCIIZs which makes up the arguments.
    426  * @status    completely implemented.
     749 * Adds new arguments to the front of the startup arguments for the program about to be
     750 * executed.
     751 *
     752 * @returns   OS/2 return code.
     753 * @param     cArgs     Count of arguments to add. At least 1!!!
     754 * @param     ...       Pointers to the arguments to add.
     755 *                      The first argument have to be the executable name. This have to the
     756 *                        the only argument in the first string.
     757 *                      The other arguements are space separated, so you could add a bunch
     758 *                        of arguments in a single string!
     759 *                      The last argument should be the old first parameter if this is to be
     760 *                        preserved. The old first parameter is overwritten since it's
     761 *                        normally the executable name.
     762 *
     763 * @status    completly implemented.
    427764 * @author    knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
     765 * @remark    Implementation note:
     766 *  The arguments convention is as follows:
     767 *      First argument, which should be the executable name, is terminated with a '\0'.
     768 *        It starts at offset 0 into the argument buffer, of course.
     769 *      All other arguemnts are separated by a space and follows the immediately after the
     770 *        first argument.
     771 *      The arguments are terminated by a double nulltermination: '\0\0'.
    428772 */
    429 static unsigned getArgsLength(const char *pachArgs)
     773APIRET AddArgsToFront(int cArgs,  ...)
    430774{
    431     unsigned    cch = 1;
    432     const char *psz = pachArgs;
    433 
     775    va_list     vaarg;                  /* Variable length argument list. */
     776    int         cchOldArgs;             /* Length of the old arguments (including the first argument). */
     777                                        /* cchOldArgs = 1 means no arguments. It don't include the very last '\0' */
     778                                        /* (remember argumets are terminated with two '\0's). */
     779    int         iSecondArg;             /* Index of the second argument. (Used to skip the first argument.) */
     780                                        /* Used first on the original arguments and them when adding the first */
     781                                        /* new argument. */
     782    int         cchNewArgs;             /* Length of the new arguments to be inserted. */
     783    int         i;                      /* Loop variable. Current function argument. */
     784    char *      psz;                    /* General string pointer. */
     785
     786
     787    /** @sketch
     788     *  Assert that we're in the right state.
     789     *  Calc the length of the existing parameters.
     790     *  Calc the length of the new arguments to determin.
     791     *  Assert that the new arguments have length > 0.
     792     */
     793    #ifdef DEBUG
     794    if (!isLdrStateExecPgm())
     795    {
     796        kprintf(("AddArgsToFront: not in tkExecPgm state.\n"));
     797        return ERROR_INVALID_PARAMETER;
     798    }
     799    #endif
     800    if (!fTkExecPgm)
     801    {
     802        kprintf(("AddArgsToFront: called when not in tkExecPgm data is invalid!\n"));
     803        return ERROR_INVALID_PARAMETER;
     804    }
     805
     806    iSecondArg = strlen(&achTkExecPgmArguments[0]) + 1;
     807    psz = &achTkExecPgmArguments[iSecondArg];
    434808    while (*psz != '\0')
    435     {
    436         register unsigned cch2 = strlen(psz);
    437         cch += cch2;
    438         psz += cch2 + 1;
    439     }
    440 
    441     return cch;
     809        psz += strlen(psz) + 1;
     810    cchOldArgs = psz - &achTkExecPgmArguments[iSecondArg];
     811
     812    va_start(vaarg, cArgs);
     813    for (cchNewArgs = i = 0; i < cArgs; i++)
     814        cchNewArgs += strlen(va_arg(vaarg, char *)) + 1; /* 1 is for space or '\0'. */
     815    va_end(vaarg);
     816    #ifdef DEBUG
     817    if (cchNewArgs == 0)
     818    {
     819        kprintf(("AddArgsToFront: the size of the arguments to add is zero!\n"));
     820        return ERROR_INVALID_PARAMETER;
     821    }
     822    #endif
     823
     824
     825    /** @sketch
     826     *  Check if we have enough room for the new arguments. Fail if not enough.
     827     *  Move the existing arguments to make room for the new ones.
     828     *    !IMPORTANT! The first existing arguments (executable name) is skipped !IMPORTANT!
     829     *    !IMPORTANT! in this move as this have to be re-added in this call!    !IMPORTANT!
     830     */
     831    if (cchOldArgs + cchNewArgs + 1 > CCHARGUMENTS)
     832    {
     833        kprintf(("AddArgsToFront: argument buffer is too small to hold the arguments to add, cchOldArgs=%d, cchNewArgs=%d\n",
     834                 cchOldArgs, cchNewArgs));
     835        return ERROR_BAD_ARGUMENTS;
     836    }
     837
     838    if (cchOldArgs > 0)
     839    {
     840        memmove(&achTkExecPgmArguments[cchNewArgs], &achTkExecPgmArguments[iSecondArg],
     841                cchOldArgs + 1);
     842    }
     843    else
     844        achTkExecPgmArguments[cchNewArgs] = '\0';
     845
     846
     847    /** @sketch
     848     *  Copy new arguments.
     849     *  Since the first argument is special case we'll do it separately. (Uses '\0' as separator.)
     850     *    We assume that the entire first argument passed into this function should be the first argument!
     851     *    (This don't have to be true for the other arguments since these are space separated. You could
     852     *     pass in more than argument in a single string.)
     853     *  Loop thru the rest of the new arguments and add them with space as separator.
     854     */
     855    va_start(vaarg, cArgs);
     856    psz = va_arg(vaarg, char *);
     857    memcpy(&achTkExecPgmArguments[0], psz, (i = strlen(psz) + 1));
     858    psz = &achTkExecPgmArguments[i];
     859
     860    for (i = 1; i < cArgs; i++)
     861    {
     862        if (i > 1) *psz++ = ' ';    //Add space if not second argument.
     863        strcpy(psz, va_arg(vaarg, char *));
     864        psz += strlen(psz);
     865    }
     866    va_end(vaarg);
     867    if (cchOldArgs > 0) *psz++ = ' ';    //Add space if old arguments
     868
     869    #ifdef DEBUG /* assertion */
     870    if (psz != &achTkExecPgmArguments[cchNewArgs])
     871    {
     872        kprintf(("AddArgsToFront: !Assertion failed! psz didn't end up where it should! (psz -> %d should be %d)\n",
     873                 psz - &achTkExecPgmArguments[0], cchNewArgs));
     874        if (cchOldArgs <= 1)
     875            psz[0] = psz[1] = '\0';
     876    }
     877    #endif
     878
     879    return NO_ERROR;
    442880}
     881
     882
     883/**
     884 * Sets the executable name of the module.
     885 * This function is normally invoked after a different executable than the one requested was
     886 * opened. It does _NOT_ set the new executable name as the first argument, since it is more
     887 * convenient to this while calling AddArgsToFront to add other arguments.
     888 *
     889 * @returns   OS/2 return code.
     890 * @param     pszExecName   Pointer to new executable name.
     891 * @status    completly implemented.
     892 * @author    knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
     893 * @remark    .
     894 */
     895APIRET SetExecName(const char *pszExecName)
     896{
     897    #ifdef DEBUG
     898    int cch;
     899    cch = strlen(pszExecName);
     900    if (cch > CCHMAXPATH)
     901    {
     902        kprintf(("ChangeExecName: filename is too long! cch=%d. name=%s\n", cch, pszExecName));
     903        return ERROR_FILENAME_EXCED_RANGE;
     904    }
     905    if (!isLdrStateExecPgm())
     906    {
     907        kprintf(("ChangeExecName: called when not in tkExecPgm state!!! FATAL ERROR!\n"));
     908        return ERROR_INVALID_PARAMETER;
     909    }
     910    #endif
     911    if (!fTkExecPgm)
     912    {
     913        kprintf(("ChangeExecName: called when not in tkExecPgm data is invalid!!! FATAL ERROR!\n"));
     914        return ERROR_INVALID_PARAMETER;
     915    }
     916
     917    strcpy(achTkExecPgmFilename, pszExecName);
     918
     919    return 0;
     920}
     921
     922
     923/**
     924 * Opens a file using the PATH environment variable of the current process.
     925 * @returns   OS2 return code.
     926 * @param     phFile        Pointer to filehandle. The filehandle is set to the SFN for the opened
     927 *                          file on successful return.
     928 *                          The filehandle is 0 on failure.
     929 * @param     pszFilename   Pointer to filename buffer. This will hold the filename on input.
     930 *                          On successful return it holds the filepath found.
     931 *                          On failiure it's undefined.
     932 * @param     pfl           Some flags set by ldrOpen.
     933 * @sketch    stub
     934 * @author    knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
     935 * @remark
     936 */
     937APIRET OpenPATH(PSFN phFile, char *pszFilename, PULONG pfl)
     938{
     939    APIRET      rc;
     940    USHORT      TCBFailErr_save;
     941    int         cchFile;                /* Filename length + 1. */
     942    const char *pszFile;                /* Pointer to filename portion. */
     943    const char *pszPath = ScanEnv(GetEnv(FALSE), "PATH"); /* Current Process environment? */
     944
     945    /**@sketch
     946     *  No PATH environment.
     947     */
     948    if (pszPath == NULL)
     949        return ERROR_FILE_NOT_FOUND;
     950
     951    /**@sketch
     952     * Skip any paths in the filename.
     953     */
     954    pszFile = pszFilename + (cchFile = strlen(pszFilename));
     955    while (pszFile >= pszFilename && *pszFile != '\\' && *pszFile != '/')
     956        pszFile--;
     957    cchFile -= pszFile - pszFilename;
     958    pszFile++;
     959
     960    /**@sketch
     961     * We'll have to save the TCBFailErr since we don't want to cause
     962     * Hard Errors while searching invalid paths, etc. (ldrOpenPath does this!)
     963     */
     964    TCBFailErr_save = tcbGetTCBFailErr(tcbGetCur());
     965
     966    /**@ sketch
     967     *  Loop thru the PATH trying to open the specified file in each
     968     *  directory.
     969     */
     970    while (*pszPath != '\0')
     971    {
     972        const char *  pszNext;
     973        int           cchPath;
     974        char          chEnd;
     975        register char ch;
     976
     977        /*
     978         * Find end of this path.
     979         */
     980        while (*pszPath == ' ') pszPath++; //skip leading spaces.
     981        if (*pszPath == '"')
     982        {
     983            chEnd = '"';
     984            pszPath++;
     985        }
     986        else
     987            chEnd = ';';
     988        pszNext = pszPath;
     989        while ((ch = *pszNext) != chEnd && ch != '\0')
     990            pszNext++;
     991
     992        cchPath = pszNext - pszPath;
     993        if (chEnd == '"')
     994        {
     995            /* Skip anything between the " and the ; or string end. */
     996            while ((ch = *pszNext) != ';' && ch != '\0')
     997                pszNext++;
     998        }
     999        else
     1000        {
     1001            /* Trim the string. */
     1002            while (cchPath > 0 && pszPath[cchPath-1] == ' ') //??
     1003                cchPath--;
     1004        }
     1005
     1006        /*
     1007         *  No length? No Path! Or path'\'filename too long? => Next
     1008         */
     1009        if (cchPath > 0 && cchPath + cchFile + 1 < CCHMAXPATH)
     1010        {
     1011            static char     achFilename[CCHMAXPATH];
     1012            /*
     1013             * Build filename
     1014             */
     1015            memcpy(achFilename, pszPath, cchPath);
     1016            if ((ch = achFilename[cchPath - 1]) == '\\' || ch == '/')
     1017                cchPath--;
     1018            else
     1019                achFilename[cchPath] = '\\';
     1020             memcpy(&achFilename[cchPath + 1], pszFile, cchFile); /* cchFile = length + 1; hence we copy the terminator too. */
     1021
     1022            /*
     1023             * Try open the file.
     1024             */
     1025            rc = myldrOpen(phFile, achFilename, pfl);
     1026            switch (rc)
     1027            {
     1028                case ERROR_FILE_NOT_FOUND:          case ERROR_PATH_NOT_FOUND:          case ERROR_ACCESS_DENIED:           case ERROR_INVALID_ACCESS:
     1029                case ERROR_INVALID_DRIVE:           case ERROR_NOT_DOS_DISK:            case ERROR_REM_NOT_LIST:            case ERROR_BAD_NETPATH:
     1030                case ERROR_NETWORK_BUSY:            case ERROR_DEV_NOT_EXIST:           case ERROR_TOO_MANY_CMDS:           case ERROR_ADAP_HDW_ERR:
     1031                case ERROR_UNEXP_NET_ERR:           case ERROR_BAD_REM_ADAP:            case ERROR_NETNAME_DELETED:         case ERROR_BAD_DEV_TYPE:
     1032                case ERROR_NETWORK_ACCESS_DENIED:   case ERROR_BAD_NET_NAME:            case ERROR_TOO_MANY_SESS:           case ERROR_REQ_NOT_ACCEP:
     1033                case ERROR_INVALID_PASSWORD:        case ERROR_OPEN_FAILED:             case ERROR_INVALID_NAME:            case ERROR_FILENAME_EXCED_RANGE:
     1034                case ERROR_VC_DISCONNECTED:
     1035                    break;
     1036
     1037                case NO_ERROR:
     1038                    strcpy(pszFilename, achFilename);
     1039                default:
     1040                    tcbSetTCBFailErr(tcbGetCur(), TCBFailErr_save);
     1041                    return rc;
     1042            }
     1043        }
     1044        #ifdef DEBUG
     1045        else if (cchPath > 0)   kprintf(("OpenPATH: Path component is too long\n"));
     1046        #endif
     1047
     1048        /*
     1049         * Next
     1050         */
     1051        if (*pszNext == '\0')
     1052            break;
     1053        pszPath = pszNext + 1;
     1054    }
     1055
     1056
     1057    /*
     1058     * File is not found.
     1059     */
     1060    *phFile = 0;
     1061    tcbSetTCBFailErr(tcbGetCur(), TCBFailErr_save);
     1062    return ERROR_FILE_NOT_FOUND;
     1063}
  • trunk/src/win32k/ldr/myldrOpenPath.cpp

    r3829 r4164  
    1 /* $Id: myldrOpenPath.cpp,v 1.1 2000-07-16 22:21:16 bird Exp $
     1/* $Id: myldrOpenPath.cpp,v 1.2 2000-09-02 21:08:10 bird Exp $
    22 *
    33 * myldrOpenPath - ldrOpenPath used to open executables we'll override
     
    1616#define INCL_NOPMAPI
    1717#define INCL_OS2KRNL_TCB
     18#define INCL_OS2KRNL_PTDA
    1819
    1920/*******************************************************************************
     
    2526#include <stdlib.h>
    2627
     28#include "devSegDf.h"                   /* Win32k segment definitions. */
    2729#include "log.h"
    2830#include "dev32.h"
     
    134136        else
    135137        {
    136             struct InfoSegLDT *pInfoSeg;
    137             pInfoSeg = (struct InfoSegLDT *)D32Hlp_GetDOSVar(DHGETDOSV_SYSINFOSEG, 0);
    138             if (pInfoSeg == NULL)
     138            PPTDA   pPTDA = ptdaGetCur();
     139            if (pPTDA)
    139140            {
    140                 pExe = getModuleByhMTE(pInfoSeg->LIS_DI); /* LIS_DI is the same as hmod in LINFOSEG from bsedos16.h.  */
     141                pExe = getModuleByhMTE(ptdaGet_ptda_module(pPTDA));
    141142                #ifdef DEBUG            /* While testing! */
    142                 kprintf(("myldrOpenPath: getModuleByhMTE returned 0x%x08 for hmod=0x%04\n",
    143                          pExe, pInfoSeg->LIS_DI));
     143                kprintf(("myldrOpenPath: getModuleByhMTE returned 0x%08x for hmod=0x%04x\n",
     144                         pExe, ptdaGet_ptda_module(pPTDA)));
    144145                #endif
    145146            }
    146             #ifdef DEBUG                /* While testing! */
    147             else
    148                 dprintf(("myldrOpenPath: D32Hlp_GetDOSVar(DHGETDOSV_SYSINFOSEG) failed.\n"));
    149             #endif
    150147        }
    151148
  • trunk/src/win32k/ldr/myldrRead.cpp

    r2501 r4164  
    1 /* $Id: myldrRead.cpp,v 1.6 2000-01-22 18:21:02 bird Exp $
     1/* $Id: myldrRead.cpp,v 1.7 2000-09-02 21:08:10 bird Exp $
    22 *
    33 * myldrRead - ldrRead.
    44 *
    5  * Copyright (c) 1998-1999 knut st. osmundsen
     5 * Copyright (c) 1998-2000 knut st. osmundsen (knut.stange.osmundsen@mynd.no)
    66 *
    77 * Project Odin Software License can be found in LICENSE.TXT
     
    2323#include <stdlib.h>
    2424
     25#include "devSegDf.h"                   /* Win32k segment definitions. */
    2526#include "log.h"
     27#include "avl.h"
    2628#include "dev32.h"
    2729#include <peexe.h>
    2830#include <exe386.h>
    2931#include "OS2Krnl.h"
     32#include "ldrCalls.h"
     33#include "ldr.h"
    3034#include "ModuleBase.h"
    3135#include "pe2lx.h"
    32 #include "avl.h"
    33 #include "ldrCalls.h"
    34 #include "ldr.h"
    3536
    3637
     38/**
     39 * Overloads ldrRead.
     40 * @returns   OS/2 return code.
     41 * @param     hFile     Filehandle to read from.
     42 * @param     pvBuffer  Buffer to read into.
     43 * @param     fpBuffer  This is not flags as I first though, but probably a far 16-bit pointer
     44 *                      to the buffer.
     45 * @param     cbToRead  Count of bytes to read.
     46 * @param     pMTE
     47 * @sketch    IF it's our module THEN
     48 *                Get module pointer. (complain if this failes and backout to ldrRead.)
     49 *                Currently - verify that it's a Pe2Lx module. (complain and fail if not.)
     50 *                Invoke the read method of the module do the requested read operation.
     51 *                Save pMTE if present and not save allready.
     52 *            ENDIF
     53 *            - backout or not our module -
     54 *            forward request to the original ldrRead.
     55 * @status    Completely implemented.
     56 * @author    knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
     57 */
    3758ULONG LDRCALL myldrRead(
    38                        SFN hFile,
    39                        ULONG ulOffset,
    40                        PVOID pBuffer,
    41                        ULONG ulFlags ,
    42                        ULONG ulBytesToRead,
    43                        PMTE pMTE
    44                        )
     59    SFN    hFile,
     60    ULONG  ulOffset,
     61    PVOID   pvBuffer,
     62    ULONG   fpBuffer,
     63    ULONG   cbToRead,
     64    PMTE    pMTE
     65    )
    4566{
    4667    ULONG   rc;
     
    5071    {
    5172        PMODULE pMod;
    52         kprintf(("ldrRead+: hF=%+04x off=%+08x pB=%+08x fl=%+08x cb=%+04x pMTE=%+08x\n",hFile,ulOffset,pBuffer,ulFlags,ulBytesToRead,pMTE));
     73        kprintf(("myldrRead: hF=%+04x off=%+08x pB=%+08x fp=%+08x cb=%+04x pMTE=%+08x\n",
     74                 hFile, ulOffset, pvBuffer, fpBuffer, cbToRead, pMTE));
    5375
    5476        pMod = getModuleBySFN(hFile);
     
    5981                pMod->pMTE = pMTE;
    6082
    61             /* debug */
    62             if (ulFlags != 0)
    63                 kprintf(("ldrRead: Warning ulFlags = 0x%x (!= 0)\n", ulFlags));
    64 
    6583            if ((pMod->fFlags & MOD_TYPE_MASK) == MOD_TYPE_PE2LX)
    66                 rc = pMod->Data.pModule->read(ulOffset, pBuffer, ulBytesToRead, ulFlags, pMTE);
     84                rc = pMod->Data.pModule->read(ulOffset, pvBuffer, fpBuffer, cbToRead, pMTE);
    6785            else
    6886            {
    69                 kprintf(("ldrRead: Invalid module type, %#x\n", pMod->fFlags & MOD_TYPE_MASK));
     87                kprintf(("myldrRead: Invalid module type, %#x\n", pMod->fFlags & MOD_TYPE_MASK));
    7088                rc = ERROR_READ_FAULT;
    7189            }
    72             return rc;
    7390        }
    7491        else
    75             kprintf(("ldrRead:  DON'T PANIC! - but I can't get Node ptr! - This is really an IPE!\n"));
     92        {
     93            kprintf(("myldrRead:  DON'T PANIC! - but I can't get Node ptr! - This is really an IPE!\n"));
     94            rc = ERROR_READ_FAULT;
     95        }
    7696    }
    77 
    78     rc = ldrRead(hFile, ulOffset, pBuffer, ulFlags, ulBytesToRead, pMTE);
    79 
     97    else
     98    {
     99        rc = ldrRead(hFile, ulOffset, pvBuffer, fpBuffer, cbToRead, pMTE);
     100    }
    80101    #if 0
    81     kprintf(("ldrRead:  hF=%+04x off=%+08x pB=%+08x fl=%+08x cb=%+04x pMTE=%+08x rc=%d\n",
    82              hFile,ulOffset,pBuffer,ulFlags,ulBytesToRead,pMTE,rc));
     102    kprintf(("myldrRead:  hF=%+04x off=%+08x pB=%+08x fp=%+08x cb=%+04x pMTE=%+08x rc=%d\n",
     103             hFile, ulOffset, pvBuffer, fpBuffer, cbToRead, pMTE, rc));
    83104    #endif
    84105
  • trunk/src/win32k/ldr/mytkExecPgm.asm

    r2872 r4164  
    1 ; $Id: mytkExecPgm.asm,v 1.10 2000-02-23 16:53:04 bird Exp $
     1; $Id: mytkExecPgm.asm,v 1.11 2000-09-02 21:08:10 bird Exp $
    22;
    33; mytkExecPgm - tkExecPgm overload
     
    1010
    1111;
     12;   Defined Constants And Macros
     13;
     14CCHFILENAME     EQU 261                 ; The size of the filename buffer
     15CCHARGUMENTS    EQU 1536                ; The size of the argument buffer
     16CCHMAXPATH      EQU CCHFILENAME - 1     ; Max path length
     17
     18;
    1219;   Include files
    1320;
    1421    include devsegdf.inc
    1522
    16 ;
    17 ;   Imported Functions
     23
     24;
     25;   Imported Functions and variables.
    1826;
    1927    extrn  _g_tkExecPgm:PROC
    20     extrn  AcquireBuffer:PROC
    21     extrn  ReleaseBuffer:PROC
    22     extrn  QueryBufferSegmentOffset:PROC
    2328
    2429    ; Scans strings until empy-string is reached.
     
    4550    extrn  _f_FuBuff:PROC
    4651
     52
     53    ; 32-bit memcpy. (see OS2KTK.h)
     54    extrn _TKFuBuff@16:PROC
     55
     56    ;
     57    ; LDR semaphore
     58    ;
     59    extrn pLdrSem:DWORD
     60    extrn _LDRClearSem@0:PROC
     61    extrn _KSEMRequestMutex@8:PROC
     62    extrn _KSEMQueryMutex@8:PROC
     63
     64    ;
     65    ; Loader State
     66    ;
     67    extrn ulLDRState:DWORD
     68
     69    ;
     70    ; Pointer to current executable module.
     71    ;
     72    extrn pExeModule:DWORD
     73
     74    ;
     75    ; DevHlp32
     76    ;
     77    extrn D32Hlp_VirtToLin:PROC
     78
     79    ;
     80    ; TKSSBase (32-bit)
     81    ;
     82    extrn pulTKSSBase32:DWORD
     83
    4784;
    4885;   Exported symbols
    4986;
    5087    public mytkExecPgm
    51 
     88    public tkExecPgmCopyEnv
     89
     90    public fTkExecPgm
     91    public achTkExecPgmFilename
     92    public achTkExecPgmArguments
     93
     94
     95
     96;
     97; Global data
     98;
     99
     100; Filename and arguments buffers + environment pointer
     101; from the tkExecPgm call.
     102;
     103; This data is only valid at isLdrStateExecPgm time
     104; (and you'll have to be behind the loader semaphore of course!)
     105DATA16 SEGMENT
     106fTkExecPgm              db 0            ; 0 - achTkExecPgmFilename and achTkExecPgmArguments is INVALID
     107                                        ; 1 - achTkExecPgmFilename and achTkExecPgmArguments is VALID.
     108achTkExecPgmFilename    db CCHFILENAME dup (0)  ; The filename  passed in to tkExecPgm if (fTkExec is TRUE)
     109achTkExecPgmArguments   db CCHARGUMENTS dup (0) ; The arguments passed in to tkExecPgm if (fTkExec is TRUE)
     110fpachTkExecPgmEnv       dd 0            ; Far pointer to environment passed in to tkExecPgm.
     111                                        ; Valid at isLdrStateExecPgm time.
     112                                        ; NOTE! User data, don't touch it directly!
     113DATA16 ENDS
    52114
    53115
    54116CODE32 SEGMENT
    55 
    56117;;
    57 ;
     118; New implementation.
    58119; @returns   same as tkExecPgm: eax, edx and carry flag
    59120; @param     ax     Exec flag
     
    65126;            may modify later if this is a UNIX shellscript or
    66127;            a PE-file started by pe.exe.
    67 ; @status
     128; @status    completely implemented.
    68129; @author    knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
    69 ; @remark
    70 ;
    71 ;   The buffer we are using is a C struct as follows.
    72 ;   struct Buffer
    73 ;   {
    74 ;       char szFilename[261];  /* offset 0   */
    75 ;       char achArg[1536-261]; /* offset 261 */
    76 ;   };
     130;
    77131;
    78132mytkExecPgm PROC FAR
    79 pBuffer     = dword ptr -04h
    80 SegBuffer   = -08h
    81 OffBuffer   = -0Ch
    82 cchFilename = dword ptr -10h
    83 cchArgs     = dword ptr -14h
    84 ;usExecFlag  = -18h
    85 ;SegFilename = -1ch
    86 ;OffFilename = -1eh
    87 ;SegEnv      = -20h
    88 ;OffEnv      = -22h
    89 ;SegArg      = -24h
    90 ;OffArg      = -26h
    91 
    92     ASSUME CS:CODE32, DS:NOTHING, SS:NOTHING
    93 ;    int     3
    94     push    ebp
    95     mov     ebp, esp
    96     lea     esp, [ebp + cchArgs]
    97 
    98     push    eax
    99     push    ecx
    100     push    ds
    101     push    es
    102     push    edi
    103 
    104     ; parameter validations
    105     mov     ax, ds                      ; pointer to filename
    106     cmp     ax, 4
    107     jb      mytkExecPgm_CalltkExecPgm_X1
    108 
    109     ;
    110     ; filename length
    111     ;
    112     mov     ax, ds
    113     mov     es, ax
    114     pushad
    115     push    es
    116     push    ds
    117     mov     bx, ds
    118     mov     di, dx                      ; es:di is now filename address (ds:dx).
    119     push    cs                          ; Problem calling far into the calltab segement.
    120     call    near ptr FLAT:_f_FuStrLen
    121     movzx   ecx, cx
    122     mov     [ebp+cchFilename], ecx
    123     pop     ds
    124     pop     es
    125     popad
    126     jc      mytkExecPgm_CalltkExecPgm_X1; If the FuStrLen call failed we bail out!
    127 
    128     ;
    129     ; if filename length is more that CCHMAXPATH then we don't do anything!.
    130     ;
    131     cmp     [ebp+cchFilename], 260
    132     jae     mytkExecPgm_CalltkExecPgm_X1; length >= 260
    133 
    134     ;
    135     ; args length
    136     ; Note: the arguments are a series of ASCIIZs ended by an empty string (ie. '\0').
    137     ;
    138     pop     edi
    139     push    edi
    140     xor     ecx, ecx
    141     cmp     di, 4                       ; The argument might me a invalid pointer...
    142     jb      mytkExecPgm_CalltkExecPgm_1
    143 
    144     pushad
    145     push    es
    146     push    ds
    147     mov     bx, di                      ;
    148     mov     di, si                      ; bx:di -> arguments
    149     push    cs                          ; Problem calling far into the calltab segement.
    150     call    near ptr FLAT:_f_FuStrLenZ
    151     movzx   ecx, cx
    152     mov     [ebp+cchArgs], ecx
    153     pop     ds
    154     pop     es
    155     popad
    156     jc      mytkExecPgm_CalltkExecPgm_X1
    157 
    158 mytkExecPgm_CalltkExecPgm_1:
    159     mov     ecx, [ebp+cchArgs]
    160     add     ecx, [ebp+cchFilename]      ; filename
    161     add     ecx, 3 + 260                ;  260 = new argument from a scrip file or something.
    162                                         ;    3 = two '\0's and a space after added argument.
    163     cmp     ecx, 1536                   ; 1536 = Buffersize.  FIXME! Define this!!!
    164     jae     mytkExecPgm_CalltkExecPgm_X1; jmp if argument + file + new file > buffer size
    165 
    166     ;
    167     ; Aquire a buffer
    168     ;
    169     call    AcquireBuffer
    170     or      eax, eax
    171     jz      mytkExecPgm_CalltkExecPgm_X1; Failed to get buffer.
    172     mov     [ebp+pBuffer], eax
    173 
    174     ;
    175     ; Get Segment and offset for the buffer
    176     ;
    177     call    QueryBufferSegmentOffset
    178     mov     cx, es
    179     mov     [ebp+OffBuffer], ax
    180     mov     [ebp+SegBuffer], es
    181     test    eax, 000570000h
    182     jnz     mytkExecPgm_CalltkExecPgm_X2
    183 
    184     ;
    185     ; Copy filename to pBuffer.
    186     ;
    187     pushad
    188     push    es
    189     push    ds
    190     mov     di, ax                      ; es:di  pBuffer
    191     mov     si, dx
    192     mov     bx, ds                      ; bx:si  Filename pointer (input ds:dx)
    193     mov     ecx, [ebp+cchFilename]
    194     push    cs                          ; Problem calling far into the calltab segement.
    195     call    near ptr FLAT:_f_FuBuff
    196     pop     ds
    197     pop     es
    198     popad
    199     jc      mytkExecPgm_CalltkExecPgm_X2
    200 
    201     ;
    202     ; Copy Args to pBuffer + 261
    203     ;
    204     ; stack: edi, es, ds, ecx, eax
    205     pop     edi
    206     push    edi
    207     add     eax, 261                    ; we'll use eax in the branch
    208     cmp     di, 4
    209     jb      mytkExecPgm_CalltkExecPgm_2
    210     pushad
    211     push    es
    212     push    ds
    213     mov     ecx, [ebp+cchArgs]
    214     mov     bx, di                      ; ds:si -> arguments
    215     mov     di, ax                      ; es:di -> buffer + 261
    216     push    cs                          ; Problem calling far into the calltab segement.
    217     call    near ptr FLAT:_f_FuBuff
    218     pop     ds
    219     pop     es
    220     popad
    221     jc      mytkExecPgm_CalltkExecPgm_X2
    222     jmp     mytkExecPgm_CalltkExecPgm_3
    223 
    224 mytkExecPgm_CalltkExecPgm_2:
    225     mov     word ptr es:[eax], 0        ; Terminate the empty string!
    226 
    227     ;
    228     ; Restore variables pushed on the stack
    229     ;
    230     ; stack: edi, es, ds, ecx, eax
    231 mytkExecPgm_CalltkExecPgm_3:
    232     pop     edi
    233     pop     es
    234     pop     ds
    235     pop     ecx
    236     pop     eax
    237 
    238     ;
    239     ; Set new input parameters (call _g_tkExecPgm)
    240     ;
    241     ; ds:dx is to become SegBuffer:OffBuffer
    242     ; di:si is to become SegBuffer:OffBuffer+261
    243     ;
    244     ; The some of the old values are stored on the stack (for the time being)
    245     push    ds
    246     push    edi
    247     push    esi
    248 
    249     mov     di, [ebp+SegBuffer]
    250     mov     ds, di
    251     mov     si, [ebp+OffBuffer]
    252     mov     dx, si                      ; ds:dx  SegBuffer:OffBuffer
    253     add     si, 261                     ; di:si  SegBuffer:OffBuffer+261
    254 
    255     ;
    256     ; Call _g_tkExecPgm
    257     ;
    258     push    cs                          ; Problem calling far into the calltab segement.
    259     call    near ptr FLAT:_g_tkExecPgm
    260     pushfd
    261 
    262     ;
    263     ; Release buffer
    264     ;
    265     push    eax
    266     mov     eax, [ebp + pBuffer]
    267     call    ReleaseBuffer
    268     mov     [ebp + pBuffer], 0
    269     pop     eax
    270 
    271     ;
    272     ; Return
    273     ;
    274     popfd
    275     pop     esi
    276     pop     edi
    277     pop     ds
    278     leave
    279     retf
    280 
    281 mytkExecPgm_CalltkExecPgm_X2:
    282     ;
    283     ; Release buffer
    284     ;
    285     mov     eax, [ebp + pBuffer]
    286     call    ReleaseBuffer
    287     mov     [ebp + pBuffer], 0
    288 
    289 mytkExecPgm_CalltkExecPgm_X1:
    290     pop     edi
    291     pop     es
    292     pop     ds
    293     pop     ecx
    294     pop     eax
    295 
    296 mytkExecPgm_CalltkExecPgm:
    297     push    cs
    298     call    near ptr FLAT:_g_tkExecPgm
    299     leave
    300     retf
    301 mytkExecPgm ENDP
    302 
    303 
    304 
    305 CODE32 ENDS
    306 
    307 if 0 ; alternate implementation.
    308 mytkExecPgm PROC FAR
    309 pBuffer     = dword ptr -04h
    310 SegBuffer   = -08h
    311 OffBuffer   = -0Ch
    312 cchFilename = -10h
    313 cchArgs     = -14h
    314 usExecFlag  = -18h
    315 SegFilename = -1ch
    316 OffFilename = -1eh
    317 SegEnv      = -20h
    318 OffEnv      = -22h
    319 SegArg      = -24h
    320 OffArg      = -26h
     133cchFilename = -4h
     134cchArgs     = -08h
     135usExecFlag  = -0ch
     136SegFilename = -10h
     137OffFilename = -12h
     138SegEnv      = -14h
     139OffEnv      = -16h
     140SegArg      = -18h
     141OffArg      = -1ah
    321142
    322143    ASSUME CS:CODE32, DS:NOTHING, SS:NOTHING
     
    325146    lea     esp, [ebp + OffArg]
    326147
    327     ; save input parameters
     148    ;
     149    ; Save input parameters
     150    ;
    328151    mov     [ebp + usExecFlag], ax
    329152    mov     ax, es
     
    332155    mov     [ebp + SegArg], di
    333156    mov     [ebp + OffArg], si
    334     mov     ax, ds
    335     mov     [ebp + SegFilename], ax
     157    mov     bx, ds
     158    mov     [ebp + SegFilename], bx
    336159    mov     [ebp + OffFilename], dx
    337160
    338     ; parameter validations
    339     cmp     ax, 4                       ; pointer to filename
    340     jb      mytkExecPgm_CalltkExecPgm_X1
    341 
    342     ;
    343     ; filename length
    344     ;
    345     mov     bx, ax
     161    ;
     162    ; Parameter validations - if any of these fail we'll just pass on to
     163    ; the real tkExecPgm without setting up any buffers stuff.
     164    ; 1) validate the file pointer.
     165    ; 2) validate the file name length < 260
     166    ; 3) validate that the arguments aren't larger than the buffer.
     167    ;
     168
     169    ; Validate filename pointer
     170    ;
     171    cmp     bx, 4                       ; pointer to filename
     172    jb      tkepgm_backout
     173
     174    ; Validate filename length
     175    ;
    346176    mov     di, dx                      ; bx:di is now filename address
    347177    push    cs                          ; Problem calling far into the calltab segement.
    348178    call    near ptr FLAT:_f_FuStrLen
    349     jc      mytkExecPgm_CalltkExecPgm_X1; If the FuStrLen call failed we bail out!
    350 
    351     ;
     179    jc      tkepgm_backout              ; If the FuStrLen call failed we bail out!
     180
    352181    ; if filename length is more that CCHMAXPATH then we don't do anything!.
    353     ;
    354     cmp     cx, 260
    355     jae     mytkExecPgm_CalltkExecPgm_X1; length >= 260
    356     mov     [ebp+cchFilename], cx
     182    cmp     cx, CCHMAXPATH
     183    jae     tkepgm_backout              ; length >= CCHMAXPATH
     184    mov     [ebp + cchFilename], cx
    357185
    358186    ;
     
    360188    ; Note: the arguments are a series of ASCIIZs ended by an empty string (ie. '\0').
    361189    ;
    362     mov     bx, [ebp+SegArg]
     190    xor     cx, cx                      ; Set length to zero.
     191    mov     bx, [ebp + SegArg]
    363192    cmp     bx, 4                       ; The argument might me an NULL pointer
    364     xor     cx, cx
    365     jb      mytkExecPgm_CalltkExecPgm_1
    366 
    367     mov     di, [ebp+OffArg]            ; bx:di -> arguments
     193    jb      tkepgm1
     194
     195    mov     di, [ebp + OffArg]          ; bx:di -> arguments
    368196    push    cs                          ; Problem calling far into the calltab segement.
    369197    call    near ptr FLAT:_f_FuStrLenZ
    370     mov     [ebp+cchArgs], cx
    371     jc      mytkExecPgm_CalltkExecPgm_X1
    372 
    373 mytkExecPgm_CalltkExecPgm_1:
    374     add     cx, [ebp+cchFilename]       ; filename length
    375     add     cx, 3 + 260                 ;  260 = new argument from a scrip file or something.
     198    jc      tkepgm_backout
     199
     200tkepgm1:
     201    mov     [ebp + cchArgs], cx
     202    add     cx, [ebp + cchFilename]     ; filename length
     203    add     cx, 3 + 260                 ;  260 = additional arguments from a script file or something.
    376204                                        ;    3 = two '\0's and a space after added argument.
    377     cmp     ecx, 1536                   ; 1536 = Buffersize.  FIXME! Define this!!!
    378     jae     mytkExecPgm_CalltkExecPgm_X1; jmp if argument + file + new file > buffer size
    379 
    380     ;
    381     ; Aquire a buffer
    382     ;
    383     call    AcquireBuffer
    384     mov     [ebp+pBuffer], eax
    385     or      eax, eax
    386     jz      mytkExecPgm_CalltkExecPgm_X1; Failed to get buffer.
    387 
    388     ;
    389     ; Get Segment and offset for the buffer
    390     ;
    391     call    QueryBufferSegmentOffset
    392     mov     cx, es
    393     mov     [ebp+OffBuffer], ax
    394     mov     [ebp+SegBuffer], es
    395     test    eax, 000570000h
    396     jnz     mytkExecPgm_CalltkExecPgm_X2
    397 
    398     ;
    399     ; Copy filename to pBuffer.
    400     ;
    401     mov     di, ax                      ; es:di  pBuffer
    402     mov     si, dx
    403     mov     bx, ds                      ; bx:si  Filename pointer (input ds:dx)
    404     mov     cx, [ebp+cchFilename]       ; cx = length of area to copy
     205    cmp     cx, CCHARGUMENTS            ; argument Buffersize.
     206    jae     tkepgm_backout              ; jmp if argument + file + additional arguments >= buffer size
     207
     208
     209    ;
     210    ; Aquire the OS/2 loader semaphore
     211    ;   Since parameters looks good, we're ready for getting the loader semaphore.
     212    ;   We use the loader semaphore to serialize access to the win32k.sys loader
     213    ;   subsystem.
     214    ;   Before we can get the loader semaphore, we'll need to set ds and es to
     215    ;   flat R0 context.
     216    ;   The loader semaphore is later requested by the original tkExecPgm so
     217    ;   this shouldn't break anything.
     218    ;
     219    mov     ax, seg FLAT:DATA32
     220    mov     ds, ax
     221    mov     es, ax
     222    ASSUME  DS:FLAT, ES:FLAT
     223
     224    mov     eax, pLdrSem                ; Get pointer to the loader semaphore.
     225    or      eax, eax                    ; Check if null. (paranoia)
     226    jz      tkepgm_backout              ; Fail if null.
     227
     228    push    0ffffffffh                  ; Wait indefinitely.
     229    push    eax                         ; Push LdrSem address (which is the handle).
     230    call    near ptr FLAT:_KSEMRequestMutex@8
     231    or      eax, eax                    ; Check if failed.
     232    jnz     tkepgm_backout              ; Backout on failure.
     233
     234
     235    ;
     236    ; From here on we won't backout to the tkepgm_backout lable but
     237    ; the tkepgm_backout2 lable. (This will restore the parameters
     238    ; and jump in at the call to tkExecPgm behind the Loader Sem.)
     239    ;
     240
     241
     242    ;
     243    ; Set global data:
     244    ;   Zeros pointer to exemodule to NULL (a bit paranoia).
     245    ;   Mark global data valid.
     246    ;   Store Environment pointer.
     247    ;   Set loader state.
     248    ;
     249    mov     pExeModule, 0               ; Sets the exemodule pointer to NULL.
     250    mov     fTkExecPgm, 1               ; Optimistic, mark the global data valid.
     251    mov     eax, [ebp + OffEnv]         ; Environment FAR pointer.
     252    mov     fpachTkExecPgmEnv, eax      ; Store the Environment pointer. This will
     253                                        ; later permit us to get the passed in
     254                                        ; environment in for ex. ldrOpenPath.
     255    mov     ulLDRState, 1               ; Set the loader state to LDRSTATE_TKEXECPGM!
     256    ASSUME  DS:NOTHING, ES:NOTHING
     257
     258
     259    ;
     260    ; Copy filename to achBuffer.
     261    ;
     262    mov     di, seg achTkExecPgmFilename
     263    mov     es, di
     264    mov     edi, offset achTkExecPgmFilename
     265                                        ; es:(e)di -> &achTkExecPgmFilename[0]
     266    mov     si, [ebp + OffFilename]
     267    mov     bx, [ebp + SegFilename]     ; bx:si  Filename pointer (input ds:dx)
     268    ASSUME DS:NOTHING
     269    mov     cx, [ebp + cchFilename]     ; cx = length of area to copy
    405270    push    cs                          ; Problem calling far into the calltab segement.
    406271    call    near ptr FLAT:_f_FuBuff
    407     jc      mytkExecPgm_CalltkExecPgm_X2
    408 
    409     ;
    410     ; Copy Args to pBuffer + 261
    411     ;
    412     mov     si, [ebp+SegArg]
    413     cmp     si, 4
    414     jb      mytkExecPgm_CalltkExecPgm_2
    415     mov     ds, si
    416     mov     si, [ebp+OffArg]            ; ds:si -> arguments
    417     mov     di, [ebp+SegBuffer]
     272    jc      tkepgm_backout2             ; In case of error back (quite unlikely).
     273
     274
     275    ;
     276    ; Copy Args to achTkExecPgmArguments
     277    ;
     278    mov     di, seg achTkExecPgmArguments
    418279    mov     es, di
    419     mov     di, [ebp+OffBuffer]
    420     add     di, 261                     ; es:di -> buffer + 261
    421     mov     cx, [ebp+cchArgs]           ; cx = length of area to copy
     280    mov     edi, offset achTkExecPgmArguments
     281                                        ; es:(e)di -> &achTkExecPgmArguments[0]
     282    mov     word ptr es:[edi], 0        ; Terminate the argument string in case
     283                                        ; there aren't any arguments.('\0\0')
     284                                        ; (We're just about to find that out.)
     285    mov     bx, [ebp + SegArg]
     286    cmp     bx, 4                       ; Is the argument pointer a null-pointer?
     287    jb      tkepgm_setup_parms          ; Skip copy if null pointer.
     288                                        ; Argument string is '\0\0'.
     289    mov     si, [ebp + OffArg]          ; bx:si -> arguments
     290    mov     cx, [ebp + cchArgs]         ; cx = length of area to copy
    422291    push    cs                          ; Problem calling far into the calltab segement.
    423292    call    near ptr FLAT:_f_FuBuff
    424     jc      mytkExecPgm_CalltkExecPgm_X2
    425     jmp     mytkExecPgm_CalltkExecPgm_3
    426 
    427 mytkExecPgm_CalltkExecPgm_2:
    428     mov     word ptr es:[eax], 0        ; Terminate the empty string!
    429 
    430     ;
    431     ; Set new input parameters (call _g_tkExecPgm)
    432     ;
    433     ; ds:dx is to become SegBuffer:OffBuffer
    434     ; di:si is to become SegBuffer:OffBuffer+261
    435     ;
    436 mytkExecPgm_CalltkExecPgm_3:
    437     mov     di, [ebp+SegBuffer]
    438     mov     ds, di
    439     mov     si, [ebp+OffBuffer]
    440     mov     dx, si                      ; ds:dx  SegBuffer:OffBuffer
    441     add     si, 261                     ; di:si  SegBuffer:OffBuffer+261
    442     mov     bx, [ebp+SegEnv]
     293    jc      tkepgm_backout2             ; In case of error back (quite unlikely).
     294
     295
     296    ;
     297    ; Setup new input parameters (call _g_tkExecPgm)
     298    ;
     299    ; ds:dx is to become &achTkExecPgmFilename[0]
     300    ; di:si is to become &achTkExecPgmArguments[0]
     301    ;
     302tkepgm_setup_parms:
     303    mov     ax, [ebp + usExecFlag]
     304    mov     di, seg achTkExecPgmArguments
     305    mov     esi, offset achTkExecPgmArguments ; di:si  &achTkExecPgmArguments[0]
     306    mov     ds, di                            ; Assumes same segment (which of course is true).
     307    mov     edx, offset achTkExecPgmFilename  ; ds:dx  &achTkExecPgmFilename[0]
     308    mov     bx, [ebp + SegEnv]
    443309    mov     es, bx
    444     mov     bx, [ebp+SegEnv]
     310    mov     bx, [ebp + OffEnv]                ; es:bx  Environment
     311
    445312
    446313    ;
    447314    ; Call _g_tkExecPgm
    448315    ;
     316tkepgm_callbehind:
    449317    push    cs                          ; Problem calling far into the calltab segement.
    450318    call    near ptr FLAT:_g_tkExecPgm
    451     pushfd
    452 
    453     ;
    454     ; Release buffer
    455     ;
    456     push    eax
    457     mov     eax, [ebp + pBuffer]
    458     call    ReleaseBuffer
    459     mov     [ebp + pBuffer], 0
    460     pop     eax
    461 
    462     ;
    463     ; Return
    464     ;
    465     push    [ebp + SegFilename]
     319    pushfd                              ; preserve flags
     320    push    eax                         ; preserve result.
     321    push    ecx                         ; preserve ecx just in case
     322    push    edx                         ; preserve edx just in case
     323    mov     ax, seg FLAT:DATA32
     324    mov     ds, ax
     325    mov     es, ax
     326    ASSUME  ds:FLAT, es:FLAT            ; both ds and es are now FLAT
     327
     328
     329    ;
     330    ; Clear loader semaphore?
     331    ; and clear loader state, current exe module and tkExecPgm global data flag.
     332    ;
     333    push    0                           ; Usage count variable.
     334    mov     eax, pulTKSSBase32          ; Get TKSSBase
     335    mov     eax, [eax]
     336    add     eax, esp                    ; Added TKSSBase to the usage count pointer
     337    push    eax                         ; Push address of usage count pointer.
     338    push    pLdrSem                     ; Push pointer to loader semaphore ( = handle).
     339    call    near ptr FLAT:_KSEMQueryMutex@8
     340    or      eax, eax                    ; Check return code. (1 = our / free; 0 = not our but take)
     341    pop     eax                         ; Pops usage count.
     342    je      tkepgm_callbehindret        ; jmp if not taken by us (rc=FALSE).
     343    or      eax, eax                    ; Check usage count.
     344    jz      tkepgm_callbehindret        ; jmp if 0 (=free).
     345    mov     ulLDRState, 0               ; Clears loaderstate. (LDRSTATE_UNKNOWN)
     346    mov     pExeModule, 0               ; Sets the exemodule pointer to NULL.
     347    mov     fTkExecPgm, 0               ; Marks global data invalid.
     348    call    near ptr FLAT:_LDRClearSem@0
     349
     350    ;
     351    ; Restore ds and es (probably unecessary but...) and Return
     352    ;
     353tkepgm_callbehindret:
     354    push    dword ptr [ebp + SegFilename]
    466355    pop     ds
    467     push    [ebp + SegEnv]
     356    push    dword ptr [ebp + SegEnv]
    468357    pop     es
    469     popfd
     358    pop     edx                         ; restore edx
     359    pop     ecx                         ; restore ecx
     360    pop     eax                         ; restore result.
     361    popfd                               ; restore flags
    470362    leave
    471363    retf
    472364
    473 mytkExecPgm_CalltkExecPgm_X2:
    474     ;
    475     ; Release buffer
    476     ;
    477     mov     eax, [ebp + pBuffer]
    478     call    ReleaseBuffer
    479     mov     [ebp + pBuffer], 0
    480 
    481 mytkExecPgm_CalltkExecPgm_X1:
    482     pop     ds
     365
     366;
     367; This is a backout were tkExecPgm probably will backout and we're
     368; allready behind the loader semaphore.
     369;
     370tkepgm_backout2:
     371    ;
     372    ; Set Flat context and invalidate buffer.
     373    ;
     374    mov     ax, seg FLAT:DATA32
     375    mov     ds, ax
     376    ASSUME ds:FLAT
     377    mov     fTkExecPgm, 0               ; Marks global data invalid.
     378
     379    ;
     380    ; Restore parameters. and call the original tkExecPgm
     381    ;
     382    mov     ax, [ebp + usExecFlag]
     383    mov     dx, [ebp + SegFilename]
     384    mov     ds, dx
     385    mov     dx, [ebp + OffFilename]
     386    mov     bx, [ebp + SegEnv]
     387    mov     es, bx
     388    mov     bx, [ebp + OffEnv]
     389    mov     di, [ebp + SegArg]
     390    mov     si, [ebp + OffArg]
     391    jmp     tkepgm_callbehind
     392
     393
     394;
     395; This is a backout were tkExecPgm too is exspected to back out.
     396;
     397tkepgm_backout:
     398    ;
     399    ; Restore parameters. and call the original tkExecPgm
     400    ;
     401    mov     ax, [ebp + usExecFlag]
     402    mov     dx, [ebp + SegFilename]
     403    mov     ds, dx
     404    mov     dx, [ebp + OffFilename]
     405    mov     bx, [ebp + SegEnv]
     406    mov     es, bx
     407    mov     bx, [ebp + OffEnv]
     408    mov     di, [ebp + SegArg]
     409    mov     si, [ebp + OffArg]
    483410
    484411mytkExecPgm_CalltkExecPgm:
    485     push    cs
     412    push    cs                          ; Problem calling far into the calltab segement.
    486413    call    near ptr FLAT:_g_tkExecPgm
    487414    leave
     
    489416mytkExecPgm ENDP
    490417
     418
     419
     420;;
     421; Function which copies the environment data passed into tkExecPgm
     422; to a given buffer.
     423; @cproto    ULONG _Optlink tkExecPgmCopyEnv(char *pachBuffer, unsigned cchBuffer);
     424; @returns   OS/2 return code - NO_ERROR on success.
     425;            0 on error or no data.
     426; @param     pachBuffer     Pointer to buffer which the environment data is
     427;                           to be copied to.
     428;                           (eax)
     429; @param     cchBuffer      Size of the buffer.
     430;                           (edx)
     431; @uses      eax, edx, ecx
     432; @sketch
     433; @status
     434; @author    knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
     435; @remark
     436tkExecPgmCopyEnv PROC NEAR
     437cchEnv  = -04h
     438    ASSUME ds:FLAT, es:FLAT, ss:NOTHING
     439    push    ebp
     440    mov     ebp, esp
     441    lea     esp, [ebp + cchEnv]
     442
     443    push    ebx
     444    mov     ebx, eax                    ; ebx now holds the buffer pointer.
     445
     446    ;
     447    ; Call tkExecPgmEnvLength to get length and check that pointer is valid.
     448    ;
     449    push    edx
     450    call    tkExecPgmEnvLength
     451    pop     ecx                         ; ecx now holds the buffer length.
     452
     453    cmp     eax, 0
     454    ja      tkepce_ok1
     455    mov     eax, 232                    ; ERROR_NO_DATA
     456    jmp     tkepce_ret                  ; Fail if no data or any other error.
     457
     458tkepce_ok1:
     459    cmp     eax, ecx                    ; (ecx is the buffer size.)
     460    jbe     tkepce_ok2                  ; Fail if buffer too small.
     461    mov     eax, 111                    ; ERROR_BUFFER_OVERFLOW
     462    jmp     tkepce_ret
     463
     464tkepce_ok2:
     465    mov     [ebp + cchEnv], eax         ; Save environment length.
     466
     467
     468    ;
     469    ; Thunk the environment 16-bit far pointer to 32-bit.
     470    ;
     471    mov     eax, fpachTkExecPgmEnv
     472    call    D32Hlp_VirtToLin
     473    or      eax, eax                    ; check if thunking were successful.
     474    jnz     tkepce_ok3                  ; Jump if success.
     475    mov     eax, edx                    ; A special feature for D32Hlp_VirtToLin is that edx
     476                                        ; have the error code in case on failure.
     477    jmp tkepce_ret
     478
     479tkepce_ok3:
     480    ;
     481    ; Copy the environment data.
     482    ;
     483    push    3                           ; Fatal if error.
     484    push    dword ptr [ebp + cchEnv]    ; Number of bytes to copy
     485    push    eax                         ; Source buffer pointer. (user)
     486    push    ebx                         ; Target buffer pointer.
     487    call    near ptr FLAT:_TKFuBuff@16
     488
     489tkepce_ret:
     490    pop     ebx
     491    leave
     492    ret
     493tkExecPgmCopyEnv ENDP
     494
     495
     496
     497;;
     498; This function gets the length of the tkExecPgm environment data.
     499; @cproto    ULONG _Optlink tkExecPgmEnvLength(void);
     500; @returns   Environment data length in bytes.
     501; @uses      eax, edx, ecx
     502; @sketch
     503; @status
     504; @author    knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
     505; @remark
     506tkExecPgmEnvLength PROC NEAR
     507    ASSUME ds:FLAT, es:FLAT, ss:NOTHING
     508    push    ebp
     509    mov     ebp, esp
     510
     511    ;
     512    ; Push register which needs to be presered.
     513    ;
     514    push    es
     515    push    ds
     516    push    esi
     517    push    edi
     518    push    ebx
     519
     520
     521    ;
     522    ; Check that the data is valid.
     523    ;
     524    cmp     ulLDRState, 1               ; LDRSTATE_TKEXECPGM
     525    jnz     tkepel_err_ret
     526
     527
     528    ;
     529    ; Check if the environment pointer is NULL.
     530    ;
     531    mov     ebx, fpachTkExecPgmEnv
     532    ror     ebx, 16
     533    cmp     bx, 4
     534    jb      tkepel_err_ret
     535
     536
     537tkepel1:
     538    ;
     539    ; Get the environment length
     540    ;
     541    mov     edi, ebx
     542    ror     edi, 16                     ; bx:di -> [fpachTkExecPgmEnv]
     543    xor     ecx, ecx
     544    push    cs                          ; Problem calling far into the calltab segement.
     545    call    near ptr FLAT:_f_FuStrLenZ
     546    jc      tkepel_err_ret
     547    movzx   eax, cx
     548    jmp     tkepel_ret
     549
     550
     551; Failure
     552tkepel_err_ret:
     553    xor     eax, eax
     554
     555
     556; Return
     557tkepel_ret:
     558    pop     ebx                         ; restore registers
     559    pop     edi
     560    pop     esi
     561    pop     ds
     562    pop     es
     563    leave
     564    ret
     565tkExecPgmEnvLength ENDP
     566
     567
     568
     569
     570
    491571CODE32 ENDS
    492 endif
    493572
    494573
Note: See TracChangeset for help on using the changeset viewer.