Changeset 1274 for trunk/src


Ignore:
Timestamp:
Oct 14, 1999, 3:39:13 AM (26 years ago)
Author:
bird
Message:

New Pe2Lx implementation.

Location:
trunk/src/kernel32
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kernel32/KERNEL32.DEF

    r1131 r1274  
    1 ; $Id: KERNEL32.DEF,v 1.41 1999-10-04 20:52:33 sandervl Exp $
     1; $Id: KERNEL32.DEF,v 1.42 1999-10-14 01:37:55 bird Exp $
    22
    33;Created by BLAST for IBM's compiler
     
    1818   DosAliasMem                 =  DOSCALLS.298
    1919  _DosAliasMem                 =  DOSCALLS.298
     20   DosQuerySysState            =  DOSCALLS.368
    2021
    2122
     
    952953    WriteLogError                 = WriteLogError                 @1214
    953954
    954 ;Used by tibfix page in exe (change ordinal in lx.cpp too!!)
    955     _RegisterPe2LxExe@48                                          @1203
    956     _RegisterPe2LxDll@48                                          @1209
     955;Used by tibfix page in exe (change ordinal in pe2lx.cpp too!!)
     956    _RegisterPe2LxExe@12                                          @1203
     957    _RegisterPe2LxDll@12                                          @1209
    957958
    958959    _CreateWin32PeLdrExe@8                                        @1236
  • trunk/src/kernel32/windllpe2lx.cpp

    r956 r1274  
    1 /* $Id: windllpe2lx.cpp,v 1.1 1999-09-15 23:39:07 sandervl Exp $ */
     1/* $Id: windllpe2lx.cpp,v 1.2 1999-10-14 01:37:55 bird Exp $ */
    22
    33/*
     
    55 *
    66 * Copyright 1999 Sander van Leeuwen (sandervl@xs4all.nl)
    7  *
     7 * Copyright 1999 knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
    88 *
    99 * Project Odin Software License can be found in LICENSE.TXT
    1010 *
    1111 */
    12 #define INCL_DOSFILEMGR          /* File Manager values      */
    13 #define INCL_DOSERRORS           /* DOS Error values         */
    14 #define INCL_DOSPROCESS          /* DOS Process values       */
    15 #define INCL_DOSMODULEMGR
    16 #define INCL_DOSMISC             /* DOS Miscellanous values  */
    17 #define INCL_WIN
    18 #include <os2wrap.h>    //Odin32 OS/2 api wrappers
    19 #include <stdio.h>
    20 #include <string.h>
     12
     13/*******************************************************************************
     14*   Defined Constants And Macros                                               *
     15*******************************************************************************/
     16#define INCL_DOSERRORS      /* DOS Error values */
     17#define INCL_DOSMODULEMGR   /* DOS Module management */
     18
     19
     20/*******************************************************************************
     21*   Header Files                                                               *
     22*******************************************************************************/
     23#include <os2wrap.h>        //Odin32 OS/2 api wrappers
     24
    2125#include <stdlib.h>
    22 #include <iostream.h>
    23 #include <fstream.h>
     26
     27#include <win32type.h>
    2428#include <misc.h>
    25 #include <win32type.h>
    26 #include <pefile.h>
    2729#include <windllpe2lx.h>
    2830#include <wprocess.h>
    29 #include "cio.h"
    30 #include "oslibmisc.h"
    31 #include "oslibdos.h"
    32 
    33 #include "conwin.h"          // Windows Header for console only
     31
     32#include "cio.h"            // I/O
     33#include "oslibmisc.h"      // OSLibGetDllName
     34#include "conwin.h"         // Windows Header for console only
    3435#include "console.h"
    3536
    36 //******************************************************************************
    37 //******************************************************************************
    38 ULONG WIN32API RegisterPe2LxDll(WIN32DLLENTRY pfnDllEntry, PIMAGE_TLS_CALLBACK *TlsCallbackAddr,
    39                                 LPDWORD TlsIndexAddr, ULONG TlsInitSize,
    40                                 ULONG TlsTotalSize, LPVOID TlsAddress,
    41                                 LONG Win32TableId, LONG NameTableId, LONG VersionResId,
    42                                 LONG Pe2lxVersion, HINSTANCE hinstance, ULONG dwAttachType)
    43 {
    44  char *name;
    45 
    46   Win32Pe2LxDll *winmod = (Win32Pe2LxDll *)Win32DllBase::findModule(hinstance);
    47   if(dwAttachType == 0)
    48   { //Process attach
    49         if(getenv("WIN32_IOPL2")) {
    50                 io_init1();
    51         }
    52         name = OSLibGetDllName(hinstance);
    53         CheckVersion(Pe2lxVersion, name);
    54 
    55         dprintf(("RegisterDll %X %s reason %d\n", hinstance, name, dwAttachType));
    56         dprintf(("RegisterDll Win32TableId = %x", Win32TableId));
    57         dprintf(("RegisterDll NameTableId  = %x", NameTableId));
    58         dprintf(("RegisterDll VersionResId = %x", VersionResId));
    59         dprintf(("RegisterDll Pe2lxVersion = %x", Pe2lxVersion));
    60 
    61         //converted win32 dll loaded by OS/2 loader
    62         winmod = new Win32Pe2LxDll(hinstance, NameTableId, Win32TableId, pfnDllEntry);
    63         if(winmod == NULL) {
    64                 eprintf(("Failed to allocate module object!\n"));
    65                 DebugInt3();
    66                 return 0;                    //fail dll load
    67         }
    68         winmod->setTLSAddress(TlsAddress);
    69         winmod->setTLSInitSize(TlsInitSize);
    70         winmod->setTLSTotalSize(TlsTotalSize);
    71         winmod->setTLSIndexAddr(TlsIndexAddr);
    72         winmod->setTLSCallBackAddr(TlsCallbackAddr);
    73 
    74         /* @@@PH 1998/03/17 console devices initialization */
    75         iConsoleDevicesRegister();
    76 
    77         //SvL: 19-8-'98
    78         winmod->AddRef();
    79         winmod->setVersionId(VersionResId);
    80 
    81         winmod->attachProcess();
    82    }
    83    else {//process detach
    84         if(winmod != NULL && !fFreeLibrary) {
    85                 return 0;   //don't unload (OS/2 dll unload bug)
    86         }
    87         //Runtime environment could already be gone, so don't do this
    88         // dprintf(("KERNEL32: Dll Removed by FreeLibrary or ExitProcess\n"));
    89    }
    90    return 1;   //success
    91 }
    92 //******************************************************************************
    93 //******************************************************************************
    94 Win32Pe2LxDll::Win32Pe2LxDll(HINSTANCE hinstance, int NameTableId, int Win32TableId,
    95                              WIN32DLLENTRY DllEntryPoint) :
    96                         Win32ImageBase(hinstance),
    97                         Win32DllBase(hinstance, DllEntryPoint),
    98                         Win32Pe2LxImage(hinstance, NameTableId, Win32TableId)
    99 {
    100   dprintf(("Win32Pe2LxDll::Win32Pe2LxDll %s", szModule));
    101 }
    102 //******************************************************************************
    103 //******************************************************************************
     37
     38/**
     39 * Register an Pe2Lx Dll module. Called from TIBFix code in Dll Pe2Lx module.
     40 * @returns   1 on success.
     41 *            0 on failure.
     42 * @param     Pe2LxVersion  Pe2Lx version. High bit is Win32k indicator and must be masked off!
     43 * @param     hInstance     Module handle (OS/2).
     44 * @param     dwAttachType  0 = attach dll
     45 *                          1 = detach dll
     46 * @sketch    Try find module.
     47 *            IF attach process THEN
     48 *            BEGIN
     49 *            END
     50 *                Init I/O.
     51 *                Get Lib name and match Pe2Lx version with kernel32 version.
     52 *                Write info to the log.
     53 *                Try create pe2lx dll object.
     54 *                Console devices initialization.
     55 *                Add reference and attach dll to process.
     56 *            ELSE
     57 *            BEGIN
     58 *                IF module found AND not freelibrary THEN
     59 *                    fail (return 0) due to OS/2 bug.
     60 *            END
     61 *            return successfully (return 1)
     62 * @status    completely implemented.
     63 * @author    Sander van Leeuwen, knut st. osmundsen
     64 */
     65ULONG WIN32API RegisterPe2LxDll(ULONG ulPe2LxVersion, HINSTANCE hinstance, ULONG ulAttachType)
     66{
     67    char *pszName;
     68
     69    //DebugInt3();
     70
     71    Win32Pe2LxDll *pWinMod = (Win32Pe2LxDll *)Win32DllBase::findModule(hinstance);
     72    if (ulAttachType == 0UL)
     73    {   /* Process attach */
     74
     75        /* Init I/O */
     76        if (getenv("WIN32_IOPL2"))
     77            io_init1();
     78
     79        /* Get Lib name and match Pe2Lx version with kernel32 version. */
     80        pszName = OSLibGetDllName(hinstance);
     81        CheckVersion(ulPe2LxVersion & ~0x80000000UL, pszName);
     82
     83        /* Write info to the log. */
     84        dprintf(("RegisterPe2LxExe: ulPe2LxVersion = %#x\n", ulPe2LxVersion));
     85        dprintf(("RegisterPe2LxExe: hinstance = %#x\n", hinstance));
     86        dprintf(("RegisterPe2LxExe: ulAttachType = %#x (reason)\n", ulAttachType));
     87        dprintf(("RegisterPe2LxExe: name = %s\n", OSLibGetDllName(hinstance)));
     88
     89        /* Try create pe2lx dll object. */
     90        try
     91        {
     92            pWinMod = new Win32Pe2LxDll(hinstance, (ulPe2LxVersion & 0x80000000UL) == 0x80000000UL);
     93            if (pWinMod == NULL)
     94                throw ((ULONG)ERROR_NOT_ENOUGH_MEMORY);
     95
     96            /* @@@PH 1998/03/17 Console devices initialization */
     97            iConsoleDevicesRegister();
     98
     99            /* Add reference and attach dll to process. */
     100            pWinMod->AddRef();
     101            pWinMod->attachProcess();
     102        }
     103        catch(ULONG ul)
     104        {
     105            eprintf(("RegisterPe2LxDLL: Failed to create module object, ul=%d\n", ul));
     106            DebugInt3();
     107            return 0;  /* fail dll load */
     108        }
     109    }
     110    else
     111    {   /* process detach */
     112        if (pWinMod != NULL && !fFreeLibrary)
     113            return 0;   /* don't unload (OS/2 dll unload bug) - see OS2.bugs in root dir. */
     114
     115        #if 0 /* Runtime environment could already be gone, so don't do this */
     116            dprintf(("KERNEL32: Dll Removed by FreeLibrary or ExitProcess\n"));
     117        #endif
     118    }
     119
     120    return 1;   /* success */
     121}
     122
     123
     124/**
     125 * Constructor - creates an pe2lx dll object from a module handle to a pe2lx dll module.
     126 * @param     hinstance   Module handle.
     127 * @param     fWin32k     TRUE:  Win32k module.
     128 *                        FALSE: Pe2Lx module.
     129 * @status    completely implemented.
     130 * @author    Sander van Leeuwen, knut st. osmundsen
     131 */
     132Win32Pe2LxDll::Win32Pe2LxDll(HINSTANCE hinstance, BOOL fWin32k) throw(ULONG)
     133    : Win32ImageBase(hinstance),
     134    Win32DllBase(hinstance, NULL),
     135    Win32Pe2LxImage(hinstance, fWin32k)
     136{
     137    dprintf(("Win32Pe2LxDll::Win32Pe2LxDll %s", szModule));
     138    /* set entry point. */
     139    dllEntryPoint = (WIN32DLLENTRY)entryPoint;
     140}
     141
     142
     143/**
     144 * Destructor - does nothing.
     145 * @status    completely implemented.
     146 * @author    Sander van Leeuwen
     147 */
    104148Win32Pe2LxDll::~Win32Pe2LxDll()
    105149{
    106   dprintf(("Win32Pe2LxDll::~Win32Pe2LxDll %s", szModule));
    107 }
    108 //******************************************************************************
    109 //******************************************************************************
     150    dprintf(("Win32Pe2LxDll::~Win32Pe2LxDll %s", szModule));
     151}
     152
     153
     154/**
     155 * Gets pointer to an exported procedure by procedure name.
     156 * @returns   Address of exported procedure. 0UL if not found.
     157 * @param     name  Exported procedure name.
     158 * @status    completely implemented.
     159 * @author    Sander van Leeuwen
     160 * @remark
     161 */
    110162ULONG Win32Pe2LxDll::getApi(char *name)
    111163{
    112   APIRET      rc;
    113   ULONG       apiaddr;
    114 
    115   rc = DosQueryProcAddr(hinstance, 0, name, (PFN *)&apiaddr);
    116   if(rc) 
    117   {
    118         return(0);
    119   }
    120   return(apiaddr);
    121 }
    122 //******************************************************************************
    123 //******************************************************************************
     164    APIRET      rc;
     165    ULONG       ulApiAddr;
     166
     167    rc = DosQueryProcAddr(hinstance, 0, name, (PFN *)&ulApiAddr);
     168    return rc == NO_ERROR ? ulApiAddr : 0;
     169}
     170
     171
     172/**
     173 * Gets pointer to an exported procedure by ordinal.
     174 * @returns   Pointer to an exported procedure. 0UL if not found.
     175 * @param     ordinal  Export ordinal number.
     176 * @status    completely implemented.
     177 * @author    Sander van Leeuwen
     178 * @remark    FIXME:
     179 *            This function should be implemented for both Exe and Dll images!
     180 *            It could be done similar in both peldr image and pe2lx images by
     181 *            accessing PE structures.
     182 */
    124183ULONG Win32Pe2LxDll::getApi(int ordinal)
    125184{
    126  APIRET      rc;
    127  ULONG       apiaddr;
    128 
    129   rc = DosQueryProcAddr(hinstance, ordinal, NULL, (PFN *)&apiaddr);
    130   if(rc)        return(0);
    131   else          return(apiaddr);
    132 }
    133 //******************************************************************************
    134 //******************************************************************************
     185    APIRET      rc;
     186    ULONG       ulApiAddr;
     187
     188    rc = DosQueryProcAddr(hinstance, ordinal, NULL, (PFN *)&ulApiAddr);
     189
     190    return rc == NO_ERROR ? ulApiAddr : 0;
     191}
     192
     193
     194/**
     195 * Simple question: -Native LX dll?
     196 *                  -No!
     197 * @returns   FALSE.
     198 * @status    completely implemented.
     199 * @author    Sander van Leeuwen
     200 */
    135201BOOL Win32Pe2LxDll::isLxDll()
    136202{
    137   return FALSE;
    138 }
    139 //******************************************************************************
    140 //******************************************************************************
     203    return FALSE;
     204}
     205
  • trunk/src/kernel32/winexepe2lx.cpp

    r956 r1274  
    1 /* $Id: winexepe2lx.cpp,v 1.1 1999-09-15 23:39:07 sandervl Exp $ */
     1/* $Id: winexepe2lx.cpp,v 1.2 1999-10-14 01:37:56 bird Exp $ */
    22
    33/*
     
    55 *
    66 * Copyright 1998-1999 Sander van Leeuwen (sandervl@xs4all.nl)
    7  *
     7 * Copyright 1999 knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
    88 *
    99 * Project Odin Software License can be found in LICENSE.TXT
    1010 *
    1111 */
    12 #define INCL_DOSFILEMGR          /* File Manager values      */
    13 #define INCL_DOSERRORS           /* DOS Error values         */
    14 #define INCL_DOSPROCESS          /* DOS Process values       */
    15 #define INCL_DOSMISC             /* DOS Miscellanous values  */
    16 #define INCL_WIN
    17 #include <os2wrap.h>    //Odin32 OS/2 api wrappers
    18 #include <stdio.h>
    19 #include <string.h>
    20 #include <stdlib.h>
    21 #include <iostream.h>
    22 #include <fstream.h>
     12
     13/*******************************************************************************
     14*   Defined Constants And Macros                                               *
     15*******************************************************************************/
     16#define INCL_DOSERRORS      /* DOS Error values         */
     17
     18
     19/*******************************************************************************
     20*   Header Files                                                               *
     21*******************************************************************************/
     22#include <os2wrap.h>        //Odin32 OS/2 api wrappers
     23
     24#include <stdlib.h>         //getenv
     25
    2326#include <misc.h>
    2427#include <win32type.h>
    2528#include <winexepe2lx.h>
    26 #include <wprocess.h>
    27 #include <pefile.h>
    28 #include "cio.h"
    2929
    30 #include "oslibmisc.h"
    31 #include "oslibdos.h"
    32 
    33 #include "conwin.h"          // Windows Header for console only
     30#include "cio.h"            // I/O
     31#include "oslibmisc.h"      // OSLibGetDllName
     32#include "conwin.h"         // Windows Header for console only
    3433#include "console.h"
    3534
    36 /******************************************************************************/
    37 //******************************************************************************
    38 void WIN32API RegisterPe2LxExe(WIN32EXEENTRY EntryPoint, PIMAGE_TLS_CALLBACK *TlsCallbackAddr,
    39                                LPDWORD TlsIndexAddr, ULONG TlsInitSize,
    40                                ULONG TlsTotalSize, LPVOID TlsAddress,
    41                                LONG Win32TableId, LONG NameTableId, LONG VersionResId,
    42                                LONG Pe2lxVersion, HINSTANCE hinstance, ULONG dwReserved)
     35
     36/**
     37 * Register a Pe2Lx Executable module.
     38 * This is called from the TIBFix code in the Pe2Lx exe. It creates the WinExe object from
     39 * the instance handle passed in.
     40 * @param     ulPe2LxVersion   Pe2Lx version number.
     41 * @param     hinstance        Module handle.
     42 * @param     ulReserved       Reserved.
     43 * @sketch    I/O init.
     44 *            Check that pe2lx version matches the version of kernel32.dll.
     45 *            Frees WinExe if is not NULL - should never happen!
     46 *            Write info to the log.
     47 *            Create Pe2Lx Exe object.
     48 *            Call start (which calls the entry point).
     49 * @status    completely implemented.
     50 * @author    Sander van Leeuwen, knut st. osmundsen
     51 */
     52void WIN32API RegisterPe2LxExe(ULONG ulPe2LxVersion, HINSTANCE hinstance, ULONG ulReserved)
    4353{
    44   if(WinExe != NULL) //should never happen
    45         delete(WinExe);
     54    /* I/O init. */
     55    if (getenv("WIN32_IOPL2"))
     56        io_init1();
    4657
    47   CheckVersion(Pe2lxVersion, OSLibGetDllName(hinstance));
     58    /* Check that pe2lx version matches the version of kernel32.dll. */
     59    CheckVersion(ulPe2LxVersion & ~0x80000000UL, OSLibGetDllName(hinstance));
    4860
    49   if(getenv("WIN32_IOPL2")) {
    50     io_init1();
    51   }
     61    /* Frees WinExe if is not NULL - should never happen! */
     62    if (WinExe != NULL)
     63    {
     64        dprintf(("RegisterPe2LxExe: WinExe != NULL\n"));
     65        delete(WinExe);
     66    }
    5267
    53   Win32Pe2LxExe *winexe;
     68    /* Write info to the log. */
     69    dprintf(("RegisterPe2LxExe: ulPe2LxVersion = %#x\n", ulPe2LxVersion));
     70    dprintf(("RegisterPe2LxExe: hinstance = %#x\n", hinstance));
     71    dprintf(("RegisterPe2LxExe: ulReserved = %#x\n", ulReserved));
     72    dprintf(("RegisterPe2LxExe: name = %s\n", OSLibGetDllName(hinstance)));
    5473
    55   winexe = new Win32Pe2LxExe(hinstance, NameTableId, Win32TableId);
     74    /* Create Pe2Lx Exe object. */
     75    try
     76    {
     77        Win32Pe2LxExe *pWinPe2LxExe;
     78        pWinPe2LxExe = new Win32Pe2LxExe(hinstance, (ulPe2LxVersion & 0x80000000UL) == 0x80000000UL);
     79        if (pWinPe2LxExe == NULL)
     80            throw ((ULONG)ERROR_NOT_ENOUGH_MEMORY);
    5681
    57   if(winexe) {
    58         dprintf(("RegisterExe Win32TableId = %x", Win32TableId));
    59         dprintf(("RegisterExe NameTableId  = %x", NameTableId));
    60         dprintf(("RegisterExe VersionResId = %x", VersionResId));
    61         dprintf(("RegisterExe Pe2lxVersion = %x", Pe2lxVersion));
     82        /* Call start (which calls the entry point). */
     83        /*DebugInt3();*/
     84        pWinPe2LxExe->start();
     85    }
     86    catch (ULONG ul)
     87    {
     88        eprintf(("Win32Pe2LxExe creation failed! ul=%d\n", ul));
     89        DebugInt3();
     90        return;
     91    }
     92}
    6293
    63         winexe->setVersionId(VersionResId);
    64         winexe->setEntryPoint((ULONG)EntryPoint);
    65         winexe->setTLSAddress(TlsAddress);
    66         winexe->setTLSInitSize(TlsInitSize);
    67         winexe->setTLSTotalSize(TlsTotalSize);
    68         winexe->setTLSIndexAddr(TlsIndexAddr);
    69         winexe->setTLSCallBackAddr(TlsCallbackAddr);
    7094
    71         winexe->start();
    72   }
    73   else {
    74         eprintf(("Win32Pe2LxExe creation failed!\n"));
    75         DebugInt3();
    76         return;
    77   }
     95/**
     96 * Constructor - creates an pe2lx exe object from a module handle to a pe2lx exe module.
     97 * @param     hinstance   Module handle.
     98 * @param     fWin32k     TRUE:  Win32k module.
     99 *                        FALSE: Pe2Lx module.
     100 * @status    completely implmented.
     101 * @author    Sander van Leeuwen, knut st. osmundsen
     102 * @remark    Win32Pe2LxImage may throw an exception!
     103 */
     104Win32Pe2LxExe::Win32Pe2LxExe(HINSTANCE hinstance, BOOL fWin32k) throw(ULONG):
     105    Win32ImageBase(hinstance),
     106    Win32ExeBase(hinstance),
     107    Win32Pe2LxImage(hinstance, fWin32k)
     108{
     109    fConsoleApp = pNtHdrs->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI;
     110
     111    /* console app? */
     112    if (fConsoleApp)
     113    {
     114        APIRET rc;
     115
     116        dprintf(("Console application!\n"));
     117
     118        rc = iConsoleInit();    /* initialize console subsystem */
     119        if (rc != NO_ERROR)     /* check for errors */
     120            dprintf(("KERNEL32:Win32Image:Init ConsoleInit failed with %u.\n", rc));
     121    }
    78122}
    79 //******************************************************************************
    80 //******************************************************************************
    81 Win32Pe2LxExe::Win32Pe2LxExe(HINSTANCE hinstance, int NameTableId, int Win32TableId) :
    82          Win32ImageBase(hinstance),
    83          Win32ExeBase(hinstance),
    84          Win32Pe2LxImage(hinstance, NameTableId, Win32TableId)
    85 {
    86   if(GET_CONSOLE(Win32TableId) == 1) {//console app
    87    dprintf(("Console application!\n"));
    88123
    89    fConsoleApp = TRUE;
    90    APIRET rc = iConsoleInit();                     /* initialize console subsystem */
    91    if (rc != NO_ERROR)                                  /* check for errors */
    92             dprintf(("KERNEL32:Win32Image:Init ConsoleInit failed with %u.\n", rc));
    93   }
    94   WinExe = this;
    95 }
    96 //******************************************************************************
    97 //******************************************************************************
     124
     125/**
     126 * Destructor - does nothing.
     127 * @status    completely implemented.
     128 * @author    Sander van Leeuwen
     129 */
    98130Win32Pe2LxExe::~Win32Pe2LxExe()
    99131{
    100132}
    101 //******************************************************************************
    102 //******************************************************************************
  • trunk/src/kernel32/winimagepe2lx.cpp

    r956 r1274  
    1 /* $Id: winimagepe2lx.cpp,v 1.1 1999-09-15 23:39:08 sandervl Exp $ */
     1/* $Id: winimagepe2lx.cpp,v 1.2 1999-10-14 01:37:56 bird Exp $ */
    22
    33/*
     
    55 *
    66 * Copyright 1998-1999 Sander van Leeuwen (sandervl@xs4all.nl)
    7  * Copyright 1998 Knut St. Osmundsen
     7 * Copyright 1998-1999 knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
    88 *
    99 * Project Odin Software License can be found in LICENSE.TXT
     
    1111 */
    1212
    13 #define INCL_DOSFILEMGR          /* File Manager values      */
    14 #define INCL_DOSMODULEMGR
    15 #define INCL_DOSERRORS           /* DOS Error values         */
    16 #define INCL_DOSPROCESS          /* DOS Process values       */
    17 #define INCL_DOSMISC             /* DOS Miscellanous values  */
    18 #define INCL_WIN
    19 #define INCL_BASE
    20 #include <os2wrap.h>             //Odin32 OS/2 api wrappers
    21 
    22 #include <stdio.h>
    23 #include <string.h>
     13/*******************************************************************************
     14*   Defined Constants And Macros                                               *
     15*******************************************************************************/
     16#define INCL_DOSERRORS          /* DOS Error values */
     17#define INCL_DOSPROFILE         /* DosQuerySysState (Toolkit 4.5) */
     18
     19#define ALIGN(a, alignment) (((a) + (alignment - 1UL)) & ~(alignment - 1UL))
     20
     21
     22/*******************************************************************************
     23*   Header Files                                                               *
     24*******************************************************************************/
     25#include <os2wrap.h>            //Odin32 OS/2 api wrappers
     26
     27#include <malloc.h>
     28#include <process.h>
    2429#include <stdlib.h>
    2530
    26 #include <assert.h>
     31#include <win32type.h>
    2732#include <misc.h>
    28 #include <win32type.h>
    2933#include <winimagebase.h>
    3034#include <winimagepe2lx.h>
    31 #include <windllbase.h>
    32 #include <winexebase.h>
    33 #include <winexepe2lx.h>
    34 #include <pefile.h>
    35 #include <unicode.h>
    36 #include <winres.h>
    37 #include "oslibmisc.h"
    38 #include "initterm.h"
    39 #include <win\virtual.h>
    40 
    41 //******************************************************************************
    42 //******************************************************************************
    43 Win32Pe2LxImage::Win32Pe2LxImage(HINSTANCE hinstance, int NameTableId, int Win32TableId)
    44                : Win32ImageBase(hinstance),
    45                  NameTable(NULL), Win32Table(NULL), VersionId(0)
    46 {
    47  APIRET rc;
    48 
    49   szFileName[0] = 0;
    50 
    51   char *name = OSLibGetDllName(hinstance);
    52   strcpy(szFileName, name);
    53   strupr(szFileName);
    54   char *dot = strstr(szFileName, ".");
    55   while(dot) {
    56         char *newdot = strstr(dot+1, ".");
    57         if(newdot == NULL)      break;
    58         dot = newdot;
    59   }
    60   if(dot)
    61         *dot = 0;
    62 
    63   this->NameTableId  = NameTableId;
    64   this->Win32TableId = Win32TableId;
    65 
    66   if(NameTableId != NO_NAMETABLE) {
    67     //Load name table resource
    68     rc = DosGetResource(hinstance, RT_RCDATA, NameTableId, (PPVOID)&NameTable);
    69     if(rc) {
    70         eprintf(("Can't find converted name resource (rc %d)!!\n", rc));
    71         return;
    72     }
    73   }
    74   else  this->NameTableId = 0;
    75 
    76   //Load win32 id table resource
    77   if((Win32TableId & 0xFFFFFF) != NO_LOOKUPTABLE) {
    78     rc = DosGetResource(hinstance, RT_RCDATA, Win32TableId, (PPVOID)&Win32Table);
    79     if(rc) {
    80         eprintf(("Can't find win32 id resource (rc %d)!!\n", rc));
    81         return;
    82     }
    83   }
    84   else  this->Win32TableId = 0;
    85 
    86 }
    87 //******************************************************************************
    88 //******************************************************************************
     35
     36
     37/*******************************************************************************
     38*   Structures and Typedefs                                                    *
     39*******************************************************************************/
     40#ifndef QS_MTE
     41   /* From OS/2 Toolkit v4.5 (BSEDOS.H) */
     42
     43   /* Global Record structure
     44    * Holds all global system information. Placed first in user buffer
     45    */
     46   typedef struct qsGrec_s {  /* qsGrec */
     47           ULONG         cThrds;
     48           ULONG         c32SSem;
     49           ULONG         cMFTNodes;
     50   }qsGrec_t;
     51
     52   /*
     53    *      System wide MTE information
     54    *      ________________________________
     55    *      |       pNextRec                |----|
     56    *      |-------------------------------|    |
     57    *      |       hmte                    |    |
     58    *      |-------------------------------|    |
     59    *      |       ctImpMod                |    |
     60    *      |-------------------------------|    |
     61    *      |       ctObj                   |    |
     62    *      |-------------------------------|    |
     63    *      |       pObjInfo                |----|----------|
     64    *      |-------------------------------|    |          |
     65    *      |       pName                   |----|----|     |
     66    *      |-------------------------------|    |    |     |
     67    *      |       imported module handles |    |    |     |
     68    *      |          .                    |    |    |     |
     69    *      |          .                    |    |    |     |
     70    *      |          .                    |    |    |     |
     71    *      |-------------------------------| <--|----|     |
     72    *      |       "pathname"              |    |          |
     73    *      |-------------------------------| <--|----------|
     74    *      |       Object records          |    |
     75    *      |       (if requested)          |    |
     76    *      |_______________________________|    |
     77    *                                      <-----
     78    *      NOTE that if the level bit is set to QS_MTE, the base Lib record will be followed
     79    *      by a series of object records (qsLObj_t); one for each object of the
     80    *      module.
     81    */
     82
     83   typedef struct qsLObjrec_s {  /* qsLOrec */
     84           ULONG         oaddr;  /* object address */
     85           ULONG         osize;  /* object size */
     86           ULONG         oflags; /* object flags */
     87   } qsLObjrec_t;
     88
     89   typedef struct qsLrec_s {     /* qsLrec */
     90           void  FAR        *pNextRec;      /* pointer to next record in buffer */
     91           USHORT           hmte;           /* handle for this mte */
     92           USHORT           fFlat;          /* true if 32 bit module */
     93           ULONG            ctImpMod;       /* # of imported modules in table */
     94           ULONG            ctObj;          /* # of objects in module (mte_objcnt)*/
     95           qsLObjrec_t FAR  *pObjInfo;      /* pointer to per object info if any */
     96           UCHAR     FAR    *pName;         /* -> name string following struc */
     97   } qsLrec_t;
     98
     99#endif
     100
     101
     102/*******************************************************************************
     103*   External Functions                                                         *
     104*******************************************************************************/
     105#ifndef QS_MTE
     106   /* from OS/2 Toolkit v4.5 */
     107
     108   APIRET APIENTRY DosQuerySysState(ULONG EntityList, ULONG EntityLevel, PID pid,
     109                                    TID tid, PVOID pDataBuf, ULONG cbBuf);
     110    #define QS_MTE         0x0004
     111#endif
     112
     113
     114
     115/**
     116 * Constructor - creates an pe2lx image object from a module handle to a pe2lx module.
     117 * @param     hinstance   OS/2 module handle.
     118 * @param     fWin32k     TRUE:  Win32k module.
     119 *                        FALSE: Pe2Lx module.
     120 * @sketch    Get section placement and sizes for this module. (paSections, cSections)
     121 *            Verify that there is at least one section - the header section.
     122 *            Locate the NT headers.
     123 *            Set pNtHdrs pointer.
     124 *            Validate the NT headers.
     125 *            Read the PE section table the set the RVAs in paSections.
     126 *            Locate and set the entrypoint.
     127 *            Locate the resource directory (if any). (pResDir, pResourceSectionStart)
     128 *            TLS - FIXME!
     129 * @status    partially implmented.
     130 * @author    knut st. osmundsen, Sander van Leeuwen
     131 */
     132Win32Pe2LxImage::Win32Pe2LxImage(HINSTANCE hinstance, BOOL fWin32k) throw(ULONG)
     133    : Win32ImageBase(hinstance),
     134    paSections(NULL), cSections(0), pNtHdrs(NULL), fWin32k(fWin32k)
     135{
     136    APIRET rc;
     137
     138    /* Get section placement and sizes for this module. (paSections, cSections) */
     139    rc = getSections();
     140    if (rc != NO_ERROR)
     141    {
     142        dprintf(("Win32Pe2LxImage::Win32Pe2LxImage: error - getSection failed with rc=%d\n",
     143                 rc));
     144        Win32Pe2LxImage::~Win32Pe2LxImage();
     145        throw((ULONG)rc);
     146    }
     147
     148    /* Verify that there is at least one section - the header section. */
     149    if (cSections < 1)
     150    {
     151        dprintf(("Win32Pe2LxImage::Win32Pe2LxImage: no header section, cSections is 0\n"));
     152        Win32Pe2LxImage::~Win32Pe2LxImage();
     153        throw((ULONG)ERROR_BAD_EXE_FORMAT);
     154    }
     155
     156    /* Locate the NT headers. */
     157    PIMAGE_DOS_HEADER pDosHdr = (PIMAGE_DOS_HEADER)paSections[0].ulAddress;
     158    if ((pDosHdr->e_magic != IMAGE_DOS_SIGNATURE
     159        || pDosHdr->e_lfanew < sizeof(IMAGE_DOS_HEADER)  /* Larger than 64 bytes */
     160        || pDosHdr->e_lfanew > 0x04000000UL              /* or less that 64MB. */
     161        )
     162        && !*(PDWORD)paSections[0].ulAddress == IMAGE_NT_SIGNATURE
     163        )
     164    {
     165        dprintf(("Win32Pe2LxImage::Win32Pe2LxImage: Not a pe2lx image!(?)\n"));
     166        Win32Pe2LxImage::~Win32Pe2LxImage();
     167        throw((ULONG)ERROR_BAD_EXE_FORMAT);
     168    }
     169
     170    /* Set pNtHdrs pointer. */
     171    if (pDosHdr->e_magic == IMAGE_DOS_SIGNATURE)
     172        pNtHdrs = (PIMAGE_NT_HEADERS)(paSections[0].ulAddress + pDosHdr->e_lfanew);
     173    else
     174        pNtHdrs = (PIMAGE_NT_HEADERS)paSections[0].ulAddress;
     175
     176    /* Validate the NT headers. */
     177    if (pNtHdrs->Signature != IMAGE_NT_SIGNATURE
     178        || pNtHdrs->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR_MAGIC
     179        || pNtHdrs->FileHeader.Machine != IMAGE_FILE_MACHINE_I386
     180        || (cSections != 1 /* all in one object */
     181            && pNtHdrs->FileHeader.NumberOfSections
     182               > cSections - 1 - (pNtHdrs->FileHeader.Characteristics & IMAGE_FILE_DLL ? 0 : 1) /* hdr section and stack */
     183            )
     184        /* TODO: add more tests? */
     185        )
     186    {
     187        dprintf(("Win32Pe2LxImage::Win32Pe2LxImage: Not a pe2lx image!(?)\n"));
     188        Win32Pe2LxImage::~Win32Pe2LxImage();
     189        throw((ULONG)ERROR_BAD_EXE_FORMAT);
     190    }
     191
     192    /* set RVAs */
     193    rc = setSectionRVAs();
     194    if (rc != NO_ERROR)
     195    {
     196        dprintf(("Win32Pe2LxImage::Win32Pe2LxImage: setSectionRVAs failed with rc=%d\n", rc));
     197        Win32Pe2LxImage::~Win32Pe2LxImage();
     198        throw((ULONG)rc);
     199    }
     200
     201    /* Locate and set the entrypoint. */
     202    setEntryPoint((ULONG)getPointerFromRVA(pNtHdrs->OptionalHeader.AddressOfEntryPoint));
     203    if (entryPoint == 0UL &&
     204        (pNtHdrs->OptionalHeader.AddressOfEntryPoint != NULL        /* getPointerFromRVA failed... */
     205        || !(pNtHdrs->FileHeader.Characteristics & IMAGE_FILE_DLL)) /* EXEs must have and entry point! */
     206        )
     207    {
     208        dprintf(("Win32Pe2LxImage::Win32Pe2LxImage: entrypoint is incorrect, AddrOfEP=0x%08x, entryPoint=0x%08x\n",
     209                 pNtHdrs->OptionalHeader.AddressOfEntryPoint, entryPoint));
     210        Win32Pe2LxImage::~Win32Pe2LxImage();
     211        throw((ULONG)ERROR_INVALID_STARTING_CODESEG);
     212    }
     213
     214    /* Locate the resource directory (if any) */
     215    if (pNtHdrs->OptionalHeader.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_RESOURCE
     216        && pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress > 0UL)
     217    {
     218        pResourceSectionStart = pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress;
     219        pResDir = (PIMAGE_RESOURCE_DIRECTORY)getPointerFromRVA(pResourceSectionStart);
     220    }
     221
     222    /* TLS - FIXME! */
     223}
     224
     225
     226/**
     227 * Free memory associated with this object.
     228 * @status    completely implemented.
     229 * @author    knut st. osmundsen, Sander van Leeuwen
     230 */
    89231Win32Pe2LxImage::~Win32Pe2LxImage()
    90232{
    91  Win32Resource *res;
    92 
    93   if(NameTable)
    94         DosFreeResource((PVOID)NameTable);
    95 
    96   if(Win32Table)
    97         DosFreeResource((PVOID)Win32Table);
    98 }
    99 //******************************************************************************
    100 //******************************************************************************
    101 int Win32Pe2LxImage::getWin32ResourceId(int id)
    102 {
    103  int         nrres, i;
    104 
    105   if(Win32Table == NULL)
    106     return(-1);
    107 
    108   nrres = *Win32Table;
    109   for(i=1;i<=nrres;i++) {
    110     if(id == (Win32Table[i] >> 16)) {
    111         dprintf(("OS/2 id -> Win32 id = %d -> %d\n", id, Win32Table[i] & 0xFFFF));
    112         return(Win32Table[i] & 0xFFFF);
    113     }
    114   }
    115   dprintf(("Original resource not found!!\n"));
    116   return(-1);
    117 }
    118 //******************************************************************************
    119 //******************************************************************************
    120 int Win32Pe2LxImage::convertNameId(char *lpszName)
    121 {
    122  NameId      *curnid;
    123  int          nrcvtnames, i;
    124  char        *upname;
    125 
    126   if(NameTable == NULL)
    127     return(0);
    128 
    129   nrcvtnames = *(USHORT *)NameTable;
    130   curnid     = (NameId *)((int)NameTable + sizeof(USHORT));;
    131   for(i=0;i<nrcvtnames;i++) {
    132     if(strcmp(lpszName, curnid->name) == 0) {
    133         return(curnid->id);
    134     }
    135     curnid = (NameId *)((char *)curnid + sizeof(NameId) + strlen(curnid->name));
    136   }
    137 
    138   //try upper case search
    139   //SvL: Copy it, since string might be located in readonly object
    140 
    141   upname = (char *)malloc(strlen(lpszName)+1); //CB: Trap with MFC Toolbar/UpDown samples
    142   strcpy(upname, lpszName);
    143   strupr(upname);
    144   dprintf(("Convert %s to id\n", upname));
    145   curnid     = (NameId *)((int)NameTable + sizeof(USHORT));;
    146   for(i=0;i<nrcvtnames;i++) {
    147     if(strcmp(upname, curnid->name) == 0) {
    148         free(upname);
    149         return(curnid->id);
    150     }
    151     curnid = (NameId *)((char *)curnid + sizeof(NameId) + strlen(curnid->name));
    152   }
    153   dprintf(("Converted name NOT found!\n"));
    154   free(upname);
    155 
    156   return(0);
    157 }
    158 //******************************************************************************
    159 //******************************************************************************
    160 
     233    cleanup();
     234}
     235
     236
     237/**
     238 * Gets the object layout for this module. Creates the paSections array.
     239 * @returns   OS2 errorcode. (NO_ERROR == success)
     240 * @sketch    Allocate output buffer.
     241 *            Call DosQuerySysState.
     242 *            IF buffer overflow THEN retry calling it with larger buffers, until buffer size is 1MB.
     243 *            IF success THEN
     244 *            BEGIN
     245 *                Find record for this module.
     246 *                IF record found THEN allocate memory for object table and copy it. (paSections, cSections)
     247 *            END
     248 * @status    Completely implemented.
     249 * @author    knut st. osmundsen
     250 */
     251ULONG  Win32Pe2LxImage::getSections()
     252{
     253    APIRET rc = NO_ERROR;
     254    qsGrec_t ** pBuf;
     255    ULONG       cbBuf = 65536;
     256
     257    pBuf = (qsGrec_t **)malloc(cbBuf);
     258    if (pBuf != NULL)
     259    {
     260        rc = DosQuerySysState(QS_MTE, QS_MTE, getpid(), 0L, pBuf, cbBuf);
     261        while (cbBuf < 1024*1024 && rc == ERROR_BUFFER_OVERFLOW)
     262        {
     263            PVOID pv = pBuf;
     264            cbBuf +=  65536;
     265            pBuf = (qsGrec_t **)realloc(pv, cbBuf);
     266            if (pBuf != NULL)
     267                rc = DosQuerySysState(QS_MTE, QS_MTE, getpid(), 0L, pBuf, cbBuf);
     268            else
     269            {
     270                rc = ERROR_NOT_ENOUGH_MEMORY;
     271                free(pv);
     272            }
     273        }
     274
     275        if (rc == NO_ERROR)
     276        {
     277            qsGrec_t *  pGrec = *pBuf;
     278            qsLrec_t *  pLrec = (qsLrec_t * )((ULONG)pGrec + sizeof(qsGrec_t));
     279            while (pLrec != NULL && pLrec->hmte != hinstance)
     280                pLrec = (qsLrec_t*)pLrec->pNextRec;
     281
     282            if (pLrec)
     283            {
     284                if (pLrec->pObjInfo != NULL)
     285                {
     286                    /* Allocate memory for paSections */
     287                    paSections = (PSECTION)malloc(pLrec->ctObj*sizeof(SECTION));
     288                    if (paSections != NULL)
     289                    {
     290                        /* objects -> section array */
     291                        for (int i = 0; i < pLrec->ctObj; i++)
     292                        {
     293                            paSections[i].ulRVA = ~0UL;
     294                            paSections[i].cbVirtual = pLrec->pObjInfo[i].osize;
     295                            paSections[i].ulAddress = pLrec->pObjInfo[i].oaddr;
     296                        }
     297                        cSections = pLrec->ctObj;
     298                    }
     299                    else
     300                        rc = ERROR_NOT_ENOUGH_MEMORY;
     301                }
     302                else
     303                {
     304                    rc = ERROR_BAD_EXE_FORMAT;
     305                    dprintf(("Win32Pe2LxImage::getSections: Error - no object table!\n"));
     306                }
     307            }
     308            else
     309                rc = ERROR_MOD_NOT_FOUND;
     310        }
     311        else
     312            dprintf(("DosQuerySysState - failed with rc=%d (cbBuf=%d)\n", rc, cbBuf));
     313
     314        if (pBuf != NULL)
     315            free(pBuf);
     316    }
     317    else
     318        rc = ERROR_NOT_ENOUGH_MEMORY;
     319
     320    return rc;
     321}
     322
     323
     324/**
     325 * Sets the ulRVA according to the original PE section table.
     326 * @returns   OS/2 errorcode. (NO_ERROR == success)
     327 * @sketch    DEBUG: Validate pNtHdrs
     328 *            Make pointer to start of PE section table.
     329 *            Set RVA for the header section.
     330 *            IF not all in one object exe? THEN
     331 *                Loop thru the sections in the PE section table.
     332 *                  Note: due to the header section: PE section no. + 1 == LX object no.
     333 *            ELSE
     334 *            BEGIN
     335 *                (try) Reallocate paSections to NumberOfSections + 3.
     336 *                Loop thru the PE sections and make paSections from them.
     337 *                Add final Stack or TIBFix+Stack section if necessary.
     338 *                Resize header section.
     339 *            END
     340 * @status    completely implemented.
     341 * @author    knut st. osmundsen
     342 * @remark    Must not be called before pNtHdrs is set.
     343 */
     344ULONG Win32Pe2LxImage::setSectionRVAs()
     345{
     346    #if DEBUG
     347    if (pNtHdrs == NULL)
     348    {
     349        DebugInt3();
     350        return ERROR_INVALID_PARAMETER;
     351    }
     352    #endif
     353
     354    PIMAGE_SECTION_HEADER paPESections = (PIMAGE_SECTION_HEADER)
     355        ((unsigned)pNtHdrs + sizeof(*pNtHdrs) +
     356         (pNtHdrs->OptionalHeader.NumberOfRvaAndSizes - IMAGE_NUMBEROF_DIRECTORY_ENTRIES) * sizeof(IMAGE_DATA_DIRECTORY)
     357        );
     358
     359    /* set RVA for the header section to 0UL. */
     360    paSections[0].ulRVA = 0UL;
     361
     362    /* All in one object exe? */
     363    if (pNtHdrs->FileHeader.NumberOfSections < cSections)
     364    {
     365        /* loop thru the other sections */
     366        for (int i = 0; i < pNtHdrs->FileHeader.NumberOfSections; i++)
     367            paSections[i+1].ulRVA = paPESections[i].VirtualAddress;
     368    }
     369    else
     370    {   /* all in one object */
     371        /* (try) Reallocate paSections to NumberOfSections + 3. */
     372        PVOID pv = realloc(paSections, sizeof(paSections[0]) * (pNtHdrs->FileHeader.NumberOfSections + 3));
     373        if (pv != NULL)
     374        {
     375            paSections = (PSECTION)pv;
     376
     377            /* loop thru the PE sections */
     378            for (int i = 0; i < pNtHdrs->FileHeader.NumberOfSections; i++)
     379            {
     380                if (paSections[0].cbVirtual < paPESections[i].VirtualAddress)
     381                {
     382                    dprintf(("Win32Pe2LxImage::setSectionRVAs: mismatch between section table and all-in-one-object"
     383                             "paSections[0].cbVirtual %#x  paPESections[i].VirtualAddress %#x\n",
     384                             paSections[0].cbVirtual, paPESections[i].VirtualAddress
     385                             ));
     386                    return ERROR_BAD_EXE_FORMAT;
     387                }
     388                paSections[i+1].ulRVA = paPESections[i].VirtualAddress;
     389                paSections[i+1].cbVirtual = max(paPESections[i].Misc.VirtualSize, paPESections[i].SizeOfRawData);
     390                paSections[i+1].ulAddress = paSections[0].ulAddress + paPESections[i].VirtualAddress;
     391            }
     392            cSections = pNtHdrs->FileHeader.NumberOfSections + 1;
     393
     394            /* add final Stack or TIBFix+Stack section if necessary */
     395            if (paSections[0].cbVirtual > paSections[i].ulRVA + ALIGN(paSections[i].cbVirtual, 0x1000))
     396            {
     397                paSections[i+1].ulRVA = ~0UL;
     398                paSections[i+1].cbVirtual = paSections[0].cbVirtual - paSections[i].ulRVA + ALIGN(paSections[i].cbVirtual, 0x1000);
     399                paSections[i+1].ulAddress = paSections[i].ulAddress + ALIGN(paSections[i].cbVirtual, 0x1000);
     400                i++;
     401                cSections++;
     402            }
     403
     404            /* resize header section */
     405            paSections[0].cbVirtual = paSections[1].ulRVA; /*....*/
     406        }
     407        else
     408            return ERROR_NOT_ENOUGH_MEMORY;
     409    }
     410
     411    return NO_ERROR;
     412}
     413
     414
     415/**
     416 * Frees memory used by this object.
     417 * When an exception is to be thrown, this function is called first to clean up
     418 * the object. Base class(es) are automatically clean up by theire destructor(s).
     419 * @status    completely implemented.
     420 * @author    knut st. osmundsen
     421 */
     422VOID  Win32Pe2LxImage::cleanup()
     423{
     424    if (paSections != NULL)
     425    {
     426        free(paSections);
     427        paSections = NULL;
     428        cSections = 0;
     429    }
     430}
     431
     432
     433/**
     434 * Converts a RVA to an pointer.
     435 * @returns   Pointer matching the given RVA, NULL on error.
     436 * @param     ulRVA  An address relative to the imagebase of the original PE image.
     437 * @sketch    DEBUG: validate state, paSections != NULL
     438 *            LOOP while more section left and ulRVA is not within section
     439 *                next section
     440 *            IF section matching ulRVA is not found THEN fail.
     441 *            return pointer matching RVA.
     442 * @status    completely implemented.
     443 * @author    knut st. osmundsen
     444 * @remark    Should not be called until getSections has returned successfully.
     445 */
     446PVOID  Win32Pe2LxImage::getPointerFromRVA(ULONG ulRVA)
     447{
     448    int i;
     449    #ifdef DEBUG
     450        if (paSections == NULL)
     451            return NULL;
     452    #endif
     453
     454    i = 0;
     455    while (i < cSections &&
     456           !(paSections[i].ulRVA <= ulRVA && paSections[i].ulRVA + paSections[i].cbVirtual > ulRVA)) /* ALIGN on page too? */
     457        i++;
     458
     459    if (i >= cSections)
     460        return NULL;
     461
     462    return (PVOID)(ulRVA - paSections[i].ulRVA + paSections[i].ulAddress);
     463}
     464
  • trunk/src/kernel32/winimgres.cpp

    r1192 r1274  
    1 /* $Id: winimgres.cpp,v 1.22 1999-10-08 16:27:21 sandervl Exp $ */
     1/* $Id: winimgres.cpp,v 1.23 1999-10-14 01:37:56 bird Exp $ */
    22
    33/*
     
    1010 *
    1111 * TODO: Check created resource objects before loading the resource!
    12  * TODO: Once the resource handling in PE2LX/win32k is changed, 
     12 * TODO: Once the resource handling in PE2LX/win32k is changed,
    1313 *       getVersionStruct/Size can be moved into the Win32ImageBase class
    1414 *
     
    3535//PE spec says names & ids are sorted; keep on searching just to be sure
    3636//******************************************************************************
    37 PIMAGE_RESOURCE_DATA_ENTRY 
     37PIMAGE_RESOURCE_DATA_ENTRY
    3838 Win32ImageBase::getPEResourceEntry(ULONG id, ULONG type, ULONG lang)
    3939{
     
    6464    for(i=0;i<MAX_RES;i++) {
    6565         if(stricmp((char *)type, ResTypes[i]) == 0)
    66                 break;
     66                break;
    6767    }
    6868    if(i == MAX_RES) {//custom resource type
    69          fNumType = FALSE;
     69         fNumType = FALSE;
    7070    }
    7171    else type   = i;
     
    7676    prdType = (PIMAGE_RESOURCE_DIRECTORY)((int)pResDir + (int)prde->u2.OffsetToData);
    7777
    78     if(i < pResDir->NumberOfNamedEntries) 
     78    if(i < pResDir->NumberOfNamedEntries)
    7979    {//name or id entry?
    8080        //SvL: 30-10-'97, high bit is set, so clear to get real offset
    81         nameOffset = prde->u1.Name & ~0x80000000;
    82 
    83         pstring = (PIMAGE_RESOURCE_DIR_STRING_U)((ULONG)pResDir + nameOffset);
    84         char *typename = (char *)malloc(pstring->Length+1);
    85         lstrcpynWtoA(typename, pstring->NameString, pstring->Length+1);
    86         typename[pstring->Length] = 0;
    87        
     81    nameOffset = prde->u1.Name & ~0x80000000;
     82
     83        pstring = (PIMAGE_RESOURCE_DIR_STRING_U)((ULONG)pResDir + nameOffset);
     84    char *typename = (char *)malloc(pstring->Length+1);
     85        lstrcpynWtoA(typename, pstring->NameString, pstring->Length+1);
     86    typename[pstring->Length] = 0;
     87
    8888        if(!fNumType) {
    8989            if(stricmp(typename, (char *)type) == 0) {
     
    100100            }
    101101        }
    102         free(typename);
     102    free(typename);
    103103    }
    104104    else {
     
    140140
    141141  if(*nodeData == 0xFFFFFFFF) {//shouldn't happen!
    142         dprintf(("ProcessResSubDir: *nodeData == 0xFFFFFFFF!\n"));
    143         return(NULL);
     142        dprintf(("ProcessResSubDir: *nodeData == 0xFFFFFFFF!\n"));
     143        return(NULL);
    144144  }
    145145  prdType = (PIMAGE_RESOURCE_DIRECTORY)((ULONG)prdType & ~0x80000000);
     
    149149  //level 3 (lang) -> get first language?
    150150  if(*nodeData == IDLANG_GETFIRST) {
    151         nrres  = prdType->NumberOfNamedEntries + prdType->NumberOfIdEntries;
    152         fNumId = (prdType->NumberOfNamedEntries == 0);
     151    nrres  = prdType->NumberOfNamedEntries + prdType->NumberOfIdEntries;
     152    fNumId = (prdType->NumberOfNamedEntries == 0);
    153153  }
    154154  else {
    155         fNumId = HIWORD(*nodeData) == 0;
    156 
    157         if(fNumId) {//numeric or string id?
    158                 nrres = prdType->NumberOfIdEntries;
    159                 prde += prdType->NumberOfNamedEntries;  //skip name entries
    160         }
    161         else    nrres = prdType->NumberOfNamedEntries;
     155    fNumId = HIWORD(*nodeData) == 0;
     156
     157    if(fNumId) {//numeric or string id?
     158        nrres = prdType->NumberOfIdEntries;
     159        prde += prdType->NumberOfNamedEntries;  //skip name entries
     160    }
     161    else    nrres = prdType->NumberOfNamedEntries;
    162162  }
    163163
    164164  for(i=0;i<nrres;i++) {
    165         /* locate directory or each resource type */
    166         prdType2 = (PIMAGE_RESOURCE_DIRECTORY)((ULONG)pResDir + (ULONG)prde->u2.OffsetToData);
    167 
    168         if(*nodeData == IDLANG_GETFIRST) {
    169                 fFound = TRUE; //always take the first one
    170         }
    171         else
    172         if(!fNumId) {//name or id entry?
    173                 nameOffset = prde->u1.Name;
    174                 if(prde->u1.s.NameIsString) //unicode directory string /*PLF Sat  97-06-21 22:30:35*/
    175                         nameOffset &= ~0x80000000;
    176 
    177                 pstring = (PIMAGE_RESOURCE_DIR_STRING_U)((ULONG)pResDir + nameOffset);
    178 
    179                 resname = (char *)malloc(pstring->Length+1);
    180                 lstrcpynWtoA(resname, pstring->NameString, pstring->Length+1);
    181                 resname[pstring->Length] = 0;
    182                 if(stricmp(resname, (char *)*nodeData) == 0) {
    183                         fFound = TRUE;
    184                 }
    185                 free(resname);
    186         }
    187         else {
    188                 if(*nodeData == prde->u1.Id)
    189                         fFound = TRUE;
    190         }
    191 
    192         if(fFound) {
    193                 if((ULONG)prdType2 & 0x80000000) {//subdirectory?
    194                         return ProcessResSubDir(prdType2, nodeData+1, 3);
    195                 }
    196                 else {
    197                         pData = (PIMAGE_RESOURCE_DATA_ENTRY)prdType2;
    198                         if(pData->Size) {//winamp17 winzip archive has resource with size 0
    199                                 return(pData);
    200                         }
    201                         else    return(NULL);
    202                 }
    203         }
    204         prde++;
     165        /* locate directory or each resource type */
     166        prdType2 = (PIMAGE_RESOURCE_DIRECTORY)((ULONG)pResDir + (ULONG)prde->u2.OffsetToData);
     167
     168        if(*nodeData == IDLANG_GETFIRST) {
     169        fFound = TRUE; //always take the first one
     170    }
     171    else
     172        if(!fNumId) {//name or id entry?
     173        nameOffset = prde->u1.Name;
     174            if(prde->u1.s.NameIsString) //unicode directory string /*PLF Sat  97-06-21 22:30:35*/
     175                    nameOffset &= ~0x80000000;
     176
     177            pstring = (PIMAGE_RESOURCE_DIR_STRING_U)((ULONG)pResDir + nameOffset);
     178
     179        resname = (char *)malloc(pstring->Length+1);
     180            lstrcpynWtoA(resname, pstring->NameString, pstring->Length+1);
     181        resname[pstring->Length] = 0;
     182            if(stricmp(resname, (char *)*nodeData) == 0) {
     183                    fFound = TRUE;
     184            }
     185        free(resname);
     186        }
     187        else {
     188            if(*nodeData == prde->u1.Id)
     189                    fFound = TRUE;
     190        }
     191
     192    if(fFound) {
     193            if((ULONG)prdType2 & 0x80000000) {//subdirectory?
     194                    return ProcessResSubDir(prdType2, nodeData+1, 3);
     195            }
     196            else {
     197                    pData = (PIMAGE_RESOURCE_DATA_ENTRY)prdType2;
     198                    if(pData->Size) {//winamp17 winzip archive has resource with size 0
     199                        return(pData);
     200                    }
     201                    else    return(NULL);
     202            }
     203        }
     204        prde++;
    205205  }
    206206  return(NULL);
     
    214214  pData = getPEResourceEntry(id, type, lang);
    215215  if(pData == NULL) {
    216         dprintf(("Win32ImageBase::getPEResourceSize: couldn't find resource %d (type %d, lang %d)", id, type, lang));
    217         return 0;
     216    dprintf(("Win32ImageBase::getPEResourceSize: couldn't find resource %d (type %d, lang %d)", id, type, lang));
     217    return 0;
    218218  }
    219219  return pData->Size;
     
    232232  fNumType = TRUE;    //assume numeric
    233233  if(HIWORD(lpszType) != 0) {//string id?
    234         for(i=0;i<MAX_RES;i++) {
    235                 if(stricmp(lpszType, ResTypes[i]) == 0)
    236                         break;
    237         }
    238         if(i == MAX_RES) {//custom resource type
    239                 fNumType = FALSE;
    240                 type = (ULONG)lpszType;
    241         }
    242         else    type = i;
     234        for(i=0;i<MAX_RES;i++) {
     235            if(stricmp(lpszType, ResTypes[i]) == 0)
     236                    break;
     237        }
     238        if(i == MAX_RES) {//custom resource type
     239            fNumType = FALSE;
     240        type = (ULONG)lpszType;
     241        }
     242        else    type = i;
    243243  }
    244244  else  type = (ULONG)lpszType;
     
    264264  pData = getPEResourceEntry(id, type, lang);
    265265  if(pData == NULL) {
    266         if(HIWORD(id)) {
    267                 dprintf(("Win32ImageBase::getPEResource %s: couldn't find resource %s (type %d, lang %d)", szModule, id, type, lang));
    268         }
    269         else    dprintf(("Win32ImageBase::getPEResource %s: couldn't find resource %d (type %d, lang %d)", szModule, id, type, lang));
    270         return 0;
     266    if(HIWORD(id)) {
     267                dprintf(("Win32ImageBase::getPEResource %s: couldn't find resource %s (type %d, lang %d)", szModule, id, type, lang));
     268    }
     269        else    dprintf(("Win32ImageBase::getPEResource %s: couldn't find resource %d (type %d, lang %d)", szModule, id, type, lang));
     270    return 0;
    271271  }
    272272  //pResourceSectionStart contains the virtual address of the imagebase in the PE header
     
    275275  char *resdata = (char *)((char *)pResDir + pData->OffsetToData - pResourceSectionStart);
    276276  if(stringid != -1) {//search for string in table
    277         USHORT *unicodestr = (USHORT *)resdata;
    278 
    279         for(i=0;i<stringid;i++) {
    280                 unicodestr += *unicodestr+1;
    281         }
    282         res = new Win32Resource(this, id, NTRT_STRING, (*unicodestr+1)*sizeof(WCHAR),
     277        USHORT *unicodestr = (USHORT *)resdata;
     278
     279        for(i=0;i<stringid;i++) {
     280            unicodestr += *unicodestr+1;
     281        }
     282        res = new Win32Resource(this, id, NTRT_STRING, (*unicodestr+1)*sizeof(WCHAR),
    283283                                (char *)(unicodestr+1));
    284         if(res == NULL) {
    285                 dprintf(("new Win32Resource failed!\n"));
    286                 return(NULL);
    287         }
     284        if(res == NULL) {
     285            dprintf(("new Win32Resource failed!\n"));
     286            return(NULL);
     287        }
    288288  }
    289289  else {
    290         switch(type) {
    291         case NTRT_MENU:
    292                 res = new Win32MenuRes(this, id, type, pData->Size, resdata);
    293                 break;
    294         default:
    295                 res = new Win32Resource(this, id, type, pData->Size, resdata);
    296                 break;
    297         }
    298        
     290    switch(type) {
     291    case NTRT_MENU:
     292            res = new Win32MenuRes(this, id, type, pData->Size, resdata);
     293        break;
     294    default:
     295            res = new Win32Resource(this, id, type, pData->Size, resdata);
     296        break;
     297    }
     298
    299299  }
    300300
     
    303303//******************************************************************************
    304304//******************************************************************************
     305#if 0
    305306HRSRC Win32Pe2LxImage::findResourceA(LPCSTR lpszName, LPSTR lpszType, ULONG lang)
    306307{
     
    351352    if(HIWORD(lpszName) != 0) {//convert string name identifier to numeric id
    352353        dprintf(("FindResource %s\n", lpszName));
    353         if(lpszName[0] == '#') {// #344
    354                 lpszName = (LPCSTR)atoi(&lpszName[1]);
    355         }
    356         else    lpszName = (LPCSTR)convertNameId((char *)lpszName);
     354        if(lpszName[0] == '#') {// #344
     355                lpszName = (LPCSTR)atoi(&lpszName[1]);
     356        }
     357        else    lpszName = (LPCSTR)convertNameId((char *)lpszName);
    357358    }
    358359    else dprintf(("FindResource %d\n", (int)lpszName));
     
    361362    if(hres)
    362363    {
    363         switch((ULONG)szType) {
    364         case NTRT_MENU:
    365                 res = new Win32MenuRes(this, hres, (ULONG)lpszName, (ULONG)szType);
    366                 break;
    367         default:
    368                 res = new Win32Resource(this, hres, (ULONG)lpszName, (ULONG)szType);
    369                 break;
    370         }
     364    switch((ULONG)szType) {
     365    case NTRT_MENU:
     366            res = new Win32MenuRes(this, hres, (ULONG)lpszName, (ULONG)szType);
     367        break;
     368    default:
     369            res = new Win32Resource(this, hres, (ULONG)lpszName, (ULONG)szType);
     370        break;
     371    }
    371372    }
    372373
    373374    if(hres == NULL && HIWORD(lpszName) == 0 && (int)szType == NTRT_STRING) {
    374         hres = O32_FindResource(hinstance, (LPCSTR)(((int)lpszName - 1)*16), (LPCSTR)NTRT_RCDATA);
    375         if(hres)
    376         {
    377                 res = new Win32Resource(this, hres, (ULONG)lpszName, (ULONG)szType);
    378         }
    379         else    dprintf(("FindResourceA can't find string %d\n", (int)lpszName));
     375        hres = O32_FindResource(hinstance, (LPCSTR)(((int)lpszName - 1)*16), (LPCSTR)NTRT_RCDATA);
     376        if(hres)
     377        {
     378            res = new Win32Resource(this, hres, (ULONG)lpszName, (ULONG)szType);
     379        }
     380        else    dprintf(("FindResourceA can't find string %d\n", (int)lpszName));
    380381    }
    381382    dprintf(("FindResourceA returned %X (%X)\n", hres, GetLastError()));
     
    383384    return (HRSRC)res;
    384385}
     386#endif
    385387//******************************************************************************
    386388//******************************************************************************
     
    391393
    392394    if(HIWORD(lpszName) != 0) {
    393                 astring1 = UnicodeToAsciiString(lpszName);
    394     }
    395     else        astring1 = (char *)lpszName;
     395            astring1 = UnicodeToAsciiString(lpszName);
     396    }
     397    else    astring1 = (char *)lpszName;
    396398
    397399    if(HIWORD(lpszType) != 0) {
    398                 astring2 = UnicodeToAsciiString(lpszType);
    399     } 
    400     else        astring2 = (char *)lpszType;
     400            astring2 = UnicodeToAsciiString(lpszType);
     401    }
     402    else    astring2 = (char *)lpszType;
    401403
    402404    hres = (HRSRC) findResourceA(astring1, astring2);
     
    410412//TODO:
    411413//******************************************************************************
     414#if 0
    412415ULONG Win32Pe2LxImage::getResourceSizeA(LPCSTR lpszName, LPSTR lpszType, ULONG lang)
    413416{
     
    415418    return 0;
    416419}
     420#endif
    417421//******************************************************************************
    418422//******************************************************************************
     
    429433
    430434    if(HIWORD(lpszName) != 0) {
    431                 astring1 = UnicodeToAsciiString((LPWSTR)lpszName);
    432     }
    433     else        astring1 = (char *)lpszName;
     435            astring1 = UnicodeToAsciiString((LPWSTR)lpszName);
     436    }
     437    else    astring1 = (char *)lpszName;
    434438
    435439    if(HIWORD(lpszType) != 0) {
    436                 astring2 = UnicodeToAsciiString(lpszType);
    437     } 
    438     else        astring2 = (char *)lpszType;
     440            astring2 = UnicodeToAsciiString(lpszType);
     441    }
     442    else    astring2 = (char *)lpszType;
    439443
    440444    ressize =  getResourceSizeA(astring2, astring1, lang);
     
    447451//******************************************************************************
    448452//******************************************************************************
     453#if 0
    449454ULONG Win32Pe2LxImage::getVersionSize()
    450455{
    451456    if(getVersionId() == -1) {
    452         dprintf(("GetVersionSize: %s has no version resource!\n", szModule));
    453         return(0);
     457        dprintf(("GetVersionSize: %s has no version resource!\n", szModule));
     458        return(0);
    454459    }
    455460    return OSLibGetResourceSize(hinstance, getVersionId());
     
    460465{
    461466    if(getVersionId() == -1) {
    462         dprintf(("GetVersionStruct: %s has no version resource!\n", szModule));
    463         return(FALSE);
     467        dprintf(("GetVersionStruct: %s has no version resource!\n", szModule));
     468        return(FALSE);
    464469    }
    465470    return OSLibGetResource(hinstance, getVersionId(), verstruct, bufLength);
    466471}
     472#endif
    467473//******************************************************************************
    468474//******************************************************************************
     
    478484
    479485  if(verstruct == NULL || bufLength == 0) {
    480         SetLastError(ERROR_INVALID_PARAMETER);
    481         return FALSE;
     486    SetLastError(ERROR_INVALID_PARAMETER);
     487    return FALSE;
    482488  }
    483489  pData = getPEResourceEntry(ID_GETFIRST, NTRT_VERSION);
    484490  if(pData == NULL) {
    485         dprintf(("Win32PeLdrImage::getVersionStruct: couldn't find version resource!"));
    486         return 0;
     491    dprintf(("Win32PeLdrImage::getVersionStruct: couldn't find version resource!"));
     492    return 0;
    487493  }
    488494  char *resdata = (char *)((char *)pResDir + pData->OffsetToData - pResourceSectionStart);
Note: See TracChangeset for help on using the changeset viewer.