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

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

dll search order changes

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