📄 read.c
字号:
/*
* win32\read.c absolute disk read
*
* This file is part of the BETA version of DISKLIB
* Copyright (C) 1998, Gregg Jennings
*
* See README.TXT for information about re-distribution.
* See DISKLIB.TXT for information about usage.
*
*/
#include "win32.h"
#include "dosio.h"
#include "debug.h"
enum { DISK_READ = 0, DISK_WRITE };
/*
* disk_read absolute disk read (INT 25h) <= 32MB
*
* Note: This function reads floppies under Windows 98.
*
* This function fails under Windows NT.
*/
extern int disk_read(int disk, long sec, void *buf, int nsecs)
{
int i;
DIOC_REGISTERS regs DBG_0;
regs.d.eax = disk;
regs.d.edx = sec; /* (truncate is okay) */
regs.d.ecx = nsecs;
regs.d.ebx = (DWORD)buf;
if ((i = win_device_io(VWIN32_DIOC_DOS_INT25,®s)) != DEVICE_OK)
return i;
if (regs.x.flags & 0x0001)
return DOS_ERR;
return DISK_OK;
}
/*
* disk_read_ext absolute disk read (INT 25h), > 32MB
*
* Note: I have not tested this function under Windows 98.
* GROTS: do the test
*
* This function fails under Windows NT.
*
*/
extern int disk_read_ext(int disk, long sec, void *buf, int nsecs)
{
int i;
struct DCB dcb DBG_0;
DIOC_REGISTERS regs DBG_0;
dcb.sector = sec;
dcb.number = (UINT16)nsecs;
dcb.buffer = buf;
regs.d.eax = disk;
regs.d.ecx = 0xFFFF;
regs.d.ebx = (DWORD)&dcb;
if ((i = win_device_io(VWIN32_DIOC_DOS_INT25,®s)) != DEVICE_OK)
return i;
if (regs.x.flags & 0x0001)
return DOS_ERR;
return DISK_OK;
}
/*
* disk_read_ioctl INT 21h/440Dh/61h
*
* Note: This function, and disk_write_ioctl, will fail under
* Windows 95 OSR2 (it's a bug in Windows 95; see Microsoft
* Knowledge Base Article # Q174569).
*
* However, INT 21h/440Dh/61h works fine with an MS-DOS
* program under Windows 95.
*
* This function fails under Windows 98 and Windows NT.
*/
extern int disk_read_ioctl(int disk, int track, int sec, int head, void *buf,
int nsecs)
{
int i;
struct RWBLOCK blk DBG_0;
blk.special = 0;
blk.head = (unsigned short)head;
blk.track = (unsigned short)track;
blk.sector = (unsigned short)(sec - 1);
blk.nsecs = (unsigned short)nsecs;
blk.buffer = buf;
/* try newer version first (FAT12, FAT16 and FAT32 support - maybe) */
if ((i = win_ioctl_ext(DOS_MINOR_READ_TRACK,disk+1,&blk)) != DEVICE_OK)
i = win_ioctl(DOS_MINOR_READ_TRACK,disk+1,&blk);
/*
TODO: Might want to catch certain errors before the retry -
Invalid Drive perhaps. But some errors such as Invalid Function
means that the older version must be tried.
*/
if (i == DEVICE_OK)
i = DISK_OK;
return i;
}
/*
* disk_read_ioctl32 INT 21h/440Dh/61h
*
* Note: This function, and disk_write_ioctl, will fail under
* Windows 95 OSR2 (it's a bug in Windows 95; see Microsoft
* Knowledge Base Article # Q174569).
*
* However, INT 21h/440Dh/61h works fine with an MS-DOS
* program under Windows 95.
*
* This function fails under Windows 98 and Windows NT.
*/
extern int disk_read_ioctl32(int disk, int track, int sec, int head, void *buf,
int nsecs)
{
int i;
struct RWBLOCK blk DBG_0;
blk.special = 0;
blk.head = (unsigned short)head;
blk.track = (unsigned short)track;
blk.sector = (unsigned short)(sec - 1);
blk.nsecs = (unsigned short)nsecs;
blk.buffer = buf;
/* try newer version first (FAT12, FAT16 and FAT32 support - maybe) */
i = win_ioctl_ext(DOS_MINOR_READ_TRACK,disk+1,&blk);
/*
TODO: Might want to catch certain errors before the retry -
Invalid Drive perhaps. But some errors such as Invalid Function
means that the older version must be tried.
*/
if (i == DEVICE_OK)
i = DISK_OK;
return i;
}
/*
* disk_read32 absolute disk read FAT32
*
*/
extern int disk_read32(int disk, long sec, void *buf, int nsecs)
{
int i;
struct DCB dcb DBG_0;
DIOC_REGISTERS regs DBG_0;
dcb.sector = sec;
dcb.number = (UINT16)nsecs;
dcb.buffer = buf;
regs.d.eax = DOS_EXT_ABS_READ_WRITE;
regs.d.edx = disk+1;
regs.d.ecx = (DWORD)-1;
regs.d.ebx = (DWORD)&dcb;
/* dangerous function! SI:0 MUST BE 0 for READ, 1 for WRITE */
regs.d.esi = DISK_READ;
/*
NOTE: Microsoft online help states that the device I/O
control code should be VWIN32_DIOC_DOS_IOCTL and states
that that value is 6. This is wrong in that the value of
6 is for VWIN32_DIOC_DOS_DRIVEINFO (...IOCTL is 1).
*/
if ((i = win_device_io(VWIN32_DIOC_DOS_DRIVEINFO,®s)) != DEVICE_OK)
return i;
if (regs.x.flags & 0x0001) {
return DOS_ERR;
}
return DISK_OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -