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

Last change on this file since 4310 was 4227, checked in by bird, 25 years ago

Experimenting with ldrSetVMflags. Page alignment possible.

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