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

Last change on this file since 5280 was 5110, checked in by bird, 25 years ago

Added new fake stuff. Lots of variables - mostly just stubbed.

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