delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/2006/04/16/09:31:58

X-Authentication-Warning: delorie.com: mail set sender to djgpp-bounces using -f
From: John Elliott <jce AT seasip DOT demon DOT co DOT uk>
Newsgroups: comp.os.msdos.djgpp
Subject: Reading sectors: Error 0x701F
Date: Sun, 16 Apr 2006 14:24:26 +0100
Lines: 121
Message-ID: <e1tgib$ns9$1$8300dec7@news.demon.co.uk>
NNTP-Posting-Host: seasip.demon.co.uk
Mime-Version: 1.0
X-Trace: news.demon.co.uk 1145193867 24457 62.49.4.197 (16 Apr 2006 13:24:27 GMT)
X-Complaints-To: abuse AT demon DOT net
NNTP-Posting-Date: Sun, 16 Apr 2006 13:24:27 +0000 (UTC)
X-Accept-Language: en-gb, en, en-us
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.6) Gecko/20040115
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp
Reply-To: djgpp AT delorie DOT com

   I'm trying to write a program that reads sectors from a hard drive 
using either INT 25h or INT 21h/AX=7305h.

   If I run it under Windows ME, the reads fail with error 0x701F, 
whether it's operating on a FAT32 drive or a FAT16 drive. I can't find 
any mention of this error in documentation; it turns up once or twice on 
Usenet, always in the context of calling INT 25h or INT 21h/AX=7305h 
from a DOS extender. That suggests I've made an error setting up the 
__dpmi_regs when making the call, but if so I can't see what it is. Does 
anyone have any suggestions?

   (this is an old djgpp, based on gcc 2.7.2, but for such a simple 
operation I wouldn't have thought that would make much of a difference).

#include <stdio.h>
#include <ctype.h>
#include <go32.h>
#include <dpmi.h>
#include <sys/farptr.h>

/* Since INT 25h leaves a word on the stack, we have a small 16-bit
  * wrapper around it */

static unsigned char code16[] =
{
         0x90,
         0x55,           /* push bp */
         0x8B, 0xEC,     /* mov bp,sp */
         0xcd, 0x25,     /* int 25 */
         0x8B, 0xE5,     /* mov sp,bp */
         0x5D,           /* pop bp */
         0xCB            /* retf */
};
void try_int25(int drive, long sector, int count, int buffer);
void try_int21(int drive, long sector, int count, int buffer);


int main(int argc, char **argv)
{
         long sector = 0;
         int count   = 1;
         int buffer  = __tb + 32;
         int drive   = 'C';

         if (argc > 1)
         {
                 drive = toupper(argv[1][0]);
         }

         try_int25(drive, sector, count, buffer);
         try_int21(drive, sector, count, buffer);
}

void try_int25(int drive, long sector, int count, int buffer)
{
         __dpmi_regs regs;

         /* Create the read packet at __tb */
         _farpokew(_dos_ds, __tb,   sector);
         _farpokew(_dos_ds, __tb+2, sector >> 16);
         _farpokew(_dos_ds, __tb+4, count);
         _farpokew(_dos_ds, __tb+6, buffer & 0x0F);
         _farpokew(_dos_ds, __tb+8, buffer >> 4);

         /* Create the 16-bit wrapper  at __tb + 16 */
         dosmemput(code16, sizeof(code16), __tb + 16);

         /* Set up the registers */
         memset(&regs, 0, sizeof(regs));

         regs.x.ax = drive - 'A';        /* Unit */
         regs.x.cx = 0xFFFF;             /* Packet read */
         regs.x.bx = __tb & 0x0F;        /* Packet address */
         regs.x.ds = __tb >> 4;
         regs.x.ip = __tb & 0x0F;        /* 16-bit stub */
         regs.x.cs = (__tb >> 4) + 1;
         _go32_dpmi_simulate_fcall(&regs);

         if (regs.x.flags & 1)
         {
                 fprintf(stderr, "INT 25 returned error: %04x\n", 
regs.x.ax);
         }
         else
         {
                 fprintf(stderr, "INT 25 succeeded\n");
         }
}


void try_int21(int drive, long sector, int count, int buffer)
{
         __dpmi_regs regs;

         /* Create the read packet at __tb */
         _farpokew(_dos_ds, __tb,   sector);
         _farpokew(_dos_ds, __tb+2, sector >> 16);
         _farpokew(_dos_ds, __tb+4, count);
         _farpokew(_dos_ds, __tb+6, buffer & 0x0F);
         _farpokew(_dos_ds, __tb+8, buffer >> 4);

         /* Set up the registers */
         memset(&regs, 0, sizeof(regs));

         regs.x.ax = 0x7305;             /* Function */
         regs.x.cx = 0xFFFF;             /* Packet read */
         regs.x.dx = drive - '@';        /* Unit */
         regs.x.bx = __tb & 0x0F;        /* Packet address */
         regs.x.ds = __tb >> 4;
	regs.x.si = 0;			/* Read */
         __dpmi_int(0x21, &regs);
         if (regs.x.flags & 1)
         {
                 fprintf(stderr, "INT 21/7305 returned error: %04x\n", 
regs.x.ax);
         }
         else
         {
                 fprintf(stderr, "INT 21/7305 succeeded\n");
         }
}

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019