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

Last change on this file since 10366 was 6288, checked in by bird, 24 years ago

New fakers.

File size: 72.1 KB
Line 
1/* $Id: fake.c,v 1.9 2001-07-10 05:26:51 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 * Creates a pseudo handle for a given memory address.
728 * @returns OS/2 return code. NO_ERROR on success.
729 * @param pvData Pointer to the data which the handle should represent.
730 * @param hobOwner Owner of the pseudo handle.
731 * @param phob Pointer to object handle variable. Upon successful return
732 * this will hold the handle value of the crated pseudo handle.
733 * @remark Used for many types of handles within the kernel.
734 * Among them are the loader HMTEs. The loader uses usOwner = 0xffa6 (ldrmte).
735 */
736APIRET KRNLCALL fakeVMCreatePseudoHandle(
737 PVOID pvData,
738 VMHOB usOwner,
739 PVMHOB phob)
740{
741 DUMMY();
742 printf("fakeVMCreatePseudoHandle: - not implemented\n");
743 return ERROR_NOT_SUPPORTED;
744}
745
746
747/**
748 * This call frees a pseudo handle pointer previously allocated by
749 * VMCreatePseudoHandle.
750 * @returns OS/2 return code.
751 * @param hob Handle to be freed.
752 */
753APIRET KRNLCALL fakeVMFreePseudoHandle(
754 VMHOB hob)
755{
756 DUMMY();
757 printf("fakeVMFreePseudoHandle: - not implemented\n");
758 return ERROR_NOT_SUPPORTED;
759}
760
761
762/**
763 * ldrOpenPath - ldrOpenPath for build 14053 and above.
764 * kernel 14053 and above.
765 *
766 * @returns OS2 return code.
767 * plv->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 * @param lLibPath New parameter in build 14053.
773 * ldrGetMte calls with 1
774 * ldrOpenNewExe calls with 3
775 * This is compared to the initial libpath index.
776 * The libpath index is:
777 * BEGINLIBPATH 1
778 * LIBPATH 2
779 * ENDLIBPATH 3
780 * The initial libpath index is either 1 or 2.
781 * - ignored -
782 *
783 */
784ULONG LDRCALL fakeldrOpenPath_new( /* retd 0x14 */
785 PCHAR pachFilename, /* ebp + 0x08 */
786 USHORT cchFilename, /* ebp + 0x0c */
787 ldrlv_t * plv, /* ebp + 0x10 */
788 PULONG pful, /* ebp + 0x14 */
789 ULONG lLibPath /* ebp + 0x18 */
790 )
791 {
792 NOREF(lLibPath);
793 return fakeldrOpenPath_old(pachFilename, cchFilename, plv, pful);
794 }
795
796
797/**
798 * myldrOpenPath - opens file eventually searching loader specific paths
799 * Pre kernel 14053.
800 *
801 * @returns OS2 return code.
802 * pLdrLv->lv_sfn is set to filename handle.
803 * @param pachFilename Pointer to modulename. Not zero terminated?
804 * @param cchFilename Modulename length.
805 * @param plv Loader local variables? (Struct from KERNEL.SDF)
806 * @param pful Pointer to flags which are passed on to ldrOpen.
807 * @status stub
808 */
809ULONG LDRCALL fakeldrOpenPath_old(PCHAR pachFilename, USHORT cchFilename, ldrlv_t *plv, PULONG pful)
810{
811 static char szPath[1024]; /* Path buffer. Used to store pathlists. 1024 should be enough */
812 /* for LIBPATH (which at had a limit of ca. 750 chars). */
813 static char sz[CCHMAXPATH]; /* Filename/path buffer. (Normally used to build filenames */
814 /* which are passed in as search experessions to DosFindFirst.) */
815
816 APIRET rc; /* Return value. (Pessimistic attitude! Init it to FALSE...) */
817
818 printf("fakeldrOpenPath: *entry* pachFilename = %.*s, cchFilename = %d, plv = %p, pful = %p\n",
819 cchFilename, pachFilename, cchFilename, plv, pful);
820
821 if (plv->lv_class != CLASS_GLOBAL)
822 rc = fakeldrOpen(&plv->lv_sfn, pachFilename, pful);
823 else
824 {
825 int iPath; /* Current path or pathlist being examined. This is the loop */
826 /* variable looping on the FINDDLL_* defines. */
827
828 /* These defines sets the order the paths and pathlists are examined. */
829 #define FINDDLL_BEGINLIBPATH 7
830 #define FINDDLL_LIBPATH 8
831 #define FINDDLL_ENDLIBPATH 9
832 #define FINDDLL_FIRST FINDDLL_BEGINLIBPATH
833 #define FINDDLL_LAST FINDDLL_ENDLIBPATH
834
835 /*
836 * Remove DLL extention from the filename.
837 */
838 if (cchFilename > 4 && !strncmp(&pachFilename[cchFilename - 4], ".DLL", 4))
839 {
840 cchFilename -= 4;
841 pachFilename[cchFilename] = '\0';
842 }
843
844 /** @sketch
845 * Loop thru the paths and pathlists searching them for the filename.
846 */
847 rc = ERROR_FILE_NOT_FOUND;
848 for (iPath = FINDDLL_FIRST; iPath <= FINDDLL_LAST; iPath++)
849 {
850 const char * pszPath; /* Pointer to the path being examined. */
851
852 /** @sketch Get the path/dir to examin. (This is determined by the value if iPath.) */
853 switch (iPath)
854 {
855 case FINDDLL_BEGINLIBPATH:
856 rc = DosQueryExtLIBPATH(szPath, BEGIN_LIBPATH);
857 break;
858 case FINDDLL_LIBPATH:
859 rc = DosQueryHeaderInfo(NULLHANDLE, 0, szPath, sizeof(szPath), QHINF_LIBPATH);
860 break;
861 case FINDDLL_ENDLIBPATH:
862 rc = DosQueryExtLIBPATH(szPath, END_LIBPATH);
863 break;
864 default: /* !internalerror! */
865 return ERROR_FILE_NOT_FOUND;
866 }
867 if (rc != NO_ERROR)
868 {
869 printf("fakeldrOpenPath: DosQueryExtLIBPATH/DosQueryHeadInfo failed with rc=%d, iPath=%d", rc, iPath);
870 continue;
871 }
872 pszPath = szPath;
873
874
875 /** @sketch
876 * pszPath is now set to the pathlist to be searched.
877 * So we'll loop thru all the paths in the list.
878 */
879 while (pszPath != NULL && *pszPath != '\0')
880 {
881 char * pszNext; /* Pointer to the next pathlist path */
882 int cch; /* Length of path (including the slash after the slash is added). */
883
884 /** @sketch
885 * Find the end of the path.
886 * Copy the path into the sz buffer.
887 * Set pszNext.
888 */
889 pszNext = strchr(pszPath, ';');
890 if (pszNext != NULL)
891 {
892 cch = pszNext - pszPath;
893 pszNext++;
894 }
895 else
896 cch = strlen(pszPath);
897
898 if (cch + cchFilename + 1 >= sizeof(sz)) /* assertion */
899 {
900 printf("fakeldrOpenPath: cch (%d) + cchFilename (%d) + 1 < sizeof(plv->sz) (%d) - paths too long!, iPath=%d",
901 cch, cchFilename, sizeof(sz), iPath);
902 pszPath = pszNext;
903 continue;
904 }
905 memcpy(sz, pszPath, cch);
906
907 /** @sketch
908 * Add a '\\' and the filename (pszFullname) to the path;
909 * then we'll have a fullpath.
910 */
911 sz[cch++] = '\\';
912 memcpy(&sz[cch], pachFilename, cchFilename);
913 memcpy(&sz[cch + cchFilename], ".DLL", 5);
914
915 rc = fakeldrOpen(&plv->lv_sfn, sz, pful);
916 switch (rc)
917 {
918 case ERROR_FILE_NOT_FOUND: case ERROR_PATH_NOT_FOUND: case ERROR_ACCESS_DENIED: case ERROR_INVALID_ACCESS:
919 case ERROR_INVALID_DRIVE: case ERROR_NOT_DOS_DISK: case ERROR_REM_NOT_LIST: case ERROR_BAD_NETPATH:
920 case ERROR_NETWORK_BUSY: case ERROR_DEV_NOT_EXIST: case ERROR_TOO_MANY_CMDS: case ERROR_ADAP_HDW_ERR:
921 case ERROR_UNEXP_NET_ERR: case ERROR_BAD_REM_ADAP: case ERROR_NETNAME_DELETED: case ERROR_BAD_DEV_TYPE:
922 case ERROR_NETWORK_ACCESS_DENIED: case ERROR_BAD_NET_NAME: case ERROR_TOO_MANY_SESS: case ERROR_REQ_NOT_ACCEP:
923 case ERROR_INVALID_PASSWORD: case ERROR_OPEN_FAILED: case ERROR_INVALID_NAME: case ERROR_FILENAME_EXCED_RANGE:
924 case ERROR_VC_DISCONNECTED:
925 rc = ERROR_FILE_NOT_FOUND;
926 pszPath = pszNext;
927 continue;
928 }
929
930 /*
931 * Fatal error or success.
932 */
933 printf("fakeldrOpenPath: *exit* plv->lv_sfn = 0x%04x, rc = %d\n", plv->lv_sfn, rc);
934 return rc;
935 }
936 } /* for iPath */
937 }
938
939 printf("fakeldrOpenPath: *exit* plv->lv_sfn = 0x%04x, rc = %d\n", plv->lv_sfn, rc);
940
941 return rc;
942}
943
944
945/**
946 * LDRClearSem - Clears the loader semaphore.
947 * (It does some garbage collection on release.)
948 * @returns NO_ERROR on sucess.
949 * OS/2 error on failure. (ERROR_INTERRUPT?)
950 * @status completely implemented.
951 */
952ULONG LDRCALL fakeLDRClearSem(void)
953{
954 return fakeKSEMReleaseMutex(&fakeLdrSem);
955}
956
957/**
958 * KSEMReuqestMutex faker.
959 * @returns NO_ERROR
960 * @param hkmtx
961 * @param ulTimeout
962 * @status completely implemented.
963 * @remark
964 */
965ULONG KRNLCALL fakeKSEMRequestMutex(HKSEMMTX hkmtx, ULONG ulTimeout)
966{
967 unsigned short usSlot = getSlot();
968 ULONG rc = NO_ERROR;
969
970 if (memcmp(&hkmtx->debug.ksem_achSignature[0], "KSEM", 4) != 0)
971 {
972 printf("fakeKSEMQueryMutex: hkmtx = %p, invalid signature (%.4s)\n", hkmtx, hkmtx->debug.ksem_achSignature);
973 return FALSE;
974 }
975
976 if (hkmtx->debug.ksem_Owner == 0)
977 {
978 hkmtx->debug.ksem_Owner = usSlot;
979 hkmtx->debug.ksem_cusNest = 1;
980 }
981 else if (hkmtx->debug.ksem_Owner == usSlot)
982 hkmtx->debug.ksem_cusNest++;
983 else
984 rc = ERROR_SEM_BUSY;
985
986 printf("fakeKSEMRequestMutex: hkmtx = %p, ulTimeout = 0x%x, owner = %d, usage count = %d, rc = %d\n",
987 hkmtx, ulTimeout, hkmtx->debug.ksem_cusNest, hkmtx->debug.ksem_Owner, ERROR_SEM_BUSY);
988
989 return rc;
990}
991
992
993/**
994 * KSEMReleaseMutex faker.
995 * @returns NO_ERROR
996 * @param hkmtx
997 * @param ulTimeout
998 * @status completely implemented.
999 * @remark
1000 */
1001ULONG KRNLCALL fakeKSEMReleaseMutex(HKSEMMTX hkmtx)
1002{
1003 unsigned int usSlot = getSlot();
1004 int rc = NO_ERROR;
1005
1006 if (memcmp(&hkmtx->debug.ksem_achSignature[0], "KSEM", 4) != 0)
1007 {
1008 printf("fakeKSEMQueryMutex: hkmtx = %p, invalid signature (%.4s)\n", hkmtx, hkmtx->debug.ksem_achSignature);
1009 return FALSE;
1010 }
1011
1012 if (hkmtx->debug.ksem_Owner == usSlot)
1013 {
1014 if (--hkmtx->debug.ksem_cusNest == 0)
1015 hkmtx->debug.ksem_Owner = 0;
1016 }
1017 else
1018 rc = ERROR_NOT_OWNER;
1019
1020 printf("fakeKSEMReleaseMutex: hkmtx = %p, usage count = %d, owner = %d, rc = %d\n",
1021 hkmtx, hkmtx->debug.ksem_cusNest, hkmtx->debug.ksem_Owner, rc);
1022
1023 return rc;
1024}
1025
1026
1027
1028/**
1029 * KSEMQueryMutex faker.
1030 * @returns TRUE if owner or clear. Clear if *pcusNest is 0.
1031 * FALSE if other owner.
1032 * @param hkmtx Handle to kernel mutex.
1033 * @param pcusNest Pointer to variable which is to receive the nesting count.
1034 * (ie. the number of times we have taken this semaphore.)
1035 * @status completely implemented.
1036 * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no)
1037 */
1038BOOL KRNLCALL fakeKSEMQueryMutex(HKSEMMTX hkmtx, PUSHORT pcusNest)
1039{
1040 unsigned int usSlot = getSlot();
1041 BOOL fRc = TRUE;
1042
1043 if (memcmp(&hkmtx->debug.ksem_achSignature[0], "KSEM", 4) != 0)
1044 {
1045 printf("fakeKSEMQueryMutex: hkmtx = %p, invalid signature (%.4s)\n", hkmtx, hkmtx->debug.ksem_achSignature);
1046 return FALSE;
1047 }
1048
1049 if (hkmtx->debug.ksem_Owner == 0)
1050 {
1051 if (pcusNest)
1052 *pcusNest = 0;
1053 fRc = FALSE;
1054 }
1055 else
1056 {
1057 fRc = (hkmtx->debug.ksem_Owner == usSlot);
1058 if (pcusNest)
1059 *pcusNest = hkmtx->debug.ksem_cusNest;
1060 }
1061
1062 printf("fakeKSEMQueryMutex: hkmtx = %p, usage count = %d, owner = %d, *pcusNest = %d, rc = %d\n",
1063 hkmtx, hkmtx->debug.ksem_cusNest, hkmtx->debug.ksem_Owner, pcusNest ? *pcusNest : -1, fRc);
1064
1065 return fRc;
1066}
1067
1068
1069/**
1070 * KSEMInit faker.
1071 * @param pksem Pointer to the semaphore struct to initiate.
1072 * @param fulType Semaphore type. (only KSEM_MUTEX is supported)
1073 * @param fulFlags Semaphore flags. (not validated)
1074 * @status partially implemented.
1075 * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no)
1076 */
1077VOID KRNLCALL fakeKSEMInit(PKSEM pksem, ULONG fulType, ULONG fulFlags)
1078{
1079 if (fulType != KSEM_MUTEX)
1080 {
1081 printf("fakeKSEMInit: Invalid fulType parameter (%d).\n", fulType);
1082 return; /*ERROR_INVALID_PARAMETER;*/
1083 }
1084
1085 memcpy(pksem->mtx.debug.ksem_achSignature, "KSEM", 4);
1086 pksem->mtx.debug.ksem_bFlags = (char)fulFlags;
1087 pksem->mtx.debug.ksem_bType = KSEM_MUTEX;
1088 pksem->mtx.debug.ksem_cusNest = 0;
1089 pksem->mtx.debug.ksem_cusPendingWriters = 0;
1090 pksem->mtx.debug.ksem_Owner = 0;
1091
1092 printf("fakeKSEMInit: pksem=%p, fulType=%d, fulFlags=0x%x.\n", pksem, fulType, fulFlags);
1093}
1094
1095
1096/**
1097 * Gets the thread slot number.
1098 * @returns Thread slot number.
1099 * @status completely implemented.
1100 * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no)
1101 */
1102unsigned short getSlot(void)
1103{
1104 PPIB ppib;
1105 PTIB ptib;
1106 BOOL f32Stack = ((int)&ppib > 0x10000);
1107
1108 if (!f32Stack) ThunkStack16To32();
1109
1110 DosGetInfoBlocks(&ptib, &ppib);
1111
1112 if (!f32Stack) ThunkStack32To16();
1113
1114 return (unsigned short)ptib->tib_ordinal;
1115}
1116
1117
1118/**
1119 * Copy user memory into system memory.
1120 * @returns OS/2 return code. (NO_ERROR is success)
1121 * @param pv Pointer to target (system) data area.
1122 * @param pvUsr Pointer to source (user) data area.
1123 * @param cb Count of bytes to copy.
1124 * @param fl Flags.
1125 * @status Partially implemented.
1126 * @remark Ignores fl. Crashes on error.
1127 */
1128ULONG KRNLCALL fakeTKFuBuff(PVOID pv, PVOID pvUsr, ULONG cb, ULONG fl)
1129{
1130 memcpy(pv, pvUsr, cb);
1131
1132 printf("fakeTKFuBuff: pv = %p, pvUsr = %p, cb = 0x%08x, fl = 0x%08x, rc = %d\n",
1133 pv, pvUsr, cb, fl, NO_ERROR);
1134
1135 return NO_ERROR;
1136}
1137
1138
1139/**
1140 * Copy system memory to user memory.
1141 * @returns OS/2 return code. (NO_ERROR is success)
1142 * @param pvUsr Pointer to target (user) data area.
1143 * @param pv Pointer to source (system) data area.
1144 * @param cb Count of bytes to copy.
1145 * @param fl Flags.
1146 * @status Partially implemented.
1147 * @remark Ignores fl. Crashes on error.
1148 */
1149ULONG KRNLCALL fakeTKSuBuff(PVOID pvUsr, PVOID pv, ULONG cb, ULONG fl)
1150{
1151 memcpy(pvUsr, pv, cb);
1152
1153 printf("fakeTKSuBuff: pvUsr = %p, pv = %p, cb = 0x%08x, fl = 0x%08x, rc = %d\n",
1154 pvUsr, pv, cb, fl, NO_ERROR);
1155
1156 return NO_ERROR;
1157}
1158
1159
1160/**
1161 * String length. (includes NULL(s))
1162 * @returns OS/2 return code. (NO_ERROR is success)
1163 * ERROR_TERMINATOR_NOT_FOUND
1164 * @param pcch Pointer to length variable.
1165 * @param pvUsr Pointer to user data to preform string length on.
1166 * @param cchMax Max string length.
1167 * @param fl Flags.
1168 * @param fDblNULL TRUE: Double '\0' (ie. '\0\0') terminated. Usefull for scanning environments.
1169 * FALSE: Single string. (ie. one '\0').
1170 * @status Partially implemented.
1171 * @remark Ignores fl. Crashes on error.
1172 */
1173ULONG KRNLCALL fakeTKFuBufLen(PLONG pcch, PVOID pvUsr, ULONG cchMax, ULONG fl, BOOL fDblNULL)
1174{
1175 ULONG rc;
1176 PSZ psz = pvUsr;
1177
1178 cchMax += (ULONG)pvUsr;
1179
1180 while ((ULONG)psz < cchMax)
1181 {
1182 if (*psz++ == '\0')
1183 if (!fDblNULL || (ULONG)psz == cchMax || *psz++ != '\0')
1184 break;
1185 }
1186
1187 *pcch = (ULONG)psz - (ULONG)pvUsr;
1188
1189 /* Hope this is the correct definition of max length: Not inclusive. */
1190 if ((ULONG)psz == cchMax)
1191 rc = ERROR_TERMINATOR_NOT_FOUND;
1192 else
1193 rc = NO_ERROR;
1194
1195 printf("fakeTKFuBufLen: pcch = %p; *pcch = 0x%08x, pvUsr = %p, cchMax = 0x%08x, fl = 0x%08x, fDblNULL = %x, rc = %d\n",
1196 pcch, *pcch, pvUsr, cchMax, fl, fDblNULL, NO_ERROR);
1197
1198 return rc;
1199}
1200
1201
1202/**
1203 * Copy user memory to user memory.
1204 * @returns OS/2 return code. (NO_ERROR is success)
1205 * @param pvUsr Pointer to target (user) data area.
1206 * @param pv Pointer to source (user) data area.
1207 * @param cb Count of bytes to copy.
1208 * @param fl Flags.
1209 * @status Partially implemented.
1210 * @remark Ignores fl. Crashes on error.
1211 */
1212ULONG KRNLCALL fakeTKSuFuBuff(PVOID pvTarget, PVOID pvSource, ULONG cb, ULONG fl)
1213{
1214 memcpy(pvTarget, pvSource, cb);
1215
1216 printf("fakeTKSuFuBuff: pvTarget = %p, pvSource = %p, cb = 0x%08x, fl = 0x%08x, rc = %d\n",
1217 pvTarget, pvSource, cb, fl, NO_ERROR);
1218
1219 return NO_ERROR;
1220}
1221
1222
1223/**
1224 * Validates an hMTE and gets the MTE pointer - FAKE.
1225 * @returns Pointer to MTE on success.
1226 * NULL on error.
1227 * @param hMTE MTE handle.
1228 * @remark If you wan't to this faster:
1229 * Use the hMTE as a HOB and get the HOB address (by using VMGetHandleInfo).
1230 * @status stub.
1231 */
1232PMTE LDRCALL fakeldrValidateMteHandle(HMTE hMTE)
1233{
1234 DUMMY();
1235
1236 printf("fakeldrValidateMteHandle: hMTE = 0x%04x, pMTE (rc) = %p\n",
1237 hMTE, NULL);
1238
1239 return NULL;
1240}
1241
1242
1243/**
1244 * C worker function for fakeg_tkExecPgm. This is called by fakeg_tkExecPgm (fakea.asm).
1245 * @returns OS/2 return code.
1246 * @param execFlag Exec flag (DosExecPgm execFlag).
1247 * @param pArg Pointer to arguments. (NULL allowed)
1248 * @param pEnv Pointer to environment. (NULL allowed)
1249 * @param pszFilename Pointer to filename.
1250 * @sketch
1251 * @status
1252 * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no)
1253 * @remark
1254 */
1255ULONG _Optlink tkExecPgmWorker(ULONG execFlag, PSZ pArg, PSZ pEnv, PSZ pszFilename)
1256{
1257 APIRET rc;
1258 ldrrei_t rei;
1259
1260 printf("tkExecPgmWorker: execFlag = %d, pArg = %p, pEnv = %p, pszFilename = %s\n", execFlag, pArg, pEnv, pszFilename);
1261
1262 /*
1263 * Take loader semaphore.
1264 */
1265 rc = KSEMRequestMutex(&fakeLdrSem, KSEM_INDEFINITE_WAIT);
1266 if (rc != NO_ERROR)
1267 {
1268 return rc;
1269 }
1270
1271 /*
1272 * Simulate loading.
1273 */
1274 rc = fakeLDRLoadExe(pszFilename, SSToDS(&rei));
1275
1276 NOREF(pArg);
1277 NOREF(pEnv);
1278 NOREF(execFlag);
1279
1280 return rc;
1281}
1282
1283
1284/**
1285 * Fake implementation of LDRLoadExe.
1286 * Not currently overriden, but used by tkExecPgmWorker to load executables.
1287 * @returns OS/2 return code.
1288 * @param pszFilename Name of executable image to load.
1289 * @param pEI It seems this is a pointer to a ldrrei_s struct.
1290 * (currently ignored)
1291 * @sketch
1292 * @status
1293 * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no)
1294 * @remark
1295 */
1296ULONG LDRCALL fakeLDRLoadExe(PSZ pszFilename, ldrrei_t *pEI)
1297{
1298 APIRET rc;
1299 int cchFilename = strlen(pszFilename);
1300
1301 printf("fakeLDRLoadExe: *entry* pszFilename = %s, pEI = %p\n",
1302 pszFilename, pEI);
1303
1304 rc = fakeldrGetModule(pszFilename, (cchFilename << 16) | (LVTYPE_EXE << 8) | CLASS_PROGRAM);
1305
1306 printf("fakeLDRLoadExe: *exit* pszFilename = %s, pEI = %p, rc = %d\n",
1307 pszFilename, pEI, rc);
1308
1309 return rc;
1310}
1311
1312
1313
1314/**
1315 * Fake implementeation of ldrGetModule.
1316 * Not currently overriden, but used by fakeLDRLoadExe to load executables.
1317 * @returns OS/2 return code.
1318 * @param pszFilename Name of executable image to load.
1319 * @param ul low 8 bits: Module CLASS_*.
1320 * high 8 bits: Executable type LVTYPE_* ?
1321 * high 16 bits: Filename length.
1322 * @sketch
1323 * OS/2 kernel seems to do:
1324 * Call Sec32GetModule
1325 * Call ldrGetMte which does the necessary loading / attaching.
1326 * Call ldrLoadImports for all imported DLLs. (and the exe?)
1327 * Call ldrProcessObjects for LX and ldrPreloadLDT for NE imported DLLs. (and the exe?)
1328 * Call ldrProcessImports.
1329 *
1330 * We do:
1331 * Call fakeldrGetMte.
1332 * Call fakeldrLoadImports.
1333 *
1334 * @status
1335 * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no)
1336 * @remark
1337 */
1338ULONG LDRCALL fakeldrGetModule(PSZ pszFilename, ULONG ul)
1339{
1340 APIRET rc;
1341 PMTE pmte = NULL;
1342
1343 printf("fakeldrGetModule: *entry* pszFilename = %s, ul = 0x%08x\n",
1344 pszFilename, ul);
1345
1346 rc = fakeldrGetMte(pszFilename, (USHORT)(ul >> 16), (UCHAR)((ul & 0xff00) >> 8), (UCHAR)(ul & 0x00ff), SSToDS(&pmte));
1347 if (rc == NO_ERROR)
1348 {
1349 rc = fakeldrLoadImports(pmte);
1350 }
1351
1352 printf("fakeldrGetModule: *exit* pszFilename = %s, ul = 0x%08x, rc = %d\n",
1353 pszFilename, ul, rc);
1354
1355 return rc;
1356}
1357
1358
1359/**
1360 *
1361 * @returns
1362 * @param
1363 * @equiv
1364 * @time
1365 * @sketch
1366 * OS/2 kernel seems to do:
1367 * IF not device driver THEN
1368 * Uppercase the name.
1369 * Call ldrFindModule to try find the module within currenly loaded modules.
1370 * ENDIF
1371 *
1372 * tryagain:
1373 * IF found THEN
1374 * Set MTEGETMTEDONE flag in mte_flags2.
1375 * Call ldrChkLoadType to ensure correct load type.
1376 * IF attached or special modules (DOSMOD, VDDMOD, FSHMOD or MVDMMOD)
1377 * IF miniIFS and !FSHMOD THEN Fail with rc=ERROR_INVALID_NAME
1378 * return successfully.
1379 * ENDIF
1380 * lv_sfn <- mte_sfn
1381 * Set the USED flag in mte_flags1
1382 * Set the MTELOADORATTACH flag in mte_flags2
1383 * Some processing of packed segments???? Dll init flags???
1384 * ELSE *not found*
1385 * IF class is CLASS_SPECIFIC AND ldrCheckGlobal returned TRUE THEN
1386 * * this is because some specific modules is promoted to global
1387 * * modules for some reasons I haven't ivestigated. (ldrPrmoteMTE)
1388 * tryagain.
1389 * ENDIF
1390 * Set some flag to false.
1391 * Calls to ldrOpenNewExe to load the exectuble from disk.
1392 * IF this failes THEN fail.
1393 * IF class is CLASS_GLOBAL and module is loaded as specific
1394 * (ldrCheckSpecific returns TRUE) THEN
1395 * Close and retry with the mte returned ldrCheckSpecific
1396 * tryagain.
1397 * ENDIF
1398 * Sets some local variable to point at pheaderbuf, where ldrOpenNewExe
1399 * has put the executable header.
1400 * Call ldrCheckLoadType and fail if this failes.
1401 * Call ldrCreateMte and fail if this failes.
1402 * Set some local variables to lv_pmte and lv_pmte->mte_swapmte.
1403 * Set the MTELOADORATTACH and MTEGETMTEDONE flags.
1404 * Call ldrInvTgtErrTxt.
1405 * IF DDInitTime AND DEVDRVMOD OR FSDMOD THEN
1406 * ptda_module of current PTDA to the mtehandle of the module.
1407 * ENDIF
1408 * IF DOSCALL1 (checks name) THEN
1409 * Set DOSLIB flag of mte_flags1.
1410 * Set global pmteDoscall1 to point to the mte.
1411 * Set global hmteDoscall1 to the handle of the mte.
1412 * ENDIF
1413 * ENDIF
1414 * IF VDDMOD THEN
1415 * call VDMMLoadingVDD with the mte handle.
1416 * ENDIF
1417 * IF NE executable THEN
1418 * Call ldrAllocSegments
1419 * ELSE
1420 * Call ldrAllocObjects
1421 * ENDIF
1422 * IF failed THEN fail.
1423 * IF LVTYPE_EXE THEN
1424 * Set the ptda_module of the ExecChild PTDA to mtehandle.
1425 * IF MTELONGNAMES THEN
1426 * Set ptda_NewFiles to something.
1427 * ENDIF
1428 * Increment usage count, ie. mte_usecnt-
1429 * ELSE IF LVTYPE_DLL AND !somelocalflag AND NOINTERNFIXUPS THEN
1430 * Remove Internal fixups?
1431 * (Calls ldrIsInternalFixup and VMReallocKHB during this processing.)
1432 * ENDIF
1433 * Clears the MTEPROCESSED flag of mte_flags1.
1434 * Sets the return mte pointer. (ppmte)
1435 * return successfully.
1436 *
1437 * We do:
1438 * Uppercase the string. (do we have to switch stack?)
1439 * Call fakeldrOpenNewExe to do it's work.
1440 * Call fakeldrCreateMte to create a fake mte.
1441 * return.
1442 *
1443 * @status
1444 * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no)
1445 * @remark
1446 */
1447ULONG LDRCALL fakeldrGetMte(PCHAR pachFilename, USHORT cchFilename, UCHAR fchType, UCHAR fchClass, PPMTE ppmte)
1448{
1449 ldrlv_t lv;
1450 APIRET rc;
1451
1452 printf("fakeldrGetMte: *entry* pachFilename = %.*s, cchFilename = %#02x, fchType %#2x, fchClass = %#2x, ppmte = %p\n",
1453 cchFilename, pachFilename, cchFilename, fchType, fchClass, ppmte);
1454
1455 /*
1456 * Initiate the local variables.
1457 */
1458 memset(SSToDS(&lv), 0, sizeof(lv));
1459 lv.lv_sfn = (USHORT)-1;
1460 lv.lv_type = fchType;
1461 lv.lv_class = fchClass;
1462
1463 /*
1464 * Uppercase the string.
1465 */
1466 fakeldrUCaseString(pachFilename, cchFilename);
1467
1468 /*
1469 * Open the new executable.
1470 */
1471 rc = fakeldrOpenNewExe(pachFilename, cchFilename, SSToDS(&lv), NULL);
1472 if (rc != NO_ERROR)
1473 {
1474 fakeldrClose(lv.lv_sfn);
1475 printf("fakeldrGetMte: *exit* pachFilename = %.*s, ppmte = %p; *ppmte = %p, rc = %d\n",
1476 cchFilename, pachFilename, ppmte, *ppmte, rc);
1477 return rc;
1478 }
1479
1480 /*
1481 * Create MTE for the opened file.
1482 */
1483 rc = fakeldrCreateMte(pheaderbuf, SSToDS(&lv));
1484 if (rc == NO_ERROR)
1485 {
1486 /*
1487 * Set some flags... More?
1488 */
1489 lv.lv_pmte->mte_flags2 |= MTEGETMTEDONE | MTELOADORATTACH;
1490 *ppmte = lv.lv_pmte;
1491 }
1492
1493 printf("fakeldrGetMte: *exit* pachFilename = %.*s, ppmte = %p; *ppmte = %p, rc = %d\n",
1494 cchFilename, pachFilename, ppmte, *ppmte, rc);
1495
1496 return rc;
1497}
1498
1499
1500
1501/**
1502 * Opens an executable module.
1503 * @returns OS2 error code.
1504 * @param pachFilename Filename of the executable module to open.
1505 * @param cchFilename Filename length.
1506 * @param plv Pointer to local variables.
1507 * @param pus Pointer to some flags (LDRQAppType flags?!).
1508 * @sketch
1509 * OS/2 kernel seems to do:
1510 * Call ldrOpenPath to open the file.
1511 * IF this fail THEN
1512 * Set lv_sfn to -1 and return errorcode.
1513 * ENDIF
1514 * Set local variable to pheaderbuf.
1515 * IF pus THEN set *pus to 1
1516 * Call ldrRead to read the MZ header.
1517 * Fail if this failed. (Don't close file caller does that.)
1518 * IF LXMAGIC of NEMAGIC found THEN
1519 * lv_new_exe_off <- 0;
1520 * ELSE
1521 * IF !EMAGIC or 'OZ' THEN
1522 * Fail with rc=ERROR_INVALID_EXE_SIGNATURE.
1523 * ENDIF
1524 * IF pus THEN set *pus to 2.
1525 * lv_new_exe_off <- e_lfanew.
1526 * ENDIF
1527 * Call ldrRead to read LX/NE header at lv_new_exe_off.
1528 * Fail if this failed.
1529 * IF NOT LXMAGIC OR NEMAGIC THEN
1530 * IF LEMAGIC AND pus THEN Set *pus to 0.
1531 * IF PEMAGIC and pus THEN Set *pus to 3.
1532 * Fail with rc=ERROR_INVALID_EXE_SIGNATURE.
1533 * ENDIF
1534 * IF pus THEN Set *pus to 0.
1535 * IF invalid LX exeheader THEN
1536 * Fail with rc=ERROR_INVALID_EXE_SIGNATURE.
1537 * ENDIF
1538 * IF NEMAGIC THEN
1539 * Call ldrExpandHeader
1540 * ELSE
1541 * Set the MTELONGNAMES flag in e32_mflags.
1542 * ENDIF
1543 * IF LDRINVALID (in e32_mflags) THEN
1544 * Fail with rc=ERROR_EXE_MARKED_INVALID.
1545 * ENDIF
1546 * Clear some e32_mflags, MTE_MEDIAFIXED, MTEMEDIACONTIG and MTEMEDIA16M.
1547 * Or in flags set by ldrOpenPath into e32_mflags. (media type flags?!)
1548 * Call ldrMungeFlags
1549 * return retur code from ldrMungeFlags.
1550 *
1551 * We do:
1552 * Call fakeldrOpenPath to open the file.
1553 * IF this fail THEN
1554 * Set lv_sfn to -1 and return errorcode.
1555 * ENDIF
1556 * IF pus THEN set *pus to 1
1557 * Call ldrRead to read the MZ header.
1558 * Fail if this failed. (Don't close file caller does that.)
1559 * If MZ header Then
1560 * Set lv_new_exe_off to e_lfanew.
1561 * else
1562 * Set lv_new_exe_off to 0.
1563 * Call ldrRead to read the LX header.
1564 * Fail if this failed. (Don't close file caller does that.)
1565 * If Not LX signature Then
1566 * Fail.
1567 * return successfully.
1568 *
1569 * @status
1570 * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no)
1571 * @remark
1572 */
1573ULONG LDRCALL fakeldrOpenNewExe(PCHAR pachFilename, USHORT cchFilename, ldrlv_t *plv, PUSHORT pus)
1574{
1575 APIRET rc;
1576 ULONG ful;
1577
1578 printf("fakeldrOpenNewExe: *entry* pachFilename = %.*s, cchFilename = %#2, plv = %p, pus = %p\n",
1579 cchFilename, pachFilename, cchFilename, plv, pus);
1580
1581 rc = fakeldrOpenPath(pachFilename, cchFilename, plv, SSToDS(&ful), 1);
1582 if (rc != NO_ERROR)
1583 {
1584 plv->lv_sfn = 0xffff;
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 if (pus) *pus = 1;
1590
1591 memset(pheaderbuf, 0, sizeof(struct exe_hdr)); //zero it just in case....
1592 rc = fakeldrRead(plv->lv_sfn, 0, pheaderbuf, 0, sizeof(struct exe_hdr), NULL);
1593 if (rc != NO_ERROR)
1594 {
1595 plv->lv_sfn = 0xffff;
1596 printf("fakeldrOpenNewExe: *exit* pachFilename = %.*s, plv->lv_sfn = %#4x, rc = %d\n",
1597 cchFilename, pachFilename, plv->lv_sfn, rc);
1598 return rc;
1599 }
1600
1601 if (*(PUSHORT)pheaderbuf == EMAGIC)
1602 plv->lv_new_exe_off = ((struct exe_hdr *)pheaderbuf)->e_lfanew;
1603 else
1604 plv->lv_new_exe_off = 0;
1605
1606 memset(pheaderbuf, 0, sizeof(struct e32_exe)); //zero it just in case....
1607 rc = fakeldrRead(plv->lv_sfn, plv->lv_new_exe_off, pheaderbuf, 0, sizeof(struct e32_exe), NULL);
1608 if (rc != NO_ERROR)
1609 {
1610 plv->lv_sfn = 0xffff;
1611 printf("fakeldrOpenNewExe: *exit* pachFilename = %.*s, plv->lv_sfn = %#4x, rc = %d\n",
1612 cchFilename, pachFilename, plv->lv_sfn, rc);
1613 return rc;
1614 }
1615
1616 if (*(PUSHORT)pheaderbuf != E32MAGIC)
1617 {
1618 plv->lv_sfn = 0xffff;
1619 rc = ERROR_INVALID_EXE_SIGNATURE;
1620 printf("fakeldrOpenNewExe: *exit* pachFilename = %.*s, plv->lv_sfn = %#4x, rc = %d\n",
1621 cchFilename, pachFilename, plv->lv_sfn, rc);
1622 return rc;
1623 }
1624
1625 printf("fakeldrOpenNewExe: *exit* pachFilename = %.*s, plv->lv_sfn = %#4x, rc = %d\n",
1626 cchFilename, pachFilename, plv->lv_sfn, rc);
1627
1628 return NO_ERROR;
1629}
1630
1631
1632/**
1633 * Fake ldrCreateMte implementation.
1634 * @returns
1635 * @param pe32 Pointer to the LX/NE header we've just read.
1636 * @param plv Pointer to local variables.
1637 * @sketch !This does a lot of thing!
1638 *
1639 * OS/2 Kernel seems to do:
1640 * Allocate a kernel heap block for the MTE
1641 *
1642 *
1643 *
1644 *
1645 *
1646 *
1647 *
1648 *
1649 *
1650 *
1651 * We do:
1652 *
1653 *
1654 * @status
1655 * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no)
1656 * @remark
1657 */
1658ULONG LDRCALL fakeldrCreateMte(struct e32_exe *pe32, ldrlv_t *plv)
1659{
1660 ULONG rc;
1661 PMTE pMte;
1662 PSMTE pSMte;
1663 PCHAR pch;
1664
1665 printf("fakeldrCreateMte: *entry* pe32 = %p, plv = %d\n",
1666 pe32, plv);
1667
1668 /*
1669 * Allocate mte and smte.
1670 * The MTE has an array of mte pointers at the end for imported modules + 1.
1671 * The SMTE has the fullpath filename, loader section and fixup section.
1672 */
1673 pMte = malloc(sizeof(MTE) + sizeof(PMTE) + sizeof(PMTE)*pe32->e32_impmodcnt);
1674 if (pMte == NULL)
1675 {
1676 rc = ERROR_NOT_ENOUGH_MEMORY;
1677 goto createmte_exit;
1678 }
1679
1680 plv->lv_csmte = sizeof(SMTE) + 260 + pe32->e32_ldrsize + pe32->e32_fixupsize;
1681 pSMte = malloc(plv->lv_csmte);
1682 if (pSMte == NULL)
1683 {
1684 rc = ERROR_NOT_ENOUGH_MEMORY;
1685 goto createmte_exit;
1686 }
1687 pch = (PCHAR)(PVOID)pSMte + sizeof(SMTE) + 260;
1688
1689
1690 /*
1691 * Initialize the MTE.
1692 */
1693 pMte->mte_flags2 = MTEFORMATLX;
1694 pMte->mte_handle = 20;
1695 pMte->mte_swapmte = pSMte;
1696 pMte->mte_link = NULL;
1697 pMte->mte_flags1 = pe32->e32_mflags;
1698 pMte->mte_impmodcnt = pe32->e32_impmodcnt;
1699 pMte->mte_sfn = plv->lv_sfn;
1700 pMte->mte_usecnt = 0;
1701 pMte->mte_modname[0]= '\0';
1702
1703 /*
1704 * Initialize the SMTE.
1705 */
1706 pSMte->smte_mpages = pe32->e32_mpages;
1707 /*- magic,border,worder,level,cpu,os,ver,mflags */
1708 pSMte->smte_mpages = pe32->e32_mpages; /* 00 Module # pages */
1709 pSMte->smte_startobj = pe32->e32_startobj; /* 04 Object # for instruction */
1710 pSMte->smte_eip = pe32->e32_eip; /* 08 Extended instruction pointer */
1711 pSMte->smte_stackobj = pe32->e32_stackobj; /* 0c Object # for stack pointer */
1712 pSMte->smte_esp = pe32->e32_esp; /* 10 Extended stack pointer */
1713 /*- pagesize*/
1714 pSMte->smte_pageshift = pe32->e32_pageshift; /* 14 Page alignment shift in .EXE */
1715 pSMte->smte_fixupsize = pe32->e32_fixupsize; /* 18 Fixup section size */
1716 /*- fixupsum,ldrsize,ldrsum*/
1717 pSMte->smte_objtab = (POTE)pe32->e32_objtab; /* 1c Object table offset - POINTER */
1718 pSMte->smte_objcnt = pe32->e32_objcnt; /* 20 Number of objects in module */
1719 pSMte->smte_objmap = pe32->e32_objmap; /* 24 Object page map offset - POINTER */
1720 pSMte->smte_itermap = pe32->e32_itermap; /* 28 Object iterated data map offset */
1721 pSMte->smte_rsrctab = pe32->e32_rsrctab; /* 2c Offset of Resource Table */
1722 pSMte->smte_rsrccnt = pe32->e32_rsrccnt; /* 30 Number of resource entries */
1723 pSMte->smte_restab = pe32->e32_restab; /* 34 Offset of resident name table - POINTER */
1724 pSMte->smte_enttab = pe32->e32_enttab; /* 38 Offset of Entry Table - POINTER */
1725 pSMte->smte_fpagetab = pe32->e32_fpagetab; /* 3c Offset of Fixup Page Table - POINTER */
1726 pSMte->smte_frectab = pe32->e32_frectab; /* 40 Offset of Fixup Record Table - POINTER */
1727 pSMte->smte_impmod = pe32->e32_impmod; /* 44 Offset of Import Module Name Table - POINTER */
1728 /*- impmodcnt*/
1729 pSMte->smte_impproc = pe32->e32_impproc; /* 48 Offset of Imp Procedure Name Tab - POINTER */
1730 /*- pagesum*/
1731 pSMte->smte_datapage = pe32->e32_datapage; /* 4c Offset of Enumerated Data Pages */
1732 /*- preload*/
1733 pSMte->smte_nrestab = pe32->e32_nrestab; /* 50 Offset of Non-resident Names Table */
1734 pSMte->smte_cbnrestab = pe32->e32_cbnrestab; /* 54 Size of Non-resident Name Table */
1735 /*- nressum*/
1736 pSMte->smte_autods = pe32->e32_autodata; /* 58 Object # for automatic data object */
1737 pSMte->smte_debuginfo = pe32->e32_debuginfo; /* 5c Offset of the debugging info */
1738 pSMte->smte_debuglen = pe32->e32_debuglen; /* 60 The len of the debug info in */
1739 /*- instpreload,instdemand*/
1740 pSMte->smte_heapsize = pe32->e32_heapsize; /* 64 use for converted 16-bit modules */
1741 /*- res3*/
1742 /* extra */
1743 pSMte->smte_path = 0; /* 68 full pathname - POINTER */
1744 pSMte->smte_semcount = 0; /* 6c Count of threads waiting on MTE semaphore. 0 => semaphore is free */
1745 pSMte->smte_semowner = 0; /* 6e Slot number of the owner of MTE semahore */
1746 pSMte->smte_pfilecache = 0; /* 70 Pointer to file cache for Dos32CacheModule */
1747 pSMte->smte_stacksize = 0; /* 74 Thread 1 Stack size from the exe header */
1748 pSMte->smte_alignshift = 0; /* 78 use for converted 16-bit modules */
1749 pSMte->smte_NEexpver = 0; /* 7a expver from NE header */
1750 pSMte->smte_pathlen = 0; /* 7c length of full pathname */
1751 pSMte->smte_NEexetype = 0; /* 7e exetype from NE header */
1752 pSMte->smte_csegpack = 0; /* 80 count of segs to pack */
1753
1754 /*
1755 * Copy filename (from where?)
1756 */
1757 pSMte->smte_path = (PCHAR)(PVOID)pSMte + sizeof(SMTE);
1758 pSMte->smte_pathlen = 0;
1759 memcpy(pSMte->smte_path, "", pSMte->smte_pathlen);
1760
1761
1762 /*
1763 * Read loader and fixup sections.
1764 */
1765 rc = fakeldrRead(plv->lv_sfn,
1766 (ULONG)pSMte->smte_objtab + plv->lv_new_exe_off,
1767 pch,
1768 0,
1769 pe32->e32_ldrsize + pe32->e32_fixupsize,
1770 NULL);
1771 if (rc)
1772 {
1773 goto createmte_exit;
1774 }
1775
1776 /*
1777 * Set pointers.
1778 */
1779 pSMte->smte_objtab = (POTE)(PVOID)pch;
1780 rc = fakeldrMTEValidatePtrs(pSMte,
1781 (ULONG)pch + plv->lv_csmte,
1782 (ULONG)pch - (ULONG)pe32->e32_objtab);
1783 if (rc)
1784 {
1785 goto createmte_exit;
1786 }
1787
1788 /*
1789 * Set mte pointer in plv.
1790 * Set hobmte in plv.
1791 */
1792 plv->lv_pmte = pMte;
1793 plv->lv_hobmte = pMte->mte_handle;
1794
1795 /*
1796 * Fix flags...
1797 */
1798 pMte->mte_flags1 |= plv->lv_class;
1799
1800createmte_exit:
1801 printf("fakeldrCreateMte: *exit* pe32 = %p, plv = %d, rc = %d\n",
1802 pe32, plv, rc);
1803
1804 return rc;
1805}
1806
1807
1808
1809/**
1810 * Fake ldrLoadImports - loads the import modules for the given module (pmte).
1811 * @returns OS2 error code.
1812 * @param pmte Pointer to mte to load imports for.
1813 * @sketch
1814 * OS/2 kernel seems to do:
1815 * Loop thru the importe module table (reverse order for NE files)
1816 * IF VDD module THEN
1817 * Uppercase the name.
1818 * try find it using ldrFindModule
1819 * fail if error, not found, not VDDMOD/MVDMMOD.
1820 * Add to array of imported module.
1821 * ENDIF
1822 * IF Not found OR !MTEGETMTEDONE THEN
1823 * call ldrGetMte to load the module (class global).
1824 * fail if error.
1825 * set MTEGETMTEDONE
1826 * Add to array of imported module.
1827 * ENDIF
1828 * IF DOSMOD and !ldrMiniFileIOFlag THEN
1829 * Replace module pointer with doscall1 pmte.
1830 * ENDIF
1831 * ENDLOOP
1832 *
1833 * We do:
1834 * Parameter validation.
1835 * Loop thru the imported module table issuing fakeldrGetMte on each entry.
1836 * 'DOSCALLS' is ignored.
1837 *
1838 * @status
1839 * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no)
1840 * @remark
1841 */
1842ULONG LDRCALL fakeldrLoadImports(PMTE pmte)
1843{
1844 int i; /* Module index. */
1845 PSZ psz; /* Module name pointer. (really pointer to pascal strings...) */
1846 PPMTE papmte; /* Pointer to array of PMTEs for imported modules. */
1847 APIRET rc;
1848
1849 printf("fakeldrLoadImport: *entry* pmte = %p, pmte->mte_impmodcnt = %d\n",
1850 pmte, pmte->mte_impmodcnt);
1851
1852 /*
1853 * Parameter validation.
1854 */
1855 if (pmte == NULL)
1856 {
1857 kprintf(("fakeldrLoadImports: !ASSERTION! pmte == NULL\n"));
1858 return ERROR_INVALID_PARAMETER;
1859 }
1860 if (pmte->mte_swapmte == NULL)
1861 {
1862 kprintf(("fakeldrLoadImports: !ASSERTION! pmte->mte_swapmte == NULL\n"));
1863 return ERROR_INVALID_PARAMETER;
1864 }
1865
1866 /*
1867 * Any imported modules?
1868 */
1869 if (pmte->mte_impmodcnt == 0)
1870 {
1871 printf("fakeldrLoadImport: *exit* pmte = %p, rc = %d\n",
1872 pmte, rc);
1873 return NO_ERROR;
1874 }
1875
1876 /* We have reserved space for imported module pointers after the mte. */
1877 papmte = (PPMTE)((unsigned)pmte + sizeof(MTE));
1878
1879 /*
1880 * Process the imported module table.
1881 */
1882 for (i = 0, rc = NO_ERROR, psz = (PSZ)pmte->mte_swapmte->smte_impmod;
1883 i < pmte->mte_impmodcnt && rc == NO_ERROR;
1884 i++, psz += 1 + *psz)
1885 {
1886 if (*psz == 8 && !strnicmp(psz+1, "DOSCALLS", 8))
1887 continue;
1888
1889 rc = fakeldrGetMte(psz + 1, *psz, LVTYPE_DLL, CLASS_GLOBAL, &papmte[i]);
1890 }
1891
1892 printf("fakeldrLoadImport: *exit* pmte = %p, rc = %d\n",
1893 pmte, rc);
1894
1895 return rc;
1896}
1897
1898
1899/**
1900 * Checks if the internal name (first name in the resident nametable) matches
1901 * the filename.
1902 * @returns NO_ERROR on success (the name matched).
1903 * ERROR_INVALID_NAME if mismatch.
1904 * @param pMTE Pointer to the MTE of the module to check.<br>
1905 * Assumes! that the filename for this module is present in ldrpFileNameBuf.
1906 */
1907ULONG LDRCALL fakeldrCheckInternalName(PMTE pMTE)
1908{
1909 PCHAR pachName; /* Pointer to the name part of pachFilename. */
1910 int cchName; /* Length of the name part of pachFilename.
1911 * Includes extention if extention is not .DLL.
1912 * this is the length relative to pachName used to match the internal name. */
1913 PCHAR pachExt; /* Pointer to the extention part of pachFilename. (not dot!) */
1914 int cchExt; /* Length of the extention part of pachFilename. (not dot!) */
1915
1916
1917 /* Return successfully if not library module. */
1918 if (!(pMTE->mte_flags1 & LIBRARYMOD))
1919 return NO_ERROR;
1920
1921 /* Uppercase and parse filename in ldrpFileNameBuf */
1922 cchName = (int)fakeldrGetFileName(ldrpFileNameBuf, (PCHAR*)SSToDS(&pachName), (PCHAR*)SSToDS(&pachExt));
1923 cchExt = (pachExt) ? strlen(pachExt) : 0;
1924 ldrUCaseString(pachName, cchName + cchExt + 1);
1925
1926 /* Compare the internal name with the filename and return accordingly. */
1927 return ( cchName <= 8
1928 && !memcmp(pMTE->mte_modname, pachName, cchName)
1929 && (cchName == 8 || pMTE->mte_modname[cchName] == '\0')
1930 )
1931 ? NO_ERROR
1932 : ERROR_INVALID_NAME;
1933}
1934
1935
1936/**
1937 * Translates a relative filename to a full qualified filename.
1938 * @returns NO_ERROR on success.
1939 * Errorcode on error.
1940 * @param pszFilename Pointer to nullterminated filename.
1941 */
1942ULONG LDRCALL fakeldrTransPath(PSZ pszFilename)
1943{
1944 return fakeIOSftTransPath(pszFilename);
1945}
1946
1947
1948/**
1949 * Parses a filename to find the name and extention.
1950 * @returns Length of the filename without the extention.
1951 * @param pachFilename Pointer to filename to parse - must have path!
1952 * @param ppachName Pointer to pointer which should hold the name pointer upon successfull return.
1953 * @param ppachExt Pointer to pointer which should hold the extention pointer upon successfull return.
1954 */
1955ULONG LDRCALL fakeldrGetFileName(PSZ pszFilename, PCHAR *ppchName, PCHAR *ppchExt)
1956{
1957 int cchName;
1958 PSZ pchName;
1959 PSZ pchExt = NULL;
1960
1961 while (*pszFilename)
1962 {
1963 if (*pszFilename == '\\' || *pszFilename == '/')
1964 pchName = pszFilename + 1;
1965 else if (*pszFilename == '.')
1966 pchExt = pszFilename + 1;
1967 pszFilename++;
1968 }
1969
1970 cchName = (pchExt <= pchName) ? strlen(pchName) : pchExt - pchName - 1;
1971 *ppchExt = pchExt;
1972 *ppchName = pchName;
1973
1974 return cchName;
1975}
1976
1977
1978/**
1979 * Uppercases the string.
1980 * @param pachString String to uppercase.
1981 * @param cchString Length of string.
1982 * @sketch Loop thru the string converting all english letters to uppercase.
1983 * @status partially implemented.
1984 * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no)
1985 * @remark This is probably written in assembly and does DBCS checks...
1986 */
1987VOID LDRCALL fakeldrUCaseString(PCHAR pachString, unsigned cchString)
1988{
1989 printf("fakeldrUCaseString: pachString = %.*s, cchString = %#8x\n",
1990 cchString, pachString, cchString);
1991
1992 while (cchString-- != 0)
1993 {
1994 if (*pachString >= 'a' && *pachString <= 'z')
1995 *pachString -= ('a' - 'A');
1996 pachString++;
1997 }
1998}
1999
2000
2001
2002
2003/**
2004 * Checks and updates the members of the swap-mte which is to be
2005 * pointers into the loader/fixup section. An array, validatetbl, contains
2006 * the offsets of the smte pointers.
2007 *
2008 * @returns NO_ERROR on success.
2009 * ERROR_BAD_EXE_FORMAT on error.
2010 * @param psmte
2011 * @param ulMaxAddr Maximum (exclusive) address.
2012 * @param off Offset delta to add to the pointer members (which
2013 * are all offsets relative to the start of the new
2014 * header) to make them pointers.
2015 * @sketch
2016 * Loop thru the validatetbl and update each field (which isn't null) by adding
2017 * the off value, and validate that the pointer is ok.
2018 * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no)
2019 * @remark
2020 */
2021ULONG LDRCALL fakeldrMTEValidatePtrs(PSMTE psmte, ULONG ulMaxAddr, ULONG off)
2022{
2023 int i;
2024
2025 printf("fakeldrMTEValidatePtrs: *entry* psmte = %p, ulMaxAddr = %p, off = %p\n",
2026 psmte, ulMaxAddr, off);
2027
2028 for (i = 0; validatetbl[i] != 0xDEAD; i++)
2029 {
2030 PULONG pul = (PULONG)(PVOID)((PCHAR)(PVOID)psmte + validatetbl[i]);
2031 if (*pul != 0UL)
2032 {
2033 *pul += off;
2034 if (*pul >= ulMaxAddr)
2035 {
2036 printf("fakeldrMTEValidatePtrs: *exit* psmte = %p, ulMaxAddr = %p, off = %p, rc = %d\n",
2037 psmte, ulMaxAddr, off, ERROR_BAD_EXE_FORMAT);
2038 return ERROR_BAD_EXE_FORMAT;
2039 }
2040 }
2041 }
2042
2043 printf("fakeldrMTEValidatePtrs: *exit* psmte = %p, ulMaxAddr = %p, off = %p, rc = %d\n",
2044 psmte, ulMaxAddr, off, NO_ERROR);
2045 return NO_ERROR;
2046}
2047
2048
2049PMTE KRNLCALL fakeldrASMpMTEFromHandle(HMTE hMTE)
2050{
2051 PMTE pMte = (PMTE)hMTE;
2052
2053 pMte += 10; //just do something!
2054
2055 return NULL;
2056}
2057
2058ULONG LDRCALL fakeldrFindModule(PCHAR pachFilename, USHORT cchFilename, USHORT usClass, PPMTE ppMTE)
2059{
2060 APIRET rc = NO_ERROR;
2061 usClass = usClass;
2062 cchFilename = cchFilename;
2063 pachFilename = pachFilename;
2064 *ppMTE = NULL;
2065 return rc;
2066}
2067
2068
2069/**
2070 * Gets the path (name with fully qualified path) from a SFN.
2071 * @returns Pointer to the path of hFile.
2072 * @param hFile SFN filehandle.
2073 */
2074PSZ SECCALL fakeSecPathFromSFN(SFN hFile)
2075{
2076 BOOL f32Stack = ((int)&hFile > 0x10000);
2077
2078 if (!f32Stack) ThunkStack16To32();
2079
2080
2081 if (!f32Stack) ThunkStack32To16();
2082
2083 printf("fakeSecPathFromSFN: - not implemented - hFile = 0x%04x\n", hFile);
2084
2085 return NULL;
2086}
2087
2088/**
2089 * PID to PTDA pointer.
2090 * @returns OS/2 return code.
2091 * @param pid Process Identifier.
2092 * @param ppPTDA Pointer to the PTDA-pointer variabel which is to receive
2093 * the PTDA pointer on successful return.
2094 */
2095ULONG KRNLCALL fakeTKPidToPTDA(PID pid, PPPTDA ppPTDA)
2096{
2097 DUMMY();
2098 printf("fakeTKPidToPTDA: - not implemented - pid = 0x%04x, ppPTDA=%p\n", pid, ppPTDA);
2099 return ERROR_NOT_SUPPORTED;
2100}
2101
2102/**
2103 * Force a thread to be made ready.
2104 * @param flFlag Which flag(s?) to set.
2105 * @param pTCB Pointer to the thread control block of the thread to be forced.
2106 */
2107void KRNLCALL fakeTKForceThread(ULONG flFlag, PTCB pTCB)
2108{
2109 DUMMY();
2110 printf("fakeTKForceThread: - not implemented\n");
2111}
2112
2113/**
2114 * Set force flag on a task.
2115 * @param flFlag Which flag(s?) to set.
2116 * @param pPTDA Pointer to the PTDA of the task to be processed.
2117 * @param fForce FALSE Just set the flag on all threads.
2118 * TRUE Force all threads ready by calling TKForceThread.
2119 */
2120void KRNLCALL fakeTKForceTask(ULONG flFlag, PPTDA pPTDA, BOOL fForce)
2121{
2122 DUMMY();
2123 printf("fakeTKForceTask: - not implemented\n");
2124}
2125
2126/**
2127 * Get priotity of a thread.
2128 * @returns Thread priority.
2129 * @param pTCB pointer to the TCB of the thread in question.
2130 */
2131ULONG KRNLCALL fakeTKGetPriority(PTCB pTCB)
2132{
2133 DUMMY();
2134 printf("fakeTKGetPriority: - not implemented\n");
2135 return -1;
2136}
2137
2138/**
2139 * Make current thread sleep.
2140 * @returns NO_ERROR on success.
2141 * ERROR_INTERRUPT if a signal is forced on the thread.
2142 * ERROR_TIMEOUT if we timeout.
2143 * @param ulSleepId 32-bit sleep id which TKWakeup will be called with.
2144 * @param ulTimeout Number of milliseconds to sleep. (0 is not yield)
2145 * -1 means forever or till wakeup.
2146 * @param fUnint TRUE: may not interrupt sleep.
2147 * FALSE: may interrupt sleep.
2148 * @param flSleepType ???
2149 */
2150ULONG KRNLCALL fakeTKSleep(ULONG ulSleepId, ULONG ulTimeout, ULONG fUnInterruptable, ULONG flWakeupType)
2151{
2152 DUMMY();
2153 printf("fakeTKSleep: - not implemented\n");
2154 return ERROR_NOT_SUPPORTED;
2155}
2156
2157/**
2158 * Wakeup sleeping thread(s).
2159 * @returns NO_ERROR on succes.
2160 * Appropriate error code on failure.
2161 * @param ulSleepId 32-bit sleep id which threads are sleeping on.
2162 * @param flWakeUpType How/what to wakeup.
2163 * @param pcWakedUp Pointer to variable which is to hold the count of
2164 * thread waked up.
2165 */
2166ULONG KRNLCALL fakeTKWakeup(ULONG ulSleepId, ULONG flWakeupType, PULONG cWakedUp)
2167{
2168 DUMMY();
2169 printf("fakeTKWakeup: - not implemented\n");
2170 return ERROR_NOT_SUPPORTED;
2171}
2172
2173
2174/**
2175 * Wake up a single thread.
2176 * @returns NO_ERROR on succes.
2177 * Appropriate error code on failure.
2178 * @param pTCB Pointer to the TCB of the thread to be waken.
2179 */
2180ULONG KRNLCALL fakeTKWakeThread(PTCB pTCB)
2181{
2182 DUMMY();
2183 printf("fakeTKWakeThread: - not implemented\n");
2184 return ERROR_NOT_SUPPORTED;
2185}
2186
2187/**
2188 * See which thread will be Wakeup.
2189 * @returns Pointer to TCB of the thread on success.
2190 * NULL on failure or no threads.
2191 * @param ulSleepId 32-bit sleep id which threads are sleeping on.
2192 * @param flWakeUpType How/what to wakeup.
2193 */
2194PTCB KRNLCALL fakeTKQueryWakeup(ULONG ulSleepId, ULONG flWakeupType)
2195{
2196 DUMMY();
2197 printf("fakeTKQueryWakeup: - not implemented\n");
2198 return ERROR_NOT_SUPPORTED;
2199}
2200
2201/**
2202 * Returns the number of bytes of physical memory available.
2203 */
2204ULONG KRNLCALL fakePGPhysAvail(void)
2205{
2206 DUMMY();
2207 printf("fakePGPhysAvail - returns 0x234563\n");
2208 return 0x234563;
2209}
2210
2211
2212/**
2213 * Returns the number of pageframes currently in use.
2214 */
2215ULONG KRNLCALL fakePGPhysPresent(void)
2216{
2217 DUMMY();
2218 printf("fakePGPhysPresent - returns 0x123534\n");
2219 return 0x123534;
2220}
2221
2222
2223/**
2224 * This function seems to find the top of the private arena.
2225 * And for high arena kernels (AURORA and W3SMP?) it is modified
2226 * to calc the top of the high private arena, given flFlag = 4.
2227 * --
2228 * This function is really intented for resizing / recaling the size of
2229 * the shared arena(s). But, it's useful for finding the highest used
2230 * private arena(s).
2231 * @param flFlags VMRSBF_* flags.
2232 * @param pulSentinelAddress Pointer to return variable (optional).
2233 */
2234VOID KRNLCALL fakevmRecalcShrBound(
2235 ULONG flFlags,
2236 PULONG pulSentinelAddress)
2237{
2238 ULONG ulRet;
2239 DUMMY();
2240
2241 if ((flFlags & 6) == 0)
2242 { /* shared tiled memory */
2243 ulRet = 128*1024*1024;
2244 }
2245 else
2246 {
2247 ulRet = 0x2c000000;
2248 if (_usFakeVerMinor < 45) /* bad emulation for Warp 3 SMP - FIXME */
2249 printf("fakePGPhysPresent - error: bad flags for non-highmem OS/2 versionn");
2250 }
2251
2252 if (pulSentinelAddress)
2253 *pulSentinelAddress = ulRet;
2254
2255 printf("fakePGPhysPresent - returns %x - flFlags=0x%02x, pulSentinelAddress=0x%08x\n",
2256 ulRet, flFlags, pulSentinelAddress);
2257
2258 return;
2259}
2260
2261
Note: See TracBrowser for help on using the repository browser.