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

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

It now COMPILES with msc60, but can't link it due to missing library files...

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