source: trunk/src/kernel32/winimagebase.cpp@ 3625

Last change on this file since 3625 was 3625, checked in by sandervl, 25 years ago

resource handling changes

File size: 10.3 KB
Line 
1/* $Id: winimagebase.cpp,v 1.21 2000-05-28 16:45:12 sandervl Exp $ */
2
3/*
4 * Win32 PE Image base class
5 *
6 * Copyright 1998-1999 Sander van Leeuwen (sandervl@xs4all.nl)
7 * Copyright 1998 Knut St. Osmundsen
8 *
9 * Project Odin Software License can be found in LICENSE.TXT
10 *
11 */
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>
24#include <stdlib.h>
25
26#include <assert.h>
27#include <misc.h>
28#include <win32type.h>
29#include <winimagebase.h>
30#include <windllbase.h>
31#include <winexebase.h>
32#include <pefile.h>
33#include <unicode.h>
34#include "oslibmisc.h"
35#include "oslibdos.h"
36#include "initterm.h"
37#include "directory.h"
38#include <win\virtual.h>
39
40#define DBG_LOCALLOG DBG_winimagebase
41#include "dbglocal.h"
42
43//******************************************************************************
44//******************************************************************************
45Win32ImageBase::Win32ImageBase(HINSTANCE hInstance) :
46 errorState(NO_ERROR), entryPoint(0), fullpath(NULL),
47 tlsAddress(0), tlsIndexAddr(0), tlsInitSize(0), tlsTotalSize(0),
48 tlsCallBackAddr(0), tlsIndex(-1), pResDir(NULL),
49 ulRVAResourceSection(0)
50{
51 magic = MAGIC_WINIMAGE;
52
53 if(hInstance != -1) {
54 this->hinstance = hInstance;
55
56 char *name = OSLibGetDllName(hinstance);
57 strcpy(szFileName, name);
58 strupr(szFileName);
59
60 //rename dll (os/2 -> win32) if necessary (i.e. OLE32OS2 -> OLE32)
61 Win32DllBase::renameDll(szFileName, FALSE);
62
63 name = strrchr(szFileName, '\\')+1;
64 strcpy(szModule, name);
65
66 char *dot = strrchr(szModule, '.');
67 if(dot)
68 *dot = 0;
69 }
70 else {
71 szModule[0] = 0;
72 this->hinstance = -1;
73 }
74}
75//******************************************************************************
76//******************************************************************************
77Win32ImageBase::~Win32ImageBase()
78{
79 if(fullpath)
80 free(fullpath);
81}
82//******************************************************************************
83//******************************************************************************
84void Win32ImageBase::setFullPath(char *name)
85{
86 dassert(name, ("setFullPath, name == NULL"));
87 fullpath = (char *)malloc(strlen(name)+1);
88 dassert(fullpath, ("setFullPath, fullpath == NULL"));
89 strcpy(fullpath, name);
90}
91//******************************************************************************
92//Add image to dependency list of this image
93//******************************************************************************
94void Win32ImageBase::addDependency(Win32DllBase *image)
95{
96 loadedDlls.Push((ULONG)image);
97}
98//******************************************************************************
99//******************************************************************************
100BOOL Win32ImageBase::dependsOn(Win32DllBase *image)
101{
102 QueueItem *item;
103 BOOL ret = FALSE;
104
105 dlllistmutex.enter();
106 item = loadedDlls.Head();
107 while(item) {
108 if(loadedDlls.getItem(item) == (ULONG)image) {
109 ret = TRUE;
110 break;
111 }
112 item = loadedDlls.getNext(item);
113 }
114 dlllistmutex.leave();
115 return ret;
116}
117//******************************************************************************
118//Returns required OS version for this image
119//******************************************************************************
120ULONG Win32ImageBase::getVersion()
121{
122 dprintf(("Win32ImageBase::getVersion: NOT IMPLEMENTED!"));
123 return 0x40000; //NT 4
124}
125//******************************************************************************
126//******************************************************************************
127BOOL Win32ImageBase::insideModule(ULONG address)
128{
129 //dummy
130 return FALSE;
131}
132//******************************************************************************
133//******************************************************************************
134BOOL Win32ImageBase::insideModuleCode(ULONG address)
135{
136 //dummy
137 return FALSE;
138}
139//******************************************************************************
140//******************************************************************************
141ULONG Win32ImageBase::getImageSize()
142{
143 //dummy
144 return 0;
145}
146//******************************************************************************
147//******************************************************************************
148BOOL Win32ImageBase::findDll(const char *szFileName, char *szFullName,
149 int cchFullFileName, const char *pszAltPath)
150{
151 char modname[CCHMAXPATH];
152 HFILE dllfile = NULL;
153 char *imagepath;
154
155 strcpy(szFullName, szFileName);
156 strupr(szFullName);
157 if(!strchr(szFullName, (int)'.')) {
158 strcat(szFullName,".DLL");
159 }
160
161 //search order:
162 //1) exe dir
163 //2) current dir
164 //3) windows system dir (kernel32 path)
165 //4) windows dir
166 //5) path
167 if(WinExe) {
168 strcpy(modname, WinExe->getFullPath());
169 //remove file name from full path
170 imagepath = modname + strlen(modname) - 1;
171 while(*imagepath != '\\') imagepath--;
172 imagepath[1] = 0;
173 strcat(modname, szFullName);
174 dllfile = OSLibDosOpen(modname, OSLIB_ACCESS_READONLY|OSLIB_ACCESS_SHAREDENYNONE);
175 }
176 if(dllfile == NULL) {
177 strcpy(modname, szFullName);
178 dllfile = OSLibDosOpen(szFullName, OSLIB_ACCESS_READONLY|OSLIB_ACCESS_SHAREDENYNONE);
179 if(dllfile == NULL) {
180 strcpy(modname, InternalGetSystemDirectoryA());
181 strcat(modname, "\\");
182 strcat(modname, szFullName);
183 dllfile = OSLibDosOpen(modname, OSLIB_ACCESS_READONLY|OSLIB_ACCESS_SHAREDENYNONE);
184 if(dllfile == NULL) {
185 strcpy(modname, InternalGetWindowsDirectoryA());
186 strcat(modname, "\\");
187 strcat(modname, szFullName);
188 dllfile = OSLibDosOpen(modname, OSLIB_ACCESS_READONLY|OSLIB_ACCESS_SHAREDENYNONE);
189 if(dllfile == NULL) {
190 if(OSLibDosSearchPath(OSLIB_SEARCHENV, "PATH", szFullName, modname, sizeof(modname)) == 0) {
191 return FALSE;
192 }
193 }
194 }
195 }
196 }
197 strcpy(szFullName, modname);
198 if(dllfile) OSLibDosClose(dllfile);
199 return TRUE;
200}
201//******************************************************************************
202//******************************************************************************
203BOOL Win32ImageBase::isPEImage(char *szFileName)
204{
205 char filename[CCHMAXPATH];
206 char *syspath;
207 HFILE dllfile;
208 IMAGE_FILE_HEADER fh;
209 HFILE win32handle;
210 ULONG ulAction = 0; /* Action taken by DosOpen */
211 ULONG ulLocal = 0; /* File pointer position after DosSetFilePtr */
212 APIRET rc = NO_ERROR; /* Return code */
213 LPVOID win32file = NULL;
214 ULONG ulRead;
215 int nSections, i;
216
217 if (!findDll(szFileName, filename, sizeof(filename)))
218 {
219 dprintf(("KERNEL32:Win32ImageBase::isPEImage(%s) findDll failed to find the file.\n",
220 szFileName, rc));
221 return FALSE;
222 }
223 rc = DosOpen(filename, /* File path name */
224 &win32handle, /* File handle */
225 &ulAction, /* Action taken */
226 0L, /* File primary allocation */
227 0L, /* File attribute */
228 OPEN_ACTION_FAIL_IF_NEW |
229 OPEN_ACTION_OPEN_IF_EXISTS, /* Open function type */
230 OPEN_FLAGS_NOINHERIT |
231 OPEN_SHARE_DENYNONE |
232 OPEN_ACCESS_READONLY, /* Open mode of the file */
233 0L); /* No extended attribute */
234
235 if (rc != NO_ERROR)
236 {
237 dprintf(("KERNEL32:Win32ImageBase::isPEImage(%s) failed with %u\n",
238 szFileName, rc));
239 return(FALSE);
240 }
241
242 /* Move the file pointer back to the beginning of the file */
243 DosSetFilePtr(win32handle, 0L, FILE_BEGIN, &ulLocal);
244
245 IMAGE_DOS_HEADER *pdoshdr = (IMAGE_DOS_HEADER *)malloc(sizeof(IMAGE_DOS_HEADER));
246 if(pdoshdr == NULL) {
247 DosClose(win32handle); /* Close the file */
248 return(FALSE);
249 }
250 rc = DosRead(win32handle, pdoshdr, sizeof(IMAGE_DOS_HEADER), &ulRead);
251 if(rc != NO_ERROR) {
252 DosClose(win32handle); /* Close the file */
253 return(FALSE);
254 }
255 ULONG hdrsize = pdoshdr->e_lfanew + SIZE_OF_NT_SIGNATURE + sizeof(IMAGE_FILE_HEADER);
256 free(pdoshdr);
257
258 /* Move the file pointer back to the beginning of the file */
259 DosSetFilePtr(win32handle, 0L, FILE_BEGIN, &ulLocal);
260
261 win32file = malloc(hdrsize);
262 if(win32file == NULL) {
263 DosClose(win32handle); /* Close the file */
264 return(FALSE);
265 }
266 rc = DosRead(win32handle, win32file, hdrsize, &ulRead);
267 if(rc != NO_ERROR) {
268 goto failure;
269 }
270
271 if(GetPEFileHeader (win32file, &fh) == FALSE) {
272 goto failure;
273 }
274
275 if(!(fh.Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE)) {//not valid
276 goto failure;
277 }
278 if(fh.Machine != IMAGE_FILE_MACHINE_I386) {
279 goto failure;
280 }
281 //IMAGE_FILE_SYSTEM == only drivers (device/file system/video etc)?
282 if(fh.Characteristics & IMAGE_FILE_SYSTEM) {
283 goto failure;
284 }
285 DosClose(win32handle);
286 return(TRUE);
287
288failure:
289 free(win32file);
290 DosClose(win32handle);
291 return(FALSE);
292}
293//******************************************************************************
294//******************************************************************************
295/**
296 * Static helper which finds the Win32ImageBase object corresponding to hModule.
297 * @returns Pointer to Win32ImageBase object corresponding to hModule.
298 * @param hModule Odin32 modulehandler. 0 and -1 is aliases for the executable module
299 * @status completely implemented and tested.
300 * @author knut st. osmundsen
301 */
302Win32ImageBase * Win32ImageBase::findModule(HMODULE hModule)
303{
304 Win32ImageBase *pRet;
305
306 if (hModule == -1 || hModule == 0 || /* note: WinNt 4, SP4 don't accept -1 as the EXE handle.*/
307 (WinExe != NULL && hModule == WinExe->getInstanceHandle())
308 )
309 pRet = WinExe;
310 else
311 pRet = Win32DllBase::findModule(hModule);
312
313 if (pRet == NULL)
314 {
315 if (WinExe == NULL)
316 dprintf(("Win32ImageBase::findModule: Module not found. WinExe is NULL, hModule=%#x\n", hModule));
317 else
318 dprintf(("Win32ImageBase::findModule: Module not found, hModule=%#x\n", hModule));
319 }
320
321 return pRet;
322}
323
324
Note: See TracBrowser for help on using the repository browser.