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

Last change on this file since 5004 was 4810, checked in by bird, 25 years ago

Synced test env. with the rest of win32k.sys.
Added testcases for testing -PE:pe vs. -P:pe.

File size: 65.1 KB
Line 
1/* $Id: fake.c,v 1.6 2000-12-16 23:03:31 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@mynd.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 "devSegDf.h" /* Win32k segment definitions. */
32
33#include "log.h"
34#include "OS2Krnl.h"
35#include "dev32.h"
36#include "ldrcalls.h"
37#include "test.h"
38#include "macros.h"
39
40#include "malloc.h"
41
42/*******************************************************************************
43* Structures and Typedefs *
44*******************************************************************************/
45typedef struct ldrrei_s /* #memb 7 size 20 (0x014) - from 14040W4 kernel.sdf */
46{
47 PVOID ei_startaddr; /* off: 0(00) size: 4(04) */
48 PVOID ei_stackaddr; /* off: 4(04) size: 4(04) */
49 PVOID ei_pstackmax; /* off: 8(08) size: 4(04) */
50 USHORT ei_ds; /* off: 12(0c) size: 2(02) */
51 USHORT ei_stacksize; /* off: 14(0e) size: 2(02) */
52 USHORT ei_heapsize; /* off: 16(10) size: 2(02) */
53 USHORT ei_loadtype; /* off: 18(12) size: 2(02) */
54} ldrrei_t;
55
56
57
58/*******************************************************************************
59* Global Variables *
60*******************************************************************************/
61/*
62 * Pointer to the loader semaphore.
63 */
64KSEMMTX fakeLdrSem;
65
66CHAR szBeginLibPath[1024];
67CHAR szEndLibPath[1024];
68CHAR szLibPath[1024];
69PSZ fakeLDRLibPath = &szLibPath[0];
70
71CHAR szldrpFileNameBuf[CCHMAXPATH];
72PSZ fakeldrpFileNameBuf = &szldrpFileNameBuf[0];
73
74static CHAR achHeaderBuffer[256]; /* Buffer to read exe header into. */
75PVOID pheaderbuf = &achHeaderBuffer[0];
76
77/*
78 * Mte list pointers.
79 */
80PMTE fakemte_h;
81PMTE fakeglobal_h;
82PMTE fakeglobal_l;
83PMTE fakespecific_h;
84PMTE fakespecific_l;
85PMTE fakeprogram_h;
86PMTE fakeprogram_l;
87
88
89/*
90 * table use by fakeldrMTEValidatePtrs.
91 */
92USHORT validatetbl[] =
93{
94 FIELDOFFSET(SMTE, smte_objmap),
95 FIELDOFFSET(SMTE, smte_rsrctab),
96 FIELDOFFSET(SMTE, smte_restab),
97 FIELDOFFSET(SMTE, smte_enttab),
98 FIELDOFFSET(SMTE, smte_fpagetab),
99 FIELDOFFSET(SMTE, smte_frectab),
100 FIELDOFFSET(SMTE, smte_impmod),
101 FIELDOFFSET(SMTE, smte_impproc),
102 0xDEAD
103};
104
105
106/*******************************************************************************
107* External Functions *
108*******************************************************************************/
109#define QHINF_EXEINFO 1 /* NE exeinfo. */
110#define QHINF_READRSRCTBL 2 /* Reads from the resource table. */
111#define QHINF_READFILE 3 /* Reads from the executable file. */
112#define QHINF_LIBPATHLENGTH 4 /* Gets the libpath length. */
113#define QHINF_LIBPATH 5 /* Gets the entire libpath. */
114#define QHINF_FIXENTRY 6 /* NE only */
115#define QHINF_STE 7 /* NE only */
116#define QHINF_MAPSEL 8 /* NE only */
117
118APIRET APIENTRY DosQueryHeaderInfo(HMODULE hmod,
119 ULONG ulIndex,
120 PVOID pvBuffer,
121 ULONG cbBuffer,
122 ULONG ulSubFunction);
123
124/*******************************************************************************
125* Internal Functions *
126*******************************************************************************/
127ULONG LDRCALL fakeLDRLoadExe(PSZ pszFilename, ldrrei_t *pEI);
128ULONG LDRCALL fakeldrGetModule(PSZ pszFilename, ULONG ul);
129ULONG LDRCALL fakeldrGetMte(PCHAR pachFilename, USHORT cchFilename, UCHAR fchType, UCHAR fchClass, PPMTE ppmte);
130ULONG LDRCALL fakeldrOpenNewExe(PCHAR pachFilename, USHORT cchFilename, ldrlv_t *plv, PUSHORT pus);
131ULONG LDRCALL fakeldrCreateMte(struct e32_exe * pe32, ldrlv_t *plv);
132ULONG LDRCALL fakeldrLoadImports(PMTE pmte);
133ULONG LDRCALL fakeldrMTEValidatePtrs(PSMTE psmte, ULONG ulMaxAddr, ULONG off);
134unsigned short getSlot(void);
135
136
137
138/**
139 * Initiate workers (imported kernel functions / vars)
140 * @status partially implemented.
141 * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no)
142 */
143void workersinit(void)
144{
145 APIRET rc;
146
147 /*
148 * Make code writable.
149 */
150 DosSetMem(&CODE16START, &CODE16END - &CODE16START, PAG_WRITE | PAG_READ);
151 DosSetMem(&CODE32START, &CODE32END - &CODE32START, PAG_WRITE | PAG_READ);
152
153 /*
154 * Loader semaphore
155 */
156 fakeKSEMInit((PKSEM)(void*)&fakeLdrSem, KSEM_MUTEX, KSEM_DEFAULT);
157
158 /*
159 * Intra process semaphore.
160 */
161 fakeKSEMInit((PKSEM)(void*)&fakeptda_ptdasem, KSEM_MUTEX, KSEM_DEFAULT);
162
163 /*
164 * LIBPaths
165 */
166 rc = DosQueryExtLIBPATH(szBeginLibPath, BEGIN_LIBPATH);
167 rc = DosQueryHeaderInfo(NULLHANDLE, 0, szLibPath, sizeof(szLibPath), QHINF_LIBPATH);
168 rc = DosQueryExtLIBPATH(szEndLibPath, END_LIBPATH);
169
170 rc = rc;
171}
172
173
174/**
175 * Fake ldrClose
176 * @returns OS2 return code.
177 * @param hFile Filehandle of the file to be closed.
178 * @status completely impelemented.
179 * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no)
180 * @remark
181 */
182ULONG LDRCALL fakeldrClose(SFN hFile)
183{
184 APIRET rc;
185 BOOL f32Stack = ((int)&hFile > 0x10000);
186
187 if (!f32Stack) ThunkStack16To32();
188
189 rc = DosClose(hFile);
190
191 if (!f32Stack) ThunkStack32To16();
192
193 printf("fakeldrClose: hFile = 0x%04x, rc = %d\n", hFile, rc);
194
195 return rc;
196}
197
198/**
199 * Fake ldrOpen.
200 * @returns OS2 return code.
201 * @param phFile Pointer to return handle.
202 * @param pszFilename Pointer to filename.
203 * @param pfl Pointer to media flags? *pfl is set to zero!
204 * @sketch Do a DosOpen on the filename.
205 * @status partially implemented.
206 * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no)
207 * @remark
208 */
209ULONG LDRCALL fakeldrOpen(PSFN phFile, PSZ pszFilename, PULONG pfl)
210{
211 ULONG ulAction;
212 HFILE hFile;
213 APIRET rc;
214 BOOL f32Stack = ((int)&hFile > 0x10000);
215
216 if (!f32Stack) ThunkStack16To32();
217
218 hFile = 0;
219 ulAction = 0;
220 rc = DosOpen(pszFilename, &hFile, &ulAction, 0, FILE_NORMAL,
221 OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS,
222 OPEN_ACCESS_READONLY | OPEN_SHARE_DENYWRITE,
223 NULL);
224 if (rc == NO_ERROR)
225 {
226 *phFile = (USHORT)hFile;
227 if (pfl != NULL)
228 *pfl = 0;
229 rc = DosQueryPathInfo(pszFilename, FIL_QUERYFULLNAME, fakeldrpFileNameBuf, CCHMAXPATH);
230 rc = NO_ERROR;
231 }
232
233 if (!f32Stack) ThunkStack32To16();
234
235 printf("fakeldrOpen: phFile = %p; *phFile = 0x%04x, pszFilename = %s, pfl = %p, rc = %d\n",
236 phFile, *phFile, pszFilename, pfl, rc);
237
238 return rc;
239}
240
241
242/**
243 * ldrRead fake.
244 * @returns OS/2 return code. (NO_ERROR on success...)
245 * @param hFile Handle to file.
246 * @param ulOffset Offset in the file to start reading at.
247 * @param pvBuffer Pointer to output buffer.
248 * @param fpBuffer Far pointer to buffer. (ignored)
249 * @param cbToRead Count of bytes to read.
250 * @param pMTE MTE pointer (used for caching?)
251 *
252 * @sketch Set Change filepointer to ulOffset.
253 * Read cbToRead into pvBufer.
254 * @status completely tested.
255 * @author knut st. osmundsen
256 * @remark
257 */
258ULONG LDRCALL fakeldrRead(SFN hFile, ULONG ulOffset, PVOID pvBuffer, ULONG fpBuffer, ULONG cbToRead, PMTE pMTE)
259{
260 ULONG cbRead,
261 ulMoved;
262 APIRET rc;
263 BOOL f32Stack = ((int)&hFile > 0x10000);
264
265 if (!f32Stack) ThunkStack16To32();
266
267 rc = DosSetFilePtr(hFile, ulOffset, FILE_BEGIN, &ulMoved);
268 if (rc == NO_ERROR)
269 rc = DosRead(hFile, pvBuffer, cbToRead, &cbRead);
270 else
271 kprintf(("fakeldrRead: DosSetFilePtr(hfile, 0x%08x(%d),..) failed with rc = %d.\n",
272 ulOffset, ulOffset, rc));
273
274 if (!f32Stack) ThunkStack32To16();
275
276 printf("fakeldrRead: hFile = 0x%04x, ulOffset = 0x%08x, pvBuffer = %p, fpBuffer = 0x%08x, cbToRead = 0x%08x, pMte = %p, rc = %d\n",
277 hFile, ulOffset, pvBuffer, fpBuffer, cbToRead, pMTE, rc);
278
279 return rc;
280}
281
282
283/**
284 * LDRQAppType faker.
285 * @returns OS/2 return code.
286 * @param pszFilename Pointer to executable to query app type for.
287 * @param pul Pointer to flag variable to return apptype flags in.
288 * @sketch
289 * @status stub.
290 * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no)
291 * @remark
292 */
293ULONG LDRCALL fakeLDRQAppType(PSZ pszFilename, PULONG pul)
294{
295 DUMMY();
296 printf("fakeLDRQAppType: pszFilename = %s, pul = %p, rc = 0\n", pszFilename, pul);
297 return NO_ERROR;
298}
299
300
301/**
302 * ldrEnum32bitRelRecs
303 * @param pMTE Pointer to MTE for this module.
304 * @param iObject Object index. 0-based!
305 * @param iPageTabl Page index. 0-based!
306 * @param pvPage Pointer to page buffer.
307 * @param ulPageAddress Note! Page is not present.
308 * @param pPTDA
309 * @status stub
310 */
311ULONG LDRCALL fakeldrEnum32bitRelRecs(
312 PMTE pMTE,
313 ULONG iObject,
314 ULONG iPageTable,
315 PVOID pvPage,
316 ULONG ulPageAddress,
317 PVOID pvPTDA
318 )
319{
320 DUMMY();
321 printf("fakeldrEnum32bitRelRecs: pMTE = %p, iObject = 0x%08x, iPageTable = 0x%08x, pvPage = 0x%08x, ulPageAddress = 0x%08x, pvPTDA = %p\n",
322 pMTE, iObject, iPageTable, pvPage, ulPageAddress, pvPTDA);
323
324 return NO_ERROR;
325}
326
327
328/**
329 * Sets the VM flags for an executable object.
330 * @returns void
331 * @param pMTE Pointer to the module table entry.
332 * @param flObj LX Object flags.
333 * @param pflFlags1 Pointer to the flFlags1 of VMAllocMem (out).
334 * @param pflFlags2 Pointer to the flFlags2 of VMAllocMem (out).
335 */
336ULONG LDRCALL fakeldrSetVMflags(
337 PMTE pMTE,
338 ULONG flObj,
339 PULONG pflFlags1,
340 PULONG pflFlags2
341 )
342{
343 *pflFlags1 = 0;
344 *pflFlags2 = 0;
345 flObj = flObj;
346 pMTE = pMTE;
347 return 0;
348}
349
350/**
351 * Opens a given file.
352 * @returns NO_ERROR on success. OS/2 error code on error.
353 * @param pszFilename Pointer to filename.
354 * @param flOpenFlags Open flags. (similar to DosOpen)
355 * @param fsOpenMode Open mode flags. (similar to DosOpen)
356 * @param phFile Pointer to filehandle.
357 * @param pulsomething 16-bit near (?) pointer to a variable - unknown. NULL is allowed. EA?
358 */
359APIRET KRNLCALL fakeIOSftOpen(
360 PSZ pszFilename,
361 ULONG flOpenFlags,
362 ULONG fsOpenMode,
363 PSFN phFile,
364 PULONG pulsomething
365 )
366{
367 ULONG ulAction;
368 HFILE hFile;
369 APIRET rc;
370 BOOL f32Stack = ((int)&hFile > 0x10000);
371
372 if (!f32Stack) ThunkStack16To32();
373
374 hFile = 0;
375 ulAction = 0;
376 rc = DosOpen(pszFilename, &hFile, &ulAction, 0, FILE_NORMAL,
377 flOpenFlags,
378 fsOpenMode,
379 NULL);
380 if (rc == NO_ERROR)
381 *phFile = (USHORT)hFile;
382
383 if (!f32Stack) ThunkStack32To16();
384
385 printf("fakeIOSftOpen: pszFilename = %s, flOpenFlags = 0x%08x, fsOpenMode = 0x%08x, phFile = %p; *phFile = 0x%04, pulsomething = %p, rc = %d\n",
386 pszFilename, flOpenFlags, fsOpenMode, phFile, *phFile, pulsomething, rc);
387
388 return rc;
389}
390
391
392/**
393 * Closes the specified file.
394 * @returns NO_ERROR on success. OS/2 error code on error.
395 * @param hFile File handle - System File Number.
396 */
397APIRET KRNLCALL fakeIOSftClose(
398 SFN hFile
399 )
400{
401 APIRET rc;
402 BOOL f32Stack = ((int)&hFile > 0x10000);
403
404 if (!f32Stack) ThunkStack16To32();
405
406 rc = DosClose(hFile);
407
408 if (!f32Stack) ThunkStack32To16();
409
410 printf("fakeIOSftClose: hFile = 0x%04, rc = %d\n",
411 hFile, rc);
412
413 return rc;
414}
415
416
417/**
418 * Probably this function will expand a relative path to a full path.
419 * @returns NO_ERROR on success. OS/2 error code on error.
420 * The ldr filename buffer will hold the expanded
421 * pathname upon successfull return.
422 * @param pszPath Pointer to path to expand. (?)
423 * @status completely implemented.
424 */
425APIRET KRNLCALL fakeIOSftTransPath(
426 PSZ pszPath
427 )
428{
429 char szBuffer[CCHMAXPATH];
430 APIRET rc;
431 BOOL f32Stack = ((int)&pszPath > 0x10000);
432
433 if (!f32Stack) ThunkStack16To32();
434
435 rc = DosQueryPathInfo(pszPath, FIL_QUERYFULLNAME, &szBuffer, sizeof(szBuffer));
436 printf("fakeIOSftTransPath: pszPath(in) = %s, pszPath(out) = %s, rc = %d\n",
437 pszPath, szBuffer, rc);
438 if (rc == NO_ERROR)
439 strcpy(pszPath, szBuffer);
440 else
441 kprintf(("fakeIOSftTransPath: DosQueryPathInfo failed with rc=%d\n", rc));
442
443
444 if (!f32Stack) ThunkStack32To16();
445
446 return rc;
447}
448
449
450/**
451 * Read at a given offset in the a file.
452 * @returns NO_ERROR on success. OS/2 error code on error.
453 * @param hFile File handle - System File Number.
454 * @param pcbActual Pointer to variable which upon input holds the number
455 * of bytes to read, on output the actual number of bytes read.
456 * @param pvBuffer Pointer to the read buffer.
457 * @param fpBuffer 16 far pointer to buffer. (ignored)
458 * @param ulOffset File offset to read from. (0=start of file)
459 */
460APIRET KRNLCALL fakeIOSftReadAt(
461 SFN hFile,
462 PULONG pcbActual,
463 PVOID pvBuffer,
464 ULONG fpBuffer,
465 ULONG ulOffset
466 )
467{
468 ULONG ulMoved;
469 APIRET rc;
470 BOOL f32Stack = ((int)&hFile > 0x10000);
471
472 if (!f32Stack) ThunkStack16To32();
473
474 rc = DosSetFilePtr(hFile, ulOffset, FILE_BEGIN, &ulMoved);
475 if (rc == NO_ERROR)
476 rc = DosRead(hFile, pvBuffer, *pcbActual, pcbActual);
477 else
478 kprintf(("fakeIOSftReadAt: DosSetFilePtr(hfile, 0x%08x(%d),..) failed with rc = %d.",
479 ulOffset, ulOffset, rc));
480
481 if (!f32Stack) ThunkStack32To16();
482
483 printf("fakeIOSftReadAt: hFile = 0x%04, pcbActual = %p; *pcbActual = 0x%08x, pvBuffer = %p, fpBuffer = %x, ulOffset = 0x%08x, rc = %d\n",
484 hFile, pcbActual, pvBuffer, fpBuffer, ulOffset, rc);
485
486 return rc;
487}
488
489
490/**
491 * Write at a given offset in the a file.
492 * @returns NO_ERROR on success. OS/2 error code on error.
493 * @param hFile File handle - System File Number.
494 * @param pcbActual Pointer to variable which upon input holds the number
495 * of bytes to write, on output the actual number of bytes write.
496 * @param pvBuffer Pointer to the write buffer.
497 * @param fpBuffer 16 far pointer to buffer. (ignored)
498 * @param ulOffset File offset to write from. (0=start of file)
499 */
500APIRET KRNLCALL fakeIOSftWriteAt(
501 SFN hFile,
502 PULONG pcbActual,
503 PVOID pvBuffer,
504 ULONG fpBuffer,
505 ULONG ulOffset
506 )
507{
508 ULONG ulMoved;
509 APIRET rc;
510 BOOL f32Stack = ((int)&hFile > 0x10000);
511
512 if (!f32Stack) ThunkStack16To32();
513
514 rc = DosSetFilePtr(hFile, ulOffset, FILE_BEGIN, &ulMoved);
515 if (rc == NO_ERROR)
516 rc = DosWrite(hFile, pvBuffer, *pcbActual, pcbActual);
517 else
518 kprintf(("fakeIOSftWriteAt: DosSetFilePtr(hfile, 0x%08x(%d),..) failed with rc = %d.",
519 ulOffset, ulOffset, rc));
520
521 if (!f32Stack) ThunkStack32To16();
522
523 printf("fakeIOSftWriteAt: hFile = 0x%04, pcbActual = %p; *pcbActual = 0x%08x, pvBuffer = %p, fpBuffer = %x, ulOffset = 0x%08x, rc = %d\n",
524 hFile, pcbActual, pvBuffer, fpBuffer, ulOffset, rc);
525
526 return rc;
527}
528
529
530/**
531 * Gets the filesize.
532 * @returns NO_ERROR on success; OS/2 error code on error.
533 * @param hFile File handle - System File Number.
534 * @param pcbFile Pointer to ULONG which will hold the file size upon return.
535 */
536APIRET KRNLCALL fakeSftFileSize(
537 SFN hFile,
538 PULONG pcbFile
539 )
540{
541 FILESTATUS3 fsts3;
542 APIRET rc;
543 BOOL f32Stack = ((int)&hFile > 0x10000);
544
545 if (!f32Stack) ThunkStack16To32();
546
547 rc = DosQueryFileInfo(hFile,
548 FIL_STANDARD,
549 &fsts3,
550 sizeof(fsts3));
551 if (rc == NO_ERROR)
552 *pcbFile = fsts3.cbFile;
553 else
554 kprintf(("fakeSftFileSize: DosQueryFileInfo failed with rc=%d\n", rc));
555
556 if (!f32Stack) ThunkStack32To16();
557
558 printf("fakeSftFileSize: hFile = 0x%04x, pcbFile = %p; *pcbFile = 0x%08x, rc = %d\n",
559 hFile, pcbFile, *pcbFile, rc);
560
561 return rc;
562}
563
564
565/**
566 * @status stub
567 */
568HMTE KRNLCALL fakeVMGetOwner(
569 ULONG ulCS,
570 ULONG ulEIP)
571{
572 DUMMY();
573
574 printf("fakeVMGetOwner: ulCS = 0x%04x, ulEiP = 0x%08x, rc = %d\n",
575 ulCS, ulEIP, 0);
576
577 return 0;
578}
579
580
581/**
582 * @status stub
583 */
584APIRET KRNLCALL fakeVMAllocMem(
585 ULONG cbSize,
586 ULONG cbCommit,
587 ULONG flFlags1,
588 HPTDA hPTDA,
589 USHORT usVMOwnerId,
590 HMTE hMTE,
591 ULONG flFlags2,
592 ULONG SomeArg2,
593 PVMAC pvmac)
594{
595 DUMMY();
596 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",
597 cbSize, cbCommit, flFlags1, hPTDA, usVMOwnerId, hMTE, flFlags2, SomeArg2, pvmac, ERROR_NOT_SUPPORTED);
598
599 return ERROR_NOT_SUPPORTED;
600}
601
602
603/**
604 * @status stub
605 */
606APIRET KRNLCALL fakeVMFreeMem(
607 PVOID pv,
608 USHORT hPTDA,
609 ULONG flFlags
610 )
611{
612 DUMMY();
613 printf("fakeVMFreeMem: pv = %p, hPTDA = 0x%04x, flFlags = %08x, rc = %d\n",
614 pv, hPTDA, flFlags, ERROR_NOT_SUPPORTED);
615
616 return ERROR_NOT_SUPPORTED;
617}
618
619
620/**
621 * @status stub
622 * @remark Used by environment stuff...
623 */
624APIRET KRNLCALL fakeVMObjHandleInfo(
625 USHORT usHob,
626 PULONG pulAddr,
627 PUSHORT pushPTDA)
628{
629 APIRET rc = NO_ERROR;
630 BOOL f32Stack = ((int)&usHob > 0x10000);
631
632 if (!f32Stack) ThunkStack16To32();
633
634 if (pulAddr > (PULONG)0x10000 && pushPTDA > (PUSHORT)0x10000)
635 {
636 PTIB pTib;
637 PPIB pPib;
638 DosGetInfoBlocks(&pTib, &pPib);
639 switch (usHob)
640 {
641 case 1: *pulAddr = (ULONG)pPib->pib_pchenv; break; //PTDA environ (fakea.asm)
642 default:
643 printf("fakeVMObjHandleInfo: Invalid handle! (usHob=0x%#4x)\n", usHob);
644 rc = ERROR_INVALID_HANDLE;
645 }
646 *pushPTDA = 10; //dummy
647 }
648 else
649 rc = ERROR_INVALID_PARAMETER;
650
651 if (!f32Stack) ThunkStack32To16();
652
653 printf("fakeVMObjHandleInfo: usHob = 0x%04x, pulAddr = %p, pushPTDA = %p, rc = %d\n",
654 usHob, pulAddr, pushPTDA, rc);
655 return rc;
656}
657
658
659APIRET KRNLCALL fakeVMMapDebugAlias(
660 ULONG flVMFlags,
661 ULONG ulAddress,
662 ULONG cbSize,
663 HPTDA hPTDA,
664 PVMAC pvmac)
665{
666 printf("fakeVMMapDebugAlias: flVMFlags = 0x%08x, ulAddress = 0x%08, cbSize = 0x%08x, hPTDA = 0x%04x, pvmac = %p - not implemented\n",
667 flVMFlags,
668 ulAddress,
669 cbSize,
670 hPTDA,
671 pvmac);
672
673 return ERROR_NOT_SUPPORTED;
674}
675
676
677
678/**
679 * ldrOpenPath - ldrOpenPath for build 14053 and above.
680 * kernel 14053 and above.
681 *
682 * @returns OS2 return code.
683 * plv->lv_sfn is set to filename handle.
684 * @param pachFilename Pointer to modulename. Not zero terminated!
685 * @param cchFilename Modulename length.
686 * @param plv Loader local variables? (Struct from KERNEL.SDF)
687 * @param pful Pointer to flags which are passed on to ldrOpen.
688 * @param lLibPath New parameter in build 14053.
689 * ldrGetMte calls with 1
690 * ldrOpenNewExe calls with 3
691 * This is compared to the initial libpath index.
692 * The libpath index is:
693 * BEGINLIBPATH 1
694 * LIBPATH 2
695 * ENDLIBPATH 3
696 * The initial libpath index is either 1 or 2.
697 * - ignored -
698 *
699 */
700ULONG LDRCALL fakeldrOpenPath_new( /* retd 0x14 */
701 PCHAR pachFilename, /* ebp + 0x08 */
702 USHORT cchFilename, /* ebp + 0x0c */
703 ldrlv_t * plv, /* ebp + 0x10 */
704 PULONG pful, /* ebp + 0x14 */
705 ULONG lLibPath /* ebp + 0x18 */
706 )
707 {
708 NOREF(lLibPath);
709 return fakeldrOpenPath_old(pachFilename, cchFilename, plv, pful);
710 }
711
712
713/**
714 * myldrOpenPath - opens file eventually searching loader specific paths
715 * Pre kernel 14053.
716 *
717 * @returns OS2 return code.
718 * pLdrLv->lv_sfn is set to filename handle.
719 * @param pachFilename Pointer to modulename. Not zero terminated?
720 * @param cchFilename Modulename length.
721 * @param plv Loader local variables? (Struct from KERNEL.SDF)
722 * @param pful Pointer to flags which are passed on to ldrOpen.
723 * @status stub
724 */
725ULONG LDRCALL fakeldrOpenPath_old(PCHAR pachFilename, USHORT cchFilename, ldrlv_t *plv, PULONG pful)
726{
727 static char szPath[1024]; /* Path buffer. Used to store pathlists. 1024 should be enough */
728 /* for LIBPATH (which at had a limit of ca. 750 chars). */
729 static char sz[CCHMAXPATH]; /* Filename/path buffer. (Normally used to build filenames */
730 /* which are passed in as search experessions to DosFindFirst.) */
731
732 APIRET rc; /* Return value. (Pessimistic attitude! Init it to FALSE...) */
733
734 printf("fakeldrOpenPath: *entry* pachFilename = %.*s, cchFilename = %d, plv = %p, pful = %p\n",
735 cchFilename, pachFilename, cchFilename, plv, pful);
736
737 if (plv->lv_class != CLASS_GLOBAL)
738 rc = fakeldrOpen(&plv->lv_sfn, pachFilename, pful);
739 else
740 {
741 int iPath; /* Current path or pathlist being examined. This is the loop */
742 /* variable looping on the FINDDLL_* defines. */
743
744 /* These defines sets the order the paths and pathlists are examined. */
745 #define FINDDLL_BEGINLIBPATH 7
746 #define FINDDLL_LIBPATH 8
747 #define FINDDLL_ENDLIBPATH 9
748 #define FINDDLL_FIRST FINDDLL_BEGINLIBPATH
749 #define FINDDLL_LAST FINDDLL_ENDLIBPATH
750
751 /*
752 * Remove DLL extention from the filename.
753 */
754 if (cchFilename > 4 && !strncmp(&pachFilename[cchFilename - 4], ".DLL", 4))
755 {
756 cchFilename -= 4;
757 pachFilename[cchFilename] = '\0';
758 }
759
760 /** @sketch
761 * Loop thru the paths and pathlists searching them for the filename.
762 */
763 rc = ERROR_FILE_NOT_FOUND;
764 for (iPath = FINDDLL_FIRST; iPath <= FINDDLL_LAST; iPath++)
765 {
766 const char * pszPath; /* Pointer to the path being examined. */
767
768 /** @sketch Get the path/dir to examin. (This is determined by the value if iPath.) */
769 switch (iPath)
770 {
771 case FINDDLL_BEGINLIBPATH:
772 rc = DosQueryExtLIBPATH(szPath, BEGIN_LIBPATH);
773 break;
774 case FINDDLL_LIBPATH:
775 rc = DosQueryHeaderInfo(NULLHANDLE, 0, szPath, sizeof(szPath), QHINF_LIBPATH);
776 break;
777 case FINDDLL_ENDLIBPATH:
778 rc = DosQueryExtLIBPATH(szPath, END_LIBPATH);
779 break;
780 default: /* !internalerror! */
781 return ERROR_FILE_NOT_FOUND;
782 }
783 if (rc != NO_ERROR)
784 {
785 printf("fakeldrOpenPath: DosQueryExtLIBPATH/DosQueryHeadInfo failed with rc=%d, iPath=%d", rc, iPath);
786 continue;
787 }
788 pszPath = szPath;
789
790
791 /** @sketch
792 * pszPath is now set to the pathlist to be searched.
793 * So we'll loop thru all the paths in the list.
794 */
795 while (pszPath != NULL && *pszPath != '\0')
796 {
797 char * pszNext; /* Pointer to the next pathlist path */
798 int cch; /* Length of path (including the slash after the slash is added). */
799
800 /** @sketch
801 * Find the end of the path.
802 * Copy the path into the sz buffer.
803 * Set pszNext.
804 */
805 pszNext = strchr(pszPath, ';');
806 if (pszNext != NULL)
807 {
808 cch = pszNext - pszPath;
809 pszNext++;
810 }
811 else
812 cch = strlen(pszPath);
813
814 if (cch + cchFilename + 1 >= sizeof(sz)) /* assertion */
815 {
816 printf("fakeldrOpenPath: cch (%d) + cchFilename (%d) + 1 < sizeof(plv->sz) (%d) - paths too long!, iPath=%d",
817 cch, cchFilename, sizeof(sz), iPath);
818 pszPath = pszNext;
819 continue;
820 }
821 memcpy(sz, pszPath, cch);
822
823 /** @sketch
824 * Add a '\\' and the filename (pszFullname) to the path;
825 * then we'll have a fullpath.
826 */
827 sz[cch++] = '\\';
828 memcpy(&sz[cch], pachFilename, cchFilename);
829 memcpy(&sz[cch + cchFilename], ".DLL", 5);
830
831 rc = fakeldrOpen(&plv->lv_sfn, sz, pful);
832 switch (rc)
833 {
834 case ERROR_FILE_NOT_FOUND: case ERROR_PATH_NOT_FOUND: case ERROR_ACCESS_DENIED: case ERROR_INVALID_ACCESS:
835 case ERROR_INVALID_DRIVE: case ERROR_NOT_DOS_DISK: case ERROR_REM_NOT_LIST: case ERROR_BAD_NETPATH:
836 case ERROR_NETWORK_BUSY: case ERROR_DEV_NOT_EXIST: case ERROR_TOO_MANY_CMDS: case ERROR_ADAP_HDW_ERR:
837 case ERROR_UNEXP_NET_ERR: case ERROR_BAD_REM_ADAP: case ERROR_NETNAME_DELETED: case ERROR_BAD_DEV_TYPE:
838 case ERROR_NETWORK_ACCESS_DENIED: case ERROR_BAD_NET_NAME: case ERROR_TOO_MANY_SESS: case ERROR_REQ_NOT_ACCEP:
839 case ERROR_INVALID_PASSWORD: case ERROR_OPEN_FAILED: case ERROR_INVALID_NAME: case ERROR_FILENAME_EXCED_RANGE:
840 case ERROR_VC_DISCONNECTED:
841 rc = ERROR_FILE_NOT_FOUND;
842 pszPath = pszNext;
843 continue;
844 }
845
846 /*
847 * Fatal error or success.
848 */
849 printf("fakeldrOpenPath: *exit* plv->lv_sfn = 0x%04x, rc = %d\n", plv->lv_sfn, rc);
850 return rc;
851 }
852 } /* for iPath */
853 }
854
855 printf("fakeldrOpenPath: *exit* plv->lv_sfn = 0x%04x, rc = %d\n", plv->lv_sfn, rc);
856
857 return rc;
858}
859
860
861/**
862 * LDRClearSem - Clears the loader semaphore.
863 * (It does some garbage collection on release.)
864 * @returns NO_ERROR on sucess.
865 * OS/2 error on failure. (ERROR_INTERRUPT?)
866 * @status completely implemented.
867 */
868ULONG LDRCALL fakeLDRClearSem(void)
869{
870 return fakeKSEMReleaseMutex(&fakeLdrSem);
871}
872
873/**
874 * KSEMReuqestMutex faker.
875 * @returns NO_ERROR
876 * @param hkmtx
877 * @param ulTimeout
878 * @status completely implemented.
879 * @remark
880 */
881ULONG KRNLCALL fakeKSEMRequestMutex(HKSEMMTX hkmtx, ULONG ulTimeout)
882{
883 unsigned short usSlot = getSlot();
884 ULONG rc = NO_ERROR;
885
886 if (memcmp(&hkmtx->debug.ksem_achSignature[0], "KSEM", 4) != 0)
887 {
888 printf("fakeKSEMQueryMutex: hkmtx = %p, invalid signature (%.4s)\n", hkmtx, hkmtx->debug.ksem_achSignature);
889 return FALSE;
890 }
891
892 if (hkmtx->debug.ksem_Owner == 0)
893 {
894 hkmtx->debug.ksem_Owner = usSlot;
895 hkmtx->debug.ksem_cusNest = 1;
896 }
897 else if (hkmtx->debug.ksem_Owner == usSlot)
898 hkmtx->debug.ksem_cusNest++;
899 else
900 rc = ERROR_SEM_BUSY;
901
902 printf("fakeKSEMRequestMutex: hkmtx = %p, ulTimeout = 0x%x, owner = %d, usage count = %d, rc = %d\n",
903 hkmtx, ulTimeout, hkmtx->debug.ksem_cusNest, hkmtx->debug.ksem_Owner, ERROR_SEM_BUSY);
904
905 return rc;
906}
907
908
909/**
910 * KSEMReleaseMutex faker.
911 * @returns NO_ERROR
912 * @param hkmtx
913 * @param ulTimeout
914 * @status completely implemented.
915 * @remark
916 */
917ULONG KRNLCALL fakeKSEMReleaseMutex(HKSEMMTX hkmtx)
918{
919 unsigned int usSlot = getSlot();
920 int rc = NO_ERROR;
921
922 if (memcmp(&hkmtx->debug.ksem_achSignature[0], "KSEM", 4) != 0)
923 {
924 printf("fakeKSEMQueryMutex: hkmtx = %p, invalid signature (%.4s)\n", hkmtx, hkmtx->debug.ksem_achSignature);
925 return FALSE;
926 }
927
928 if (hkmtx->debug.ksem_Owner == usSlot)
929 {
930 if (--hkmtx->debug.ksem_cusNest == 0)
931 hkmtx->debug.ksem_Owner = 0;
932 }
933 else
934 rc = ERROR_NOT_OWNER;
935
936 printf("fakeKSEMReleaseMutex: hkmtx = %p, usage count = %d, owner = %d, rc = %d\n",
937 hkmtx, hkmtx->debug.ksem_cusNest, hkmtx->debug.ksem_Owner, rc);
938
939 return rc;
940}
941
942
943
944/**
945 * KSEMQueryMutex faker.
946 * @returns TRUE if owner or clear. Clear if *pcusNest is 0.
947 * FALSE if other owner.
948 * @param hkmtx Handle to kernel mutex.
949 * @param pcusNest Pointer to variable which is to receive the nesting count.
950 * (ie. the number of times we have taken this semaphore.)
951 * @status completely implemented.
952 * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no)
953 */
954BOOL KRNLCALL fakeKSEMQueryMutex(HKSEMMTX hkmtx, PUSHORT pcusNest)
955{
956 unsigned int usSlot = getSlot();
957 BOOL fRc = TRUE;
958
959 if (memcmp(&hkmtx->debug.ksem_achSignature[0], "KSEM", 4) != 0)
960 {
961 printf("fakeKSEMQueryMutex: hkmtx = %p, invalid signature (%.4s)\n", hkmtx, hkmtx->debug.ksem_achSignature);
962 return FALSE;
963 }
964
965 if (hkmtx->debug.ksem_Owner == 0)
966 {
967 if (pcusNest)
968 *pcusNest = 0;
969 fRc = FALSE;
970 }
971 else
972 {
973 fRc = (hkmtx->debug.ksem_Owner == usSlot);
974 if (pcusNest)
975 *pcusNest = hkmtx->debug.ksem_cusNest;
976 }
977
978 printf("fakeKSEMQueryMutex: hkmtx = %p, usage count = %d, owner = %d, *pcusNest = %d, rc = %d\n",
979 hkmtx, hkmtx->debug.ksem_cusNest, hkmtx->debug.ksem_Owner, pcusNest ? *pcusNest : -1, fRc);
980
981 return fRc;
982}
983
984
985/**
986 * KSEMInit faker.
987 * @param pksem Pointer to the semaphore struct to initiate.
988 * @param fulType Semaphore type. (only KSEM_MUTEX is supported)
989 * @param fulFlags Semaphore flags. (not validated)
990 * @status partially implemented.
991 * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no)
992 */
993VOID KRNLCALL fakeKSEMInit(PKSEM pksem, ULONG fulType, ULONG fulFlags)
994{
995 if (fulType != KSEM_MUTEX)
996 {
997 printf("fakeKSEMInit: Invalid fulType parameter (%d).\n", fulType);
998 return; /*ERROR_INVALID_PARAMETER;*/
999 }
1000
1001 memcpy(pksem->mtx.debug.ksem_achSignature, "KSEM", 4);
1002 pksem->mtx.debug.ksem_bFlags = (char)fulFlags;
1003 pksem->mtx.debug.ksem_bType = KSEM_MUTEX;
1004 pksem->mtx.debug.ksem_cusNest = 0;
1005 pksem->mtx.debug.ksem_cusPendingWriters = 0;
1006 pksem->mtx.debug.ksem_Owner = 0;
1007
1008 printf("fakeKSEMInit: pksem=%p, fulType=%d, fulFlags=0x%x.\n", pksem, fulType, fulFlags);
1009}
1010
1011
1012/**
1013 * Gets the thread slot number.
1014 * @returns Thread slot number.
1015 * @status completely implemented.
1016 * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no)
1017 */
1018unsigned short getSlot(void)
1019{
1020 PPIB ppib;
1021 PTIB ptib;
1022 BOOL f32Stack = ((int)&ppib > 0x10000);
1023
1024 if (!f32Stack) ThunkStack16To32();
1025
1026 DosGetInfoBlocks(&ptib, &ppib);
1027
1028 if (!f32Stack) ThunkStack32To16();
1029
1030 return (unsigned short)ptib->tib_ordinal;
1031}
1032
1033
1034/**
1035 * Copy user memory into system memory.
1036 * @returns OS/2 return code. (NO_ERROR is success)
1037 * @param pv Pointer to target (system) data area.
1038 * @param pvUsr Pointer to source (user) data area.
1039 * @param cb Count of bytes to copy.
1040 * @param fl Flags.
1041 * @status Partially implemented.
1042 * @remark Ignores fl. Crashes on error.
1043 */
1044ULONG KRNLCALL fakeTKFuBuff(PVOID pv, PVOID pvUsr, ULONG cb, ULONG fl)
1045{
1046 memcpy(pv, pvUsr, cb);
1047
1048 printf("fakeTKFuBuff: pv = %p, pvUsr = %p, cb = 0x%08x, fl = 0x%08x, rc = %d\n",
1049 pv, pvUsr, cb, fl, NO_ERROR);
1050
1051 return NO_ERROR;
1052}
1053
1054
1055/**
1056 * Copy system memory to user memory.
1057 * @returns OS/2 return code. (NO_ERROR is success)
1058 * @param pvUsr Pointer to target (user) data area.
1059 * @param pv Pointer to source (system) data area.
1060 * @param cb Count of bytes to copy.
1061 * @param fl Flags.
1062 * @status Partially implemented.
1063 * @remark Ignores fl. Crashes on error.
1064 */
1065ULONG KRNLCALL fakeTKSuBuff(PVOID pvUsr, PVOID pv, ULONG cb, ULONG fl)
1066{
1067 memcpy(pvUsr, pv, cb);
1068
1069 printf("fakeTKSuBuff: pvUsr = %p, pv = %p, cb = 0x%08x, fl = 0x%08x, rc = %d\n",
1070 pvUsr, pv, cb, fl, NO_ERROR);
1071
1072 return NO_ERROR;
1073}
1074
1075
1076/**
1077 * String length. (includes NULL(s))
1078 * @returns OS/2 return code. (NO_ERROR is success)
1079 * ERROR_TERMINATOR_NOT_FOUND
1080 * @param pcch Pointer to length variable.
1081 * @param pvUsr Pointer to user data to preform string length on.
1082 * @param cchMax Max string length.
1083 * @param fl Flags.
1084 * @param fDblNULL TRUE: Double '\0' (ie. '\0\0') terminated. Usefull for scanning environments.
1085 * FALSE: Single string. (ie. one '\0').
1086 * @status Partially implemented.
1087 * @remark Ignores fl. Crashes on error.
1088 */
1089ULONG KRNLCALL fakeTKFuBufLen(PLONG pcch, PVOID pvUsr, ULONG cchMax, ULONG fl, BOOL fDblNULL)
1090{
1091 ULONG rc;
1092 PSZ psz = pvUsr;
1093
1094 cchMax += (ULONG)pvUsr;
1095
1096 while ((ULONG)psz < cchMax)
1097 {
1098 if (*psz++ == '\0')
1099 if (!fDblNULL || (ULONG)psz == cchMax || *psz++ != '\0')
1100 break;
1101 }
1102
1103 *pcch = (ULONG)psz - (ULONG)pvUsr;
1104
1105 /* Hope this is the correct definition of max length: Not inclusive. */
1106 if ((ULONG)psz == cchMax)
1107 rc = ERROR_TERMINATOR_NOT_FOUND;
1108 else
1109 rc = NO_ERROR;
1110
1111 printf("fakeTKFuBufLen: pcch = %p; *pcch = 0x%08x, pvUsr = %p, cchMax = 0x%08x, fl = 0x%08x, fDblNULL = %x, rc = %d\n",
1112 pcch, *pcch, pvUsr, cchMax, fl, fDblNULL, NO_ERROR);
1113
1114 return rc;
1115}
1116
1117
1118/**
1119 * Copy user memory to user memory.
1120 * @returns OS/2 return code. (NO_ERROR is success)
1121 * @param pvUsr Pointer to target (user) data area.
1122 * @param pv Pointer to source (user) data area.
1123 * @param cb Count of bytes to copy.
1124 * @param fl Flags.
1125 * @status Partially implemented.
1126 * @remark Ignores fl. Crashes on error.
1127 */
1128ULONG KRNLCALL fakeTKSuFuBuff(PVOID pvTarget, PVOID pvSource, ULONG cb, ULONG fl)
1129{
1130 memcpy(pvTarget, pvSource, cb);
1131
1132 printf("fakeTKSuFuBuff: pvTarget = %p, pvSource = %p, cb = 0x%08x, fl = 0x%08x, rc = %d\n",
1133 pvTarget, pvSource, cb, fl, NO_ERROR);
1134
1135 return NO_ERROR;
1136}
1137
1138
1139/**
1140 * Validates an hMTE and gets the MTE pointer - FAKE.
1141 * @returns Pointer to MTE on success.
1142 * NULL on error.
1143 * @param hMTE MTE handle.
1144 * @remark If you wan't to this faster:
1145 * Use the hMTE as a HOB and get the HOB address (by using VMGetHandleInfo).
1146 * @status stub.
1147 */
1148PMTE LDRCALL fakeldrValidateMteHandle(HMTE hMTE)
1149{
1150 DUMMY();
1151
1152 printf("fakeldrValidateMteHandle: hMTE = 0x%04x, pMTE (rc) = %p\n",
1153 hMTE, NULL);
1154
1155 return NULL;
1156}
1157
1158
1159/**
1160 * C worker function for fakeg_tkExecPgm. This is called by fakeg_tkExecPgm (fakea.asm).
1161 * @returns OS/2 return code.
1162 * @param execFlag Exec flag (DosExecPgm execFlag).
1163 * @param pArg Pointer to arguments. (NULL allowed)
1164 * @param pEnv Pointer to environment. (NULL allowed)
1165 * @param pszFilename Pointer to filename.
1166 * @sketch
1167 * @status
1168 * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no)
1169 * @remark
1170 */
1171ULONG _Optlink tkExecPgmWorker(ULONG execFlag, PSZ pArg, PSZ pEnv, PSZ pszFilename)
1172{
1173 APIRET rc;
1174 ldrrei_t rei;
1175
1176 printf("tkExecPgmWorker: execFlag = %d, pArg = %p, pEnv = %p, pszFilename = %s\n", execFlag, pArg, pEnv, pszFilename);
1177
1178 /*
1179 * Take loader semaphore.
1180 */
1181 rc = KSEMRequestMutex(&fakeLdrSem, KSEM_INDEFINITE_WAIT);
1182 if (rc != NO_ERROR)
1183 {
1184 return rc;
1185 }
1186
1187 /*
1188 * Simulate loading.
1189 */
1190 rc = fakeLDRLoadExe(pszFilename, SSToDS(&rei));
1191
1192 NOREF(pArg);
1193 NOREF(pEnv);
1194 NOREF(execFlag);
1195
1196 return rc;
1197}
1198
1199
1200/**
1201 * Fake implementation of LDRLoadExe.
1202 * Not currently overriden, but used by tkExecPgmWorker to load executables.
1203 * @returns OS/2 return code.
1204 * @param pszFilename Name of executable image to load.
1205 * @param pEI It seems this is a pointer to a ldrrei_s struct.
1206 * (currently ignored)
1207 * @sketch
1208 * @status
1209 * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no)
1210 * @remark
1211 */
1212ULONG LDRCALL fakeLDRLoadExe(PSZ pszFilename, ldrrei_t *pEI)
1213{
1214 APIRET rc;
1215 int cchFilename = strlen(pszFilename);
1216
1217 printf("fakeLDRLoadExe: *entry* pszFilename = %s, pEI = %p\n",
1218 pszFilename, pEI);
1219
1220 rc = fakeldrGetModule(pszFilename, (cchFilename << 16) | (LVTYPE_EXE << 8) | CLASS_PROGRAM);
1221
1222 printf("fakeLDRLoadExe: *exit* pszFilename = %s, pEI = %p, rc = %d\n",
1223 pszFilename, pEI, rc);
1224
1225 return rc;
1226}
1227
1228
1229
1230/**
1231 * Fake implementeation of ldrGetModule.
1232 * Not currently overriden, but used by fakeLDRLoadExe to load executables.
1233 * @returns OS/2 return code.
1234 * @param pszFilename Name of executable image to load.
1235 * @param ul low 8 bits: Module CLASS_*.
1236 * high 8 bits: Executable type LVTYPE_* ?
1237 * high 16 bits: Filename length.
1238 * @sketch
1239 * OS/2 kernel seems to do:
1240 * Call Sec32GetModule
1241 * Call ldrGetMte which does the necessary loading / attaching.
1242 * Call ldrLoadImports for all imported DLLs. (and the exe?)
1243 * Call ldrProcessObjects for LX and ldrPreloadLDT for NE imported DLLs. (and the exe?)
1244 * Call ldrProcessImports.
1245 *
1246 * We do:
1247 * Call fakeldrGetMte.
1248 * Call fakeldrLoadImports.
1249 *
1250 * @status
1251 * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no)
1252 * @remark
1253 */
1254ULONG LDRCALL fakeldrGetModule(PSZ pszFilename, ULONG ul)
1255{
1256 APIRET rc;
1257 PMTE pmte = NULL;
1258
1259 printf("fakeldrGetModule: *entry* pszFilename = %s, ul = 0x%08x\n",
1260 pszFilename, ul);
1261
1262 rc = fakeldrGetMte(pszFilename, (USHORT)(ul >> 16), (UCHAR)((ul & 0xff00) >> 8), (UCHAR)(ul & 0x00ff), SSToDS(&pmte));
1263 if (rc == NO_ERROR)
1264 {
1265 rc = fakeldrLoadImports(pmte);
1266 }
1267
1268 printf("fakeldrGetModule: *exit* pszFilename = %s, ul = 0x%08x, rc = %d\n",
1269 pszFilename, ul, rc);
1270
1271 return rc;
1272}
1273
1274
1275/**
1276 *
1277 * @returns
1278 * @param
1279 * @equiv
1280 * @time
1281 * @sketch
1282 * OS/2 kernel seems to do:
1283 * IF not device driver THEN
1284 * Uppercase the name.
1285 * Call ldrFindModule to try find the module within currenly loaded modules.
1286 * ENDIF
1287 *
1288 * tryagain:
1289 * IF found THEN
1290 * Set MTEGETMTEDONE flag in mte_flags2.
1291 * Call ldrChkLoadType to ensure correct load type.
1292 * IF attached or special modules (DOSMOD, VDDMOD, FSHMOD or MVDMMOD)
1293 * IF miniIFS and !FSHMOD THEN Fail with rc=ERROR_INVALID_NAME
1294 * return successfully.
1295 * ENDIF
1296 * lv_sfn <- mte_sfn
1297 * Set the USED flag in mte_flags1
1298 * Set the MTELOADORATTACH flag in mte_flags2
1299 * Some processing of packed segments???? Dll init flags???
1300 * ELSE *not found*
1301 * IF class is CLASS_SPECIFIC AND ldrCheckGlobal returned TRUE THEN
1302 * * this is because some specific modules is promoted to global
1303 * * modules for some reasons I haven't ivestigated. (ldrPrmoteMTE)
1304 * tryagain.
1305 * ENDIF
1306 * Set some flag to false.
1307 * Calls to ldrOpenNewExe to load the exectuble from disk.
1308 * IF this failes THEN fail.
1309 * IF class is CLASS_GLOBAL and module is loaded as specific
1310 * (ldrCheckSpecific returns TRUE) THEN
1311 * Close and retry with the mte returned ldrCheckSpecific
1312 * tryagain.
1313 * ENDIF
1314 * Sets some local variable to point at pheaderbuf, where ldrOpenNewExe
1315 * has put the executable header.
1316 * Call ldrCheckLoadType and fail if this failes.
1317 * Call ldrCreateMte and fail if this failes.
1318 * Set some local variables to lv_pmte and lv_pmte->mte_swapmte.
1319 * Set the MTELOADORATTACH and MTEGETMTEDONE flags.
1320 * Call ldrInvTgtErrTxt.
1321 * IF DDInitTime AND DEVDRVMOD OR FSDMOD THEN
1322 * ptda_module of current PTDA to the mtehandle of the module.
1323 * ENDIF
1324 * IF DOSCALL1 (checks name) THEN
1325 * Set DOSLIB flag of mte_flags1.
1326 * Set global pmteDoscall1 to point to the mte.
1327 * Set global hmteDoscall1 to the handle of the mte.
1328 * ENDIF
1329 * ENDIF
1330 * IF VDDMOD THEN
1331 * call VDMMLoadingVDD with the mte handle.
1332 * ENDIF
1333 * IF NE executable THEN
1334 * Call ldrAllocSegments
1335 * ELSE
1336 * Call ldrAllocObjects
1337 * ENDIF
1338 * IF failed THEN fail.
1339 * IF LVTYPE_EXE THEN
1340 * Set the ptda_module of the ExecChild PTDA to mtehandle.
1341 * IF MTELONGNAMES THEN
1342 * Set ptda_NewFiles to something.
1343 * ENDIF
1344 * Increment usage count, ie. mte_usecnt-
1345 * ELSE IF LVTYPE_DLL AND !somelocalflag AND NOINTERNFIXUPS THEN
1346 * Remove Internal fixups?
1347 * (Calls ldrIsInternalFixup and VMReallocKHB during this processing.)
1348 * ENDIF
1349 * Clears the MTEPROCESSED flag of mte_flags1.
1350 * Sets the return mte pointer. (ppmte)
1351 * return successfully.
1352 *
1353 * We do:
1354 * Uppercase the string. (do we have to switch stack?)
1355 * Call fakeldrOpenNewExe to do it's work.
1356 * Call fakeldrCreateMte to create a fake mte.
1357 * return.
1358 *
1359 * @status
1360 * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no)
1361 * @remark
1362 */
1363ULONG LDRCALL fakeldrGetMte(PCHAR pachFilename, USHORT cchFilename, UCHAR fchType, UCHAR fchClass, PPMTE ppmte)
1364{
1365 ldrlv_t lv;
1366 APIRET rc;
1367
1368 printf("fakeldrGetMte: *entry* pachFilename = %.*s, cchFilename = %#02x, fchType %#2x, fchClass = %#2x, ppmte = %p\n",
1369 cchFilename, pachFilename, cchFilename, fchType, fchClass, ppmte);
1370
1371 /*
1372 * Initiate the local variables.
1373 */
1374 memset(SSToDS(&lv), 0, sizeof(lv));
1375 lv.lv_sfn = (USHORT)-1;
1376 lv.lv_type = fchType;
1377 lv.lv_class = fchClass;
1378
1379 /*
1380 * Uppercase the string.
1381 */
1382 fakeldrUCaseString(pachFilename, cchFilename);
1383
1384 /*
1385 * Open the new executable.
1386 */
1387 rc = fakeldrOpenNewExe(pachFilename, cchFilename, SSToDS(&lv), NULL);
1388 if (rc != NO_ERROR)
1389 {
1390 fakeldrClose(lv.lv_sfn);
1391 printf("fakeldrGetMte: *exit* pachFilename = %.*s, ppmte = %p; *ppmte = %p, rc = %d\n",
1392 cchFilename, pachFilename, ppmte, *ppmte, rc);
1393 return rc;
1394 }
1395
1396 /*
1397 * Create MTE for the opened file.
1398 */
1399 rc = fakeldrCreateMte(pheaderbuf, SSToDS(&lv));
1400 if (rc == NO_ERROR)
1401 {
1402 /*
1403 * Set some flags... More?
1404 */
1405 lv.lv_pmte->mte_flags2 |= MTEGETMTEDONE | MTELOADORATTACH;
1406 *ppmte = lv.lv_pmte;
1407 }
1408
1409 printf("fakeldrGetMte: *exit* pachFilename = %.*s, ppmte = %p; *ppmte = %p, rc = %d\n",
1410 cchFilename, pachFilename, ppmte, *ppmte, rc);
1411
1412 return rc;
1413}
1414
1415
1416
1417/**
1418 * Opens an executable module.
1419 * @returns OS2 error code.
1420 * @param pachFilename Filename of the executable module to open.
1421 * @param cchFilename Filename length.
1422 * @param plv Pointer to local variables.
1423 * @param pus Pointer to some flags (LDRQAppType flags?!).
1424 * @sketch
1425 * OS/2 kernel seems to do:
1426 * Call ldrOpenPath to open the file.
1427 * IF this fail THEN
1428 * Set lv_sfn to -1 and return errorcode.
1429 * ENDIF
1430 * Set local variable to pheaderbuf.
1431 * IF pus THEN set *pus to 1
1432 * Call ldrRead to read the MZ header.
1433 * Fail if this failed. (Don't close file caller does that.)
1434 * IF LXMAGIC of NEMAGIC found THEN
1435 * lv_new_exe_off <- 0;
1436 * ELSE
1437 * IF !EMAGIC or 'OZ' THEN
1438 * Fail with rc=ERROR_INVALID_EXE_SIGNATURE.
1439 * ENDIF
1440 * IF pus THEN set *pus to 2.
1441 * lv_new_exe_off <- e_lfanew.
1442 * ENDIF
1443 * Call ldrRead to read LX/NE header at lv_new_exe_off.
1444 * Fail if this failed.
1445 * IF NOT LXMAGIC OR NEMAGIC THEN
1446 * IF LEMAGIC AND pus THEN Set *pus to 0.
1447 * IF PEMAGIC and pus THEN Set *pus to 3.
1448 * Fail with rc=ERROR_INVALID_EXE_SIGNATURE.
1449 * ENDIF
1450 * IF pus THEN Set *pus to 0.
1451 * IF invalid LX exeheader THEN
1452 * Fail with rc=ERROR_INVALID_EXE_SIGNATURE.
1453 * ENDIF
1454 * IF NEMAGIC THEN
1455 * Call ldrExpandHeader
1456 * ELSE
1457 * Set the MTELONGNAMES flag in e32_mflags.
1458 * ENDIF
1459 * IF LDRINVALID (in e32_mflags) THEN
1460 * Fail with rc=ERROR_EXE_MARKED_INVALID.
1461 * ENDIF
1462 * Clear some e32_mflags, MTE_MEDIAFIXED, MTEMEDIACONTIG and MTEMEDIA16M.
1463 * Or in flags set by ldrOpenPath into e32_mflags. (media type flags?!)
1464 * Call ldrMungeFlags
1465 * return retur code from ldrMungeFlags.
1466 *
1467 * We do:
1468 * Call fakeldrOpenPath to open the file.
1469 * IF this fail THEN
1470 * Set lv_sfn to -1 and return errorcode.
1471 * ENDIF
1472 * IF pus THEN set *pus to 1
1473 * Call ldrRead to read the MZ header.
1474 * Fail if this failed. (Don't close file caller does that.)
1475 * If MZ header Then
1476 * Set lv_new_exe_off to e_lfanew.
1477 * else
1478 * Set lv_new_exe_off to 0.
1479 * Call ldrRead to read the LX header.
1480 * Fail if this failed. (Don't close file caller does that.)
1481 * If Not LX signature Then
1482 * Fail.
1483 * return successfully.
1484 *
1485 * @status
1486 * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no)
1487 * @remark
1488 */
1489ULONG LDRCALL fakeldrOpenNewExe(PCHAR pachFilename, USHORT cchFilename, ldrlv_t *plv, PUSHORT pus)
1490{
1491 APIRET rc;
1492 ULONG ful;
1493
1494 printf("fakeldrOpenNewExe: *entry* pachFilename = %.*s, cchFilename = %#2, plv = %p, pus = %p\n",
1495 cchFilename, pachFilename, cchFilename, plv, pus);
1496
1497 rc = fakeldrOpenPath(pachFilename, cchFilename, plv, SSToDS(&ful), 1);
1498 if (rc != NO_ERROR)
1499 {
1500 plv->lv_sfn = 0xffff;
1501 printf("fakeldrOpenNewExe: *exit* pachFilename = %.*s, plv->lv_sfn = %#4x, rc = %d\n",
1502 cchFilename, pachFilename, plv->lv_sfn, rc);
1503 return rc;
1504 }
1505 if (pus) *pus = 1;
1506
1507 memset(pheaderbuf, 0, sizeof(struct exe_hdr)); //zero it just in case....
1508 rc = fakeldrRead(plv->lv_sfn, 0, pheaderbuf, 0, sizeof(struct exe_hdr), NULL);
1509 if (rc != NO_ERROR)
1510 {
1511 plv->lv_sfn = 0xffff;
1512 printf("fakeldrOpenNewExe: *exit* pachFilename = %.*s, plv->lv_sfn = %#4x, rc = %d\n",
1513 cchFilename, pachFilename, plv->lv_sfn, rc);
1514 return rc;
1515 }
1516
1517 if (*(PUSHORT)pheaderbuf == EMAGIC)
1518 plv->lv_new_exe_off = ((struct exe_hdr *)pheaderbuf)->e_lfanew;
1519 else
1520 plv->lv_new_exe_off = 0;
1521
1522 memset(pheaderbuf, 0, sizeof(struct e32_exe)); //zero it just in case....
1523 rc = fakeldrRead(plv->lv_sfn, plv->lv_new_exe_off, pheaderbuf, 0, sizeof(struct e32_exe), NULL);
1524 if (rc != NO_ERROR)
1525 {
1526 plv->lv_sfn = 0xffff;
1527 printf("fakeldrOpenNewExe: *exit* pachFilename = %.*s, plv->lv_sfn = %#4x, rc = %d\n",
1528 cchFilename, pachFilename, plv->lv_sfn, rc);
1529 return rc;
1530 }
1531
1532 if (*(PUSHORT)pheaderbuf != E32MAGIC)
1533 {
1534 plv->lv_sfn = 0xffff;
1535 rc = ERROR_INVALID_EXE_SIGNATURE;
1536 printf("fakeldrOpenNewExe: *exit* pachFilename = %.*s, plv->lv_sfn = %#4x, rc = %d\n",
1537 cchFilename, pachFilename, plv->lv_sfn, rc);
1538 return rc;
1539 }
1540
1541 printf("fakeldrOpenNewExe: *exit* pachFilename = %.*s, plv->lv_sfn = %#4x, rc = %d\n",
1542 cchFilename, pachFilename, plv->lv_sfn, rc);
1543
1544 return NO_ERROR;
1545}
1546
1547
1548/**
1549 * Fake ldrCreateMte implementation.
1550 * @returns
1551 * @param pe32 Pointer to the LX/NE header we've just read.
1552 * @param plv Pointer to local variables.
1553 * @sketch !This does a lot of thing!
1554 *
1555 * OS/2 Kernel seems to do:
1556 * Allocate a kernel heap block for the MTE
1557 *
1558 *
1559 *
1560 *
1561 *
1562 *
1563 *
1564 *
1565 *
1566 *
1567 * We do:
1568 *
1569 *
1570 * @status
1571 * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no)
1572 * @remark
1573 */
1574ULONG LDRCALL fakeldrCreateMte(struct e32_exe *pe32, ldrlv_t *plv)
1575{
1576 ULONG rc;
1577 PMTE pMte;
1578 PSMTE pSMte;
1579 PCHAR pch;
1580
1581 printf("fakeldrCreateMte: *entry* pe32 = %p, plv = %d\n",
1582 pe32, plv);
1583
1584 /*
1585 * Allocate mte and smte.
1586 * The MTE has an array of mte pointers at the end for imported modules + 1.
1587 * The SMTE has the fullpath filename, loader section and fixup section.
1588 */
1589 pMte = malloc(sizeof(MTE) + sizeof(PMTE) + sizeof(PMTE)*pe32->e32_impmodcnt);
1590 if (pMte == NULL)
1591 {
1592 rc = ERROR_NOT_ENOUGH_MEMORY;
1593 goto createmte_exit;
1594 }
1595
1596 plv->lv_csmte = sizeof(SMTE) + 260 + pe32->e32_ldrsize + pe32->e32_fixupsize;
1597 pSMte = malloc(plv->lv_csmte);
1598 if (pSMte == NULL)
1599 {
1600 rc = ERROR_NOT_ENOUGH_MEMORY;
1601 goto createmte_exit;
1602 }
1603 pch = (PCHAR)(PVOID)pSMte + sizeof(SMTE) + 260;
1604
1605
1606 /*
1607 * Initialize the MTE.
1608 */
1609 pMte->mte_flags2 = MTEFORMATLX;
1610 pMte->mte_handle = 20;
1611 pMte->mte_swapmte = pSMte;
1612 pMte->mte_link = NULL;
1613 pMte->mte_flags1 = pe32->e32_mflags;
1614 pMte->mte_impmodcnt = pe32->e32_impmodcnt;
1615 pMte->mte_sfn = plv->lv_sfn;
1616 pMte->mte_usecnt = 0;
1617 pMte->mte_modname[0]= '\0';
1618
1619 /*
1620 * Initialize the SMTE.
1621 */
1622 pSMte->smte_mpages = pe32->e32_mpages;
1623 /*- magic,border,worder,level,cpu,os,ver,mflags */
1624 pSMte->smte_mpages = pe32->e32_mpages; /* 00 Module # pages */
1625 pSMte->smte_startobj = pe32->e32_startobj; /* 04 Object # for instruction */
1626 pSMte->smte_eip = pe32->e32_eip; /* 08 Extended instruction pointer */
1627 pSMte->smte_stackobj = pe32->e32_stackobj; /* 0c Object # for stack pointer */
1628 pSMte->smte_esp = pe32->e32_esp; /* 10 Extended stack pointer */
1629 /*- pagesize*/
1630 pSMte->smte_pageshift = pe32->e32_pageshift; /* 14 Page alignment shift in .EXE */
1631 pSMte->smte_fixupsize = pe32->e32_fixupsize; /* 18 Fixup section size */
1632 /*- fixupsum,ldrsize,ldrsum*/
1633 pSMte->smte_objtab = (POTE)pe32->e32_objtab; /* 1c Object table offset - POINTER */
1634 pSMte->smte_objcnt = pe32->e32_objcnt; /* 20 Number of objects in module */
1635 pSMte->smte_objmap = pe32->e32_objmap; /* 24 Object page map offset - POINTER */
1636 pSMte->smte_itermap = pe32->e32_itermap; /* 28 Object iterated data map offset */
1637 pSMte->smte_rsrctab = pe32->e32_rsrctab; /* 2c Offset of Resource Table */
1638 pSMte->smte_rsrccnt = pe32->e32_rsrccnt; /* 30 Number of resource entries */
1639 pSMte->smte_restab = pe32->e32_restab; /* 34 Offset of resident name table - POINTER */
1640 pSMte->smte_enttab = pe32->e32_enttab; /* 38 Offset of Entry Table - POINTER */
1641 pSMte->smte_fpagetab = pe32->e32_fpagetab; /* 3c Offset of Fixup Page Table - POINTER */
1642 pSMte->smte_frectab = pe32->e32_frectab; /* 40 Offset of Fixup Record Table - POINTER */
1643 pSMte->smte_impmod = pe32->e32_impmod; /* 44 Offset of Import Module Name Table - POINTER */
1644 /*- impmodcnt*/
1645 pSMte->smte_impproc = pe32->e32_impproc; /* 48 Offset of Imp Procedure Name Tab - POINTER */
1646 /*- pagesum*/
1647 pSMte->smte_datapage = pe32->e32_datapage; /* 4c Offset of Enumerated Data Pages */
1648 /*- preload*/
1649 pSMte->smte_nrestab = pe32->e32_nrestab; /* 50 Offset of Non-resident Names Table */
1650 pSMte->smte_cbnrestab = pe32->e32_cbnrestab; /* 54 Size of Non-resident Name Table */
1651 /*- nressum*/
1652 pSMte->smte_autods = pe32->e32_autodata; /* 58 Object # for automatic data object */
1653 pSMte->smte_debuginfo = pe32->e32_debuginfo; /* 5c Offset of the debugging info */
1654 pSMte->smte_debuglen = pe32->e32_debuglen; /* 60 The len of the debug info in */
1655 /*- instpreload,instdemand*/
1656 pSMte->smte_heapsize = pe32->e32_heapsize; /* 64 use for converted 16-bit modules */
1657 /*- res3*/
1658 /* extra */
1659 pSMte->smte_path = 0; /* 68 full pathname - POINTER */
1660 pSMte->smte_semcount = 0; /* 6c Count of threads waiting on MTE semaphore. 0 => semaphore is free */
1661 pSMte->smte_semowner = 0; /* 6e Slot number of the owner of MTE semahore */
1662 pSMte->smte_pfilecache = 0; /* 70 Pointer to file cache for Dos32CacheModule */
1663 pSMte->smte_stacksize = 0; /* 74 Thread 1 Stack size from the exe header */
1664 pSMte->smte_alignshift = 0; /* 78 use for converted 16-bit modules */
1665 pSMte->smte_NEexpver = 0; /* 7a expver from NE header */
1666 pSMte->smte_pathlen = 0; /* 7c length of full pathname */
1667 pSMte->smte_NEexetype = 0; /* 7e exetype from NE header */
1668 pSMte->smte_csegpack = 0; /* 80 count of segs to pack */
1669
1670 /*
1671 * Copy filename (from where?)
1672 */
1673 pSMte->smte_path = (PCHAR)(PVOID)pSMte + sizeof(SMTE);
1674 pSMte->smte_pathlen = 0;
1675 memcpy(pSMte->smte_path, "", pSMte->smte_pathlen);
1676
1677
1678 /*
1679 * Read loader and fixup sections.
1680 */
1681 rc = fakeldrRead(plv->lv_sfn,
1682 (ULONG)pSMte->smte_objtab + plv->lv_new_exe_off,
1683 pch,
1684 0,
1685 pe32->e32_ldrsize + pe32->e32_fixupsize,
1686 NULL);
1687 if (rc)
1688 {
1689 goto createmte_exit;
1690 }
1691
1692 /*
1693 * Set pointers.
1694 */
1695 pSMte->smte_objtab = (POTE)(PVOID)pch;
1696 rc = fakeldrMTEValidatePtrs(pSMte,
1697 (ULONG)pch + plv->lv_csmte,
1698 (ULONG)pch - (ULONG)pe32->e32_objtab);
1699 if (rc)
1700 {
1701 goto createmte_exit;
1702 }
1703
1704 /*
1705 * Set mte pointer in plv.
1706 * Set hobmte in plv.
1707 */
1708 plv->lv_pmte = pMte;
1709 plv->lv_hobmte = pMte->mte_handle;
1710
1711 /*
1712 * Fix flags...
1713 */
1714 pMte->mte_flags1 |= plv->lv_class;
1715
1716createmte_exit:
1717 printf("fakeldrCreateMte: *exit* pe32 = %p, plv = %d, rc = %d\n",
1718 pe32, plv, rc);
1719
1720 return rc;
1721}
1722
1723
1724
1725/**
1726 * Fake ldrLoadImports - loads the import modules for the given module (pmte).
1727 * @returns OS2 error code.
1728 * @param pmte Pointer to mte to load imports for.
1729 * @sketch
1730 * OS/2 kernel seems to do:
1731 * Loop thru the importe module table (reverse order for NE files)
1732 * IF VDD module THEN
1733 * Uppercase the name.
1734 * try find it using ldrFindModule
1735 * fail if error, not found, not VDDMOD/MVDMMOD.
1736 * Add to array of imported module.
1737 * ENDIF
1738 * IF Not found OR !MTEGETMTEDONE THEN
1739 * call ldrGetMte to load the module (class global).
1740 * fail if error.
1741 * set MTEGETMTEDONE
1742 * Add to array of imported module.
1743 * ENDIF
1744 * IF DOSMOD and !ldrMiniFileIOFlag THEN
1745 * Replace module pointer with doscall1 pmte.
1746 * ENDIF
1747 * ENDLOOP
1748 *
1749 * We do:
1750 * Parameter validation.
1751 * Loop thru the imported module table issuing fakeldrGetMte on each entry.
1752 * 'DOSCALLS' is ignored.
1753 *
1754 * @status
1755 * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no)
1756 * @remark
1757 */
1758ULONG LDRCALL fakeldrLoadImports(PMTE pmte)
1759{
1760 int i; /* Module index. */
1761 PSZ psz; /* Module name pointer. (really pointer to pascal strings...) */
1762 PPMTE papmte; /* Pointer to array of PMTEs for imported modules. */
1763 APIRET rc;
1764
1765 printf("fakeldrLoadImport: *entry* pmte = %p, pmte->mte_impmodcnt = %d\n",
1766 pmte, pmte->mte_impmodcnt);
1767
1768 /*
1769 * Parameter validation.
1770 */
1771 if (pmte == NULL)
1772 {
1773 kprintf(("fakeldrLoadImports: !ASSERTION! pmte == NULL\n"));
1774 return ERROR_INVALID_PARAMETER;
1775 }
1776 if (pmte->mte_swapmte == NULL)
1777 {
1778 kprintf(("fakeldrLoadImports: !ASSERTION! pmte->mte_swapmte == NULL\n"));
1779 return ERROR_INVALID_PARAMETER;
1780 }
1781
1782 /*
1783 * Any imported modules?
1784 */
1785 if (pmte->mte_impmodcnt == 0)
1786 {
1787 printf("fakeldrLoadImport: *exit* pmte = %p, rc = %d\n",
1788 pmte, rc);
1789 return NO_ERROR;
1790 }
1791
1792 /* We have reserved space for imported module pointers after the mte. */
1793 papmte = (PPMTE)((unsigned)pmte + sizeof(MTE));
1794
1795 /*
1796 * Process the imported module table.
1797 */
1798 for (i = 0, rc = NO_ERROR, psz = (PSZ)pmte->mte_swapmte->smte_impmod;
1799 i < pmte->mte_impmodcnt && rc == NO_ERROR;
1800 i++, psz += 1 + *psz)
1801 {
1802 if (*psz == 8 && !strnicmp(psz+1, "DOSCALLS", 8))
1803 continue;
1804
1805 rc = fakeldrGetMte(psz + 1, *psz, LVTYPE_DLL, CLASS_GLOBAL, &papmte[i]);
1806 }
1807
1808 printf("fakeldrLoadImport: *exit* pmte = %p, rc = %d\n",
1809 pmte, rc);
1810
1811 return rc;
1812}
1813
1814
1815/**
1816 * Checks if the internal name (first name in the resident nametable) matches
1817 * the filename.
1818 * @returns NO_ERROR on success (the name matched).
1819 * ERROR_INVALID_NAME if mismatch.
1820 * @param pMTE Pointer to the MTE of the module to check.<br>
1821 * Assumes! that the filename for this module is present in ldrpFileNameBuf.
1822 */
1823ULONG LDRCALL fakeldrCheckInternalName(PMTE pMTE)
1824{
1825 PCHAR pachName; /* Pointer to the name part of pachFilename. */
1826 int cchName; /* Length of the name part of pachFilename.
1827 * Includes extention if extention is not .DLL.
1828 * this is the length relative to pachName used to match the internal name. */
1829 PCHAR pachExt; /* Pointer to the extention part of pachFilename. (not dot!) */
1830 int cchExt; /* Length of the extention part of pachFilename. (not dot!) */
1831
1832
1833 /* Return successfully if not library module. */
1834 if (!(pMTE->mte_flags1 & LIBRARYMOD))
1835 return NO_ERROR;
1836
1837 /* Uppercase and parse filename in ldrpFileNameBuf */
1838 cchName = (int)fakeldrGetFileName(ldrpFileNameBuf, (PCHAR*)SSToDS(&pachName), (PCHAR*)SSToDS(&pachExt));
1839 cchExt = (pachExt) ? strlen(pachExt) : 0;
1840 ldrUCaseString(pachName, cchName + cchExt + 1);
1841
1842 /* Compare the internal name with the filename and return accordingly. */
1843 return ( cchName <= 8
1844 && !memcmp(pMTE->mte_modname, pachName, cchName)
1845 && (cchName == 8 || pMTE->mte_modname[cchName] == '\0')
1846 )
1847 ? NO_ERROR
1848 : ERROR_INVALID_NAME;
1849}
1850
1851
1852/**
1853 * Translates a relative filename to a full qualified filename.
1854 * @returns NO_ERROR on success.
1855 * Errorcode on error.
1856 * @param pszFilename Pointer to nullterminated filename.
1857 */
1858ULONG LDRCALL fakeldrTransPath(PSZ pszFilename)
1859{
1860 return fakeIOSftTransPath(pszFilename);
1861}
1862
1863
1864/**
1865 * Parses a filename to find the name and extention.
1866 * @returns Length of the filename without the extention.
1867 * @param pachFilename Pointer to filename to parse - must have path!
1868 * @param ppachName Pointer to pointer which should hold the name pointer upon successfull return.
1869 * @param ppachExt Pointer to pointer which should hold the extention pointer upon successfull return.
1870 */
1871ULONG LDRCALL fakeldrGetFileName(PSZ pszFilename, PCHAR *ppchName, PCHAR *ppchExt)
1872{
1873 int cchName;
1874 PSZ pchName;
1875 PSZ pchExt = NULL;
1876
1877 while (*pszFilename)
1878 {
1879 if (*pszFilename == '\\' || *pszFilename == '/')
1880 pchName = pszFilename + 1;
1881 else if (*pszFilename == '.')
1882 pchExt = pszFilename + 1;
1883 pszFilename++;
1884 }
1885
1886 cchName = (pchExt <= pchName) ? strlen(pchName) : pchExt - pchName - 1;
1887 *ppchExt = pchExt;
1888 *ppchName = pchName;
1889
1890 return cchName;
1891}
1892
1893
1894/**
1895 * Uppercases the string.
1896 * @param pachString String to uppercase.
1897 * @param cchString Length of string.
1898 * @sketch Loop thru the string converting all english letters to uppercase.
1899 * @status partially implemented.
1900 * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no)
1901 * @remark This is probably written in assembly and does DBCS checks...
1902 */
1903VOID LDRCALL fakeldrUCaseString(PCHAR pachString, unsigned cchString)
1904{
1905 printf("fakeldrUCaseString: pachString = %.*s, cchString = %#8x\n",
1906 cchString, pachString, cchString);
1907
1908 while (cchString-- != 0)
1909 {
1910 if (*pachString >= 'a' && *pachString <= 'z')
1911 *pachString -= ('a' - 'A');
1912 pachString++;
1913 }
1914}
1915
1916
1917
1918
1919/**
1920 * Checks and updates the members of the swap-mte which is to be
1921 * pointers into the loader/fixup section. An array, validatetbl, contains
1922 * the offsets of the smte pointers.
1923 *
1924 * @returns NO_ERROR on success.
1925 * ERROR_BAD_EXE_FORMAT on error.
1926 * @param psmte
1927 * @param ulMaxAddr Maximum (exclusive) address.
1928 * @param off Offset delta to add to the pointer members (which
1929 * are all offsets relative to the start of the new
1930 * header) to make them pointers.
1931 * @sketch
1932 * Loop thru the validatetbl and update each field (which isn't null) by adding
1933 * the off value, and validate that the pointer is ok.
1934 * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no)
1935 * @remark
1936 */
1937ULONG LDRCALL fakeldrMTEValidatePtrs(PSMTE psmte, ULONG ulMaxAddr, ULONG off)
1938{
1939 int i;
1940
1941 printf("fakeldrMTEValidatePtrs: *entry* psmte = %p, ulMaxAddr = %p, off = %p\n",
1942 psmte, ulMaxAddr, off);
1943
1944 for (i = 0; validatetbl[i] != 0xDEAD; i++)
1945 {
1946 PULONG pul = (PULONG)(PVOID)((PCHAR)(PVOID)psmte + validatetbl[i]);
1947 if (*pul != 0UL)
1948 {
1949 *pul += off;
1950 if (*pul >= ulMaxAddr)
1951 {
1952 printf("fakeldrMTEValidatePtrs: *exit* psmte = %p, ulMaxAddr = %p, off = %p, rc = %d\n",
1953 psmte, ulMaxAddr, off, ERROR_BAD_EXE_FORMAT);
1954 return ERROR_BAD_EXE_FORMAT;
1955 }
1956 }
1957 }
1958
1959 printf("fakeldrMTEValidatePtrs: *exit* psmte = %p, ulMaxAddr = %p, off = %p, rc = %d\n",
1960 psmte, ulMaxAddr, off, NO_ERROR);
1961 return NO_ERROR;
1962}
1963
1964
1965PMTE KRNLCALL fakeldrASMpMTEFromHandle(HMTE hMTE)
1966{
1967 PMTE pMte = (PMTE)hMTE;
1968
1969 pMte += 10; //just do something!
1970
1971 return NULL;
1972}
1973
1974ULONG LDRCALL fakeldrFindModule(PCHAR pachFilename, USHORT cchFilename, USHORT usClass, PPMTE ppMTE)
1975{
1976 APIRET rc = NO_ERROR;
1977 usClass = usClass;
1978 cchFilename = cchFilename;
1979 pachFilename = pachFilename;
1980 *ppMTE = NULL;
1981 return rc;
1982}
1983
1984
1985/**
1986 * Gets the path (name with fully qualified path) from a SFN.
1987 * @returns Pointer to the path of hFile.
1988 * @param hFile SFN filehandle.
1989 */
1990PSZ SECCALL fakeSecPathFromSFN(SFN hFile)
1991{
1992 BOOL f32Stack = ((int)&hFile > 0x10000);
1993
1994 if (!f32Stack) ThunkStack16To32();
1995
1996
1997 if (!f32Stack) ThunkStack32To16();
1998
1999 printf("fakeSecPathFromSFN: - not implemented - hFile = 0x%04x\n", hFile);
2000
2001 return NULL;
2002}
2003
2004/**
2005 * PID to PTDA pointer.
2006 * @returns OS/2 return code.
2007 * @param pid Process Identifier.
2008 * @param ppPTDA Pointer to the PTDA-pointer variabel which is to receive
2009 * the PTDA pointer on successful return.
2010 */
2011ULONG KRNLCALL fakeTKPidToPTDA(PID pid, PPPTDA ppPTDA)
2012{
2013 DUMMY();
2014 printf("fakeTKPidToPTDA: - not implemented - pid = 0x%04x, ppPTDA=%p\n", pid, ppPTDA);
2015 return ERROR_NOT_SUPPORTED;
2016}
2017
Note: See TracBrowser for help on using the repository browser.