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

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

GetFileAttributes, pe loader & command line fixes

File size: 9.3 KB
Line 
1/* $Id: winimagebase.cpp,v 1.11 2000-04-14 22:35:28 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 <winres.h>
35#include "oslibmisc.h"
36#include "oslibdos.h"
37#include "initterm.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), winres(NULL), 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 Win32Resource *res;
80
81 while(winres)
82 {
83 res = winres->next;
84 delete(winres);
85 winres = res;
86 }
87 if(fullpath)
88 free(fullpath);
89}
90//******************************************************************************
91//******************************************************************************
92void Win32ImageBase::setFullPath(char *name)
93{
94 dassert(name, ("setFullPath, name == NULL"));
95 fullpath = (char *)malloc(strlen(name)+1);
96 dassert(fullpath, ("setFullPath, fullpath == NULL"));
97 strcpy(fullpath, name);
98}
99//******************************************************************************
100//Add image to dependency list of this image
101//******************************************************************************
102void Win32ImageBase::addDependency(Win32DllBase *image)
103{
104 loadedDlls.Push((ULONG)image);
105}
106//******************************************************************************
107//******************************************************************************
108BOOL Win32ImageBase::dependsOn(Win32DllBase *image)
109{
110 QueueItem *item;
111 BOOL ret = FALSE;
112
113 dlllistmutex.enter();
114 item = loadedDlls.Head();
115 while(item) {
116 if(loadedDlls.getItem(item) == (ULONG)image) {
117 ret = TRUE;
118 break;
119 }
120 item = loadedDlls.getNext(item);
121 }
122 dlllistmutex.leave();
123 return ret;
124}
125//******************************************************************************
126//Returns required OS version for this image
127//******************************************************************************
128ULONG Win32ImageBase::getVersion()
129{
130 dprintf(("Win32ImageBase::getVersion: NOT IMPLEMENTED!"));
131 return 0x40000; //NT 4
132}
133//******************************************************************************
134//******************************************************************************
135void Win32ImageBase::findDll(char *szFileName, char *szFullName, int cchFullFileName)
136{
137 char modname[CCHMAXPATH];
138 HFILE dllfile;
139 char *imagepath;
140
141 strcpy(szFullName, szFileName);
142 strupr(szFullName);
143 if(!strchr(szFullName, (int)'.')) {
144 strcat(szFullName,".DLL");
145 }
146 //search order:
147 //1) current dir
148 //2) exe dir
149 //3) windows system dir (kernel32 path)
150 //4) path
151 dllfile = OSLibDosOpen(szFullName, OSLIB_ACCESS_READONLY|OSLIB_ACCESS_SHAREDENYNONE);
152 if(dllfile == NULL) {//search in libpath for dll
153 strcpy(modname, WinExe->getFullPath());
154 //remove file name from full path
155 imagepath = modname + strlen(modname) - 1;
156 while(*imagepath != '\\') imagepath--;
157 imagepath[1] = 0;
158 strcat(modname, szFileName);
159 dllfile = OSLibDosOpen(modname, OSLIB_ACCESS_READONLY|OSLIB_ACCESS_SHAREDENYNONE);
160 if(dllfile == NULL) {
161 strcpy(modname, kernel32Path);
162 strcat(modname, szFileName);
163 dllfile = OSLibDosOpen(modname, OSLIB_ACCESS_READONLY|OSLIB_ACCESS_SHAREDENYNONE);
164 if(dllfile == NULL) {
165 OSLibDosSearchPath(OSLIB_SEARCHENV, "PATH", modname, szFullName, cchFullFileName);
166 }
167 else {
168 strcpy(szFullName, modname);
169 OSLibDosClose(dllfile);
170 }
171 }
172 else {
173 strcpy(szFullName, modname);
174 OSLibDosClose(dllfile);
175 }
176 }
177 else OSLibDosClose(dllfile);
178}
179//******************************************************************************
180//******************************************************************************
181BOOL Win32ImageBase::isPEImage(char *szFileName)
182{
183 char filename[CCHMAXPATH];
184 char *syspath;
185 HFILE dllfile;
186 IMAGE_FILE_HEADER fh;
187 HFILE win32handle;
188 ULONG ulAction = 0; /* Action taken by DosOpen */
189 ULONG ulLocal = 0; /* File pointer position after DosSetFilePtr */
190 APIRET rc = NO_ERROR; /* Return code */
191 LPVOID win32file = NULL;
192 ULONG ulRead;
193 int nSections, i;
194
195 findDll(szFileName, filename, sizeof(filename));
196 rc = DosOpen(filename, /* File path name */
197 &win32handle, /* File handle */
198 &ulAction, /* Action taken */
199 0L, /* File primary allocation */
200 0L, /* File attribute */
201 OPEN_ACTION_FAIL_IF_NEW |
202 OPEN_ACTION_OPEN_IF_EXISTS, /* Open function type */
203 OPEN_FLAGS_NOINHERIT |
204 OPEN_SHARE_DENYNONE |
205 OPEN_ACCESS_READONLY, /* Open mode of the file */
206 0L); /* No extended attribute */
207
208 if (rc != NO_ERROR)
209 {
210 dprintf(("KERNEL32:Win32ImageBase::isPEImage(%s) failed with %u\n",
211 szFileName, rc));
212 return(FALSE);
213 }
214
215 /* Move the file pointer back to the beginning of the file */
216 DosSetFilePtr(win32handle, 0L, FILE_BEGIN, &ulLocal);
217
218 IMAGE_DOS_HEADER *pdoshdr = (IMAGE_DOS_HEADER *)malloc(sizeof(IMAGE_DOS_HEADER));
219 if(pdoshdr == NULL) {
220 DosClose(win32handle); /* Close the file */
221 return(FALSE);
222 }
223 rc = DosRead(win32handle, pdoshdr, sizeof(IMAGE_DOS_HEADER), &ulRead);
224 if(rc != NO_ERROR) {
225 DosClose(win32handle); /* Close the file */
226 return(FALSE);
227 }
228 ULONG hdrsize = pdoshdr->e_lfanew + SIZE_OF_NT_SIGNATURE + sizeof(IMAGE_FILE_HEADER);
229 free(pdoshdr);
230
231 /* Move the file pointer back to the beginning of the file */
232 DosSetFilePtr(win32handle, 0L, FILE_BEGIN, &ulLocal);
233
234 win32file = malloc(hdrsize);
235 if(win32file == NULL) {
236 DosClose(win32handle); /* Close the file */
237 return(FALSE);
238 }
239 rc = DosRead(win32handle, win32file, hdrsize, &ulRead);
240 if(rc != NO_ERROR) {
241 goto failure;
242 }
243
244 if(GetPEFileHeader (win32file, &fh) == FALSE) {
245 goto failure;
246 }
247
248 if(!(fh.Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE)) {//not valid
249 goto failure;
250 }
251 if(fh.Machine != IMAGE_FILE_MACHINE_I386) {
252 goto failure;
253 }
254 //IMAGE_FILE_SYSTEM == only drivers (device/file system/video etc)?
255 if(fh.Characteristics & IMAGE_FILE_SYSTEM) {
256 goto failure;
257 }
258 DosClose(win32handle);
259 return(TRUE);
260
261failure:
262 free(win32file);
263 DosClose(win32handle);
264 return(FALSE);
265}
266//******************************************************************************
267//******************************************************************************
268/**
269 * Static helper which finds the Win32ImageBase object corresponding to hModule.
270 * @returns Pointer to Win32ImageBase object corresponding to hModule.
271 * @param hModule Odin32 modulehandler. 0 and -1 is aliases for the executable module
272 * @status completely implemented and tested.
273 * @author knut st. osmundsen
274 */
275Win32ImageBase * Win32ImageBase::findModule(HMODULE hModule)
276{
277 Win32ImageBase *pRet;
278
279 if (hModule == -1 || hModule == 0 || /* note: WinNt 4, SP4 don't accept -1 as the EXE handle.*/
280 (WinExe != NULL && hModule == WinExe->getInstanceHandle())
281 )
282 pRet = WinExe;
283 else
284 pRet = Win32DllBase::findModule(hModule);
285
286 if (pRet == NULL)
287 {
288 if (WinExe == NULL)
289 dprintf(("Win32ImageBase::findModule: Module not found. WinExe is NULL, hModule=%#x\n", hModule));
290 else
291 dprintf(("Win32ImageBase::findModule: Module not found, hModule=%#x\n", hModule));
292 }
293
294 return pRet;
295}
296
297
Note: See TracBrowser for help on using the repository browser.