home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 11 Util
/
11-Util.zip
/
GDT.ZIP
/
DEVHLP.DOC
< prev
next >
Wrap
Text File
|
1989-03-15
|
6KB
|
153 lines
DEVHLP.SYS -- preliminary documentation
This is abbreviated documentation for DEVHLP.SYS, an OS/2 device
driver that gives normal OS/2 applications access to the DevHlp
facilities. In particular, DEVHLP.SYS gives OS/2 applications access
to the PhysToUVirt DevHlp.
Because it is a device driver, DEVHLP.SYS must be loaded from
an OS/2 CONFIG.SYS file with the statement:
DEVICE=DEVHLP.SYS
Applications call DEVHLP.SYS using the OS/2DosDevIOCtl function
call. DosDevIOCtl takes five parameters:
FAR PTR TO BUFFER -- receives data
FAR PTR TO BUFFER -- contains parameters
WORD -- function number
WORD -- category number
WORD -- device handle
This requires that your application have a device handle to
DEVHLP.SYS. The ASCII string name of DEVHLP.SYS is "DEVHLPXX." To
get a device handle to DEVHLPXX, use the DosOpen call. For example,
from C:
#define INCL_DOS
#define INCL_DOSDEVICES
#include "os2.h"
#include "devhlp.h"
...
unsigned short devhlp = 0;
unsigned short action = 0;
...
/* open up DEVHLP device */
if (DosOpen("DEVHLPXX", &devhlp, &action, 0, 0, 1, 0x40, 0))
return fail("Can't find DEVHLP.SYS");
/* at this point, devhlp contains device handle */
The category number used by DEVHLP.SYS is 128, and the function
number is hex 60 (there are reasons for these seemingly arbitrary
numbers, but we won't get into them here).
The two far pointers required to call DEVHLP.SYS through
DosDevIOCtl should each point to a 18-byte data structure. The two
far pointers can point to the _same_ 18-byte buffer, similar to
the int86() interface used in MS-DOS C compilers. The structure
of this buffer is:
typedef struct {
unsigned short ax, bx, cx, dx, si, di, ds, es, flags;
} REGS;
For applications written in C, this data structure is defined in
the #include file DEVHLP.H. In addition, the last field, flags, is
defined as a C bitfield for easy access to the carry flag.
For example:
...
REGS regs;
...
DosDevIOCtl(®s, ®s, 0x60, 128, devhlp);
...
For the input buffer, DEVHLP.SYS will use the AX, BX, CX, DX, and
DI registers. DEVHLP.SYS will load the *real* registers from these
fields of the input buffer, and will call DevHlp. Upon return from
DevHlp, DEVHLP.SYS will store the contents of AX, BX, ES, DS, SI, DI,
and the flags into the appropriate fields of the output data
structure. For example, here is a C function that provides a
convenient way to call the PhysToUVirt DevHlp:
#define MAKEUSHORT(l, h) (((USHORT)(l)) | ((USHORT)(h)) << 8)
#define MK_FP(seg,off) ((void far *)(((ULONG)(seg) << 16) | (off)))
#define DevHlp_PhysToUVirt 0x17
#define UVirt_ReadWrite 1
...
/* turn physical address into virtual address */
void far *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) ? (void far *) 0 :
MK_FP(regs.es, regs.bx);
}
...
/* get read/write access to 20 bytes at 0FE008 */
ptr = PhysToUVirt(0xF, 0xE008, 20, UVirt_ReadWrite);
The placement of values in the REGS data structure corresponds
to what an OS/2 device driver would do to invoke the PhysToUVirt
facility, as described in the OS/2 device drivers kit documentation
or in Ray Duncan's ADVANCED PROGRAMMER'S GUIDE TO OS/2 (Microsoft
Press, 1989):
AX:BX -- 32-bit physical address
CX -- length in bytes
DH -- request type (0=executable, 1=read/write, 2=release)
DL -- 17 hex
Similarly, an application must examine the output buffer in the
same way that a device driver would examine the actual machine
registers. In the case of PhysToUVirt, after calling DevHlp:
; if function successful
CARRY FLAG -- clear
ES:BX -- virtual address
; if function unsuccessful
CARRY FLAG --set
AX -- error code
Note that DEVHLP.SYS does not check the carry flag after calling
DevHlp. It does, however, place the flags in the output structure. It
is up to your application to check the carry flag to see if an error
occurred (if you don't use DEVHLP.H, the carry flag is: regs.carry & 1).
DEVHLP.SYS performs no validation of your input parameters.
However, DEVHLP.SYS *will* check to make sure that the pointers you
passed in do in fact point to memory to which your application has
legal rights. If the pointers are not valid for your application, it
will be terminated with a general protection (GP) fault. For
example, a guaranteed way to generate a GP fault:
/* bad code! */
DosDevIOCtl(666L, 666L, 0x60, 128, devhlp);
When you are done using DEVHLP.SYS, close the device handle with
a call to DosClose:
DosClose(devhlp);
More thorough documentation on DEVHLP.SYS will be available soon.
In the meantime, read the comments in DEVHLP.ASM, and examine the
sample application GDT.C. You may find GDT.EXE interesting in its
own right (see the documentation GDT.DOC).
-- Andrew Schulman
32 Andrew (!) Street
Cambridge MA 02139
617-876-2102 (h)
617-57-8500 x7148 (w)
4 January 1988