Solved

Brequest in DPMI

Posted on 1997-04-28
10
262 Views
Last Modified: 2012-06-21
Using BP70 to create a DOS-Program.
How to use the btrcall-Interface from brequest
in DPMI-Mode? Or, in other words: how to call
real-Mode Interrupts which need pointers to realmode-memory
as parameters in DPMI-Mode.
Any Idea?
0
Comment
Question by:nmm
  • 5
  • 3
  • 2
10 Comments
 

Expert Comment

by:kilobug
ID: 1215320
Does a value must be passed to a segment register (DS/ES)???
0
 

Author Comment

by:nmm
ID: 1215321
Yes, there is a data-structure like

bparam=record
  buff: ^byte; {a realmode pointer to the databuffer!}
  len  : word; {the length of the databuffer}
  info: ^word;
 {etc...}
end;

a variable of this type:

var params:bparam;

and you have to put the segment of @params (the pointer to params) to DS , its offset to DX and call INT $7b

For windows there is a DLL: btrcall.dll, exporting a
function (no INT call necessary explicit).

If it is impossible to perform the interupt corrctly, may be one can use the DLL in the DPMI-DOS-Program in some manner??

Any ideas?

Mircea


 
0
 

Expert Comment

by:kilobug
ID: 1215322
I have the same problem: you can set the segment value "normally" because this will make a GPF (Error 216)...

Maybe in the SWAGS (http://www.gdsoft.com/swag/swag.html)
0
Active Directory Webinar

We all know we need to protect and secure our privileges, but where to start? Join Experts Exchange and ManageEngine on Tuesday, April 11, 2017 10:00 AM PDT to learn how to track and secure privileged users in Active Directory.

 

Author Comment

by:nmm
ID: 1215323
Hey, this was a nice comment! Yes there is something about our
problem!

0
 

Accepted Solution

by:
aajw earned 80 total points
ID: 1215324
Firstly, allocate a buffer in conventional memory to put the params, using the GlobalDOSAlloc function.var paramptr:pointer;  rmseg:word;  sel:word;  res:longint;...  res := GlobalDOSAlloc(sizeof(bparam)); {allocate memory}  if res=0 then  begin    writeln('Error allocating mem');    halt(0);  end;  sel := LoWord(res);  rmseg := hiword(res);  paramptr := ptr(sel,0); {assign pointer to memory}Having allocated the memory, the data must be copied across.  move(params,paramptr^,sizeof(bparam));(alternatively, store the data directly in the allocated mem)Then the real mode int can be called, using the DPMI function 0300h.type DPMIRegs = record  EDI,ESI,EBP:longint;  Res1:longint;  EBX,EDX,ECX,EAX:longint;  Flags:word;  ES,DS,FS,GS:word;  IP,CS:word;  SP,SS:word;end;var regs:Registers;  DRegs:DPMIRegs;...  Regs.ax := $300; {function number}  Regs.bx := $7b;  {interrupt to call}  Regs.cx := 0; {no params on stack}  Regs.es := seg(DRegs); {point to DPMI reg struc}  Regs.di := ofs(DRegs);  DRegs.ss := 0; {no stack}  DRegs.sp := 0;  DRegs.es := rmseg; {segment of pointer}  DRegs.edi := 0;    {offset=0}  {set up other parts of DRegs here}  Intr($31,Regs); {Do the interrupt}  Then copy the data back to the variable (optional)  move(paramptr^,params,sizeof(bparam));
And free the block  sel := GlobalDosFree(sel);  if sel<>0 then  begin    writeln('Error freeing block');    halt(0);  end;Hope this does the trick
0
 

Author Comment

by:nmm
ID: 1215325
Sorry I was absent for a while, but now I will check
your answer, aajw!
Cheers nmm
0
 

Author Comment

by:nmm
ID: 1215326
Hi aajw!
Sorry but it simply crashes, what is wrong?

Here is the code I used (with your extensions, DPMI is
defined)

UNIT BTRCALL;

Interface
uses dos{$ifdef dpmi},winapi{$endif};

const
      b_open    : word =    0;
      b_close   : word =    1;
      b_Insert  : word =    2;
      b_update  : word =    3;
      b_delete  : word =    4;
      b_geteq   : word =    5;
      b_getnx   : word =    6;
      b_getpr   : word =    7;
      b_getgr   : word =    8;
      b_getge   : word =    9;
      b_getlt   : word =   10;
      b_getle   : word =   11;
      b_getfi   : word =   12;
      b_getla   : word =   13;
      b_create  : word =   14;
      b_stat    : word =   15;
      b_extend  : word =   16;
      b_setdir  : word =   17;
      b_getdir  : word =   18;
      b_begtran : word =   19;
      b_endtran : word =   20;
      b_abotran : word =   21;
      b_getpos  : word =   22;
      b_setpos  : word =   23;
      b_snext   : word =   24;
      b_stop    : word =   25;
      b_version : word =   26;
      b_unlock  : word =   27;
      b_reset   : word =   28;
      b_setown  : word =   29;
      b_clrown  : word =   30;
      b_creinx  : word =   31;
      b_droinx  : word =   32;
      b_sfirst  : word =   33;
      b_slast   : word =   34;
      b_sprev   : word =   35;
      s_lockw   : word =  100;
      s_locknw  : word =  200;
      m_lockw   : word =  300;
      m_locknw  : word =  400;
      e_gnext   : word =   36;
      e_gprev   : word =   37;
      e_snext   : word =   38;
      e_sprev   : word =   39;
      e_insert  : word =   40;

      b_getkey_offset : word = 50;

{------- nur fr Btrieve 6.1. belangvoll -------}
      g_percent : word =   44;
      f_percent : word =   45;

type bparameter = record
     btr_data   : ^byte;  {eigentlich der Datenpuffer}
     btr_dlen   :  word;  {Datenpufferl„nge}
     btr_info   : ^word;  {eigentlich Infoblock}
     btr_fcb    : ^byte;  {eigentlich FCB}
     op_code    :  word;  {Operationscode}
     btr_key    : ^byte;
     {eigentlich Key}
     btr_klen   :  byte;
     btr_knr    :  shortint;
     status     : ^word;  {Rckgabewert}
     iface_id   :  word;  {const}
    end;
{$ifdef DPMI}
 type DPMIRegs = record
            EDI,ESI,EBP:longint;
            Res1:longint;
            EBX,EDX,ECX,EAX:longint;
            Flags:word; ES,DS,FS,GS:word;
            IP,CS:word;
            SP,SS:word;
         end;
{$endif}

 function BTRV(op,dlen : word;var pos_block,dat_block,key_block;
               klen,knr:integer) : word;


 var btr_status : word;

 function BTRVaktiv:Boolean;

Implementation

 var btrpar   : bparameter;
{$ifdef DPMI}
     paramptr : pointer;
     rmseg    : word;
     sel      : word;
     res      : longint;

{$endif}

 function BTRVaktiv:Boolean;
 type a=record
         l,h:word;
        end;
 var   bptr : pointer;
       b :a absolute bptr;
 begin
{  getIntVec($7b,bptr);
  BTRVaktiv:=word(bptr)=$33;}
 end;

{$ifndef DPMI}
  procedure aufruf;
  var   regs : registers;
  begin
   with btrpar do
   begin
    if  not BTRVaktiv then
    begin
     status^:=20;
     exit;
    end;
    with regs do
    begin
     bx:=0;
     es:=0;
     dx:= ofs(btrpar);
     ds:= seg(btrpar);
    end;
    intr($7b,regs);
   end;
  end;
{$else}
procedure aufruf;
var regs : Registers;
   DRegs : DPMIRegs;
begin
 move(btrpar,paramptr^,sizeof(btrpar));
 {alternatively, store the data directly in the allocated mem}
{ Then the real mode int can be called, using the DPMI function 0300h.}
 Regs.ax   := $300;       {function number}
 Regs.bx   := $7b;        {interrupt to call}
 Regs.cx   := 0;          {no params on stack}
 Regs.es   := seg(DRegs); {point to DPMI reg struc}
 Regs.di   := ofs(DRegs);
 DRegs.ss  := 0; {no stack}
 DRegs.sp  := 0;
 DRegs.es  := rmseg; {segment of pointer}
 DRegs.edi := 0; {offset=0} {set up other parts of DRegs here}
 Intr($31,Regs); {Do the interrupt}
  { Then copy the  data back to the variable (optional)}
 move(paramptr^,btrpar,sizeof(btrpar));
end;
{$endif}

  procedure Init_Parameter;
  begin
   with btrpar do
   begin
    btr_status:=0;
    iface_id   := $6176;
    status := @btr_status;
   end;
  end;

  function BTRV(op,dlen : word;var pos_block,dat_block,key_block;
                klen,knr:integer) : word;
  var s : word;
      b : array[1..125] of byte absolute pos_block;
  begin
   Init_Parameter;
   with btrpar do
   begin
    op_code :=op;
    btr_dlen:=dlen;
    btr_key :=@key_block;
    btr_data:=@dat_block;
    btr_info:=@pos_block;
    btr_fcb :=@b[91];
    btr_knr :=knr;
    btr_klen:=klen;
    aufruf;
    btrv:=status^;
   end;
  end;

{$ifdef DPMI}
var     ExitSave : Pointer;

procedure BtrCallExit;far;
begin
 ExitProc:=ExitSave;
 { And free the block}
 sel := GlobalDosFree(sel);
 if sel<>0 then
 begin
  writeln('Error freeing block'); halt(0);
 end;
end;

begin
 ExitSave:=ExitProc;
 ExitProc:=@BtrCallExit;
 res := GlobalDOSAlloc(sizeof(btrpar)); {allocate memory}
 if res=0 then
 begin
  writeln('Error allocating mem');
  halt(0);
 end;
 sel      := LoWord(res);

 rmseg    := hiword(res);
 paramptr := ptr(sel,0); {assign pointer to memory}
 {Hope this does the trick}
{$endif}
end.

0
 

Expert Comment

by:aajw
ID: 1215327
The memory allocation/deallocation routines work OK on my system.However, the set up of DRegs in your example is not how you described above. I'm sorry if I didn't make it clear, but DRegs should contain the registers as they are needed to call the interrupt. Unfortunately, the registers must be stored as the 32bit EAX,EBX etc, but assigning a word calue to them will just reference the low 16 bits, the normal regs AX,BX etc. and clear the (unused) high 16 bits.
0
 

Author Comment

by:nmm
ID: 1215328
Hi aajw!
Is does not work, sorry.
The problem semms to be, that in the strucure btrpar
are elements, which are pointers again to some
DOS-Memory.
If I allocate this mem also via globaldosalloc, I dont know how to get real-mode Pointer to it.
I tried to use wbtrcall.dll, the requestor for windows 3.11, but
it will not run (RTM.exe says: invalid entrypoint called)
Mircea
0
 

Expert Comment

by:aajw
ID: 1215329
You can allocate a RM pointer using the rmseg value returned in the call to GlobalDOSAlloc -var  rmptr:pointer;begin...{allocate mem here}  rmptr := ptr(rmseg,0);{Only use rmptr in real mode, or in structures which will be used in real mode}
0

Featured Post

Networking for the Cloud Era

Join Microsoft and Riverbed for a discussion and demonstration of enhancements to SteelConnect:
-One-click orchestration and cloud connectivity in Azure environments
-Tight integration of SD-WAN and WAN optimization capabilities
-Scalability and resiliency equal to a data center

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

In this article we will learn how to fix  “Cannot install SQL Server 2014 Service Pack 2: Unable to install windows installer msi file” error ?
In case you ever have to remove a faulty web part from a page , add the following to the end of the page url ?contents=1
Microsoft Active Directory, the widely used IT infrastructure, is known for its high risk of credential theft. The best way to test your Active Directory’s vulnerabilities to pass-the-ticket, pass-the-hash, privilege escalation, and malware attacks …
Two types of users will appreciate AOMEI Backupper Pro: 1 - Those with PCIe drives (and haven't found cloning software that works on them). 2 - Those who want a fast clone of their boot drive (no re-boots needed) and it can clone your drive wh…

829 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question