Changeset 1274 for trunk/src/kernel32
- Timestamp:
- Oct 14, 1999, 3:39:13 AM (26 years ago)
- Location:
- trunk/src/kernel32
- Files:
-
- 5 edited
-
KERNEL32.DEF (modified) (3 diffs)
-
windllpe2lx.cpp (modified) (2 diffs)
-
winexepe2lx.cpp (modified) (2 diffs)
-
winimagepe2lx.cpp (modified) (3 diffs)
-
winimgres.cpp (modified) (23 diffs)
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 break;66 break; 67 67 } 68 68 if(i == MAX_RES) {//custom resource type 69 fNumType = FALSE;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 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 88 88 if(!fNumType) { 89 89 if(stricmp(typename, (char *)type) == 0) { … … 100 100 } 101 101 } 102 free(typename);102 free(typename); 103 103 } 104 104 else { … … 140 140 141 141 if(*nodeData == 0xFFFFFFFF) {//shouldn't happen! 142 dprintf(("ProcessResSubDir: *nodeData == 0xFFFFFFFF!\n"));143 return(NULL);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 nrres = prdType->NumberOfNamedEntries + prdType->NumberOfIdEntries;152 fNumId = (prdType->NumberOfNamedEntries == 0);151 nrres = prdType->NumberOfNamedEntries + prdType->NumberOfIdEntries; 152 fNumId = (prdType->NumberOfNamedEntries == 0); 153 153 } 154 154 else { 155 fNumId = HIWORD(*nodeData) == 0;156 157 if(fNumId) {//numeric or string id?158 nrres = prdType->NumberOfIdEntries;159 prde += prdType->NumberOfNamedEntries; //skip name entries160 }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; 162 162 } 163 163 164 164 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 one170 }171 else172 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 0199 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++; 205 205 } 206 206 return(NULL); … … 214 214 pData = getPEResourceEntry(id, type, lang); 215 215 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; 218 218 } 219 219 return pData->Size; … … 232 232 fNumType = TRUE; //assume numeric 233 233 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 type239 fNumType = FALSE;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 if(HIWORD(id)) {267 dprintf(("Win32ImageBase::getPEResource %s: couldn't find resource %s (type %d, lang %d)", szModule, id, type, lang));268 }269 elsedprintf(("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; 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 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), 283 283 (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 } 288 288 } 289 289 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 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 if(lpszName[0] == '#') {// #344354 lpszName = (LPCSTR)atoi(&lpszName[1]);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 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 } 371 372 } 372 373 373 374 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)); 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 astring1 = UnicodeToAsciiString(lpszName);394 } 395 else astring1 = (char *)lpszName;395 astring1 = UnicodeToAsciiString(lpszName); 396 } 397 else astring1 = (char *)lpszName; 396 398 397 399 if(HIWORD(lpszType) != 0) { 398 astring2 = UnicodeToAsciiString(lpszType);399 } 400 else astring2 = (char *)lpszType;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 astring1 = UnicodeToAsciiString((LPWSTR)lpszName);432 } 433 else astring1 = (char *)lpszName;435 astring1 = UnicodeToAsciiString((LPWSTR)lpszName); 436 } 437 else astring1 = (char *)lpszName; 434 438 435 439 if(HIWORD(lpszType) != 0) { 436 astring2 = UnicodeToAsciiString(lpszType);437 } 438 else astring2 = (char *)lpszType;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 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); 454 459 } 455 460 return OSLibGetResourceSize(hinstance, getVersionId()); … … 460 465 { 461 466 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); 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 SetLastError(ERROR_INVALID_PARAMETER);481 return FALSE;486 SetLastError(ERROR_INVALID_PARAMETER); 487 return FALSE; 482 488 } 483 489 pData = getPEResourceEntry(ID_GETFIRST, NTRT_VERSION); 484 490 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; 487 493 } 488 494 char *resdata = (char *)((char *)pResDir + pData->OffsetToData - pResourceSectionStart);
Note:
See TracChangeset
for help on using the changeset viewer.
