source: trunk/src/win16ldr/odindll.c@ 5954

Last change on this file since 5954 was 5954, checked in by sandervl, 24 years ago

Preliminary verison of win16 loader

File size: 6.8 KB
Line 
1#include <windows.h>
2#include <string.h>
3#include "peexe.h"
4
5DWORD FAR PASCAL MyGetVersion();
6UINT FAR _loadds PASCAL MyWinExec(LPCSTR lpszCmdLine, UINT fuShowCmd);
7
8BOOL GetPEFileHeader (LPVOID lpFile, PIMAGE_FILE_HEADER pHeader);
9BOOL GetPEOptionalHeader (LPVOID lpFile, PIMAGE_OPTIONAL_HEADER pHeader);
10
11typedef DWORD (FAR * WINAPI FUNC_GetVersion)(void);
12typedef UINT (FAR *WINAPI FUNC_WinExec)(LPCSTR, UINT);
13
14BYTE oldcodeVER;
15DWORD olddataVER;
16UINT selVER;
17BYTE oldcodeEXEC;
18DWORD olddataEXEC;
19UINT selEXEC;
20BYTE FAR *jumpVER;
21BYTE FAR *jumpEXEC;
22
23BOOL fUnloaded = FALSE;
24BOOL fInit = FALSE;
25
26char szPEPath[256] = {0};
27
28//*****************************************************************************************
29//*****************************************************************************************
30int FAR _loadds CALLBACK LibMain(HINSTANCE hinst, WORD wDataSeg, WORD cbHeap, LPSTR lpszCmdLine)
31{
32 FUNC_GetVersion getver;
33 FUNC_WinExec winexec;
34 DWORD FAR *addr;
35
36 if (fInit == FALSE) {
37 fInit = TRUE;
38
39 GetProfileString("Odin", "PEPath", "PE.EXE", szPEPath, sizeof(szPEPath));
40 getver = (FUNC_GetVersion)&GetVersion;
41 selVER = AllocSelector(0);
42 PrestoChangoSelector(SELECTOROF(getver), selVER);
43
44 jumpVER = MAKELP(selVER, OFFSETOF(getver));
45 addr = (DWORD FAR *)(jumpVER+1);
46 oldcodeVER = *jumpVER;
47 olddataVER = *addr;
48 *jumpVER = 0xEA; //jmp
49 *addr = (DWORD)&MyGetVersion;
50
51 winexec = (FUNC_WinExec)&WinExec;
52 selEXEC = AllocSelector(0);
53 PrestoChangoSelector(SELECTOROF(winexec), selEXEC);
54
55 jumpEXEC = MAKELP(selEXEC, OFFSETOF(winexec));
56 addr = (DWORD FAR *)(jumpEXEC+1);
57 oldcodeEXEC = *jumpEXEC;
58 olddataEXEC = *addr;
59 *jumpEXEC = 0xEA; //jmp
60 *addr = (DWORD)&MyWinExec;
61 }
62 return 1;
63}
64//*****************************************************************************************
65//*****************************************************************************************
66int FAR _loadds PASCAL WEP(int entry)
67{
68 DWORD FAR *addr;
69
70 /* Your WEP functionality goes here */
71 if(!fUnloaded) {
72 fUnloaded = TRUE;
73
74 //restore entrypoints
75 addr = (DWORD FAR *)(jumpVER + 1);
76 *jumpVER = oldcodeVER;
77 *addr = olddataVER;
78
79 addr = (DWORD FAR *)(jumpEXEC + 1);
80 *jumpEXEC = oldcodeEXEC;
81 *addr = olddataEXEC;
82 }
83 return 1;
84}
85//*****************************************************************************************
86//*****************************************************************************************
87DWORD FAR PASCAL MyGetVersion()
88{
89 return 0x00005F0C;
90}
91//*****************************************************************************************
92//*****************************************************************************************
93UINT FAR _loadds PASCAL MyWinExec(LPCSTR lpszCmdLine, UINT fuShowCmd)
94{
95 LPSTR cmdline, tmp;
96 UINT ret;
97 OFSTRUCT of = {0};
98 HFILE hFile = 0;
99 int hdrsize;
100 IMAGE_DOS_HEADER doshdr;
101 IMAGE_FILE_HEADER fh;
102 IMAGE_OPTIONAL_HEADER oh;
103 DWORD FAR *addr;
104 UINT bytesRead;
105 char FAR *header;
106 HGLOBAL hMem1 = 0, hMem2 = 0, hMem3 = 0, hMem4 = 0;
107 BOOL fFail = TRUE;
108
109 of.cBytes = sizeof(OFSTRUCT);
110
111 hMem1 = GlobalAlloc(GPTR, strlen(lpszCmdLine)+1);
112 cmdline = GlobalLock(hMem1);
113 if(cmdline == NULL) goto calloldfunc;
114
115 strcpy(cmdline, lpszCmdLine);
116
117 while(*cmdline == ' ') cmdline++;
118 tmp = cmdline;
119 while(*tmp != ' ' && *tmp != 0) tmp++;
120 tmp++;
121 *tmp = 0;
122
123 hFile = OpenFile(cmdline, &of, OF_READ);
124 bytesRead = _lread(hFile, &doshdr, sizeof(doshdr));
125 if(bytesRead != sizeof(doshdr)) goto calloldfunc;
126 if(doshdr.e_magic != IMAGE_DOS_SIGNATURE) goto calloldfunc;
127 hdrsize = doshdr.e_lfanew + SIZE_OF_NT_SIGNATURE + sizeof(IMAGE_FILE_HEADER) + sizeof(IMAGE_OPTIONAL_HEADER);
128
129 _llseek(hFile, 0, 0);
130 hMem3 = GlobalAlloc(GPTR, hdrsize);
131 header = GlobalLock(hMem3);
132 if(header == NULL) goto calloldfunc;
133
134 bytesRead = _lread(hFile, header, hdrsize);
135 if(bytesRead != hdrsize) {
136 goto calloldfunc;
137 }
138 if(GetPEFileHeader (header, &fh) == FALSE) {
139 goto calloldfunc;
140 }
141 if(GetPEOptionalHeader (header, &oh) == FALSE) {
142 goto calloldfunc;
143 }
144
145 if(!(fh.Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE)) {//not valid
146 goto calloldfunc;
147 }
148 if(fh.Machine != IMAGE_FILE_MACHINE_I386) {
149 goto calloldfunc;
150 }
151 //IMAGE_FILE_SYSTEM == only drivers (device/file system/video etc)?
152 if(fh.Characteristics & IMAGE_FILE_SYSTEM) {
153 goto calloldfunc;
154 }
155
156 tmp = cmdline;
157 hMem4 = hMem1;
158
159 hMem1 = GlobalAlloc(GPTR, strlen(tmp)+16+strlen(szPEPath));
160 cmdline = GlobalLock(hMem1);
161 if(cmdline == NULL) {
162 goto calloldfunc;
163 }
164
165 strcpy(cmdline, szPEPath);
166 strcat(cmdline, " ");
167 strcat(cmdline, tmp);
168
169 fFail = FALSE;
170
171calloldfunc:
172 if(hMem4) {
173 GlobalUnlock(hMem4);
174 GlobalFree(hMem4);
175 }
176 if(hMem3) {
177 GlobalUnlock(hMem3);
178 GlobalFree(hMem3);
179 }
180 if(hMem2) {
181 GlobalUnlock(hMem2);
182 GlobalFree(hMem2);
183 }
184 if(hFile)
185 _lclose(hFile);
186
187 addr = (DWORD FAR *)(jumpEXEC + 1);
188 *jumpEXEC = oldcodeEXEC;
189 *addr = olddataEXEC;
190
191 if(fFail) {
192 ret = WinExec(lpszCmdLine, fuShowCmd);
193 }
194 else {
195 ret = WinExec(cmdline, fuShowCmd);
196 if(ret >= 32) {
197 DWORD tickcount1, tickcount2;
198
199 //give PE a chance to load the exe file
200 tickcount1 = GetTickCount();
201 do {
202 Yield();
203 tickcount2 = GetTickCount();
204 }
205 while(tickcount2 - tickcount1 < 2000UL);
206 }
207 }
208
209 *jumpEXEC = 0xEA; //jmp
210 *addr = (DWORD)&MyWinExec;
211
212 if(hMem1) {
213 GlobalUnlock(hMem1);
214 GlobalFree(hMem1);
215 }
216 return ret;
217}
218//******************************************************************************
219//******************************************************************************
220BOOL GetPEFileHeader (LPVOID lpFile, PIMAGE_FILE_HEADER pHeader)
221{
222 if(*(WORD *)lpFile == IMAGE_DOS_SIGNATURE &&
223 *(DWORD *)PE_HEADER (lpFile) == IMAGE_NT_SIGNATURE)
224 {
225 memcpy ((LPVOID)pHeader, PEHEADEROFF (lpFile), sizeof (IMAGE_FILE_HEADER));
226 return TRUE;
227 }
228 else return FALSE;
229}
230//******************************************************************************
231//******************************************************************************
232BOOL GetPEOptionalHeader (LPVOID lpFile, PIMAGE_OPTIONAL_HEADER pHeader)
233{
234 if(*(WORD *)lpFile == IMAGE_DOS_SIGNATURE &&
235 *(DWORD *)PE_HEADER (lpFile) == IMAGE_NT_SIGNATURE)
236 {
237 memcpy ((LPVOID)pHeader, OPTHEADEROFF (lpFile), sizeof (IMAGE_OPTIONAL_HEADER));
238 return TRUE;
239 }
240 else return FALSE;
241}
242//*****************************************************************************************
243//*****************************************************************************************
Note: See TracBrowser for help on using the repository browser.