home *** CD-ROM | disk | FTP | other *** search
- /* gdt.c -- walks through Global Descriptor Table */
- /* (c) Andrew Schulman December 1988 */
- /* revised 17-December-1988 */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <setjmp.h>
- #include <string.h>
- #include <ctype.h>
- #define INCL_DOS
- #define INCL_DOSDEVICES
- #define INCL_DOSSIGNALS
- #include "os2.h"
- #include "devhlp.h"
-
- typedef char far *FP;
-
- #define FP_SEG(p) HIUSHORT(p)
- #define FP_OFF(p) LOUSHORT(p)
- #define MK_FP(seg,off) ((FP)(((ULONG)(seg) << 16) | (off)))
-
- #define RING_3_ALIAS(seg0) ((seg0) + 3)
-
- #define REC_TO_SEG(r) ((r) << 3)
- #define SEG_TO_REC(s) ((s) >> 3)
- #define LDT_REC_TO_SEG(s) (RING_3_ALIAS(REC_TO_SEG(s)))
- /* replace above with: */
- typedef struct {
- USHORT rpl : 2;
- USHORT table : 1;
- USHORT index : 15;
- } SEG;
- /* replace most uses of USHORT with SEG */
- /* perhaps use enums also!! */
- /* most of program should consist of data structures */
-
- /* again, use SEG type instead of macro ! */
- #define IGNORE_RPL(seg) ((seg) >> 2)
-
- /* program should be redone, dispatching on type of seg. for each seg
- type, should be a describe() function and a show() function */
-
- #define NULLPTR ((FP) 0)
- #define REG /*register*/
-
- /* types of gates */
- #define TSS 1
- #define LDT 2
- #define BUSY_TSS 3
- #define CALL_GATE 4
- #define TASK_GATE 5
- #define INTERRUPT_GATE 6
- #define TRAP_GATE 7
-
- #pragma pack(1)
-
- /* contents of 6-byte structure filled in by SGDT instruction */
- typedef struct {
- USHORT limit;
- USHORT base_lo;
- BYTE base_hi;
- BYTE reserved;
- } GDT;
-
- typedef GDT IDT; /* IDTR is same as GDTR */
-
- /* "nonstandard extension: bitfield other than int" */
- typedef union {
- BYTE a;
- struct {
- BYTE type : 4;
- BYTE segment : 1;
- BYTE dpl : 2;
- BYTE present : 1;
- } b;
- struct {
- BYTE accessed : 1;
- BYTE read_write : 1;
- BYTE conform_expand : 1;
- BYTE code_data : 1;
- BYTE segment : 1;
- BYTE dpl : 2;
- BYTE present : 1;
- } c;
- } LAR;
-
- #define LAR_FM_USHORT(u) (*((LAR *) &(u)))
-
- typedef struct {
- USHORT limit;
- USHORT base_lo;
- BYTE base_hi;
- LAR lar;
- USHORT reserved;
- } DESCRIPTOR;
-
- #define ISGATE(seglar) ((seglar).b.segment == 0)
- #define ISCODE(seglar) ((seglar).c.code_data == 1)
- #define ISREAD(seglar) (ISCODE(seglar) && ((seglar).c.read_write == 1))
- #define ISWRITE(seglar) (! ISCODE(seglar) && ((seglar).c.read_write == 1))
-
- #define GATE_TYPE(seglar) ((seglar).b.type)
-
- #define ISBIMODAL(seg, phys) ((phys) == 0x10 * (seg))
-
- extern void far gdt(GDT far *gdt);
- extern void far idt(IDT far *idt);
- extern USHORT far ldt(void);
- extern USHORT far lsl(USHORT seg);
- extern USHORT far lar(USHORT seg);
- extern BOOL far verr(USHORT seg);
- extern BOOL far verw(USHORT seg);
- /* extern void Debugger(void); */
-
- int fail(char *msg);
- void walk_dt(DESCRIPTOR far *desc, void (*f)());
- void walk(FP base, USHORT start, USHORT stop);
- void walk_ldt(FP base, USHORT start, USHORT stop);
- void walk_idt(void);
- void describe(FP base, USHORT rec, BOOL show_empties, USHORT care_lar,
- BOOL is_ldt);
- void show_seg(USHORT rec);
- void peek(BYTE hi, USHORT lo, USHORT limit);
- void unassemble_uvirt(FP base, USHORT seg, USHORT off);
- void unassemble_phys(BYTE hi, USHORT lo, USHORT limit, USHORT off);
- void dump(BYTE hi, USHORT lo, FP fp, USHORT size);
- void search(FP base, USHORT lar);
- char *name(USHORT type);
- char *get_doscall_name(USHORT seg);
- USHORT hatoi(char *);
- void help(void);
- void init(void);
- void init_doscalls(void);
- void far pascal break_handler(USHORT sig_num, USHORT sig_arg);
- void breakpoint(void);
-
- FP PhysToUVirt(USHORT hi, USHORT lo, USHORT limit, BYTE type);
- BOOL ReleaseUVirt(FP fp);
-
- static char *PHYSTOUVIRT_FAIL = "PhysTOUVirt fails!";
- static char *RELEASEUVIRT_FAIL = "ReleaseUVirt fails!";
- static char *SOMETHING_WRONG = "Something wrong! Is this 386 OS/2?";
- static char *DESCRIPTOR_MASK =
- "[seg %04X] %02X%04X <limit %05u> <lar %02X> [%s]\n";
- static char *env_str = "GDTCODESEG";
- static char *my_ldt = "** MY LOCAL DESCRIPTOR TABLE **\n";
- static char *gdt_at_msg = "GDT at %02X%04X <limit %05u> <%u entries>\n";
-
- static char *GATE_NAMES[] = {
- "Invalid gate", "TSS gate", "LDT", "Busy TSS gate", "Call gate",
- "Task gate", "Interrupt gate", "Trap gate", "Reserved gate",
- "Reserved gate", "Reserved gate", "Reserved gate", "Reserved gate",
- "Reserved gate", "Reserved gate", "Reserved gate" };
-
- static GDT g;
- static DESCRIPTOR far *gdt_ptr;
- static USHORT devhlp;
- static USHORT entries;
- static jmp_buf toplevel;
- static FP uvirt_p = NULLPTR;
- static USHORT radix = 16;
-
- static char *gdt_exe;
-
- int main(int argc, char *argv[])
- {
- char buf[128], *p = buf;
- USHORT action = 0;
-
- /* second copy of GDT.EXE, runs under CodeView */
- if (! strcmp("CVP", getenv("GDTEXE")))
- {
- USHORT seg = atoi(getenv(env_str));
- if (! seg)
- printf("Error: SET GDTEXE= and retry\n");
- DosGetSeg(seg);
- breakpoint();
- DosFreeSeg(seg);
- return 0;
- }
-
- gdt_exe = argv[0];
-
- gdt(&g);
-
- entries = g.limit / sizeof(DESCRIPTOR);
- printf(gdt_at_msg, g.base_hi, g.base_lo, g.limit, entries);
- if (g.reserved != 0)
- puts(SOMETHING_WRONG);
-
- /* open up DEVHLP device */
- if (DosOpen("DEVHLPXX", &devhlp, &action, 0, 0, 1, 0x40, 0))
- return fail("Can't find DEVHLP.SYS");
-
- gdt_ptr =
- (DESCRIPTOR far *) PhysToUVirt(g.base_hi, g.base_lo, g.limit,
- UVirt_ReadWrite);
- if (! gdt_ptr)
- return fail(PHYSTOUVIRT_FAIL);
-
- /* must be a 386 version of OS/2!! */
- if (FP_OFF(gdt_ptr) != 0)
- return fail(SOMETHING_WRONG);
-
- init();
- init_doscalls();
-
- puts("Type H for help");
-
- if (setjmp(toplevel))
- printf("\n[back to toplevel]\n");
-
- for (;;)
- {
- printf("$ ");
- gets(buf);
-
- switch (toupper(*p))
- {
- case '!':
- system(p+2); break;
- case '?':
- show_seg(SEG_TO_REC(hatoi(p+2))); break;
- case '.':
- describe(gdt_ptr, SEG_TO_REC(hatoi(p+2)), TRUE, -1, FALSE);
- break;
- case 'H':
- help(); break;
- case 'I':
- walk_idt(); break;
- case 'L':
- {
- /* walk through seg as if an LDT */
- USHORT rec = SEG_TO_REC(hatoi(p+2));
- DESCRIPTOR far *desc = gdt_ptr + rec;
- if ((desc->limit + 1) % 8)
- printf("Definitely not an LDT\n");
- else
- {
- if (REC_TO_SEG(rec) == ldt())
- printf(my_ldt);
- walk_dt(desc, walk_ldt);
- }
- break;
- }
- case 'P':
- {
- USHORT hi = hatoi(strtok(p+2," "));
- USHORT lo = hatoi(strtok(0," "));
- USHORT limit = hatoi(strtok(0," "));
- peek(hi,lo,limit);
- break;
- }
- case 'R':
- radix = atoi(p+2);
- if (radix != 10 || radix != 16)
- radix = 16;
- break;
- case 'S':
- search(gdt_ptr, hatoi(p+2)); break;
- case 'U':
- {
- /* unassemble: similar to peek */
- USHORT seg = hatoi(strtok(p+2,": "));
- USHORT off = hatoi(strtok(0," "));
- unassemble_uvirt(gdt_ptr,seg,off);
- break;
- }
- case 'W':
- printf(gdt_at_msg, g.base_hi, g.base_lo, g.limit, entries);
- if (strlen(p) > 3)
- {
- USHORT start = SEG_TO_REC(hatoi(strtok(p+2," ")));
- USHORT stop = SEG_TO_REC(hatoi(strtok(0, " ")));
- walk(gdt_ptr, start, stop);
- }
- else
- walk(gdt_ptr, 0, entries);
- break;
- case 'X':
- case 'Q':
- return (ReleaseUVirt(gdt_ptr)) ? 0 : fail(RELEASEUVIRT_FAIL);
- break;
- }
- }
- }
-
- /* turn physical address into virtual address */
- FP PhysToUVirt(USHORT hi, USHORT lo, USHORT limit, BYTE type)
- {
- REGS regs;
- USHORT ret;
- regs.ax = hi;
- regs.bx = lo;
- regs.cx = limit;
- regs.di = 0;
- regs.dx = MAKEUSHORT(DevHlp_PhysToUVirt, type);
- ret = DosDevIOCtl(®s, ®s, 0x60, 128, devhlp);
- return (ret || regs.flags.carry) ? NULLPTR :
- MK_FP(regs.es, regs.bx);
- }
-
- /* dispose of the virtual address */
- BOOL ReleaseUVirt(FP fp)
- {
- REGS regs;
- USHORT ret;
- regs.ax = FP_SEG(fp);
- regs.bx = 0;
- regs.cx = 0;
- regs.di = 0;
- regs.dx = MAKEUSHORT(DevHlp_PhysToUVirt, 2); /* free */
- ret = DosDevIOCtl(®s, ®s, 0x60, 128, devhlp);
- return (! (ret || regs.flags.carry));
- }
-
- int fail(char *msg)
- {
- puts(msg);
- return 1;
- }
-
- void describe(FP base, USHORT rec, BOOL show_empties, USHORT care_lar,
- BOOL is_ldt)
- {
- DESCRIPTOR far *p = ((DESCRIPTOR far *) base) + rec;
- if (rec && ! show_empties && (! p->limit || ! p->lar.a))
- return;
- if (care_lar != -1 && (care_lar != p->lar.a))
- return;
- if (ISGATE(p->lar))
- {
- switch (GATE_TYPE(p->lar))
- {
- case CALL_GATE:
- {
- DESCRIPTOR far *p2;
- char *name;
- /* temp here -- should be separate function for each seg type:
- create dispatch type and dispatch on type! */
- /* actually, need two tables: one for describe_ functions, the
- other for show_ functions */
- /* Morse, 286, p.163 */
- printf("<Call gate %04X:0000> ", REC_TO_SEG(rec));
- /* need another union -- for call gate, byte is word count,
- _not_ base_hi; next word is destination _selector_, _not_
- base_lo; next word is destination offset, not limit! */
- printf("<code %04X:%04X> ", p->base_lo, p->limit);
-
- p2 = ((DESCRIPTOR far *) base) + SEG_TO_REC(p->base_lo);
- printf("<phys %02X%04X> ",
- p2->base_hi, p2->base_lo + p->limit);
-
- name = get_doscall_name(REC_TO_SEG(rec));
- /* see if its a special name, not DOSxxxxx */
- if (name && *name =='*')
- printf("%s ", name+1);
- else if (name)
- printf("DOS%s ", name);
- else
- printf("??? ");
-
- printf("(%u wds)\n", p->base_hi); /* words expects as args */
- }
- break;
- case TRAP_GATE:
- case INTERRUPT_GATE:
- printf("[seg %04X] %04X:%04X <lar %02X> [%s]\n",
- (is_ldt) ? LDT_REC_TO_SEG(rec) : REC_TO_SEG(rec),
- p->base_lo, p->limit,
- p->lar.a, name(p->lar.a));
- break;
- default:
- goto deflt;
- }
- }
- else
- {
- deflt:
- printf(DESCRIPTOR_MASK,
- (is_ldt) ? LDT_REC_TO_SEG(rec) : REC_TO_SEG(rec),
- p->base_hi, p->base_lo,
- p->limit,
- p->lar.a,
- name(p->lar.a)
- );
- }
- }
-
- /* step through a Descriptor Table */
- void walk(FP base, USHORT start, USHORT stop)
- {
- REG USHORT i;
- for (i=start; i<entries && i<=stop; i++)
- describe(base, i, FALSE, -1, FALSE);
- }
-
- /* step through a Local Descriptor Table */
- void walk_ldt(FP base, USHORT start, USHORT stop)
- {
- REG USHORT i;
- for (i=start; i<entries && i<=stop; i++)
- describe(base, i, FALSE, -1, TRUE);
- }
-
- /* step through a Descriptor Table */
- void search(FP base, USHORT lar)
- {
- REG USHORT i;
- for (i=0; i<entries; i++)
- describe(base, i, FALSE, lar, FALSE);
- }
-
- void peek(BYTE hi, USHORT lo, USHORT limit)
- {
- FP fp = PhysToUVirt(hi, lo, limit, UVirt_ReadWrite);
- uvirt_p = fp;
- if (fp)
- dump(hi, lo, fp, limit);
- if (! ReleaseUVirt(fp))
- puts(RELEASEUVIRT_FAIL);
- uvirt_p = NULLPTR;
- }
-
- void unassemble_uvirt(FP base, USHORT seg, USHORT off)
- {
- DESCRIPTOR far *p = ((DESCRIPTOR far *) base) + SEG_TO_REC(seg);
- unassemble_phys(p->base_hi, p->base_lo, p->limit, off);
- }
-
- void unassemble_phys(BYTE hi, USHORT lo, USHORT limit, USHORT off)
- {
- char cmd[128];
- char env[128];
- FP fp;
- USHORT sel;
-
- if (! (fp = PhysToUVirt(hi, lo, limit, UVirt_Exec)))
- return;
-
- DosAllocSeg(limit, &sel, SEG_GETTABLE);
- movedata(FP_SEG(fp),FP_OFF(fp),sel,0,limit);
-
- uvirt_p = fp;
-
- /* get CodeView to do our disassembling for us -- run in
- sequential mode (/T), with startup commands (/C).
- NOTE! CVP U does not require exec seg, but seg must
- be mapped into debugee's address space! Our second copy
- of gdt.exe has to get it, then we have to set breakpoint
- ourselves, then CVP runs some more commands we've put
- on the command line: set radix to 16, set cs, unassemble */
-
- putenv("GDTEXE=CVP");
- sprintf(env, "%s=%u", env_str, sel);
- putenv(env);
-
- sprintf(cmd, "CVP /T /C\"n16;bp %x;g;r cs %x;u %x\" %s",
- (void near *) breakpoint, sel, off, gdt_exe);
- printf("EXEC: %s\n", cmd);
- system(cmd);
-
- sprintf(env,"%s=",env_str); putenv(env);
- putenv("GDTEXE=");
-
- DosFreeSeg(sel);
- if (! ReleaseUVirt(fp))
- puts(RELEASEUVIRT_FAIL);
- uvirt_p = NULLPTR;
- }
-
- void show_seg(USHORT rec)
- {
- DESCRIPTOR far *desc = gdt_ptr + rec;
- FP p = PhysToUVirt(desc->base_hi, desc->base_lo, desc->limit,
- UVirt_ReadWrite);
- uvirt_p = p;
- if (p)
- {
- printf(DESCRIPTOR_MASK, REC_TO_SEG(rec),
- desc->base_hi, desc->base_lo, desc->limit, desc->lar.a,
- name(desc->lar.a));
-
- if (ISGATE(desc->lar))
- {
- /* have to do something special for Call gate!: limit is
- actually offset */
-
- switch (GATE_TYPE(desc->lar))
- {
- case LDT:
- /* why is only one LDT showing up???? */
- if (REC_TO_SEG(rec) == ldt())
- printf(my_ldt);
- walk_ldt(p, 0, desc->limit / sizeof(DESCRIPTOR));
- break;
- default:
- dump(desc->base_hi, desc->base_lo, p, desc->limit);
- }
- }
- else
- {
- dump(desc->base_hi, desc->base_lo, p, desc->limit);
- }
-
- if (! ReleaseUVirt(p))
- puts(RELEASEUVIRT_FAIL);
- uvirt_p = NULLPTR;
- }
- else
- puts(PHYSTOUVIRT_FAIL);
- }
-
- #define WIDTH 16
- #define WIDTH_SHIFT 4
-
- void dump(BYTE hi, USHORT lo, FP fp, USHORT size)
- {
- BYTE far *p;
- USHORT blocks = size / WIDTH;
- USHORT slop = size % WIDTH;
- REG USHORT i;
- REG USHORT j;
-
- for (i=0; i<blocks; i++, fp += WIDTH)
- {
- printf("%02X%04X ", hi, lo + (i << WIDTH_SHIFT));
- for (j=0, p=fp; j<WIDTH; j++, p++)
- printf("%02X ", *p);
- putchar(' '); putchar(' '); putchar(' ');
- for (j=0, p=fp; j<WIDTH; j++, p++)
- putchar(isalpha(*p) ? *p : '.');
- putchar('\n');
- }
- if (slop)
- {
- printf("%02X%04X ", hi, lo + (i << WIDTH_SHIFT));
- for (j=0, p=fp; j<WIDTH; j++, p++)
- if (j<slop) printf("%02X ", *p);
- else printf(" ");
- putchar(' '); putchar(' '); putchar(' ');
- for (j=0, p=fp; j<slop; j++, p++)
- putchar(isalpha(*p) ? *p : '.');
- putchar('\n');
- }
- }
-
- char *name(LAR lar)
- {
- if (ISGATE(lar))
- return GATE_NAMES[GATE_TYPE(lar)];
- else if (ISCODE(lar))
- return (ISREAD(lar)) ? "Readable code" : "Execute-only code";
- else
- return (ISWRITE(lar)) ? "Writable data" : "Read-only data";
- }
-
- void far pascal break_handler(USHORT sig_num, USHORT sig_arg)
- {
- /* have to acknowledge the signal first */
- ULONG prevaddr;
- USHORT prevact;
- DosSetSigHandler(0L, &prevaddr, &prevact, 4, 1); /* ack */
-
- if (uvirt_p)
- {
- ReleaseUVirt(uvirt_p);
- uvirt_p = NULLPTR;
- }
-
- longjmp(toplevel, -1);
- }
-
- void init(void)
- {
- USHORT handtype, devattr;
-
- /* make sure stdin is KBD and stdout is VIO */
- DosQHandType(0, &handtype, &devattr);
- if (handtype == 1)
- DosQHandType(1, &handtype, &devattr);
- if (handtype == 1)
- {
- ULONG prevaddr;
- USHORT prevact;
- DosSetSigHandler(break_handler, &prevaddr, &prevact, 2, 1); /* ^C */
- DosSetSigHandler(0L, &prevaddr, &prevact, 1, 3); /* ignore TERM */
- DosSetSigHandler(0L, &prevaddr, &prevact, 1, 4); /* ignore ^break */
- }
- }
-
- static char *helpmsg[] = {
- "GDT.EXE walks through the protected-mode Global Descriptor Table",
- "used by OS/2. It uses the SGDT instruction to get the 24-bit",
- "physical base address of the GDT, and the PhysToUVirt DevHlp,",
- "made available by DEVHLP.SYS, to turn the physical address into",
- "a virtual selector:offset address that can be used by a normal",
- "Ring 3 app like GDT.EXE.",
- "Commands:",
- "\tW [start] [stop] -- walk Global Descriptor Table",
- "\tL <seg> -- walk seg as if an LDT \(maybe it is\)",
- "\tI -- walk Interrupt Descriptor Table",
- "\tQ or X -- exit back to OS/2",
- "\tS <lar> -- search for segments with designated access rights",
- "\tU <seg:off> -- run CVP to unassemble code",
- "\tP <hi> <lo> <limit> -- peek at arbitrary address",
- "\t. <seg> -- displays one segment description from the GDT",
- "\t? <seg> -- hexdump of segment referenced in GDT",
- "\t! <cmdstr> -- runs an external program or OS/2 command",
- "Examples:",
- "\tw\t\t\t; display the entire GDT",
- "\tw 90 100\t\t; focus on portion of GDT",
- "\ts F1\t\t\t; find all segments with LAR 0xF1",
- "\t. 60\t\t\t; display info on segment 0x60",
- "\t? 60\t\t\t; hexdump of segment 0x60",
- "\tu b0:adfc\t\t\; unassemble code at 00B0:ADFC",
- ""
- } ;
-
- void help(void)
- {
- char **p = helpmsg;
- while (**p)
- {
- puts(*p);
- p++;
- }
- }
-
- USHORT hatoi(char *s)
- {
- USHORT i = 0, t;
-
- if (radix == 10) return atoi(s);
-
- while (*s == ' ' || *s == '\t')
- s++;
- while (1)
- {
- char c = *s;
- if (c >= '0' && c <= '9') t = 48;
- else if (c >= 'A' && c <= 'F') t = 55;
- else if (c >= 'a' && c <= 'f') t = 87;
- else break;
- i = (i << 4) + (c - t);
- s++;
- }
- return i;
- }
-
- /**********************************************************************/
- #define NUM_DOSCALLS 111
-
- extern USHORT far pascal DOSPTRACE();
- extern USHORT far pascal DOSSGSWITCH();
- extern USHORT far pascal DOSSGSWITCHME();
- extern USHORT far pascal DOSSYSTRACE();
-
- typedef struct {
- char *name;
- ULONG procaddr; /* USHORT (far pascal *procaddr)(); */
- } DOSCALLS;
-
- static DOSCALLS dosfuncs[NUM_DOSCALLS] = {
- "ALLOCHUGE", (ULONG) DosAllocHuge,
- "ALLOCSEG", (ULONG) DosAllocSeg,
- "ALLOCSHRSEG", (ULONG) DosAllocShrSeg,
- "BEEP", (ULONG) DosBeep,
- "BUFRESET", (ULONG) DosBufReset,
- "CHDIR", (ULONG) DosChdir,
- "CHGFILEPTR", (ULONG) DosChgFilePtr,
- "CLIACCESS", (ULONG) DosCLIAccess,
- "CLOSE", (ULONG) DosClose,
- "CLOSESEM", (ULONG) DosCloseSem,
- "CREATECSALIAS", (ULONG) DosCreateCSAlias,
- "CREATESEM", (ULONG) DosCreateSem,
- "CREATETHREAD", (ULONG) DosCreateThread,
- "CWAIT", (ULONG) DosCWait,
- "DELETE", (ULONG) DosDelete,
- "DEVCONFIG", (ULONG) DosDevConfig,
- "DEVIOCTL", (ULONG) DosDevIOCtl,
- "DUPHANDLE", (ULONG) DosDupHandle,
- "ENTERCRITSEC", (ULONG) DosEnterCritSec,
- "ERRCLASS", (ULONG) DosErrClass,
- "ERROR", (ULONG) DosError,
- "EXECPGM", (ULONG) DosExecPgm,
- "EXIT", (ULONG) DosExit,
- "EXITCRITSEC", (ULONG) DosExitCritSec,
- "EXITLIST", (ULONG) DosExitList,
- "FILELOCKS", (ULONG) DosFileLocks,
- "FINDCLOSE", (ULONG) DosFindClose,
- "FINDFIRST", (ULONG) DosFindFirst,
- "FINDNEXT", (ULONG) DosFindNext,
- "FLAGPROCESS", (ULONG) DosFlagProcess,
- "FREEMODULE", (ULONG) DosFreeModule,
- "FREESEG", (ULONG) DosFreeSeg,
- "GETCP", (ULONG) DosGetCp,
- "GETDATETIME", (ULONG) DosGetDateTime,
- "GETENV", (ULONG) DosGetEnv,
- "GETHUGESHIFT", (ULONG) DosGetHugeShift,
- "GETINFOSEG", (ULONG) DosGetInfoSeg,
- "GETMACHINEMODE", (ULONG) DosGetMachineMode,
- "GETMODHANDLE", (ULONG) DosGetModHandle,
- "GETMODNAME", (ULONG) DosGetModName,
- "GETPID", (ULONG) DosGetPid,
- "GETPROCADDR", (ULONG) DosGetProcAddr,
- "GETPRTY", (ULONG) DosGetPrty,
- "GETSEG", (ULONG) DosGetSeg,
- "GETSHRSEG", (ULONG) DosGetShrSeg,
- "GETVERSION", (ULONG) DosGetVersion,
- "GIVESEG", (ULONG) DosGiveSeg,
- "HOLDSIGNAL", (ULONG) DosHoldSignal,
- "KILLPROCESS", (ULONG) DosKillProcess,
- "LOADMODULE", (ULONG) DosLoadModule,
- "LOCKSEG", (ULONG) DosLockSeg,
- "MAKEPIPE", (ULONG) DosMakePipe,
- "MEMAVAIL", (ULONG) DosMemAvail,
- "MKDIR", (ULONG) DosMkdir,
- "MOVE", (ULONG) DosMove,
- "MUXSEMWAIT", (ULONG) DosMuxSemWait,
- "NEWSIZE", (ULONG) DosNewSize,
- "OPEN", (ULONG) DosOpen,
- "OPENSEM", (ULONG) DosOpenSem,
- "PHYSICALDISK", (ULONG) DosPhysicalDisk,
- "PORTACCESS", (ULONG) DosPortAccess,
- "PTRACE", (ULONG) DOSPTRACE,
- "QCURDIR", (ULONG) DosQCurDir,
- "QCURDISK", (ULONG) DosQCurDisk,
- "QFHANDSTATE", (ULONG) DosQFHandState,
- "QFILEINFO", (ULONG) DosQFileInfo,
- "QFILEMODE", (ULONG) DosQFileMode,
- "QFSINFO", (ULONG) DosQFSInfo,
- "QHANDTYPE", (ULONG) DosQHandType,
- "QVERIFY", (ULONG) DosQVerify,
- "READ", (ULONG) DosRead,
- "READASYNC", (ULONG) DosReadAsync,
- "REALLOCHUGE", (ULONG) DosReallocHuge,
- "REALLOCSEG", (ULONG) DosReallocSeg,
- "RESUMETHREAD", (ULONG) DosResumeThread,
- "RMDIR", (ULONG) DosRmdir,
- "SCANENV", (ULONG) DosScanEnv,
- "SEARCHPATH", (ULONG) DosSearchPath,
- "SELECTDISK", (ULONG) DosSelectDisk,
- "SEMCLEAR", (ULONG) DosSemClear,
- "SEMREQUEST", (ULONG) DosSemRequest,
- "SEMSET", (ULONG) DosSemSet,
- "SEMSETWAIT", (ULONG) DosSemSetWait,
- "SEMWAIT", (ULONG) DosSemWait,
- "SENDSIGNAL", (ULONG) DosSendSignal,
- "SETCP", (ULONG) DosSetCp,
- "SETDATETIME", (ULONG) DosSetDateTime,
- "SETFHANDSTATE", (ULONG) DosSetFHandState,
- "SETFILEINFO", (ULONG) DosSetFileInfo,
- "SETFILEMODE", (ULONG) DosSetFileMode,
- "SETFSINFO", (ULONG) DosSetFSInfo,
- "SETMAXFH", (ULONG) DosSetMaxFH,
- "SETPRTY", (ULONG) DosSetPrty,
- "SETSIGHANDLER", (ULONG) DosSetSigHandler,
- "SETVEC", (ULONG) DosSetVec,
- "SETVERIFY", (ULONG) DosSetVerify,
- "SGSWITCH", (ULONG) DOSSGSWITCH,
- "SGSWITCHME", (ULONG) DOSSGSWITCHME,
- "SLEEP", (ULONG) DosSleep,
- "SUBALLOC", (ULONG) DosSubAlloc,
- "SUBFREE", (ULONG) DosSubFree,
- "SUBSET", (ULONG) DosSubSet,
- "SUSPENDTHREAD", (ULONG) DosSuspendThread,
- "SYSTEMSERVICE", (ULONG) DosSystemService,
- "SYSTRACE", (ULONG) DOSSYSTRACE,
- "TIMERASYNC", (ULONG) DosTimerAsync,
- "TIMERSTART", (ULONG) DosTimerStart,
- "TIMERSTOP", (ULONG) DosTimerStop,
- "UNLOCKSEG", (ULONG) DosUnlockSeg,
- "WRITE", (ULONG) DosWrite,
- "WRITEASYNC", (ULONG) DosWriteAsync,
- } ;
-
- #define NUM_NEWCALLS 51
-
- /* table stores ordinal numbers, until replaced by procaddr */
- /* add asterisks so they show up clearly */
- static DOSCALLS newcalls[NUM_NEWCALLS] = {
- "CALLBACK *", 157L,
- "FSRAMSEMCLEAR *", 162L,
- "FSRAMSEMREQUEST *", 161L,
- "GETSTDA *", 119L, /* 3 wds */
- "GLOBALSEG *", 132L,
- "HUGEINCR *", 136L,
- "HUGESHIFT *", 135L,
- "ICANONICALIZE *", 100L, /* 7 wds */
- "ICREATETHREAD *", 1L, /* 4 wds */
- "IEXECPGM *", 4L, /* 12 wds */
- "IRAMSEMWAKE *", 125L, /* 3 wds */
- "IREAD *", 79L, /* 6 wds */
- "ISEMREQUEST *", 18L, /* 4 wds */
- "ISEMWAIT *", 21L, /* 4 wds */
- "ISETCP *", 131L, /* 2 wds */
- "ISYSSEMCLEAR *", 17L, /* 2 wds */
- "ISYSSEMSET *", 19L, /* 2 wds */
- "IWRITE *", 87L, /* 6 wds */
- "LIBINIT *", 96L, /* 2 wds */
- "PROFILE *", 133L, /* 9 wds */
- "QAPPTYPE *", 163L,
- "QPROCSTATUS *", 184L,
- "QSYSINFO *", 166L, /* 4 wds */
- "QTRACEINFO *", 93L,
- "R2STACKREALLOC *", 160L, /* 1 wds */
- "READPHYS *", 103L,
- "SETFGND *", 101L, /* 2 wds */
- "SETPROCCP *", 155L, /* 5 wds */
- "SGSWITCHPROC *", 124L,
- "SIZESEG *", 126L, /* 3 wds */
- "SWAPTASKINIT *", 102L,
-
- /* names that don't have DOS in front of them */
- "*GETADDR *", 111L,
- "*GETHEADERS *", 108L,
- "*GETSELADDR *", 110L,
- "*STRUCHECK *", 106L,
- "*STRURESUPDATE *", 107L,
- "*UNUSEDA *", 98L,
- "*UNUSEDB *", 99L,
- "*UNUSEDC *", 126L,
- "*UNUSEDD *", 128L,
- "*UNUSEDE *", 104L,
- "*UNUSEDF *", 105L,
- "*UNUSEDG *", 95L,
- "*DBGETKVAR *", 109L,
- "*DBGETOWNER *", 117L,
- "*DBMEMFREE *", 116L,
- "*DBMEMLOCK *", 112L,
- "*DBMEMREALLOC *", 15L,
- "*DBMEMUNLOCK *", 113L,
- "*DBPHYSINFO *", 118L,
- "*DBSEGALLOC *", 114L,
- } ;
-
- int cmp_doscalls(DOSCALLS *dc1, DOSCALLS *dc2)
- {
- return (dc1->procaddr == dc2->procaddr) ? 0 :
- (dc1->procaddr < dc2->procaddr) ? -1 : 1;
- }
-
- int srch_doscall(USHORT *seg, DOSCALLS *dc)
- {
- USHORT ndx1 = IGNORE_RPL(*seg);
- USHORT ndx2 = IGNORE_RPL(FP_SEG(dc->procaddr));
- return (ndx1 == ndx2) ? 0 : (ndx1 < ndx2) ? -1 : 1;
- }
-
- #define FAILBUFSIZE 128
-
- void init_doscalls(void)
- {
- /* try to install new functions */
- char failbuffer[FAILBUFSIZE];
- ULONG procaddr;
- USHORT doscalls;
- REG DOSCALLS *p;
- REG USHORT i;
-
- DosLoadModule(failbuffer, FAILBUFSIZE, "DOSCALLS", &doscalls);
-
- /* sort dosfuncs by address */
- qsort(dosfuncs, NUM_DOSCALLS, sizeof(DOSCALLS), cmp_doscalls);
-
- /* before loop, newcalls[i].procaddr contains DOSCALLS.ord# */
- for (i=0, p=newcalls; i<NUM_NEWCALLS; i++, p++)
- if (! DosGetProcAddr(doscalls, p->procaddr, &procaddr))
- {
- LAR ar;
- USHORT u = lar(FP_SEG(procaddr));
- ar = LAR_FM_USHORT(u);
- if (ISGATE(ar) && GATE_TYPE(ar) == CALL_GATE)
- p->procaddr = procaddr;
- }
-
- /* sort newcalls by address */
- qsort(newcalls, NUM_NEWCALLS, sizeof(DOSCALLS), cmp_doscalls);
- }
-
- char *get_doscall_name(USHORT seg)
- {
- DOSCALLS *p;
-
- return
- (p = bsearch(&seg, dosfuncs, NUM_DOSCALLS, sizeof(DOSCALLS),
- srch_doscall)) ? p->name :
- (p = bsearch(&seg, newcalls, NUM_NEWCALLS, sizeof(DOSCALLS),
- srch_doscall)) ? p->name :
- /*otherwise*/ (char *) 0;
- }
-
- /* target for CodeView breakpoint */
- void breakpoint(void)
- {
- /* this code intentionally left blank */
- }
-
- void walk_idt(void)
- {
- IDT i;
- idt(&i);
- walk_dt(&i, walk);
- }
-
- /* walk a descriptor table */
- /* or, change dump() params so it fits in same scheme */
- void walk_dt(DESCRIPTOR far *desc, void (*f)())
- {
- FP p;
-
- p = PhysToUVirt(desc->base_hi, desc->base_lo, desc->limit,
- UVirt_ReadWrite);
- uvirt_p = p;
- if (p)
- (*f)(p, 0, desc->limit / sizeof(DESCRIPTOR));
- if (! ReleaseUVirt(p))
- puts(RELEASEUVIRT_FAIL);
- uvirt_p = NULLPTR;
- }
-