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

Last change on this file since 5978 was 5978, checked in by bird, 24 years ago

Now it COMPILES with Watcom too.

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