X-Authentication-Warning: delorie.com: mail set sender to djgpp-bounces using -f From: John Elliott Newsgroups: comp.os.msdos.djgpp Subject: Reading sectors: Error 0x701F Date: Sun, 16 Apr 2006 14:24:26 +0100 Lines: 121 Message-ID: NNTP-Posting-Host: seasip.demon.co.uk Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit 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 #include #include #include #include /* 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(®s, 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(®s); 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(®s, 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, ®s); 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"); } }