Solved

how to code a DPMI call

Posted on 1997-04-01
11
355 Views
Last Modified: 2008-03-06
I need some code about makeing a DPMI 0x0300 call in order
to make a disk read with int13h under WIN 3.1 platform

I tried to use the documentation and it doesn't work at all.

Thanx
Damian Ionut
0
Comment
Question by:damian
  • 4
  • 2
  • 2
  • +2
11 Comments
 

Expert Comment

by:alexander031597
ID: 1249789
Please, explain what's your steps ?
0
 

Expert Comment

by:alexander031597
ID: 1249790
Please, explain what's your steps ?
0
 

Author Comment

by:damian
ID: 1249791
I need exactly the C coded function  like:

MakeInt13hRead(void far *buffer,int sect,int track,int side);
and
MakeInt13hWrite(...)

I allready implemented a general int 13h call function but it doesn't work at all. Maybe it could be a problem with the "void far *buffer" param wich is WINDOWS memory alloc chunk (alocated with DELPHI's new(buffer)
function call, lets say, or with Alloc and Fix etc. ) ... Any further information
nedeed ?? ;)

See ya !
Slash
0
 

Expert Comment

by:alexander031597
ID: 1249792
For 16 bit applications the DPMI host automatically handles all
INT nn opcodes to provide BIOS and DOS services transparently.
So you have not the reasons to simulate real mode interrupt.
For checking it I included to my C program following code for reading sector from diskette and it runs OK:
  __asm mov ah,02h
  __asm mov al,01h
  __asm mov ch,00h
  __asm mov cl,01h
  __asm mov dl,00h
  __asm mov dh,01h
  __asm mov bx,seg wrkbuf
  __asm mov es,bx
  __asm mov bx,offset wrkbuf
  __asm int 13h
  __asm mov errcode,ah
According to documentation,Win32 applications cannot communicate with VxDs by the same means that 16-bit can (software interrupts, callbacks, VxD services, etc.) Win32 applications must use
DeviceIOControl interface to communicate with VxDs that support
device I/O calls.
0
 

Author Comment

by:damian
ID: 1249793
I think you have not tested it ... ;)
I have done it allready ...

Saa ya !
0
What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 

Expert Comment

by:alexander031597
ID: 1249794
I tested it on QuickC for Windows v.1.0. I could see that diskette drive started work, wrkbuf was filled some information, but I didn't check this information, becouse you sad INT 13h didn't work at all. Of course, I can check it too, but I think
it's not necessary, it's run OK. But if you have done it allready and my code didn't run on your hardware too, you should see the Diskette Parameter Table using INT 1Eh or you can get this address from BIOS directly at 0:0078 If you will have troubles
in this cause too, just E-mail me, I will try to help you :-).

0
 
LVL 13

Expert Comment

by:John Mc Hale
ID: 1249795
I have a vested interest in the area that you have asked about. My angle is that I am currently writing a Windows 3.1 utility program to copy diskettes. This requires the use of int13 subfunctions 2,3,4,5, and 0 naturally. I cannot even help you unless I know what angle you are coming from. Specifically, what subfunctions are you interested in? and what are your problems with them? I have had a lot of problems myself and am  working around them one by one. If you  would like to work with me if possible. I know a little about DPMI. Myb e-mail is:

mchalej@iol.ie
0
 

Expert Comment

by:slash
ID: 1249796
Ok guiz!
Thanx a lot for help, but I found the code on MSDN CD. It is not that easy as it seems.

BTW, with FDD is more easy than HDD... you can use a lot of other functions ...
PS: If you need this code, I'll be glad to share it with you !
See ya
0
 
LVL 13

Expert Comment

by:John Mc Hale
ID: 1249797
Sample code for FDD\Win16

Yes please slash.

mchalej@iol.ie

Thanxx.
0
 

Expert Comment

by:slash
ID: 1249798
I'll send you by e-mail ....
BTW ... send me your datas at slash@buc.soros.ro and I'll reply you with the code !!!

See ya !
0
 
LVL 5

Accepted Solution

by:
icd earned 210 total points
ID: 1249799
Here is some code I wrote to do CD-ROM disc access under DPMI and with a small amount of work you should be able to modify it to make your own calls to int13h.

The important points to note are the use of GlobalDosAlloc functions to allocate buffers and the setting up of the dpmi registers. Ignore the pvRequest structure, this is specific to MSCDEX calls for CD-ROM drives.

It compiles under MSVC 1.52 under large memory model.

There may be a problem with line wrap. If you can't work it out give me an e-mail and I will reply with the code in that way.

icd@pobox.com

--- cut here ---
#include <windows.h>
#include <malloc.h>
#include <memory.h>


typedef      struct      _dpmi_regs_ DPMI_REGS;
//
// Request Header structure. (MSCDEX)
//
typedef struct
      {
      unsigned char      rhLength;            // length of structure
      unsigned char      rhUnit;                  // minor device
      unsigned char      rhFunction;            //
      unsigned int      rhStatus;            // status return word
      unsigned char      rhReserved[8];      // reserved
      unsigned char      cAddrMode;            // addressing mode
      unsigned long      lTranAddr;            // transfer address
      unsigned int      nSecs;                  // number of sectors to read
      unsigned long      lStartSec;            // start sector
      unsigned char      cMode;                  // data read mode
      unsigned char      cILSize;            // interleave size
      unsigned char      cILSkip;            // interleave skip factor
      } REQSTRC;

struct _dpmi_regs_
{
      long      ddi;
      long      dsi;
      long      dbp;
      long      zero;
      long      dbx;
      long      ddx;
      long      dcx;
      long      dax;
      WORD      flags;
      WORD      des;
      WORD      dds;
      WORD      dfs;
      WORD      dgs;
      WORD      dip;
      WORD      dcs;
      WORD      dsp;
      WORD      dss;
};


#define      CARRY_FLAG                  0x01
#define FLAG_DIRECTORY      2


static unsigned int      WinCallRMInt(WORD wInt, DPMI_REGS *pDPMIregs);
static int                  LmReadCDSector(int nDrive, long lSector, void *pvSectorBuffer, int mode);


//*****************************************************************************
//
//      NAME:      CDReadSector
//
//      DESCRIPTION:
//            Read a single 'sector' from the CD-ROM in drive 'volumeIndex' in cooked
//            mode and put the results into the 'pBuffer'.
//
//      PARAMETERS:
//            volumeIndex      The drive number of the CD-ROM drive containing the disc
//                              to be tested where 0 = drive letter 'A'
//            sector            The sector number to read
//            pBuffer            The buffer to put the cooked (2048 bytes) of data into
//
//      RETURN VALUE:
//            ...                  Return values defined by LmReadCDSector.
//
//      GLOBALS:
//            none.
//
//*****************************************************************************
//
int   CDReadSector(int volumeIndex, unsigned long sector, void *pBuffer)
{
       return LmReadCDSector((int)volumeIndex, sector, pBuffer, 0);
}


//*****************************************************************************
//
//      NAME:      LmReadCDSector
//
//      DESCRIPTION:
//            Read a sector from a CD-ROM using the 'Send Device Driver Request, Read long' method
//
//*****************************************************************************
//
static int LmReadCDSector(int nDrive, long lSector, void *pvSectorBuffer, int mode)
{  
      DPMI_REGS      dpmiregs;
      void            *pvRealModeBuffer;            // Pointer to real mode buffer to hold sector data
      REQSTRC            *pvRequest;                        // Pointer to real mode request buffer
      DWORD       dwGDMemSector;                  // Global DOS memory for sector data
      DWORD            dwGDMemRequest;                  // Global DOS memory for request structure
      int                  nResult;                        // Result from INT 2f function
      int                  retval;                              // Return value from function
      
      memset(&dpmiregs, 0, sizeof(DPMI_REGS));

      // Allocate DOS memory for reading sectors (and drive list)
      dwGDMemSector = GlobalDosAlloc((DWORD)2352);
      dwGDMemRequest = GlobalDosAlloc((DWORD)sizeof(REQSTRC));

      if (dwGDMemSector == NULL || dwGDMemRequest == NULL)
            retval = 1;
      else
      {
            pvRequest = MAKELP(LOWORD(dwGDMemRequest), 0);
                        
            memset(&dpmiregs, 0, sizeof(DPMI_REGS));
            memset(pvRequest, 0, sizeof(REQSTRC));
            pvRequest->rhLength = sizeof(REQSTRC);
            pvRequest->rhFunction = 128;
            pvRequest->lTranAddr = dwGDMemSector & 0xFFFF0000l;
            pvRequest->nSecs = 1;
            pvRequest->lStartSec = lSector;
            pvRequest->cMode = mode;
            
            dpmiregs.dax = 0x1510;
            dpmiregs.dcx = (int)nDrive - 1;
            dpmiregs.des = HIWORD(dwGDMemRequest);
            dpmiregs.dbx = 0;

            nResult = WinCallRMInt(0x2f, &dpmiregs);
      
            if ((nResult == 0) && (!(dpmiregs.flags & CARRY_FLAG)))
            {
                  // Protected mode address
                  pvRealModeBuffer = MAKELP(LOWORD(dwGDMemSector), 0);
                  memcpy(pvSectorBuffer, pvRealModeBuffer, mode ? 2352: 2048);
                  retval = 0;
            }    
            else
                  retval = 2;
      }

      if (dwGDMemSector) GlobalDosFree(LOWORD(dwGDMemSector));
      if (dwGDMemRequest) GlobalDosFree(LOWORD(dwGDMemRequest));
      return(retval);
}


#pragma optimize("", off)
//*****************************************************************************
//
//      NAME:      WinCallRMInt
//
//      DESCRIPTION:
//            Simulate the Real Mode Interrupt by calling the DPMI function 0x0300
//
//*****************************************************************************
//
static unsigned int WinCallRMInt(WORD wInt, DPMI_REGS *pDPMIregs)
{              
      WORD            wSel;
      WORD            wOff;
      int                  nReturn;

      wSel = SELECTOROF(pDPMIregs);
      wOff = OFFSETOF(pDPMIregs);
      _asm {
            mov            ax, 0x0300
            mov            bx, wInt
            mov            cx, 0
            mov            es, wSel
            mov            di, wOff

            int            0x31
            jc            dpmi_error
            xor            ax, ax                  //      Success.
            
dpmi_error:
            mov            nReturn, ax            // Return code
      }
      // Returns: AX == 0 if ok, or DPMI error code
      
      return nReturn;
}
#pragma
0

Featured Post

Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

Join & Write a Comment

Preface I don't like visual development tools that are supposed to write a program for me. Even if it is Xcode and I can use Interface Builder. Yes, it is a perfect tool and has helped me a lot, mainly, in the beginning, when my programs were small…
This tutorial is posted by Aaron Wojnowski, administrator at SDKExpert.net.  To view more iPhone tutorials, visit www.sdkexpert.net. This is a very simple tutorial on finding the user's current location easily. In this tutorial, you will learn ho…
The goal of this video is to provide viewers with basic examples to understand and use structures in the C programming language.
The goal of this video is to provide viewers with basic examples to understand recursion in the C programming language.

759 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

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now