source: trunk/src/win32k/test/fake.c@ 4114

Last change on this file since 4114 was 3829, checked in by bird, 25 years ago

Early development.

File size: 52.0 KB
Line 
1/* $Id: fake.c,v 1.1 2000-07-16 22:18:14 bird Exp $
2 *
3 * Fake stubs for the ldr and kernel functions we imports or overloads.
4 *
5 * Copyright (c) 2000 knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
6 *
7 * Project Odin Software License can be found in LICENSE.TXT
8 *
9 */
10
11/*******************************************************************************
12* Defined Constants And Macros *
13*******************************************************************************/
14#define INCL_BASE
15#define FOR_EXEHDR 1 /* To make all object flags OBJ???. */
16#define INCL_OS2KRNL_ALL
17#define DWORD ULONG
18#define WORD USHORT
19
20#define DUMMY() int dummy; dummy = 0; dummy = dummy + 1;
21
22/*******************************************************************************
23* Header Files *
24*******************************************************************************/
25#include <os2.h>
26#include <newexe.h> /* OS/2 NE structs and definitions. */
27#include <exe386.h> /* OS/2 LX structs and definitions. */
28
29#include <string.h>
30
31#include "log.h"
32#include "OS2Krnl.h"
33#include "dev32.h"
34#include "ldrcalls.h"
35#include "test.h"
36#include "macros.h"
37
38#include "malloc.h"
39
40/*******************************************************************************
41* Structures and Typedefs *
42*******************************************************************************/
43typedef struct ldrrei_s /* #memb 7 size 20 (0x014) - from 14040W4 kernel.sdf */
44{
45 PVOID ei_startaddr; /* off: 0(00) size: 4(04) */
46 PVOID ei_stackaddr; /* off: 4(04) size: 4(04) */
47 PVOID ei_pstackmax; /* off: 8(08) size: 4(04) */
48 USHORT ei_ds; /* off: 12(0c) size: 2(02) */
49 USHORT ei_stacksize; /* off: 14(0e) size: 2(02) */
50 USHORT ei_heapsize; /* off: 16(10) size: 2(02) */
51 USHORT ei_loadtype; /* off: 18(12) size: 2(02) */
52} ldrrei_t;
53
54
55
56/*******************************************************************************
57* Global Variables *
58*******************************************************************************/
59/*
60 * Pointer to the loader semaphore.
61 */
62static LONG lfakeLDRSem = 0; /* Used as a counter. */
63HKMTX fakeLDRSem = (HKMTX)&lfakeLDRSem;
64
65static CHAR achHeaderBuffer[256]; /* Buffer to read exe header into. */
66PVOID pheaderbuf = &achHeaderBuffer[0];
67
68/*
69 * table use by fakeldrMTEValidatePtrs.
70 */
71USHORT validatetbl[] =
72{
73 FIELDOFFSET(SMTE, smte_objmap),
74 FIELDOFFSET(SMTE, smte_rsrctab),
75 FIELDOFFSET(SMTE, smte_restab),
76 FIELDOFFSET(SMTE, smte_enttab),
77 FIELDOFFSET(SMTE, smte_fpagetab),
78 FIELDOFFSET(SMTE, smte_frectab),
79 FIELDOFFSET(SMTE, smte_impmod),
80 FIELDOFFSET(SMTE, smte_impproc),
81 0xDEAD
82};
83
84
85/*******************************************************************************
86* External Functions *
87*******************************************************************************/
88#define QHINF_EXEINFO 1 /* NE exeinfo. */
89#define QHINF_READRSRCTBL 2 /* Reads from the resource table. */
90#define QHINF_READFILE 3 /* Reads from the executable file. */
91#define QHINF_LIBPATHLENGTH 4 /* Gets the libpath length. */
92#define QHINF_LIBPATH 5 /* Gets the entire libpath. */
93#define QHINF_FIXENTRY 6 /* NE only */
94#define QHINF_STE 7 /* NE only */
95#define QHINF_MAPSEL 8 /* NE only */
96
97APIRET APIENTRY DosQueryHeaderInfo(HMODULE hmod,
98 ULONG ulIndex,
99 PVOID pvBuffer,
100 ULONG cbBuffer,
101 ULONG ulSubFunction);
102
103/*******************************************************************************
104* Internal Functions *
105*******************************************************************************/
106ULONG LDRCALL fakeLDRLoadExe(PSZ pszFilename, ldrrei_t *pEI);
107ULONG LDRCALL fakeldrGetModule(PSZ pszFilename, ULONG ul);
108ULONG LDRCALL fakeldrGetMte(PCHAR pachFilename, USHORT cchFilename, UCHAR fchType, UCHAR fchClass, PPMTE ppmte);
109ULONG LDRCALL fakeldrOpenNewExe(PCHAR pachFilename, USHORT cchFilename, ldrlv_t *plv, PUSHORT pus);
110ULONG LDRCALL fakeldrCreateMte(struct e32_exe * pe32, ldrlv_t *plv);
111ULONG LDRCALL fakeldrLoadImports(PMTE pmte);
112VOID LDRCALL fakeldrUCaseString(PCHAR pachString, USHORT cchString);
113ULONG LDRCALL fakeldrMTEValidatePtrs(PSMTE psmte, ULONG ulMaxAddr, ULONG off);
114
115
116/**
117 * Fake ldrClose
118 * @returns OS2 return code.
119 * @param hFile Filehandle of the file to be closed.
120 * @status completely impelemented.
121 * @author knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
122 * @remark
123 */
124ULONG LDRCALL fakeldrClose(SFN hFile)
125{
126 APIRET rc;
127 BOOL f32Stack = ((int)&hFile > 0x10000);
128
129 if (!f32Stack) ThunkStack16To32();
130
131 rc = DosClose(hFile);
132
133 if (!f32Stack) ThunkStack32To16();
134
135 printf("fakeldrClose: hFile = 0x%04x, rc = %d\n", hFile, rc);
136
137 return rc;
138}
139
140/**
141 * Fake ldrOpen.
142 * @returns OS2 return code.
143 * @param phFile Pointer to return handle.
144 * @param pszFilename Pointer to filename.
145 * @param pfl Pointer to media flags? *pfl is set to zero!
146 * @sketch Do a DosOpen on the filename.
147 * @status partially implemented.
148 * @author knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
149 * @remark
150 */
151ULONG LDRCALL fakeldrOpen(PSFN phFile, PSZ pszFilename, PULONG pfl)
152{
153 ULONG ulAction;
154 HFILE hFile;
155 APIRET rc;
156 BOOL f32Stack = ((int)&hFile > 0x10000);
157
158 if (!f32Stack) ThunkStack16To32();
159
160 hFile = 0;
161 ulAction = 0;
162 rc = DosOpen(pszFilename, &hFile, &ulAction, 0, FILE_NORMAL,
163 OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS,
164 OPEN_ACCESS_READONLY | OPEN_SHARE_DENYWRITE,
165 NULL);
166 if (rc == NO_ERROR)
167 {
168 *phFile = (USHORT)hFile;
169 if (pfl != NULL)
170 *pfl = 0;
171 }
172
173 if (!f32Stack) ThunkStack32To16();
174
175 printf("fakeldrOpen: phFile = %p; *phFile = 0x%04x, pszFilename = %s, pfl = %p, rc = %d\n",
176 phFile, *phFile, pszFilename, pfl, rc);
177
178 return rc;
179}
180
181
182/**
183 * ldrRead fake.
184 * @returns OS/2 return code. (NO_ERROR on success...)
185 * @param hFile Handle to file.
186 * @param ulOffset Offset in the file to start reading at.
187 * @param pvBuffer Pointer to output buffer.
188 * @param fpBuffer Far pointer to buffer. (ignored)
189 * @param cbToRead Count of bytes to read.
190 * @param pMTE MTE pointer (used for caching?)
191 *
192 * @sketch Set Change filepointer to ulOffset.
193 * Read cbToRead into pvBufer.
194 * @status completely tested.
195 * @author knut st. osmundsen
196 * @remark
197 */
198ULONG LDRCALL fakeldrRead(SFN hFile, ULONG ulOffset, PVOID pvBuffer, ULONG fpBuffer, ULONG cbToRead, PMTE pMTE)
199{
200 ULONG cbRead,
201 ulMoved;
202 APIRET rc;
203 BOOL f32Stack = ((int)&hFile > 0x10000);
204
205 if (!f32Stack) ThunkStack16To32();
206
207 rc = DosSetFilePtr(hFile, ulOffset, FILE_BEGIN, &ulMoved);
208 if (rc == NO_ERROR)
209 rc = DosRead(hFile, pvBuffer, cbToRead, &cbRead);
210 else
211 kprintf(("fakeldrRead: DosSetFilePtr(hfile, 0x%08x(%d),..) failed with rc = %d.\n",
212 ulOffset, ulOffset, rc));
213
214 if (!f32Stack) ThunkStack32To16();
215
216 printf("fakeldrRead: hFile = 0x%04x, ulOffset = 0x%08x, pvBuffer = %p, fpBuffer = 0x%08x, cbToRead = 0x%08x, pMte = %p, rc = %d\n",
217 hFile, ulOffset, pvBuffer, fpBuffer, cbToRead, pMTE, rc);
218
219 return rc;
220}
221
222
223/**
224 * LDRQAppType faker.
225 * @returns OS/2 return code.
226 * @param pszFilename Pointer to executable to query app type for.
227 * @param pul Pointer to flag variable to return apptype flags in.
228 * @sketch
229 * @status stub.
230 * @author knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
231 * @remark
232 */
233ULONG LDRCALL fakeLDRQAppType(PSZ pszFilename, PULONG pul)
234{
235 DUMMY();
236 printf("fakeLDRQAppType: pszFilename = %s, pul = %p, rc = 0\n", pszFilename, pul);
237 return NO_ERROR;
238}
239
240
241/**
242 * ldrEnum32bitRelRecs
243 * @param pMTE Pointer to MTE for this module.
244 * @param iObject Object index. 0-based!
245 * @param iPageTabl Page index. 0-based!
246 * @param pvPage Pointer to page buffer.
247 * @param ulPageAddress Note! Page is not present.
248 * @param pPTDA
249 * @status stub
250 */
251ULONG LDRCALL fakeldrEnum32bitRelRecs(
252 PMTE pMTE,
253 ULONG iObject,
254 ULONG iPageTable,
255 PVOID pvPage,
256 ULONG ulPageAddress,
257 PVOID pvPTDA
258 )
259{
260 DUMMY();
261 printf("fakeldrEnum32bitRelRecs: pMTE = %p, iObject = 0x%08x, iPageTable = 0x%08x, pvPage = 0x%08x, ulPageAddress = 0x%08x, pvPTDA = %p\n",
262 pMTE, iObject, iPageTable, pvPage, ulPageAddress, pvPTDA);
263
264 return NO_ERROR;
265}
266
267/**
268 * Opens a given file.
269 * @returns NO_ERROR on success. OS/2 error code on error.
270 * @param pszFilename Pointer to filename.
271 * @param flOpenFlags Open flags. (similar to DosOpen)
272 * @param fsOpenMode Open mode flags. (similar to DosOpen)
273 * @param phFile Pointer to filehandle.
274 * @param pulsomething 16-bit near (?) pointer to a variable - unknown. NULL is allowed. EA?
275 */
276APIRET KRNLCALL fakeIOSftOpen(
277 PSZ pszFilename,
278 ULONG flOpenFlags,
279 ULONG fsOpenMode,
280 PSFN phFile,
281 PULONG pulsomething
282 )
283{
284 ULONG ulAction;
285 HFILE hFile;
286 APIRET rc;
287 BOOL f32Stack = ((int)&hFile > 0x10000);
288
289 if (!f32Stack) ThunkStack16To32();
290
291 hFile = 0;
292 ulAction = 0;
293 rc = DosOpen(pszFilename, &hFile, &ulAction, 0, FILE_NORMAL,
294 flOpenFlags,
295 fsOpenMode,
296 NULL);
297 if (rc == NO_ERROR)
298 *phFile = (USHORT)hFile;
299
300 if (!f32Stack) ThunkStack32To16();
301
302 printf("fakeIOSftOpen: pszFilename = %s, flOpenFlags = 0x%08x, fsOpenMode = 0x%08x, phFile = %p; *phFile = 0x%04, pulsomething = %p, rc = %d\n",
303 pszFilename, flOpenFlags, fsOpenMode, phFile, *phFile, pulsomething, rc);
304
305 return rc;
306}
307
308
309/**
310 * Closes the specified file.
311 * @returns NO_ERROR on success. OS/2 error code on error.
312 * @param hFile File handle - System File Number.
313 */
314APIRET KRNLCALL fakeIOSftClose(
315 SFN hFile
316 )
317{
318 APIRET rc;
319 BOOL f32Stack = ((int)&hFile > 0x10000);
320
321 if (!f32Stack) ThunkStack16To32();
322
323 rc = DosClose(hFile);
324
325 if (!f32Stack) ThunkStack32To16();
326
327 printf("fakeIOSftClose: hFile = 0x%04, rc = %d\n",
328 hFile, rc);
329
330 return rc;
331}
332
333
334/**
335 * Probably this function will expand a relative path to a full path.
336 * @returns NO_ERROR on success. OS/2 error code on error.
337 * @param pszPath Pointer to path to expand. Contains the full path upon return. (?)
338 * This buffer should probably be of CCHMAXPATH length.
339 * @status completely implemented.
340 */
341APIRET KRNLCALL fakeIOSftTransPath(
342 PSZ pszPath
343 )
344{
345 char szBuffer[CCHMAXPATH];
346 APIRET rc;
347 BOOL f32Stack = ((int)&pszPath > 0x10000);
348
349 if (!f32Stack) ThunkStack16To32();
350
351 rc = DosQueryPathInfo(pszPath, FIL_QUERYFULLNAME, &szBuffer, sizeof(szBuffer));
352 printf("fakeIOSftTransPath: pszPath(in) = %s, pszPath(out) = %s, rc = %d\n",
353 pszPath, szBuffer, rc);
354 if (rc == NO_ERROR)
355 strcpy(pszPath, szBuffer);
356 else
357 kprintf(("fakeIOSftTransPath: DosQueryPathInfo failed with rc=%d\n", rc));
358
359
360 if (!f32Stack) ThunkStack32To16();
361
362 return rc;
363}
364
365
366/**
367 * Read at a given offset in the a file.
368 * @returns NO_ERROR on success. OS/2 error code on error.
369 * @param hFile File handle - System File Number.
370 * @param pcbActual Pointer to variable which upon input holds the number
371 * of bytes to read, on output the actual number of bytes read.
372 * @param pvBuffer Pointer to the read buffer.
373 * @param fpBuffer 16 far pointer to buffer. (ignored)
374 * @param ulOffset File offset to read from. (0=start of file)
375 */
376APIRET KRNLCALL fakeIOSftReadAt(
377 SFN hFile,
378 PULONG pcbActual,
379 PVOID pvBuffer,
380 ULONG fpBuffer,
381 ULONG ulOffset
382 )
383{
384 ULONG ulMoved;
385 APIRET rc;
386 BOOL f32Stack = ((int)&hFile > 0x10000);
387
388 if (!f32Stack) ThunkStack16To32();
389
390 rc = DosSetFilePtr(hFile, ulOffset, FILE_BEGIN, &ulMoved);
391 if (rc == NO_ERROR)
392 rc = DosRead(hFile, pvBuffer, *pcbActual, pcbActual);
393 else
394 kprintf(("fakeIOSftReadAt: DosSetFilePtr(hfile, 0x%08x(%d),..) failed with rc = %d.",
395 ulOffset, ulOffset, rc));
396
397 if (!f32Stack) ThunkStack32To16();
398
399 printf("fakeIOSftReadAt: hFile = 0x%04, pcbActual = %p; *pcbActual = 0x%08x, pvBuffer = %p, fpBuffer = %x, ulOffset = 0x%08x, rc = %d\n",
400 hFile, pcbActual, pvBuffer, fpBuffer, ulOffset, rc);
401
402 return rc;
403}
404
405
406/**
407 * Write at a given offset in the a file.
408 * @returns NO_ERROR on success. OS/2 error code on error.
409 * @param hFile File handle - System File Number.
410 * @param pcbActual Pointer to variable which upon input holds the number
411 * of bytes to write, on output the actual number of bytes write.
412 * @param pvBuffer Pointer to the write buffer.
413 * @param fpBuffer 16 far pointer to buffer. (ignored)
414 * @param ulOffset File offset to write from. (0=start of file)
415 */
416APIRET KRNLCALL fakeIOSftWriteAt(
417 SFN hFile,
418 PULONG pcbActual,
419 PVOID pvBuffer,
420 ULONG fpBuffer,
421 ULONG ulOffset
422 )
423{
424 ULONG ulMoved;
425 APIRET rc;
426 BOOL f32Stack = ((int)&hFile > 0x10000);
427
428 if (!f32Stack) ThunkStack16To32();
429
430 rc = DosSetFilePtr(hFile, ulOffset, FILE_BEGIN, &ulMoved);
431 if (rc == NO_ERROR)
432 rc = DosWrite(hFile, pvBuffer, *pcbActual, pcbActual);
433 else
434 kprintf(("fakeIOSftWriteAt: DosSetFilePtr(hfile, 0x%08x(%d),..) failed with rc = %d.",
435 ulOffset, ulOffset, rc));
436
437 if (!f32Stack) ThunkStack32To16();
438
439 printf("fakeIOSftWriteAt: hFile = 0x%04, pcbActual = %p; *pcbActual = 0x%08x, pvBuffer = %p, fpBuffer = %x, ulOffset = 0x%08x, rc = %d\n",
440 hFile, pcbActual, pvBuffer, fpBuffer, ulOffset, rc);
441
442 return rc;
443}
444
445
446/**
447 * Gets the filesize.
448 * @returns NO_ERROR on success; OS/2 error code on error.
449 * @param hFile File handle - System File Number.
450 * @param pcbFile Pointer to ULONG which will hold the file size upon return.
451 */
452APIRET KRNLCALL fakeSftFileSize(
453 SFN hFile,
454 PULONG pcbFile
455 )
456{
457 FILESTATUS3 fsts3;
458 APIRET rc;
459 BOOL f32Stack = ((int)&hFile > 0x10000);
460
461 if (!f32Stack) ThunkStack16To32();
462
463 rc = DosQueryFileInfo(hFile,
464 FIL_STANDARD,
465 &fsts3,
466 sizeof(fsts3));
467 if (rc == NO_ERROR)
468 *pcbFile = fsts3.cbFile;
469 else
470 kprintf(("fakeSftFileSize: DosQueryFileInfo failed with rc=%d\n", rc));
471
472 if (!f32Stack) ThunkStack32To16();
473
474 printf("fakeSftFileSize: hFile = 0x%04x, pcbFile = %p; *pcbFile = 0x%08x, rc = %d\n",
475 hFile, pcbFile, *pcbFile, rc);
476
477 return rc;
478}
479
480
481/**
482 * @status stub
483 */
484HMTE KRNLCALL fakeVMGetOwner(
485 ULONG ulCS,
486 ULONG ulEIP)
487{
488 DUMMY();
489
490 printf("fakeVMGetOwner: ulCS = 0x%04x, ulEiP = 0x%08x, rc = %d\n",
491 ulCS, ulEIP, 0);
492
493 return 0;
494}
495
496
497/**
498 * @status stub
499 */
500APIRET KRNLCALL fakeVMAllocMem(
501 ULONG cbSize,
502 ULONG cbCommit,
503 ULONG flFlags1,
504 HPTDA hPTDA,
505 USHORT usVMOwnerId,
506 HMTE hMTE,
507 ULONG flFlags2,
508 ULONG SomeArg2,
509 PVMAC pvmac)
510{
511 DUMMY();
512 printf("fakeVMAllocMem: cbSize = 0x%08x, cbCommit = 0x%08x, flFlags1 = 0x%08x, hPTDA = 0x%04x, usVMOwnerId = 0x%04x, hMTE = 0x%04x, flFlags2 = 0x%08x, SomeArg2 = 0x%08x, pvmac = %p, rc = %d\n",
513 cbSize, cbCommit, flFlags1, hPTDA, usVMOwnerId, hMTE, flFlags2, SomeArg2, pvmac, 0);
514
515 return ERROR_NOT_SUPPORTED;
516}
517
518
519/**
520 * @status stub
521 * @remark Used by environment stuff...
522 */
523APIRET KRNLCALL fakeVMObjHandleInfo(
524 USHORT usHob,
525 PULONG pulAddr,
526 PUSHORT pushPTDA)
527{
528 APIRET rc = NO_ERROR;
529 BOOL f32Stack = ((int)&usHob > 0x10000);
530
531 if (!f32Stack) ThunkStack16To32();
532
533 if (pulAddr > (PULONG)0x10000 && pushPTDA > (PUSHORT)0x10000)
534 {
535 PTIB pTib;
536 PPIB pPib;
537 DosGetInfoBlocks(&pTib, &pPib);
538 switch (usHob)
539 {
540 case 1: *pulAddr = (ULONG)pPib->pib_pchenv; break; //PTDA environ (fakea.asm)
541 default:
542 printf("fakeVMObjHandleInfo: Invalid handle! (usHob=0x%#4x)\n", usHob);
543 rc = ERROR_INVALID_HANDLE;
544 }
545 *pushPTDA = 10; //dummy
546 }
547 else
548 rc = ERROR_INVALID_PARAMETER;
549
550 if (!f32Stack) ThunkStack32To16();
551
552 printf("fakeVMObjHandleInfo: usHob = 0x%04x, pulAddr = %p, pushPTDA = %p, rc = %d\n",
553 usHob, pulAddr, pushPTDA, rc);
554 return rc;
555}
556
557
558/**
559 * myldrOpenPath - opens file eventually searching loader specific paths
560 *
561 * @returns OS2 return code.
562 * pLdrLv->lv_sfn is set to filename handle.
563 * @param pachFilename Pointer to modulename. Not zero terminated?
564 * @param cchFilename Modulename length.
565 * @param plv Loader local variables? (Struct from KERNEL.SDF)
566 * @param pful Pointer to flags which are passed on to ldrOpen.
567 * @status stub
568 */
569ULONG LDRCALL fakeldrOpenPath(PCHAR pachFilename, USHORT cchFilename, ldrlv_t *plv, PULONG pful)
570{
571 static char szPath[1024]; /* Path buffer. Used to store pathlists. 1024 should be enough */
572 /* for LIBPATH (which at had a limit of ca. 750 chars). */
573 static char sz[CCHMAXPATH]; /* Filename/path buffer. (Normally used to build filenames */
574 /* which are passed in as search experessions to DosFindFirst.) */
575
576 APIRET rc; /* Return value. (Pessimistic attitude! Init it to FALSE...) */
577
578 printf("fakeldrOpenPath: *entry* pachFilename = %.*s, cchFilename = %d, plv = %p, pful = %p\n",
579 cchFilename, pachFilename, cchFilename, plv, pful);
580
581 if (plv->lv_class != CLASS_GLOBAL)
582 rc = fakeldrOpen(&plv->lv_sfn, pachFilename, pful);
583 else
584 {
585 int iPath; /* Current path or pathlist being examined. This is the loop */
586 /* variable looping on the FINDDLL_* defines. */
587
588 /* These defines sets the order the paths and pathlists are examined. */
589 #define FINDDLL_BEGINLIBPATH 7
590 #define FINDDLL_LIBPATH 8
591 #define FINDDLL_ENDLIBPATH 9
592 #define FINDDLL_FIRST FINDDLL_BEGINLIBPATH
593 #define FINDDLL_LAST FINDDLL_ENDLIBPATH
594
595 /*
596 * Remove DLL extention from the filename.
597 */
598 if (cchFilename > 4 && !strncmp(&pachFilename[cchFilename - 4], ".DLL", 4))
599 {
600 cchFilename -= 4;
601 pachFilename[cchFilename] = '\0';
602 }
603
604 /** @sketch
605 * Loop thru the paths and pathlists searching them for the filename.
606 */
607 rc = ERROR_FILE_NOT_FOUND;
608 for (iPath = FINDDLL_FIRST; iPath <= FINDDLL_LAST; iPath++)
609 {
610 const char * pszPath; /* Pointer to the path being examined. */
611
612 /** @sketch Get the path/dir to examin. (This is determined by the value if iPath.) */
613 switch (iPath)
614 {
615 case FINDDLL_BEGINLIBPATH:
616 rc = DosQueryExtLIBPATH(szPath, BEGIN_LIBPATH);
617 break;
618 case FINDDLL_LIBPATH:
619 rc = DosQueryHeaderInfo(NULLHANDLE, 0, szPath, sizeof(szPath), QHINF_LIBPATH);
620 break;
621 case FINDDLL_ENDLIBPATH:
622 rc = DosQueryExtLIBPATH(szPath, END_LIBPATH);
623 break;
624 default: /* !internalerror! */
625 return ERROR_FILE_NOT_FOUND;
626 }
627 if (rc != NO_ERROR)
628 {
629 printf("fakeldrOpenPath: DosQueryExtLIBPATH/DosQueryHeadInfo failed with rc=%d, iPath=%d", rc, iPath);
630 continue;
631 }
632 pszPath = szPath;
633
634
635 /** @sketch
636 * pszPath is now set to the pathlist to be searched.
637 * So we'll loop thru all the paths in the list.
638 */
639 while (pszPath != NULL && *pszPath != '\0')
640 {
641 char * pszNext; /* Pointer to the next pathlist path */
642 int cch; /* Length of path (including the slash after the slash is added). */
643
644 /** @sketch
645 * Find the end of the path.
646 * Copy the path into the sz buffer.
647 * Set pszNext.
648 */
649 pszNext = strchr(pszPath, ';');
650 if (pszNext != NULL)
651 {
652 cch = pszNext - pszPath;
653 pszNext++;
654 }
655 else
656 cch = strlen(pszPath);
657
658 if (cch + cchFilename + 1 >= sizeof(sz)) /* assertion */
659 {
660 printf("fakeldrOpenPath: cch (%d) + cchFilename (%d) + 1 < sizeof(plv->sz) (%d) - paths too long!, iPath=%d",
661 cch, cchFilename, sizeof(sz), iPath);
662 pszPath = pszNext;
663 continue;
664 }
665 memcpy(sz, pszPath, cch);
666
667 /** @sketch
668 * Add a '\\' and the filename (pszFullname) to the path;
669 * then we'll have a fullpath.
670 */
671 sz[cch++] = '\\';
672 memcpy(&sz[cch], pachFilename, cchFilename);
673 memcpy(&sz[cch + cchFilename], ".DLL", 5);
674
675 rc = fakeldrOpen(&plv->lv_sfn, sz, pful);
676 switch (rc)
677 {
678 case ERROR_FILE_NOT_FOUND: case ERROR_PATH_NOT_FOUND: case ERROR_ACCESS_DENIED: case ERROR_INVALID_ACCESS:
679 case ERROR_INVALID_DRIVE: case ERROR_NOT_DOS_DISK: case ERROR_REM_NOT_LIST: case ERROR_BAD_NETPATH:
680 case ERROR_NETWORK_BUSY: case ERROR_DEV_NOT_EXIST: case ERROR_TOO_MANY_CMDS: case ERROR_ADAP_HDW_ERR:
681 case ERROR_UNEXP_NET_ERR: case ERROR_BAD_REM_ADAP: case ERROR_NETNAME_DELETED: case ERROR_BAD_DEV_TYPE:
682 case ERROR_NETWORK_ACCESS_DENIED: case ERROR_BAD_NET_NAME: case ERROR_TOO_MANY_SESS: case ERROR_REQ_NOT_ACCEP:
683 case ERROR_INVALID_PASSWORD: case ERROR_OPEN_FAILED: case ERROR_INVALID_NAME: case ERROR_FILENAME_EXCED_RANGE:
684 case ERROR_VC_DISCONNECTED:
685 rc = ERROR_FILE_NOT_FOUND;
686 pszPath = pszNext;
687 continue;
688 }
689
690 /*
691 * Fatal error or success.
692 */
693 printf("fakeldrOpenPath: *exit* plv->lv_sfn = 0x%04x, rc = %d\n", plv->lv_sfn, rc);
694 return rc;
695 }
696 } /* for iPath */
697 }
698
699 printf("fakeldrOpenPath: *exit* plv->lv_sfn = 0x%04x, rc = %d\n", plv->lv_sfn, rc);
700
701 return rc;
702}
703
704
705/**
706 * LDRClearSem - Clears the loader semaphore.
707 * (It does some garbage collection on release.)
708 * @returns NO_ERROR on sucess.
709 * OS/2 error on failure. (ERROR_INTERRUPT?)
710 * @status completely implemented.
711 */
712ULONG LDRCALL fakeLDRClearSem(void)
713{
714 if (lfakeLDRSem == 0)
715 kprintf(("fakeLDRClearSem: lfakeLDRSem is 0 allready\n"));
716 else
717 lfakeLDRSem--;
718
719 printf("fakeLDRClearSem: usage count = %d, rc = %d\n", lfakeLDRSem, NO_ERROR);
720
721 return NO_ERROR;
722}
723
724/**
725 * KSEMReuqestMutex faker.
726 * @returns NO_ERROR
727 * @param hkmtx
728 * @param ulTimeout
729 * @status completely implemented.
730 * @remark
731 */
732ULONG KRNLCALL fakeKSEMRequestMutex(HKMTX hkmtx, ULONG ulTimeout)
733{
734 (*(PLONG)hkmtx)++;
735
736 printf("fakeKSEMRequestMutex: hkmtx = %p, ulTimeout = 0x%x, usage count = %d, rc = %d\n",
737 hkmtx, ulTimeout, *(PLONG)hkmtx, NO_ERROR);
738
739 return NO_ERROR;
740}
741
742
743/**
744 * Copy user memory into system memory.
745 * @returns OS/2 return code. (NO_ERROR is success)
746 * @param pv Pointer to target (system) data area.
747 * @param pvUsr Pointer to source (user) data area.
748 * @param cb Count of bytes to copy.
749 * @param fl Flags.
750 * @status Partially implemented.
751 * @remark Ignores fl. Crashes on error.
752 */
753ULONG KRNLCALL fakeTKFuBuff(PVOID pv, PVOID pvUsr, ULONG cb, ULONG fl)
754{
755 memcpy(pv, pvUsr, cb);
756
757 printf("fakeTKFuBuff: pv = %p, pvUsr = %p, cb = 0x%08x, fl = 0x%08x, rc = %d\n",
758 pv, pvUsr, cb, fl, NO_ERROR);
759
760 return NO_ERROR;
761}
762
763
764/**
765 * Copy system memory to user memory.
766 * @returns OS/2 return code. (NO_ERROR is success)
767 * @param pvUsr Pointer to target (user) data area.
768 * @param pv Pointer to source (system) data area.
769 * @param cb Count of bytes to copy.
770 * @param fl Flags.
771 * @status Partially implemented.
772 * @remark Ignores fl. Crashes on error.
773 */
774ULONG KRNLCALL fakeTKSuBuff(PVOID pvUsr, PVOID pv, ULONG cb, ULONG fl)
775{
776 memcpy(pvUsr, pv, cb);
777
778 printf("fakeTKSuBuff: pvUsr = %p, pv = %p, cb = 0x%08x, fl = 0x%08x, rc = %d\n",
779 pvUsr, pv, cb, fl, NO_ERROR);
780
781 return NO_ERROR;
782}
783
784
785/**
786 * String length. (includes NULL(s))
787 * @returns OS/2 return code. (NO_ERROR is success)
788 * ERROR_TERMINATOR_NOT_FOUND
789 * @param pcch Pointer to length variable.
790 * @param pvUsr Pointer to user data to preform string length on.
791 * @param cchMax Max string length.
792 * @param fl Flags.
793 * @param fDblNULL TRUE: Double '\0' (ie. '\0\0') terminated. Usefull for scanning environments.
794 * FALSE: Single string. (ie. one '\0').
795 * @status Partially implemented.
796 * @remark Ignores fl. Crashes on error.
797 */
798ULONG KRNLCALL fakeTKFuBufLen(PLONG pcch, PVOID pvUsr, ULONG cchMax, ULONG fl, BOOL fDblNULL)
799{
800 ULONG rc;
801 PSZ psz = pvUsr;
802
803 cchMax += (ULONG)pvUsr;
804
805 while ((ULONG)psz < cchMax)
806 {
807 if (*psz++ == '\0')
808 if (!fDblNULL || (ULONG)psz == cchMax || *psz++ != '\0')
809 break;
810 }
811
812 *pcch = (ULONG)psz - (ULONG)pvUsr;
813
814 /* Hope this is the correct definition of max length: Not inclusive. */
815 if ((ULONG)psz == cchMax)
816 rc = ERROR_TERMINATOR_NOT_FOUND;
817 else
818 rc = NO_ERROR;
819
820 printf("fakeTKFuBufLen: pcch = %p; *pcch = 0x%08x, pvUsr = %p, cchMax = 0x%08x, fl = 0x%08x, fDblNULL = %x, rc = %d\n",
821 pcch, *pcch, pvUsr, cchMax, fl, fDblNULL, NO_ERROR);
822
823 return rc;
824}
825
826
827/**
828 * Validates an hMTE and gets the MTE pointer - FAKE.
829 * @returns Pointer to MTE on success.
830 * NULL on error.
831 * @param hMTE MTE handle.
832 * @remark If you wan't to this faster:
833 * Use the hMTE as a HOB and get the HOB address (by using VMGetHandleInfo).
834 * @status stub.
835 */
836PMTE LDRCALL fakeldrValidateMteHandle(HMTE hMTE)
837{
838 DUMMY();
839
840 printf("fakeldrValidateMteHandle: hMTE = 0x%04x, pMTE (rc) = %p\n",
841 hMTE, NULL);
842
843 return NULL;
844}
845
846
847/**
848 * C worker function for fakeg_tkExecPgm. This is called by fakeg_tkExecPgm (fakea.asm).
849 * @returns OS/2 return code.
850 * @param execFlag Exec flag (DosExecPgm execFlag).
851 * @param pArg Pointer to arguments. (NULL allowed)
852 * @param pEnv Pointer to environment. (NULL allowed)
853 * @param pszFilename Pointer to filename.
854 * @sketch
855 * @status
856 * @author knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
857 * @remark
858 */
859ULONG _Optlink tkExecPgmWorker(ULONG execFlag, PSZ pArg, PSZ pEnv, PSZ pszFilename)
860{
861 APIRET rc;
862 ldrrei_t rei;
863
864 printf("tkExecPgmWorker: execFlag = %d, pArg = %p, pEnv = %p, pszFilename = %s\n", execFlag, pArg, pEnv, pszFilename);
865
866 /*
867 * Simulate loading.
868 */
869 rc = fakeLDRLoadExe(pszFilename, SSToDS(&rei));
870
871 NOREF(pArg);
872 NOREF(pEnv);
873 NOREF(execFlag);
874
875 return rc;
876}
877
878
879/**
880 * Fake implementation of LDRLoadExe.
881 * Not currently overriden, but used by tkExecPgmWorker to load executables.
882 * @returns OS/2 return code.
883 * @param pszFilename Name of executable image to load.
884 * @param pEI It seems this is a pointer to a ldrrei_s struct.
885 * (currently ignored)
886 * @sketch
887 * @status
888 * @author knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
889 * @remark
890 */
891ULONG LDRCALL fakeLDRLoadExe(PSZ pszFilename, ldrrei_t *pEI)
892{
893 APIRET rc;
894 int cchFilename = strlen(pszFilename);
895
896 printf("fakeLDRLoadExe: *entry* pszFilename = %s, pEI = %p\n",
897 pszFilename, pEI);
898
899 rc = fakeldrGetModule(pszFilename, (cchFilename << 16) | (LVTYPE_EXE << 8) | CLASS_PROGRAM);
900
901 printf("fakeLDRLoadExe: *exit* pszFilename = %s, pEI = %p, rc = %d\n",
902 pszFilename, pEI, rc);
903
904 return rc;
905}
906
907
908
909/**
910 * Fake implementeation of ldrGetModule.
911 * Not currently overriden, but used by fakeLDRLoadExe to load executables.
912 * @returns OS/2 return code.
913 * @param pszFilename Name of executable image to load.
914 * @param ul low 8 bits: Module CLASS_*.
915 * high 8 bits: Executable type LVTYPE_* ?
916 * high 16 bits: Filename length.
917 * @sketch
918 * OS/2 kernel seems to do:
919 * Call Sec32GetModule
920 * Call ldrGetMte which does the necessary loading / attaching.
921 * Call ldrLoadImports for all imported DLLs. (and the exe?)
922 * Call ldrProcessObjects for LX and ldrPreloadLDT for NE imported DLLs. (and the exe?)
923 * Call ldrProcessImports.
924 *
925 * We do:
926 * Call fakeldrGetMte.
927 * Call fakeldrLoadImports.
928 *
929 * @status
930 * @author knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
931 * @remark
932 */
933ULONG LDRCALL fakeldrGetModule(PSZ pszFilename, ULONG ul)
934{
935 APIRET rc;
936 PMTE pmte = NULL;
937
938 printf("fakeldrGetModule: *entry* pszFilename = %s, ul = 0x%08x\n",
939 pszFilename, ul);
940
941 rc = fakeldrGetMte(pszFilename, (USHORT)(ul >> 16), (UCHAR)((ul & 0xff00) >> 8), (UCHAR)(ul & 0x00ff), SSToDS(&pmte));
942 if (rc == NO_ERROR)
943 {
944 rc = fakeldrLoadImports(pmte);
945 }
946
947 printf("fakeldrGetModule: *exit* pszFilename = %s, ul = 0x%08x, rc = %d\n",
948 pszFilename, ul, rc);
949
950 return rc;
951}
952
953
954/**
955 *
956 * @returns
957 * @param
958 * @equiv
959 * @time
960 * @sketch
961 * OS/2 kernel seems to do:
962 * IF not device driver THEN
963 * Uppercase the name.
964 * Call ldrFindModule to try find the module within currenly loaded modules.
965 * ENDIF
966 *
967 * tryagain:
968 * IF found THEN
969 * Set MTEGETMTEDONE flag in mte_flags2.
970 * Call ldrChkLoadType to ensure correct load type.
971 * IF attached or special modules (DOSMOD, VDDMOD, FSHMOD or MVDMMOD)
972 * IF miniIFS and !FSHMOD THEN Fail with rc=ERROR_INVALID_NAME
973 * return successfully.
974 * ENDIF
975 * lv_sfn <- mte_sfn
976 * Set the USED flag in mte_flags1
977 * Set the MTELOADORATTACH flag in mte_flags2
978 * Some processing of packed segments???? Dll init flags???
979 * ELSE *not found*
980 * IF class is CLASS_SPECIFIC AND ldrCheckGlobal returned TRUE THEN
981 * * this is because some specific modules is promoted to global
982 * * modules for some reasons I haven't ivestigated. (ldrPrmoteMTE)
983 * tryagain.
984 * ENDIF
985 * Set some flag to false.
986 * Calls to ldrOpenNewExe to load the exectuble from disk.
987 * IF this failes THEN fail.
988 * IF class is CLASS_GLOBAL and module is loaded as specific
989 * (ldrCheckSpecific returns TRUE) THEN
990 * Close and retry with the mte returned ldrCheckSpecific
991 * tryagain.
992 * ENDIF
993 * Sets some local variable to point at pheaderbuf, where ldrOpenNewExe
994 * has put the executable header.
995 * Call ldrCheckLoadType and fail if this failes.
996 * Call ldrCreateMte and fail if this failes.
997 * Set some local variables to lv_pmte and lv_pmte->mte_swapmte.
998 * Set the MTELOADORATTACH and MTEGETMTEDONE flags.
999 * Call ldrInvTgtErrTxt.
1000 * IF DDInitTime AND DEVDRVMOD OR FSDMOD THEN
1001 * ptda_module of current PTDA to the mtehandle of the module.
1002 * ENDIF
1003 * IF DOSCALL1 (checks name) THEN
1004 * Set DOSLIB flag of mte_flags1.
1005 * Set global pmteDoscall1 to point to the mte.
1006 * Set global hmteDoscall1 to the handle of the mte.
1007 * ENDIF
1008 * ENDIF
1009 * IF VDDMOD THEN
1010 * call VDMMLoadingVDD with the mte handle.
1011 * ENDIF
1012 * IF NE executable THEN
1013 * Call ldrAllocSegments
1014 * ELSE
1015 * Call ldrAllocObjects
1016 * ENDIF
1017 * IF failed THEN fail.
1018 * IF LVTYPE_EXE THEN
1019 * Set the ptda_module of the ExecChild PTDA to mtehandle.
1020 * IF MTELONGNAMES THEN
1021 * Set ptda_NewFiles to something.
1022 * ENDIF
1023 * Increment usage count, ie. mte_usecnt-
1024 * ELSE IF LVTYPE_DLL AND !somelocalflag AND NOINTERNFIXUPS THEN
1025 * Remove Internal fixups?
1026 * (Calls ldrIsInternalFixup and VMReallocKHB during this processing.)
1027 * ENDIF
1028 * Clears the MTEPROCESSED flag of mte_flags1.
1029 * Sets the return mte pointer. (ppmte)
1030 * return successfully.
1031 *
1032 * We do:
1033 * Uppercase the string. (do we have to switch stack?)
1034 * Call fakeldrOpenNewExe to do it's work.
1035 * Call fakeldrCreateMte to create a fake mte.
1036 * return.
1037 *
1038 * @status
1039 * @author knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
1040 * @remark
1041 */
1042ULONG LDRCALL fakeldrGetMte(PCHAR pachFilename, USHORT cchFilename, UCHAR fchType, UCHAR fchClass, PPMTE ppmte)
1043{
1044 ldrlv_t lv;
1045 APIRET rc;
1046
1047 printf("fakeldrGetMte: *entry* pachFilename = %.*s, cchFilename = %#02x, fchType %#2x, fchClass = %#2x, ppmte = %p\n",
1048 cchFilename, pachFilename, cchFilename, fchType, fchClass, ppmte);
1049
1050 /*
1051 * Initiate the local variables.
1052 */
1053 memset(SSToDS(&lv), 0, sizeof(lv));
1054 lv.lv_sfn = (USHORT)-1;
1055 lv.lv_type = fchType;
1056 lv.lv_class = fchClass;
1057
1058 /*
1059 * Uppercase the string.
1060 */
1061 fakeldrUCaseString(pachFilename, cchFilename);
1062
1063 /*
1064 * Open the new executable.
1065 */
1066 rc = fakeldrOpenNewExe(pachFilename, cchFilename, SSToDS(&lv), NULL);
1067 if (rc != NO_ERROR)
1068 {
1069 fakeldrClose(lv.lv_sfn);
1070 printf("fakeldrGetMte: *exit* pachFilename = %.*s, ppmte = %p; *ppmte = %p, rc = %d\n",
1071 cchFilename, pachFilename, ppmte, *ppmte, rc);
1072 return rc;
1073 }
1074
1075 /*
1076 * Create MTE for the opened file.
1077 */
1078 rc = fakeldrCreateMte(pheaderbuf, SSToDS(&lv));
1079 if (rc == NO_ERROR)
1080 {
1081 /*
1082 * Set some flags... More?
1083 */
1084 lv.lv_pmte->mte_flags2 |= MTEGETMTEDONE | MTELOADORATTACH;
1085 *ppmte = lv.lv_pmte;
1086 }
1087
1088 printf("fakeldrGetMte: *exit* pachFilename = %.*s, ppmte = %p; *ppmte = %p, rc = %d\n",
1089 cchFilename, pachFilename, ppmte, *ppmte, rc);
1090
1091 return rc;
1092}
1093
1094
1095
1096/**
1097 * Opens an executable module.
1098 * @returns OS2 error code.
1099 * @param pachFilename Filename of the executable module to open.
1100 * @param cchFilename Filename length.
1101 * @param plv Pointer to local variables.
1102 * @param pus Pointer to some flags (LDRQAppType flags?!).
1103 * @sketch
1104 * OS/2 kernel seems to do:
1105 * Call ldrOpenPath to open the file.
1106 * IF this fail THEN
1107 * Set lv_sfn to -1 and return errorcode.
1108 * ENDIF
1109 * Set local variable to pheaderbuf.
1110 * IF pus THEN set *pus to 1
1111 * Call ldrRead to read the MZ header.
1112 * Fail if this failed. (Don't close file caller does that.)
1113 * IF LXMAGIC of NEMAGIC found THEN
1114 * lv_new_exe_off <- 0;
1115 * ELSE
1116 * IF !EMAGIC or 'OZ' THEN
1117 * Fail with rc=ERROR_INVALID_EXE_SIGNATURE.
1118 * ENDIF
1119 * IF pus THEN set *pus to 2.
1120 * lv_new_exe_off <- e_lfanew.
1121 * ENDIF
1122 * Call ldrRead to read LX/NE header at lv_new_exe_off.
1123 * Fail if this failed.
1124 * IF NOT LXMAGIC OR NEMAGIC THEN
1125 * IF LEMAGIC AND pus THEN Set *pus to 0.
1126 * IF PEMAGIC and pus THEN Set *pus to 3.
1127 * Fail with rc=ERROR_INVALID_EXE_SIGNATURE.
1128 * ENDIF
1129 * IF pus THEN Set *pus to 0.
1130 * IF invalid LX exeheader THEN
1131 * Fail with rc=ERROR_INVALID_EXE_SIGNATURE.
1132 * ENDIF
1133 * IF NEMAGIC THEN
1134 * Call ldrExpandHeader
1135 * ELSE
1136 * Set the MTELONGNAMES flag in e32_mflags.
1137 * ENDIF
1138 * IF LDRINVALID (in e32_mflags) THEN
1139 * Fail with rc=ERROR_EXE_MARKED_INVALID.
1140 * ENDIF
1141 * Clear some e32_mflags, MTE_MEDIAFIXED, MTEMEDIACONTIG and MTEMEDIA16M.
1142 * Or in flags set by ldrOpenPath into e32_mflags. (media type flags?!)
1143 * Call ldrMungeFlags
1144 * return retur code from ldrMungeFlags.
1145 *
1146 * We do:
1147 * Call fakeldrOpenPath to open the file.
1148 * IF this fail THEN
1149 * Set lv_sfn to -1 and return errorcode.
1150 * ENDIF
1151 * IF pus THEN set *pus to 1
1152 * Call ldrRead to read the MZ header.
1153 * Fail if this failed. (Don't close file caller does that.)
1154 * If MZ header Then
1155 * Set lv_new_exe_off to e_lfanew.
1156 * else
1157 * Set lv_new_exe_off to 0.
1158 * Call ldrRead to read the LX header.
1159 * Fail if this failed. (Don't close file caller does that.)
1160 * If Not LX signature Then
1161 * Fail.
1162 * return successfully.
1163 *
1164 * @status
1165 * @author knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
1166 * @remark
1167 */
1168ULONG LDRCALL fakeldrOpenNewExe(PCHAR pachFilename, USHORT cchFilename, ldrlv_t *plv, PUSHORT pus)
1169{
1170 APIRET rc;
1171 ULONG ful;
1172
1173 printf("fakeldrOpenNewExe: *entry* pachFilename = %.*s, cchFilename = %#2, plv = %p, pus = %p\n",
1174 cchFilename, pachFilename, cchFilename, plv, pus);
1175
1176 rc = fakeldrOpenPath(pachFilename, cchFilename, plv, SSToDS(&ful));
1177 if (rc != NO_ERROR)
1178 {
1179 plv->lv_sfn = 0xffff;
1180 printf("fakeldrOpenNewExe: *exit* pachFilename = %.*s, plv->lv_sfn = %#4x, rc = %d\n",
1181 cchFilename, pachFilename, plv->lv_sfn, rc);
1182 return rc;
1183 }
1184 if (pus) *pus = 1;
1185
1186 memset(pheaderbuf, 0, sizeof(struct exe_hdr)); //zero it just in case....
1187 rc = fakeldrRead(plv->lv_sfn, 0, pheaderbuf, 0, sizeof(struct exe_hdr), NULL);
1188 if (rc != NO_ERROR)
1189 {
1190 plv->lv_sfn = 0xffff;
1191 printf("fakeldrOpenNewExe: *exit* pachFilename = %.*s, plv->lv_sfn = %#4x, rc = %d\n",
1192 cchFilename, pachFilename, plv->lv_sfn, rc);
1193 return rc;
1194 }
1195
1196 if (*(PUSHORT)pheaderbuf == EMAGIC)
1197 plv->lv_new_exe_off = ((struct exe_hdr *)pheaderbuf)->e_lfanew;
1198 else
1199 plv->lv_new_exe_off = 0;
1200
1201 memset(pheaderbuf, 0, sizeof(struct e32_exe)); //zero it just in case....
1202 rc = fakeldrRead(plv->lv_sfn, plv->lv_new_exe_off, pheaderbuf, 0, sizeof(struct e32_exe), NULL);
1203 if (rc != NO_ERROR)
1204 {
1205 plv->lv_sfn = 0xffff;
1206 printf("fakeldrOpenNewExe: *exit* pachFilename = %.*s, plv->lv_sfn = %#4x, rc = %d\n",
1207 cchFilename, pachFilename, plv->lv_sfn, rc);
1208 return rc;
1209 }
1210
1211 if (*(PUSHORT)pheaderbuf != E32MAGIC)
1212 {
1213 plv->lv_sfn = 0xffff;
1214 rc = ERROR_INVALID_EXE_SIGNATURE;
1215 printf("fakeldrOpenNewExe: *exit* pachFilename = %.*s, plv->lv_sfn = %#4x, rc = %d\n",
1216 cchFilename, pachFilename, plv->lv_sfn, rc);
1217 return rc;
1218 }
1219
1220 printf("fakeldrOpenNewExe: *exit* pachFilename = %.*s, plv->lv_sfn = %#4x, rc = %d\n",
1221 cchFilename, pachFilename, plv->lv_sfn, rc);
1222
1223 return NO_ERROR;
1224}
1225
1226
1227/**
1228 * Fake ldrCreateMte implementation.
1229 * @returns
1230 * @param pe32 Pointer to the LX/NE header we've just read.
1231 * @param plv Pointer to local variables.
1232 * @sketch !This does a lot of thing!
1233 *
1234 * OS/2 Kernel seems to do:
1235 * Allocate a kernel heap block for the MTE
1236 *
1237 *
1238 *
1239 *
1240 *
1241 *
1242 *
1243 *
1244 *
1245 *
1246 * We do:
1247 *
1248 *
1249 * @status
1250 * @author knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
1251 * @remark
1252 */
1253ULONG LDRCALL fakeldrCreateMte(struct e32_exe *pe32, ldrlv_t *plv)
1254{
1255 ULONG rc;
1256 PMTE pMte;
1257 PSMTE pSMte;
1258 PCHAR pch;
1259
1260 printf("fakeldrCreateMte: *entry* pe32 = %p, plv = %d\n",
1261 pe32, plv);
1262
1263 /*
1264 * Allocate mte and smte.
1265 * The MTE has an array of mte pointers at the end for imported modules + 1.
1266 * The SMTE has the fullpath filename, loader section and fixup section.
1267 */
1268 pMte = malloc(sizeof(MTE) + sizeof(PMTE) + sizeof(PMTE)*pe32->e32_impmodcnt);
1269 if (pMte == NULL)
1270 {
1271 rc = ERROR_NOT_ENOUGH_MEMORY;
1272 goto createmte_exit;
1273 }
1274
1275 plv->lv_csmte = sizeof(SMTE) + 260 + pe32->e32_ldrsize + pe32->e32_fixupsize;
1276 pSMte = malloc(plv->lv_csmte);
1277 if (pSMte == NULL)
1278 {
1279 rc = ERROR_NOT_ENOUGH_MEMORY;
1280 goto createmte_exit;
1281 }
1282 pch = (PCHAR)(PVOID)pSMte + sizeof(SMTE) + 260;
1283
1284
1285 /*
1286 * Initialize the MTE.
1287 */
1288 pMte->mte_flags2 = MTEFORMATLX;
1289 pMte->mte_handle = 20;
1290 pMte->mte_swapmte = pSMte;
1291 pMte->mte_link = NULL;
1292 pMte->mte_flags1 = pe32->e32_mflags;
1293 pMte->mte_impmodcnt = pe32->e32_impmodcnt;
1294 pMte->mte_sfn = plv->lv_sfn;
1295 pMte->mte_usecnt = 0;
1296 pMte->mte_modname[0]= '\0';
1297
1298 /*
1299 * Initialize the SMTE.
1300 */
1301 pSMte->smte_mpages = pe32->e32_mpages;
1302 /*- magic,border,worder,level,cpu,os,ver,mflags */
1303 pSMte->smte_mpages = pe32->e32_mpages; /* 00 Module # pages */
1304 pSMte->smte_startobj = pe32->e32_startobj; /* 04 Object # for instruction */
1305 pSMte->smte_eip = pe32->e32_eip; /* 08 Extended instruction pointer */
1306 pSMte->smte_stackobj = pe32->e32_stackobj; /* 0c Object # for stack pointer */
1307 pSMte->smte_esp = pe32->e32_esp; /* 10 Extended stack pointer */
1308 /*- pagesize*/
1309 pSMte->smte_pageshift = pe32->e32_pageshift; /* 14 Page alignment shift in .EXE */
1310 pSMte->smte_fixupsize = pe32->e32_fixupsize; /* 18 Fixup section size */
1311 /*- fixupsum,ldrsize,ldrsum*/
1312 pSMte->smte_objtab = (POTE)pe32->e32_objtab; /* 1c Object table offset - POINTER */
1313 pSMte->smte_objcnt = pe32->e32_objcnt; /* 20 Number of objects in module */
1314 pSMte->smte_objmap = pe32->e32_objmap; /* 24 Object page map offset - POINTER */
1315 pSMte->smte_itermap = pe32->e32_itermap; /* 28 Object iterated data map offset */
1316 pSMte->smte_rsrctab = pe32->e32_rsrctab; /* 2c Offset of Resource Table */
1317 pSMte->smte_rsrccnt = pe32->e32_rsrccnt; /* 30 Number of resource entries */
1318 pSMte->smte_restab = pe32->e32_restab; /* 34 Offset of resident name table - POINTER */
1319 pSMte->smte_enttab = pe32->e32_enttab; /* 38 Offset of Entry Table - POINTER */
1320 pSMte->smte_fpagetab = pe32->e32_fpagetab; /* 3c Offset of Fixup Page Table - POINTER */
1321 pSMte->smte_frectab = pe32->e32_frectab; /* 40 Offset of Fixup Record Table - POINTER */
1322 pSMte->smte_impmod = pe32->e32_impmod; /* 44 Offset of Import Module Name Table - POINTER */
1323 /*- impmodcnt*/
1324 pSMte->smte_impproc = pe32->e32_impproc; /* 48 Offset of Imp Procedure Name Tab - POINTER */
1325 /*- pagesum*/
1326 pSMte->smte_datapage = pe32->e32_datapage; /* 4c Offset of Enumerated Data Pages */
1327 /*- preload*/
1328 pSMte->smte_nrestab = pe32->e32_nrestab; /* 50 Offset of Non-resident Names Table */
1329 pSMte->smte_cbnrestab = pe32->e32_cbnrestab; /* 54 Size of Non-resident Name Table */
1330 /*- nressum*/
1331 pSMte->smte_autods = pe32->e32_autodata; /* 58 Object # for automatic data object */
1332 pSMte->smte_debuginfo = pe32->e32_debuginfo; /* 5c Offset of the debugging info */
1333 pSMte->smte_debuglen = pe32->e32_debuglen; /* 60 The len of the debug info in */
1334 /*- instpreload,instdemand*/
1335 pSMte->smte_heapsize = pe32->e32_heapsize; /* 64 use for converted 16-bit modules */
1336 /*- res3*/
1337 /* extra */
1338 pSMte->smte_path = 0; /* 68 full pathname - POINTER */
1339 pSMte->smte_semcount = 0; /* 6c Count of threads waiting on MTE semaphore. 0 => semaphore is free */
1340 pSMte->smte_semowner = 0; /* 6e Slot number of the owner of MTE semahore */
1341 pSMte->smte_pfilecache = 0; /* 70 Pointer to file cache for Dos32CacheModule */
1342 pSMte->smte_stacksize = 0; /* 74 Thread 1 Stack size from the exe header */
1343 pSMte->smte_alignshift = 0; /* 78 use for converted 16-bit modules */
1344 pSMte->smte_NEexpver = 0; /* 7a expver from NE header */
1345 pSMte->smte_pathlen = 0; /* 7c length of full pathname */
1346 pSMte->smte_NEexetype = 0; /* 7e exetype from NE header */
1347 pSMte->smte_csegpack = 0; /* 80 count of segs to pack */
1348
1349 /*
1350 * Copy filename (from where?)
1351 */
1352 pSMte->smte_path = (PCHAR)(PVOID)pSMte + sizeof(SMTE);
1353 pSMte->smte_pathlen = 0;
1354 memcpy(pSMte->smte_path, "", pSMte->smte_pathlen);
1355
1356
1357 /*
1358 * Read loader and fixup sections.
1359 */
1360 rc = fakeldrRead(plv->lv_sfn,
1361 (ULONG)pSMte->smte_objtab + plv->lv_new_exe_off,
1362 pch,
1363 0,
1364 pe32->e32_ldrsize + pe32->e32_fixupsize,
1365 NULL);
1366 if (rc)
1367 {
1368 goto createmte_exit;
1369 }
1370
1371 /*
1372 * Set pointers.
1373 */
1374 pSMte->smte_objtab = (POTE)(PVOID)pch;
1375 rc = fakeldrMTEValidatePtrs(pSMte,
1376 (ULONG)pch + plv->lv_csmte,
1377 (ULONG)pch - (ULONG)pe32->e32_objtab);
1378 if (rc)
1379 {
1380 goto createmte_exit;
1381 }
1382
1383 /*
1384 * Set mte pointer in plv.
1385 * Set hobmte in plv.
1386 */
1387 plv->lv_pmte = pMte;
1388 plv->lv_hobmte = pMte->mte_handle;
1389
1390 /*
1391 * Fix flags...
1392 */
1393 pMte->mte_flags1 |= plv->lv_class;
1394
1395createmte_exit:
1396 printf("fakeldrCreateMte: *exit* pe32 = %p, plv = %d, rc = %d\n",
1397 pe32, plv, rc);
1398
1399 return rc;
1400}
1401
1402
1403
1404/**
1405 * Fake ldrLoadImports - loads the import modules for the given module (pmte).
1406 * @returns OS2 error code.
1407 * @param pmte Pointer to mte to load imports for.
1408 * @sketch
1409 * OS/2 kernel seems to do:
1410 * Loop thru the importe module table (reverse order for NE files)
1411 * IF VDD module THEN
1412 * Uppercase the name.
1413 * try find it using ldrFindModule
1414 * fail if error, not found, not VDDMOD/MVDMMOD.
1415 * Add to array of imported module.
1416 * ENDIF
1417 * IF Not found OR !MTEGETMTEDONE THEN
1418 * call ldrGetMte to load the module (class global).
1419 * fail if error.
1420 * set MTEGETMTEDONE
1421 * Add to array of imported module.
1422 * ENDIF
1423 * IF DOSMOD and !ldrMiniFileIOFlag THEN
1424 * Replace module pointer with doscall1 pmte.
1425 * ENDIF
1426 * ENDLOOP
1427 *
1428 * We do:
1429 * Parameter validation.
1430 * Loop thru the imported module table issuing fakeldrGetMte on each entry.
1431 * 'DOSCALLS' is ignored.
1432 *
1433 * @status
1434 * @author knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
1435 * @remark
1436 */
1437ULONG LDRCALL fakeldrLoadImports(PMTE pmte)
1438{
1439 int i; /* Module index. */
1440 PSZ psz; /* Module name pointer. (really pointer to pascal strings...) */
1441 PPMTE papmte; /* Pointer to array of PMTEs for imported modules. */
1442 APIRET rc;
1443
1444 printf("fakeldrLoadImport: *entry* pmte = %p, pmte->mte_impmodcnt = %d\n",
1445 pmte, pmte->mte_impmodcnt);
1446
1447 /*
1448 * Parameter validation.
1449 */
1450 if (pmte == NULL)
1451 {
1452 kprintf(("fakeldrLoadImports: !ASSERTION! pmte == NULL\n"));
1453 return ERROR_INVALID_PARAMETER;
1454 }
1455 if (pmte->mte_swapmte == NULL)
1456 {
1457 kprintf(("fakeldrLoadImports: !ASSERTION! pmte->mte_swapmte == NULL\n"));
1458 return ERROR_INVALID_PARAMETER;
1459 }
1460
1461 /*
1462 * Any imported modules?
1463 */
1464 if (pmte->mte_impmodcnt == 0)
1465 {
1466 printf("fakeldrLoadImport: *exit* pmte = %p, rc = %d\n",
1467 pmte, rc);
1468 return NO_ERROR;
1469 }
1470
1471 /* We have reserved space for imported module pointers after the mte. */
1472 papmte = (PPMTE)((unsigned)pmte + sizeof(MTE));
1473
1474 /*
1475 * Process the imported module table.
1476 */
1477 for (i = 0, rc = NO_ERROR, psz = (PSZ)pmte->mte_swapmte->smte_impmod;
1478 i < pmte->mte_impmodcnt && rc == NO_ERROR;
1479 i++, psz += 1 + *psz)
1480 {
1481 if (!memcmp(psz+1, "DOSCALLS", *psz))
1482 continue;
1483
1484 rc = fakeldrGetMte(psz + 1, *psz, LVTYPE_DLL, CLASS_GLOBAL, &papmte[i]);
1485 }
1486
1487 printf("fakeldrLoadImport: *exit* pmte = %p, rc = %d\n",
1488 pmte, rc);
1489
1490 return rc;
1491}
1492
1493
1494
1495/**
1496 * Uppercases the string.
1497 * @param pachString String to uppercase.
1498 * @param cchString Length of string.
1499 * @sketch Loop thru the string converting all english letters to uppercase.
1500 * @status partially implemented.
1501 * @author knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
1502 * @remark This is probably written in assembly and does DBCS checks...
1503 */
1504VOID LDRCALL fakeldrUCaseString(PCHAR pachString, USHORT cchString)
1505{
1506 printf("fakeldrUCaseString: pachString = %.*s, cchString = %#8x\n",
1507 cchString, pachString, cchString);
1508
1509 while (cchString-- != 0)
1510 {
1511 if (*pachString >= 'a' && *pachString <= 'z')
1512 *pachString -= ('a' - 'A');
1513 pachString++;
1514 }
1515}
1516
1517
1518
1519
1520/**
1521 * Checks and updates the members of the swap-mte which is to be
1522 * pointers into the loader/fixup section. An array, validatetbl, contains
1523 * the offsets of the smte pointers.
1524 *
1525 * @returns NO_ERROR on success.
1526 * ERROR_BAD_EXE_FORMAT on error.
1527 * @param psmte
1528 * @param ulMaxAddr Maximum (exclusive) address.
1529 * @param off Offset delta to add to the pointer members (which
1530 * are all offsets relative to the start of the new
1531 * header) to make them pointers.
1532 * @sketch
1533 * Loop thru the validatetbl and update each field (which isn't null) by adding
1534 * the off value, and validate that the pointer is ok.
1535 * @author knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
1536 * @remark
1537 */
1538ULONG LDRCALL fakeldrMTEValidatePtrs(PSMTE psmte, ULONG ulMaxAddr, ULONG off)
1539{
1540 int i;
1541
1542 printf("fakeldrMTEValidatePtrs: *entry* psmte = %p, ulMaxAddr = %p, off = %p\n",
1543 psmte, ulMaxAddr, off);
1544
1545 for (i = 0; validatetbl[i] != 0xDEAD; i++)
1546 {
1547 PULONG pul = (PULONG)(PVOID)((PCHAR)(PVOID)psmte + validatetbl[i]);
1548 if (*pul != 0UL)
1549 {
1550 *pul += off;
1551 if (*pul >= ulMaxAddr)
1552 {
1553 printf("fakeldrMTEValidatePtrs: *exit* psmte = %p, ulMaxAddr = %p, off = %p, rc = %d\n",
1554 psmte, ulMaxAddr, off, ERROR_BAD_EXE_FORMAT);
1555 return ERROR_BAD_EXE_FORMAT;
1556 }
1557 }
1558 }
1559
1560 printf("fakeldrMTEValidatePtrs: *exit* psmte = %p, ulMaxAddr = %p, off = %p, rc = %d\n",
1561 psmte, ulMaxAddr, off, NO_ERROR);
1562 return NO_ERROR;
1563}
1564
Note: See TracBrowser for help on using the repository browser.