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

Last change on this file since 5107 was 5086, checked in by bird, 25 years ago

Moved ldrCalls.h into the OS2Krnl.h tree as OS2KLDR.h.
Also moved the Ldr definitions from OS2Krnl.h and into OS2KLDR.h.

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