source: trunk/src/win32k/kKrnlLib/tools/kDevTest/kdtLoad.c

Last change on this file was 9311, checked in by bird, 23 years ago

Initial coding.

File size: 31.7 KB
Line 
1/* $Id: kdtLoad.c,v 1.1 2002-09-30 23:53:54 bird Exp $
2 *
3 * Ring-3 Device Testing: Loader and Load Hacks.
4 *
5 * Copyright (c) 2000-2002 knut st. osmundsen <bird@anduin.net>
6 *
7 *
8 * This file is part of kKrnlLib.
9 *
10 * kKrnlLib is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * kKrnlLib is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with kKrnlLib; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 *
24 */
25
26
27/*******************************************************************************
28* Defined Constants And Macros *
29*******************************************************************************/
30#define DWORD ULONG
31#define WORD USHORT
32#define FOR_EXEHDR 1
33
34
35/*******************************************************************************
36* Header Files *
37*******************************************************************************/
38#define INCL_BASE
39#include <os2.h>
40#include <exe386.h>
41
42#include <stdio.h>
43#include <string.h>
44#include <stdlib.h>
45
46#include "kDevTest.h"
47
48#ifndef QS_MTE
49/*******************************************************************************
50* From the OS/2 4.5 toolkit. *
51*******************************************************************************/
52/* defines and structures for DosQuerySysState */
53#pragma pack(1)
54/* record types */
55#define QS_PROCESS 0x0001
56#define QS_SEMAPHORE 0x0002
57//#define QS_MTE 0x0004
58#define QS_FILESYS 0x0008
59#define QS_SHMEMORY 0x0010
60#define QS_DISK 0x0020
61#define QS_HWCONFIG 0x0040
62#define QS_NAMEDPIPE 0x0080
63#define QS_THREAD 0x0100
64#define QS_MODVER 0x0200
65
66/* valid EntityList bit settings */
67#define QS_SUPPORTED (QS_PROCESS|QS_SEMAPHORE|QS_MTE|QS_FILESYS|QS_SHMEMORY|QS_MODVER)
68
69/* All structures must be padded to dword boundaries if necessary */
70/* The semicolon that is needed to terminate the structure field */
71/* must be added in the structure definition itself, because H2INC */
72/* ignores it in a #define statement. */
73#define PADSHORT USHORT pad_sh
74#define PADCHAR UCHAR pad_ch
75
76#define QS_END 0L /* last FILESYS record */
77
78/* Global Record structure
79 * Holds all global system information. Placed first in user buffer
80 */
81typedef struct _QSGREC { /* qsGrec */
82 ULONG cThrds;
83 ULONG c32SSem;
84 ULONG cMFTNodes;
85} QSGREC;
86
87/* Thread Record structure
88 * Holds all per thread information.
89 */
90typedef struct _QSTREC { /* qsTrec */
91 ULONG RecType; /* Record Type */
92 USHORT tid; /* thread ID */
93 USHORT slot; /* "unique" thread slot number */
94 ULONG sleepid; /* sleep id thread is sleeping on */
95 ULONG priority; /* thread priority */
96 ULONG systime; /* thread system time */
97 ULONG usertime; /* thread user time */
98 UCHAR state; /* thread state */
99 PADCHAR;
100 PADSHORT;
101} QSTREC;
102
103/* Process Record structure
104 * Holds all per process information.
105 * ________________________________
106 * | RecType |
107 * |-------------------------------|
108 * | pThrdRec |----|
109 * |-------------------------------| |
110 * | pid | |
111 * |-------------------------------| |
112 * | ppid | |
113 * |-------------------------------| |
114 * | type | |
115 * |-------------------------------| |
116 * | stat | |
117 * |-------------------------------| |
118 * | sgid | |
119 * |-------------------------------| |
120 * | hMte | |
121 * |-------------------------------| |
122 * | cTCB | |
123 * |-------------------------------| |
124 * | c32PSem | |
125 * |-------------------------------| |
126 * | p32SemRec |----|---|
127 * |-------------------------------| | |
128 * | c16Sem | | |
129 * |-------------------------------| | |
130 * | cLib | | |
131 * |-------------------------------| | |
132 * | cShrMem | | |
133 * |-------------------------------| | |
134 * | cFS | | |
135 * |-------------------------------| | |
136 * | p16SemRec |----|---|----|
137 * |-------------------------------| | | |
138 * | pLibRec |----|---|----|------|
139 * |-------------------------------| | | | |
140 * | pShrMemRec |----|---|----|------|----|
141 * |-------------------------------| | | | | |
142 * | pFSRec |----|---|----|------|----|-----|
143 * |-------------------------------| | | | | | |
144 * | 32SemPPRUN[0] |<---|---| | | | |
145 * | . | | | | | |
146 * | . | | | | | |
147 * | . | | | | | |
148 * | 32SemPPRUN[c32PSem-1] | | | | | |
149 * |-------------------------------| | | | | |
150 * | 16SemIndx[0] |<---|--------| | | |
151 * | . | | | | |
152 * | . | | | | |
153 * | . | | | | |
154 * | 16SemIndx[c16Sem-1] | | | | |
155 * |-------------------------------| | | | |
156 * | hmte[0] (or "name str") |<---|---------------| | |
157 * | . | | | |
158 * | . | | | |
159 * | . | | | |
160 * | hmte[cLib-1] | | | |
161 * |-------------------------------| | | |
162 * | hshmem[0] |<---|--------------------| |
163 * | . | | |
164 * | . | | |
165 * | . | | |
166 * | hshmem[cShrMem-1] | | |
167 * |-------------------------------| | |
168 * | fsinfo[0] |<---|--------------------------|
169 * | . | |
170 * | . | |
171 * | . | |
172 * | fsinfo[cFS-1] | |
173 * |-------------------------------| |
174 * <-----
175 * NOTE that the process name string will be stored in place of hmtes
176 * if MTE information is NOT being requested.
177 * NOTE that following this structure in the user buffer is
178 * an array c32Sems long of PRUN structures for 32 bit sems
179 * an array c16Sems long of indices for 16 bit sems
180 * the process name string
181 */
182typedef struct _QSPREC { /* qsPrec */
183 ULONG RecType; /* type of record being processed */
184 QSTREC FAR *pThrdRec; /* ptr to thread recs for this proc */
185 USHORT pid; /* process ID */
186 USHORT ppid; /* parent process ID */
187 ULONG type; /* process type */
188 ULONG stat; /* process status */
189 ULONG sgid; /* process screen group */
190 USHORT hMte; /* program module handle for process */
191 USHORT cTCB; /* # of TCBs in use */
192 ULONG c32PSem; /* # of private 32-bit sems in use */
193 void FAR *p32SemRec; /* pointer to head of 32bit sem info */
194 USHORT c16Sem; /* # of 16 bit system sems in use */
195 USHORT cLib; /* number of runtime linked libraries */
196 USHORT cShrMem; /* number of shared memory handles */
197 USHORT cFH; /* number of open files - BUGBUG see SFNContainer! */
198 USHORT FAR *p16SemRec; /* pointer to head of 16 bit sem info */
199 USHORT FAR *pLibRec; /* ptr to list of runtime libraries */
200 USHORT FAR *pShrMemRec; /* ptr to list of shared mem handles */
201 USHORT FAR *pFSRec; /* pointer to list of file handles */
202} QSPREC;
203
204/*
205 * 16 bit system semaphore structure
206 * ________________________________
207 * | pNextRec |----|
208 * |-------------------------------| |
209 * |SysSemData : | |
210 * | SysSemOwner | |
211 * | SysSemFlag | |
212 * | SysSemRecCnt | |
213 * | SysSemProcCnt | |
214 * |-------------------------------| |
215 * |-------------------------------| |
216 * |-------------------------------| |
217 * | SysSemPtr | |
218 * |-------------------------------| |
219 * |SysSemName: | |
220 * | "pathname" | |
221 * |-------------------------------| |
222 * <-----
223 */
224
225
226/* SysSemFlag values */
227
228#define QS_SYSSEM_WAITING 0x01 /* a thread is waiting on the sem */
229#define QS_SYSSEM_MUXWAITING 0x02 /* a thread is muxwaiting on the sem */
230#define QS_SYSSEM_OWNER_DIED 0x04 /* the process/thread owning the sem died */
231#define QS_SYSSEM_EXCLUSIVE 0x08 /* indicates a exclusive system semaphore */
232#define QS_SYSSEM_NAME_CLEANUP 0x10 /* name table entry needs to be removed */
233#define QS_SYSSEM_THREAD_OWNER_DIED 0x20 /* the thread owning the sem died */
234#define QS_SYSSEM_EXITLIST_OWNER 0x40 /* the exitlist thread owns the sem */
235
236typedef struct _QSS16REC { /* qsS16rec */
237 ULONG NextRec; /* offset to next record in buffer */
238 /* System Semaphore Table Structure */
239 USHORT SysSemOwner ; /* thread owning this semaphore */
240 UCHAR SysSemFlag ; /* system semaphore flag bit field */
241 UCHAR SysSemRefCnt ; /* number of references to this sys sem */
242 UCHAR SysSemProcCnt ; /* number of requests for this owner */
243 UCHAR SysSemPad ; /* pad byte to round structure up to word */
244 USHORT pad_sh;
245 USHORT SemPtr; /* RMP SysSemPtr field */
246 char SemName; /* start of semaphore name string */
247} QSS16REC;
248
249typedef struct _QSS16HEADREC { /* qsS16Hrec */
250 ULONG SRecType;
251 ULONG SpNextRec; /* overlays NextRec of 1st QSS16REC*/
252 ULONG S32SemRec;
253 ULONG S16TblOff; /* offset of SysSemDataTable */
254 ULONG pSem16Rec;
255} QSS16HEADREC;
256
257/*
258 * System wide Shared Mem information
259 * ________________________________
260 * | NextRec |
261 * |-------------------------------|
262 * | hmem |
263 * |-------------------------------|
264 * | sel |
265 * |-------------------------------|
266 * | refcnt |
267 * |-------------------------------|
268 * | name |
269 * |_______________________________|
270 *
271 */
272typedef struct _QSMREC { /* qsMrec */
273 ULONG MemNextRec; /* offset to next record in buffer */
274 USHORT hmem; /* handle for shared memory */
275 USHORT sel; /* selector */
276 USHORT refcnt; /* reference count */
277 char Memname; /* start of shared memory name string */
278} QSMREC;
279
280/*
281 * 32 bit system semaphore structure
282 * ________________________________
283 * | pNextRec |----|
284 * |-------------------------------| |
285 * | QSHUN[0] | |
286 * |-------------------------------| |
287 * | MuxQ | |
288 * |-------------------------------| |
289 * | OpenQ | |
290 * |-------------------------------| |
291 * | SemName | |
292 * |-------------------------------|<---|
293 * | . |
294 * | . |
295 * |-------------------------------|<---|
296 * | pNextRec |----|
297 * |-------------------------------| |
298 * | QSHUN[c32SSem-1] | |
299 * |-------------------------------| |
300 * | MuxQ | |
301 * |-------------------------------| |
302 * | OpenQ | |
303 * |-------------------------------| |
304 * | SemName | |
305 * |-------------------------------|<---|
306 */
307
308/*
309 * 32- bit Semaphore flags
310 */
311
312#define QS_DC_SEM_SHARED 0x0001 // Shared Mutex, Event or MUX semaphore
313#define QS_DCMW_WAIT_ANY 0x0002 // Wait on any event/mutex to occur
314#define QS_DCMW_WAIT_ALL 0x0004 // Wait on all events/mutexs to occur
315#define QS_DCM_MUTEX_SEM 0x0008 // Mutex semaphore
316#define QS_DCE_EVENT_SEM 0x0010 // Event semaphore
317#define QS_DCMW_MUX_SEM 0x0020 // Muxwait semaphore
318#define QS_DC_SEM_PM 0x0040 // PM Shared Event Semphore
319#define QS_DE_POSTED 0x0040 // event sem is in the posted state
320#define QS_DM_OWNER_DIED 0x0080 // The owning process died
321#define QS_DMW_MTX_MUX 0x0100 // MUX contains mutex sems
322#define QS_DHO_SEM_OPEN 0x0200 // Device drivers have opened this semaphore
323#define QS_DE_16BIT_MW 0x0400 // Part of a 16-bit MuxWait
324#define QS_DCE_POSTONE 0x0800 // Post one flag event semaphore
325#define QS_DCE_AUTORESET 0x1000 // Auto-reset event semaphore
326
327typedef struct qsopenq_s { /* qsopenq */
328 PID pidOpener; /* process id of opening process */
329 USHORT OpenCt; /* number of opens for this process */
330} QSOPENQ;
331typedef struct qsevent_s { /* qsevent */
332 QSOPENQ *pOpenQ; /* pointer to open q entries */
333 UCHAR *pName; /* pointer to semaphore name */
334 ULONG *pMuxQ; /* pointer to the mux queue */
335 USHORT flags;
336 USHORT PostCt; /* # of posts */
337} QSEVENT;
338typedef struct qsmutex_s { /* qsmutex */
339 QSOPENQ *pOpenQ; /* pointer to open q entries */
340 UCHAR *pName; /* pointer to semaphore name */
341 ULONG *pMuxQ; /* pointer to the mux queue */
342 USHORT flags;
343 USHORT ReqCt; /* # of requests */
344 USHORT SlotNum; /* slot # of owning thread */
345 PADSHORT;
346} QSMUTEX;
347typedef struct qsmux_s { /* qsmux */
348 QSOPENQ *pOpenQ; /* pointer to open q entries */
349 UCHAR *pName; /* pointer to semaphore name */
350 void *pSemRec; /* array of semaphore record entries */
351 USHORT flags;
352 USHORT cSemRec; /* count of semaphore records */
353 USHORT WaitCt; /* # threads waiting on the mux */
354 PADSHORT;
355} QSMUX;
356typedef struct qsshun_s { /* qsshun */
357 QSEVENT qsSEvt; /* shared event sem */
358 QSMUTEX qsSMtx; /* shared mutex sem */
359 QSMUX qsSMux; /* shared mux sem */
360} QSHUN;
361typedef struct _QSS32REC { /* qsS32rec */
362 void *pNextRec; /* pointer to next record in buffer */
363 QSHUN qsh; /* qstate version of SHUN record */
364} QSS32REC;
365
366/*
367 * System wide MTE information
368 * ________________________________
369 * | pNextRec |----|
370 * |-------------------------------| |
371 * | hmte | |
372 * |-------------------------------| |
373 * | ctImpMod | |
374 * |-------------------------------| |
375 * | ctObj | |
376 * |-------------------------------| |
377 * | pObjInfo |----|----------|
378 * |-------------------------------| | |
379 * | pName |----|----| |
380 * |-------------------------------| | | |
381 * | imported module handles | | | |
382 * | . | | | |
383 * | . | | | |
384 * | . | | | |
385 * |-------------------------------| <--|----| |
386 * | "pathname" | | |
387 * |-------------------------------| <--|----------|
388 * | Object records | |
389 * | (if requested) | |
390 * |_______________________________| |
391 * <-----
392 * NOTE that if the level bit is set to QS_MTE, the base Lib record will be followed
393 * by a series of object records (qsLObj_t); one for each object of the
394 * module.
395 */
396
397typedef struct _QSLOBJREC { /* qsLOrec */
398 ULONG oaddr; /* object address */
399 ULONG osize; /* object size */
400 ULONG oflags; /* object flags */
401} QSLOBJREC;
402
403typedef struct _QSLREC { /* qsLrec */
404 void FAR *pNextRec; /* pointer to next record in buffer */
405 USHORT hmte; /* handle for this mte */
406 USHORT fFlat; /* true if 32 bit module */
407 ULONG ctImpMod; /* # of imported modules in table */
408 ULONG ctObj; /* # of objects in module (mte_objcnt)*/
409 QSLOBJREC FAR *pObjInfo; /* pointer to per object info if any */
410 UCHAR FAR *pName; /* -> name string following struc */
411#if 0
412 USHORT ahmte[1]; /* Array of imported module hmtes */
413#endif
414} QSLREC;
415
416/* Used for 9th bit (Extended Module Data Summary)*/
417typedef struct _QSEXLREC { /* qsELrec */
418 struct _QSEXLREC *next; /* Pointer to next Extended Module Data */
419 USHORT hndmod; /* Module Handle */
420 USHORT pid; /* Process ID */
421 USHORT type; /* Type of Module */
422 ULONG refcnt; /* Size of reference array */
423 ULONG segcnt; /* Number of segments in module */
424 void *_reserved_;
425 UCHAR FAR *name; /* Pointer to Module Name */
426 ULONG ModuleVersion; /* Module version value */
427 UCHAR FAR *ShortModName; /* New Pointer to Module short name */
428 ULONG modref; /* Start of array of handles of module */
429} QSEXLREC;
430
431/*
432 * System wide FILE information
433 * ________________________________
434 * | RecType |
435 * |-------------------------------|
436 * | pNextRec |-------|
437 * |-------------------------------| |
438 * | ctSft | |
439 * |-------------------------------| |
440 * | pSft |---| |
441 * |-------------------------------| | |
442 * | name | | |
443 * |-------------------------------|<--| |
444 * | qsSft[0] | |
445 * |-------------------------------| |
446 * | ... | |
447 * |-------------------------------| |
448 * | qsSft[ctSft -1] | |
449 * |_______________________________| |
450 * | name |
451 * |_______________________________|
452 * <-------|
453 */
454typedef struct _QSSFT { /* qsSft - the size of this should be 0x16! */
455 USHORT sfn; /* 0 SFN sf_fsi.sfi_selfSFN */
456 USHORT refcnt; /* 2 sf_ref_count */
457 USHORT flags; /* 4 sf_flags */
458 USHORT flags2; /* 6 sf_flags2 */
459 USHORT mode; /* 8 sf_fsi.sfi_mode - mode of access */
460 USHORT mode2; /* 10 sf_fsi.sfi_mode2 - mode of access */
461 ULONG size; /* 12 sf_fsi.sfi_size */
462 USHORT hVPB; /* 16 sf_fsi.sfi_hVPB handle of volume */
463 USHORT attr; /* 18 sf_attr */
464 PADSHORT; /* 20 */
465} QSSFT;
466
467typedef struct qsFrec_s { /* qsFrec */
468 ULONG RecType; /* Record Type */
469 void *pNextRec; /* pointer to next record in buffer */
470 ULONG ctSft; /* # sft entries for this MFT entry */
471 QSSFT *pSft; /* -> start of sft entries in buf */
472#if 0
473 char name[1]; /* kso: start of name? */
474#endif
475} QSFREC;
476
477
478/* Pointer Record Structure
479 * This structure is the first in the user buffer.
480 * It contains pointers to heads of record types that are loaded
481 * into the buffer.
482 */
483
484typedef struct _QSPTRREC { /* qsPRec */
485 QSGREC *pGlobalRec;
486 QSPREC *pProcRec; /* ptr to head of process records */
487 QSS16HEADREC *p16SemRec; /* ptr to head of 16 bit sem recds */
488 QSS32REC *p32SemRec; /* ptr to head of 32 bit sem recds */
489 QSMREC *pMemRec; /* ptr to head of shared mem recs */
490 QSLREC *pLibRec; /* ptr to head of mte records */
491 QSMREC *pShrMemRec; /* ptr to head of shared mem records */
492 QSFREC *pFSRec; /* ptr to head of file sys records */
493} QSPTRREC;
494
495#pragma pack()
496#endif
497
498/* IMPORTANT, the sizeof QSSFT is 0x16 bytes! */
499#define SIZEOFQSSFT_T 0x16
500
501
502
503
504/*******************************************************************************
505* External Functions *
506*******************************************************************************/
507#ifndef QS_MTE
508 /* from OS/2 Toolkit v4.5 */
509
510 APIRET APIENTRY DosQuerySysState(ULONG EntityList, ULONG EntityLevel, PID pid,
511 TID tid, PVOID pDataBuf, ULONG cbBuf);
512 #define QS_MTE 0x0004
513#endif
514
515
516/*******************************************************************************
517* Internal Functions *
518*******************************************************************************/
519BOOL kdtLoadModule(const char *pszModule, PMODINFO pModInfo);
520
521
522
523BOOL kdtLoadModule(const char *pszModule, PMODINFO pModInfo)
524{
525 static char achBuffer[1024*256];
526 char szError[256];
527 HMODULE hmod = NULLHANDLE;
528 int rc;
529 char szName[CCHMAXPATH];
530 char * pszSrcName;
531 const char * pszName;
532 const char * psz2;
533 char * pszTmp;
534 ULONG ulAction;
535 HFILE hFile;
536 struct e32_exe* pe32 = (struct e32_exe*)(void*)&achBuffer[0];
537 QSPTRREC * pPtrRec = (QSPTRREC*)(void*)&achBuffer[0];
538 QSLREC * pLrec;
539 int i;
540 FILESTATUS3 fsts3;
541
542 memset(pModInfo, 0, sizeof(*pModInfo));
543
544 /*
545 * Make a temporary copy of the module in the temp directory.
546 */
547 if (DosScanEnv("TMP", &pszTmp) != NO_ERROR || pszTmp == NULL)
548 {
549 printf("Environment variable TMP is not set.\n");
550 return FALSE;
551 }
552 strcpy(szName, pszTmp);
553 if (szName[strlen(pszTmp) - 1] != '\\' && szName[strlen(pszTmp) - 1] != '/')
554 strcat(szName, "\\");
555
556 pszName = strrchr(pszModule, '\\');
557 if (!pszName || (psz2 = strrchr(pszModule, '/')) > pszName)
558 pszName = psz2;
559 if (!pszName || (psz2 = strrchr(pszModule, ':')) > pszName)
560 pszName = psz2;
561 if (!pszName)
562 pszName = pszModule;
563 strcat(szName, pszName);
564 rc = DosCopy((PSZ)pszModule, szName, DCPY_EXISTING);
565 if (rc != NO_ERROR)
566 {
567 printf("Failed to copy %s to %s.\n", pszSrcName, szName);
568 return FALSE;
569 }
570 if (DosQueryPathInfo(szName, FIL_STANDARD, &fsts3, sizeof(fsts3)) != NO_ERROR
571 || !(fsts3.attrFile = FILE_ARCHIVED)
572 || DosSetPathInfo(szName, FIL_STANDARD, &fsts3, sizeof(fsts3), 0) != NO_ERROR
573 )
574 {
575 printf("Failed to set attributes for %s.\n", szName);
576 return FALSE;
577 }
578
579 /*
580 * Patch the module.
581 * Remove the entrypoint and mark it as DLL.
582 */
583 ulAction = 0;
584 rc = DosOpen(szName, &hFile, &ulAction, 0, FILE_NORMAL,
585 OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS,
586 OPEN_SHARE_DENYNONE | OPEN_ACCESS_READWRITE,
587 NULL);
588 if (rc != NO_ERROR)
589 {
590 printf("Failed to open temporary module file %s. rc = %d\n", &szName[0], rc);
591 return FALSE;
592 }
593 rc = DosRead(hFile, &achBuffer[0], 0x200, &ulAction);
594 if (rc != NO_ERROR)
595 {
596 DosClose(hFile);
597 printf("Failed to read LX header from temporary module file.\n");
598 return FALSE;
599 }
600 pe32 = (struct e32_exe*)(void*)&achBuffer[*(unsigned long*)(void*)&achBuffer[0x3c]];
601 if (*(PUSHORT)pe32->e32_magic != E32MAGIC)
602 {
603 DosClose(hFile);
604 printf("Failed to read LX header from temporary module file (2).\n");
605 return FALSE;
606 }
607 pe32->e32_eip = 0;
608 pe32->e32_startobj = 0;
609 pe32->e32_mflags &= ~(E32LIBTERM | E32LIBINIT | E32MODMASK);
610 pe32->e32_mflags |= E32MODDLL;
611 if ((rc = DosSetFilePtr(hFile, *(unsigned long*)(void*)&achBuffer[0x3c], FILE_BEGIN, &ulAction)) != NO_ERROR
612 || (rc = DosWrite(hFile, pe32, sizeof(struct e32_exe), &ulAction)) != NO_ERROR)
613 {
614 DosClose(hFile);
615 printf("Failed to write patched LX header to temporary module file. rc=%d\n", rc);
616 return FALSE;
617 }
618 DosClose(hFile);
619
620 /*
621 * Load the module.
622 */
623 rc = DosLoadModule(szError, sizeof(szError), szName, &hmod);
624 if (rc != NO_ERROR && (rc != ERROR_INVALID_PARAMETER && hmod == NULLHANDLE))
625 {
626 printf("Failed to load %s image %s.", szName, szError);
627 return FALSE;
628 }
629
630 /*
631 * Get object information.
632 */
633 rc = DosQuerySysState(QS_MTE, QS_MTE, 0L, 0L, pPtrRec, sizeof(achBuffer));
634 if (rc != NO_ERROR)
635 {
636 printf("DosQuerySysState failed with rc=%d.\n", rc);
637 return FALSE;
638 }
639
640 pLrec = pPtrRec->pLibRec;
641 while (pLrec != NULL)
642 {
643 /*
644 * Bug detected in OS/2 FP13. Probably a problem which occurs
645 * in _LDRSysMteInfo when qsCheckCache is calle before writing
646 * object info. The result is that the cache flushed and the
647 * attempt of updating the QSLREC next and object pointer is
648 * not done. This used to work earlier and on Aurora AFAIK.
649 *
650 * The fix for this problem is to check if the pObjInfo is NULL
651 * while the number of objects isn't 0 and correct this. pNextRec
652 * will also be NULL at this time. This will be have to corrected
653 * before we exit the loop or moves to the next record.
654 * There is also a nasty alignment of the object info... Hope
655 * I got it right. (This aligment seems new to FP13.)
656 */
657 if (pLrec->pObjInfo == NULL /*&& pLrec->pNextRec == NULL*/ && pLrec->ctObj > 0)
658 {
659 pLrec->pObjInfo = (QSLOBJREC*)(void*)(
660 (char*)(void*)pLrec
661 + ((sizeof(QSLREC) /* size of the lib record */
662 + pLrec->ctImpMod * sizeof(short) /* size of the array of imported modules */
663 + strlen((char*)(void*)pLrec->pName) + 1 /* size of the filename */
664 + 3) & ~3)); /* the size is align on 4 bytes boundrary */
665 pLrec->pNextRec = (QSLREC*)(void*)((char*)(void*)pLrec->pObjInfo
666 + sizeof(QSLOBJREC) * pLrec->ctObj);
667 }
668 if (pLrec->hmte == hmod)
669 break;
670
671 /*
672 * Next record
673 */
674 pLrec = (QSLREC*)pLrec->pNextRec;
675 }
676
677 if (pLrec == NULL)
678 {
679 printf("DosQuerySysState(%s): not found\n", pszName);
680 return FALSE;
681 }
682 if (pLrec->pObjInfo == NULL)
683 {
684 printf("DosQuerySysState(%s): no object info\n", pszName);
685 return FALSE;
686 }
687
688
689 /*
690 * Fill the module info stuff.
691 */
692 for (i = 0; i < pLrec->ctObj; i++)
693 {
694 pModInfo->aObjs[i].ote_size = pLrec->pObjInfo[i].osize;
695 pModInfo->aObjs[i].ote_base = pLrec->pObjInfo[i].oaddr;
696 pModInfo->aObjs[i].ote_flags = pLrec->pObjInfo[i].oflags;
697 pModInfo->aObjs[i].ote_pagemap = i > 0 ? pModInfo->aObjs[i-1].ote_pagemap + pModInfo->aObjs[i-1].ote_mapsize : 0;
698 pModInfo->aObjs[i].ote_mapsize = (pLrec->pObjInfo[i].osize + 0x0FFF) / 0x1000;
699 pModInfo->aObjs[i].ote_sel = ((ULONG)FlatToSel(pLrec->pObjInfo[i].oaddr)) >> 16;
700 pModInfo->aObjs[i].ote_hob = 0;
701 }
702 pModInfo->cObjs = pLrec->ctObj;
703 pModInfo->hmod = hmod;
704 strcpy(pModInfo->szName, pszName);
705
706
707 return TRUE;
708
709}
710
711
712/**
713 * Loads a device driver into memory using DosLoadModule.
714 *
715 * @returns Pointer to module info structure which the caller
716 * is responsible for cleaning up!
717 * @returns NULL on failure, error message is written to screen.
718 * @param pszModule Name of the module to load.
719 * @remark 32-bit stack.
720 */
721PMODINFO kdtLoadDriver(const char *pszModule)
722{
723 PMODINFO pModInfo = malloc(sizeof(MODINFO));
724 if (pModInfo)
725 {
726 if (kdtLoadModule(pszModule, pModInfo))
727 {
728 return pModInfo;
729 }
730 free(pModInfo);
731 }
732
733 return NULL;
734}
735
736
737
738/**
739 * Validates that the module is a correctly linked driver module.
740 *
741 * @returns Success indicator.
742 * @param pModInfo Pointer to module in question.
743 */
744BOOL kdtLoadValidateDriver(PMODINFO pModInfo)
745{
746 if (pModInfo->cObjs <= 2)
747 {
748 printf("kDevTest: Invalid driver module - too few objects! (%d)\n", pModInfo->cObjs);
749 return FALSE;
750 }
751
752 if ( !(pModInfo->aObjs[0].ote_flags & OBJWRITE)
753 || (pModInfo->aObjs[0].ote_flags & OBJBIGDEF)
754 )
755 {
756 printf("kDevTest: Invalid driver module - 1st object isn't 16-bit data!\n");
757 return FALSE;
758 }
759
760 if ( !(pModInfo->aObjs[1].ote_flags & OBJEXEC)
761 || (pModInfo->aObjs[1].ote_flags & OBJBIGDEF)
762 )
763 {
764 printf("kDevTest: Invalid driver module - 2nd object isn't 16-bit code!\n");
765 return FALSE;
766 }
767
768 return TRUE;
769}
770
771
Note: See TracBrowser for help on using the repository browser.