- Timestamp:
- Oct 14, 1999, 3:39:13 AM (26 years ago)
- Location:
- trunk/src/kernel32
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kernel32/KERNEL32.DEF
r1131 r1274 1 ; $Id: KERNEL32.DEF,v 1.4 1 1999-10-04 20:52:33 sandervlExp $1 ; $Id: KERNEL32.DEF,v 1.42 1999-10-14 01:37:55 bird Exp $ 2 2 3 3 ;Created by BLAST for IBM's compiler … … 18 18 DosAliasMem = DOSCALLS.298 19 19 _DosAliasMem = DOSCALLS.298 20 DosQuerySysState = DOSCALLS.368 20 21 21 22 … … 952 953 WriteLogError = WriteLogError @1214 953 954 954 ;Used by tibfix page in exe (change ordinal in lx.cpp too!!)955 _RegisterPe2LxExe@ 48@1203956 _RegisterPe2LxDll@ 48@1209955 ;Used by tibfix page in exe (change ordinal in pe2lx.cpp too!!) 956 _RegisterPe2LxExe@12 @1203 957 _RegisterPe2LxDll@12 @1209 957 958 958 959 _CreateWin32PeLdrExe@8 @1236 -
trunk/src/kernel32/windllpe2lx.cpp
r956 r1274 1 /* $Id: windllpe2lx.cpp,v 1. 1 1999-09-15 23:39:07 sandervlExp $ */1 /* $Id: windllpe2lx.cpp,v 1.2 1999-10-14 01:37:55 bird Exp $ */ 2 2 3 3 /* … … 5 5 * 6 6 * Copyright 1999 Sander van Leeuwen (sandervl@xs4all.nl) 7 * 7 * Copyright 1999 knut st. osmundsen (knut.stange.osmundsen@pmsc.no) 8 8 * 9 9 * Project Odin Software License can be found in LICENSE.TXT 10 10 * 11 11 */ 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 21 25 #include <stdlib.h> 22 #include <iostream.h> 23 #include < fstream.h>26 27 #include <win32type.h> 24 28 #include <misc.h> 25 #include <win32type.h>26 #include <pefile.h>27 29 #include <windllpe2lx.h> 28 30 #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 34 35 #include "console.h" 35 36 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 */ 65 ULONG 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 */ 132 Win32Pe2LxDll::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 */ 104 148 Win32Pe2LxDll::~Win32Pe2LxDll() 105 149 { 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 */ 110 162 ULONG Win32Pe2LxDll::getApi(char *name) 111 163 { 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 */ 124 183 ULONG Win32Pe2LxDll::getApi(int ordinal) 125 184 { 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 */ 135 201 BOOL Win32Pe2LxDll::isLxDll() 136 202 { 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 sandervlExp $ */1 /* $Id: winexepe2lx.cpp,v 1.2 1999-10-14 01:37:56 bird Exp $ */ 2 2 3 3 /* … … 5 5 * 6 6 * Copyright 1998-1999 Sander van Leeuwen (sandervl@xs4all.nl) 7 * 7 * Copyright 1999 knut st. osmundsen (knut.stange.osmundsen@pmsc.no) 8 8 * 9 9 * Project Odin Software License can be found in LICENSE.TXT 10 10 * 11 11 */ 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 23 26 #include <misc.h> 24 27 #include <win32type.h> 25 28 #include <winexepe2lx.h> 26 #include <wprocess.h>27 #include <pefile.h>28 #include "cio.h"29 29 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 34 33 #include "console.h" 35 34 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 */ 52 void WIN32API RegisterPe2LxExe(ULONG ulPe2LxVersion, HINSTANCE hinstance, ULONG ulReserved) 43 53 { 44 if(WinExe != NULL) //should never happen 45 delete(WinExe); 54 /* I/O init. */ 55 if (getenv("WIN32_IOPL2")) 56 io_init1(); 46 57 47 CheckVersion(Pe2lxVersion, OSLibGetDllName(hinstance)); 58 /* Check that pe2lx version matches the version of kernel32.dll. */ 59 CheckVersion(ulPe2LxVersion & ~0x80000000UL, OSLibGetDllName(hinstance)); 48 60 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 } 52 67 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))); 54 73 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); 56 81 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 } 62 93 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);70 94 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 */ 104 Win32Pe2LxExe::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 } 78 122 } 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 app87 dprintf(("Console application!\n"));88 123 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 */ 98 130 Win32Pe2LxExe::~Win32Pe2LxExe() 99 131 { 100 132 } 101 //******************************************************************************102 //****************************************************************************** -
trunk/src/kernel32/winimagepe2lx.cpp
r956 r1274 1 /* $Id: winimagepe2lx.cpp,v 1. 1 1999-09-15 23:39:08 sandervlExp $ */1 /* $Id: winimagepe2lx.cpp,v 1.2 1999-10-14 01:37:56 bird Exp $ */ 2 2 3 3 /* … … 5 5 * 6 6 * Copyright 1998-1999 Sander van Leeuwen (sandervl@xs4all.nl) 7 * Copyright 1998 Knut St. Osmundsen7 * Copyright 1998-1999 knut st. osmundsen (knut.stange.osmundsen@pmsc.no) 8 8 * 9 9 * Project Odin Software License can be found in LICENSE.TXT … … 11 11 */ 12 12 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> 24 29 #include <stdlib.h> 25 30 26 #include < assert.h>31 #include <win32type.h> 27 32 #include <misc.h> 28 #include <win32type.h>29 33 #include <winimagebase.h> 30 34 #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 */ 132 Win32Pe2LxImage::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 */ 89 231 Win32Pe2LxImage::~Win32Pe2LxImage() 90 232 { 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 */ 251 ULONG 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 */ 344 ULONG 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 */ 422 VOID 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 */ 446 PVOID 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.2 2 1999-10-08 16:27:21 sandervlExp $ */1 /* $Id: winimgres.cpp,v 1.23 1999-10-14 01:37:56 bird Exp $ */ 2 2 3 3 /* … … 10 10 * 11 11 * 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, 13 13 * getVersionStruct/Size can be moved into the Win32ImageBase class 14 14 * … … 35 35 //PE spec says names & ids are sorted; keep on searching just to be sure 36 36 //****************************************************************************** 37 PIMAGE_RESOURCE_DATA_ENTRY 37 PIMAGE_RESOURCE_DATA_ENTRY 38 38 Win32ImageBase::getPEResourceEntry(ULONG id, ULONG type, ULONG lang) 39 39 { … … 64 64 for(i=0;i<MAX_RES;i++) { 65 65 if(stricmp((char *)type, ResTypes[i]) == 0) 66 66 break; 67 67 } 68 68 if(i == MAX_RES) {//custom resource type 69 69 fNumType = FALSE; 70 70 } 71 71 else type = i; … … 76 76 prdType = (PIMAGE_RESOURCE_DIRECTORY)((int)pResDir + (int)prde->u2.OffsetToData); 77 77 78 if(i < pResDir->NumberOfNamedEntries) 78 if(i < pResDir->NumberOfNamedEntries) 79 79 {//name or id entry? 80 80 //SvL: 30-10-'97, high bit is set, so clear to get real offset 81 82 83 84 85 86 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 88 88 if(!fNumType) { 89 89 if(stricmp(typename, (char *)type) == 0) { … … 100 100 } 101 101 } 102 102 free(typename); 103 103 } 104 104 else { … … 140 140 141 141 if(*nodeData == 0xFFFFFFFF) {//shouldn't happen! 142 143 142 dprintf(("ProcessResSubDir: *nodeData == 0xFFFFFFFF!\n")); 143 return(NULL); 144 144 } 145 145 prdType = (PIMAGE_RESOURCE_DIRECTORY)((ULONG)prdType & ~0x80000000); … … 149 149 //level 3 (lang) -> get first language? 150 150 if(*nodeData == IDLANG_GETFIRST) { 151 152 151 nrres = prdType->NumberOfNamedEntries + prdType->NumberOfIdEntries; 152 fNumId = (prdType->NumberOfNamedEntries == 0); 153 153 } 154 154 else { 155 156 157 158 159 160 161 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; 162 162 } 163 163 164 164 for(i=0;i<nrres;i++) { 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 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++; 205 205 } 206 206 return(NULL); … … 214 214 pData = getPEResourceEntry(id, type, lang); 215 215 if(pData == NULL) { 216 217 216 dprintf(("Win32ImageBase::getPEResourceSize: couldn't find resource %d (type %d, lang %d)", id, type, lang)); 217 return 0; 218 218 } 219 219 return pData->Size; … … 232 232 fNumType = TRUE; //assume numeric 233 233 if(HIWORD(lpszType) != 0) {//string id? 234 235 236 237 238 239 240 type = (ULONG)lpszType; 241 242 elsetype = 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; 243 243 } 244 244 else type = (ULONG)lpszType; … … 264 264 pData = getPEResourceEntry(id, type, lang); 265 265 if(pData == NULL) { 266 267 268 269 elsedprintf(("Win32ImageBase::getPEResource %s: couldn't find resource %d (type %d, lang %d)", szModule, id, type, lang));270 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; 271 271 } 272 272 //pResourceSectionStart contains the virtual address of the imagebase in the PE header … … 275 275 char *resdata = (char *)((char *)pResDir + pData->OffsetToData - pResourceSectionStart); 276 276 if(stringid != -1) {//search for string in table 277 278 279 280 281 282 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), 283 283 (char *)(unicodestr+1)); 284 285 286 287 284 if(res == NULL) { 285 dprintf(("new Win32Resource failed!\n")); 286 return(NULL); 287 } 288 288 } 289 289 else { 290 291 292 293 294 295 296 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 299 299 } 300 300 … … 303 303 //****************************************************************************** 304 304 //****************************************************************************** 305 #if 0 305 306 HRSRC Win32Pe2LxImage::findResourceA(LPCSTR lpszName, LPSTR lpszType, ULONG lang) 306 307 { … … 351 352 if(HIWORD(lpszName) != 0) {//convert string name identifier to numeric id 352 353 dprintf(("FindResource %s\n", lpszName)); 353 354 355 356 elselpszName = (LPCSTR)convertNameId((char *)lpszName);354 if(lpszName[0] == '#') {// #344 355 lpszName = (LPCSTR)atoi(&lpszName[1]); 356 } 357 else lpszName = (LPCSTR)convertNameId((char *)lpszName); 357 358 } 358 359 else dprintf(("FindResource %d\n", (int)lpszName)); … … 361 362 if(hres) 362 363 { 363 364 365 366 367 368 369 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 } 371 372 } 372 373 373 374 if(hres == NULL && HIWORD(lpszName) == 0 && (int)szType == NTRT_STRING) { 374 375 376 377 378 379 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)); 380 381 } 381 382 dprintf(("FindResourceA returned %X (%X)\n", hres, GetLastError())); … … 383 384 return (HRSRC)res; 384 385 } 386 #endif 385 387 //****************************************************************************** 386 388 //****************************************************************************** … … 391 393 392 394 if(HIWORD(lpszName) != 0) { 393 394 } 395 else 395 astring1 = UnicodeToAsciiString(lpszName); 396 } 397 else astring1 = (char *)lpszName; 396 398 397 399 if(HIWORD(lpszType) != 0) { 398 399 } 400 else 400 astring2 = UnicodeToAsciiString(lpszType); 401 } 402 else astring2 = (char *)lpszType; 401 403 402 404 hres = (HRSRC) findResourceA(astring1, astring2); … … 410 412 //TODO: 411 413 //****************************************************************************** 414 #if 0 412 415 ULONG Win32Pe2LxImage::getResourceSizeA(LPCSTR lpszName, LPSTR lpszType, ULONG lang) 413 416 { … … 415 418 return 0; 416 419 } 420 #endif 417 421 //****************************************************************************** 418 422 //****************************************************************************** … … 429 433 430 434 if(HIWORD(lpszName) != 0) { 431 432 } 433 else 435 astring1 = UnicodeToAsciiString((LPWSTR)lpszName); 436 } 437 else astring1 = (char *)lpszName; 434 438 435 439 if(HIWORD(lpszType) != 0) { 436 437 } 438 else 440 astring2 = UnicodeToAsciiString(lpszType); 441 } 442 else astring2 = (char *)lpszType; 439 443 440 444 ressize = getResourceSizeA(astring2, astring1, lang); … … 447 451 //****************************************************************************** 448 452 //****************************************************************************** 453 #if 0 449 454 ULONG Win32Pe2LxImage::getVersionSize() 450 455 { 451 456 if(getVersionId() == -1) { 452 453 457 dprintf(("GetVersionSize: %s has no version resource!\n", szModule)); 458 return(0); 454 459 } 455 460 return OSLibGetResourceSize(hinstance, getVersionId()); … … 460 465 { 461 466 if(getVersionId() == -1) { 462 463 467 dprintf(("GetVersionStruct: %s has no version resource!\n", szModule)); 468 return(FALSE); 464 469 } 465 470 return OSLibGetResource(hinstance, getVersionId(), verstruct, bufLength); 466 471 } 472 #endif 467 473 //****************************************************************************** 468 474 //****************************************************************************** … … 478 484 479 485 if(verstruct == NULL || bufLength == 0) { 480 481 486 SetLastError(ERROR_INVALID_PARAMETER); 487 return FALSE; 482 488 } 483 489 pData = getPEResourceEntry(ID_GETFIRST, NTRT_VERSION); 484 490 if(pData == NULL) { 485 486 491 dprintf(("Win32PeLdrImage::getVersionStruct: couldn't find version resource!")); 492 return 0; 487 493 } 488 494 char *resdata = (char *)((char *)pResDir + pData->OffsetToData - pResourceSectionStart);
Note:
See TracChangeset
for help on using the changeset viewer.