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

Last change on this file since 4503 was 4347, checked in by bird, 25 years ago

Implemented tool for generating calltab for kernel imports. (mkcalltab)
Implemented API for accessing memory in another process. (*ProcessReadWrite)
Added kernel imports needed to implemented ProcessReadWrite.
Removed unused kernel imports.

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