* fhandler.h (class fhandler_dev_raw): Delete current_position and

eof_detected status flag.  Delete is_eom and is_eof methods.
	Move drive_size, bytes_per_sector, eom_detected status flag, as well
	as the methods read_file, write_file, raw_read and raw_write to ...
	(class fhandler_dev_floppy): ... here. Remove is_eom and is_eof
	methods.  Add dup method.
	* fhandler_floppy.cc (IS_EOM): New macro.
	(fhandler_dev_floppy::is_eom): Remove.
	(fhandler_dev_floppy::is_eof): Remove.
	(fhandler_dev_floppy::fhandler_dev_floppy): Initialize status flags.
	(fhandler_dev_floppy::get_drive_info): Only call EX functions on
	systems supporting them and stop suffering strange delays.
	(fhandler_dev_floppy::read_file): Move here, drop setting
	current_position.
	(fhandler_dev_floppy::write_file): Move here, drop setting
	current_position.
	(fhandler_dev_floppy::open): Rearrange comment.
	(fhandler_dev_floppy::dup): New method.
	(fhandler_dev_floppy::get_current_position): New inline method.  Use
	instead of former current_position were appropriate.
	(fhandler_dev_floppy::raw_read): Move here.  Drop EOF handling.
	(fhandler_dev_floppy::raw_write): Move here.  Drop EOF handling.
	(fhandler_dev_floppy::lseek): Remove useless conditions.  Convert
	sector_aligned_offset to LARGE_INTEGER to improve SetFilePointer call.
	(fhandler_dev_floppy::ioctl): Move blocksize check in RDSETBLK case
	to here.
	* fhandler_raw.cc (fhandler_dev_raw::is_eom): Remove.
	(fhandler_dev_raw::is_eof): Remove.
	(fhandler_dev_raw::write_file): Remove.
	(fhandler_dev_raw::read_file): Remove.
	(fhandler_dev_raw::raw_read): Remove.
	(fhandler_dev_raw::raw_write): Remove.
	(fhandler_dev_raw::dup): Drop copying removed members.
	(fhandler_dev_raw::ioctl): Drop blocksize testing.
	* wincap.h: Implement has_disk_ex_ioctls throughout.
	* wincap.cc: Ditto.
	(wincap_vista): Preliminary wincaps for Windows Vista/Longhorn.
	(wincapc::init): Add Vista/Longhorn handling.
This commit is contained in:
Corinna Vinschen 2005-09-28 19:33:18 +00:00
parent dcb091caaf
commit f098767559
6 changed files with 428 additions and 346 deletions

View File

@ -1,3 +1,44 @@
2005-09-28 Corinna Vinschen <corinna@vinschen.de>
* fhandler.h (class fhandler_dev_raw): Delete current_position and
eof_detected status flag. Delete is_eom and is_eof methods.
Move drive_size, bytes_per_sector, eom_detected status flag, as well
as the methods read_file, write_file, raw_read and raw_write to ...
(class fhandler_dev_floppy): ... here. Remove is_eom and is_eof
methods. Add dup method.
* fhandler_floppy.cc (IS_EOM): New macro.
(fhandler_dev_floppy::is_eom): Remove.
(fhandler_dev_floppy::is_eof): Remove.
(fhandler_dev_floppy::fhandler_dev_floppy): Initialize status flags.
(fhandler_dev_floppy::get_drive_info): Only call EX functions on
systems supporting them and stop suffering strange delays.
(fhandler_dev_floppy::read_file): Move here, drop setting
current_position.
(fhandler_dev_floppy::write_file): Move here, drop setting
current_position.
(fhandler_dev_floppy::open): Rearrange comment.
(fhandler_dev_floppy::dup): New method.
(fhandler_dev_floppy::get_current_position): New inline method. Use
instead of former current_position were appropriate.
(fhandler_dev_floppy::raw_read): Move here. Drop EOF handling.
(fhandler_dev_floppy::raw_write): Move here. Drop EOF handling.
(fhandler_dev_floppy::lseek): Remove useless conditions. Convert
sector_aligned_offset to LARGE_INTEGER to improve SetFilePointer call.
(fhandler_dev_floppy::ioctl): Move blocksize check in RDSETBLK case
to here.
* fhandler_raw.cc (fhandler_dev_raw::is_eom): Remove.
(fhandler_dev_raw::is_eof): Remove.
(fhandler_dev_raw::write_file): Remove.
(fhandler_dev_raw::read_file): Remove.
(fhandler_dev_raw::raw_read): Remove.
(fhandler_dev_raw::raw_write): Remove.
(fhandler_dev_raw::dup): Drop copying removed members.
(fhandler_dev_raw::ioctl): Drop blocksize testing.
* wincap.h: Implement has_disk_ex_ioctls throughout.
* wincap.cc: Ditto.
(wincap_vista): Preliminary wincaps for Windows Vista/Longhorn.
(wincapc::init): Add Vista/Longhorn handling.
2005-09-28 Christopher Faylor <cgf@timesys.com> 2005-09-28 Christopher Faylor <cgf@timesys.com>
* dcrt0.cc (getstack): New function. * dcrt0.cc (getstack): New function.

View File

@ -551,50 +551,29 @@ public:
class fhandler_dev_raw: public fhandler_base class fhandler_dev_raw: public fhandler_base
{ {
protected: protected:
_off64_t drive_size;
_off64_t current_position;
unsigned long bytes_per_sector;
char *devbuf; char *devbuf;
size_t devbufsiz; size_t devbufsiz;
size_t devbufstart; size_t devbufstart;
size_t devbufend; size_t devbufend;
struct status_flags struct status_flags
{ {
unsigned eom_detected : 1;
unsigned eof_detected : 1;
unsigned lastblk_to_read : 1; unsigned lastblk_to_read : 1;
public: public:
status_flags () : status_flags () : lastblk_to_read (0) {}
eom_detected (0), eof_detected (0), lastblk_to_read (0)
{}
} status; } status;
IMPLEMENT_STATUS_FLAG (bool, eom_detected)
IMPLEMENT_STATUS_FLAG (bool, eof_detected)
IMPLEMENT_STATUS_FLAG (bool, lastblk_to_read) IMPLEMENT_STATUS_FLAG (bool, lastblk_to_read)
virtual BOOL write_file (const void *buf, DWORD to_write,
DWORD *written, int *err);
virtual BOOL read_file (void *buf, DWORD to_read, DWORD *read, int *err);
/* returns not null, if `win_error' determines an end of media condition */
virtual int is_eom(int win_error);
/* returns not null, if `win_error' determines an end of file condition */
virtual int is_eof(int win_error);
fhandler_dev_raw (); fhandler_dev_raw ();
public: public:
~fhandler_dev_raw (); ~fhandler_dev_raw ();
int open (int flags, mode_t mode = 0); int open (int flags, mode_t mode = 0);
void raw_read (void *ptr, size_t& ulen);
int raw_write (const void *ptr, size_t ulen);
int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2))); int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));
int dup (fhandler_base *child); int dup (fhandler_base *child);
int ioctl (unsigned int cmd, void *buf); int ioctl (unsigned int cmd, void *buf);
void fixup_after_fork (HANDLE); void fixup_after_fork (HANDLE);
@ -604,20 +583,32 @@ class fhandler_dev_raw: public fhandler_base
class fhandler_dev_floppy: public fhandler_dev_raw class fhandler_dev_floppy: public fhandler_dev_raw
{ {
private: private:
_off64_t drive_size;
unsigned long bytes_per_sector;
struct status_flags
{
unsigned eom_detected : 1;
public:
status_flags () : eom_detected (0) {}
} status;
IMPLEMENT_STATUS_FLAG (bool, eom_detected)
inline _off64_t get_current_position ();
int fhandler_dev_floppy::get_drive_info (struct hd_geometry *geo); int fhandler_dev_floppy::get_drive_info (struct hd_geometry *geo);
protected: BOOL write_file (const void *buf, DWORD to_write, DWORD *written, int *err);
virtual int is_eom (int win_error); BOOL read_file (void *buf, DWORD to_read, DWORD *read, int *err);
virtual int is_eof (int win_error);
public: public:
fhandler_dev_floppy (); fhandler_dev_floppy ();
virtual int open (int flags, mode_t mode = 0); int open (int flags, mode_t mode = 0);
int dup (fhandler_base *child);
virtual _off64_t lseek (_off64_t offset, int whence); void raw_read (void *ptr, size_t& ulen);
int raw_write (const void *ptr, size_t ulen);
virtual int ioctl (unsigned int cmd, void *buf); _off64_t lseek (_off64_t offset, int whence);
int ioctl (unsigned int cmd, void *buf);
}; };
class fhandler_dev_tape: public fhandler_dev_raw class fhandler_dev_tape: public fhandler_dev_raw

View File

@ -14,6 +14,7 @@ details. */
#include <unistd.h> #include <unistd.h>
#include <winioctl.h> #include <winioctl.h>
#include <asm/socket.h> #include <asm/socket.h>
#include <cygwin/rdevio.h>
#include <cygwin/hdreg.h> #include <cygwin/hdreg.h>
#include <cygwin/fs.h> #include <cygwin/fs.h>
#include "cygerrno.h" #include "cygerrno.h"
@ -21,31 +22,15 @@ details. */
#include "path.h" #include "path.h"
#include "fhandler.h" #include "fhandler.h"
#define IS_EOM(err) ((err) == ERROR_INVALID_PARAMETER \
|| (err) == ERROR_SEEK \
|| (err) == ERROR_SECTOR_NOT_FOUND)
/**********************************************************************/ /**********************************************************************/
/* fhandler_dev_floppy */ /* fhandler_dev_floppy */
int
fhandler_dev_floppy::is_eom (int win_error)
{
int ret = (win_error == ERROR_INVALID_PARAMETER
|| win_error == ERROR_SEEK
|| win_error == ERROR_SECTOR_NOT_FOUND);
if (ret)
debug_printf ("end of medium");
return ret;
}
int
fhandler_dev_floppy::is_eof (int)
{
int ret = 0;
if (ret)
debug_printf ("end of file");
return ret;
}
fhandler_dev_floppy::fhandler_dev_floppy () fhandler_dev_floppy::fhandler_dev_floppy ()
: fhandler_dev_raw () : fhandler_dev_raw (), status ()
{ {
} }
@ -62,9 +47,22 @@ fhandler_dev_floppy::get_drive_info (struct hd_geometry *geo)
/* Always try using the new EX ioctls first (>= XP). If not available, /* Always try using the new EX ioctls first (>= XP). If not available,
fall back to trying the old non-EX ioctls. */ fall back to trying the old non-EX ioctls. */
if (wincap.has_disk_ex_ioctls ())
{
if (!DeviceIoControl (get_handle (), if (!DeviceIoControl (get_handle (),
IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, NULL, 0, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, NULL, 0,
dbuf, 256, &bytes_read, NULL)) dbuf, 256, &bytes_read, NULL))
{
__seterrno ();
return -1;
}
di = &((DISK_GEOMETRY_EX *) dbuf)->Geometry;
if (DeviceIoControl (get_handle (),
IOCTL_DISK_GET_PARTITION_INFO_EX, NULL, 0,
pbuf, 256, &bytes_read, NULL))
pix = (PARTITION_INFORMATION_EX *) pbuf;
}
else
{ {
if (!DeviceIoControl (get_handle (), if (!DeviceIoControl (get_handle (),
IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0,
@ -74,18 +72,11 @@ fhandler_dev_floppy::get_drive_info (struct hd_geometry *geo)
return -1; return -1;
} }
di = (DISK_GEOMETRY *) dbuf; di = (DISK_GEOMETRY *) dbuf;
}
else
di = &((DISK_GEOMETRY_EX *) dbuf)->Geometry;
if (DeviceIoControl (get_handle (), if (DeviceIoControl (get_handle (),
IOCTL_DISK_GET_PARTITION_INFO_EX, NULL, 0,
pbuf, 256, &bytes_read, NULL))
pix = (PARTITION_INFORMATION_EX *) pbuf;
else if (DeviceIoControl (get_handle (),
IOCTL_DISK_GET_PARTITION_INFO, NULL, 0, IOCTL_DISK_GET_PARTITION_INFO, NULL, 0,
pbuf, 256, &bytes_read, NULL)) pbuf, 256, &bytes_read, NULL))
pi = (PARTITION_INFORMATION *) pbuf; pi = (PARTITION_INFORMATION *) pbuf;
}
debug_printf ("disk geometry: (%ld cyl)*(%ld trk)*(%ld sec)*(%ld bps)", debug_printf ("disk geometry: (%ld cyl)*(%ld trk)*(%ld sec)*(%ld bps)",
di->Cylinders.LowPart, di->Cylinders.LowPart,
@ -132,22 +123,46 @@ fhandler_dev_floppy::get_drive_info (struct hd_geometry *geo)
return 0; return 0;
} }
/* Wrapper functions for ReadFile and WriteFile to simplify error handling. */
BOOL
fhandler_dev_floppy::read_file (void *buf, DWORD to_read, DWORD *read, int *err)
{
BOOL ret;
*err = 0;
if (!(ret = ReadFile (get_handle (), buf, to_read, read, 0)))
*err = GetLastError ();
syscall_printf ("%d (err %d) = ReadFile (%d, %d, to_read %d, read %d, 0)",
ret, *err, get_handle (), buf, to_read, *read);
return ret;
}
BOOL
fhandler_dev_floppy::write_file (const void *buf, DWORD to_write,
DWORD *written, int *err)
{
BOOL ret;
*err = 0;
if (!(ret = WriteFile (get_handle (), buf, to_write, written, 0)))
*err = GetLastError ();
syscall_printf ("%d (err %d) = WriteFile (%d, %d, write %d, written %d, 0)",
ret, *err, get_handle (), buf, to_write, *written);
return ret;
}
int int
fhandler_dev_floppy::open (int flags, mode_t) fhandler_dev_floppy::open (int flags, mode_t)
{ {
/* The correct size of the buffer would be 512 bytes, /* The correct size of the buffer would be 512 bytes, which is the atomic
* which is the atomic size, supported by WinNT. size, supported by WinNT. Unfortunately, the performance is worse than
* Unfortunately, the performance is worse than access to file system on same device! Setting buffer size to a
* access to file system on same device! relatively big value increases performance by means. The new ioctl call
* Setting buffer size to a relatively big value with 'rdevio.h' header file supports changing this value.
* increases performance by means.
* The new ioctl call with 'rdevio.h' header file Let's try to be smart: Let's take a multiple of typical tar and cpio
* supports changing this value. buffer sizes by default. */
* devbufsiz = 61440L;
* Let's be smart: Let's take a multiplier of typical tar
* and cpio buffer sizes by default!
*/
devbufsiz = 61440L; /* 512L; */
int ret = fhandler_dev_raw::open (flags); int ret = fhandler_dev_raw::open (flags);
if (ret && get_drive_info (NULL)) if (ret && get_drive_info (NULL))
@ -159,59 +174,244 @@ fhandler_dev_floppy::open (int flags, mode_t)
return ret; return ret;
} }
int
fhandler_dev_floppy::dup (fhandler_base *child)
{
int ret = fhandler_dev_raw::dup (child);
if (!ret)
{
fhandler_dev_floppy *fhc = (fhandler_dev_floppy *) child;
fhc->drive_size = drive_size;
fhc->bytes_per_sector = bytes_per_sector;
fhc->eom_detected (eom_detected ());
}
return ret;
}
inline _off64_t
fhandler_dev_floppy::get_current_position ()
{
LARGE_INTEGER off = { QuadPart: 0LL };
off.LowPart = SetFilePointer (get_handle (), 0, &off.HighPart, FILE_CURRENT);
return off.QuadPart;
}
void
fhandler_dev_floppy::raw_read (void *ptr, size_t& ulen)
{
DWORD bytes_read = 0;
DWORD read2;
DWORD bytes_to_read;
int ret;
size_t len = ulen;
char *tgt;
char *p = (char *) ptr;
/* Checking a previous end of media */
if (eom_detected () && !lastblk_to_read ())
{
set_errno (ENOSPC);
goto err;
}
if (devbuf)
{
while (len > 0)
{
if (devbufstart < devbufend)
{
bytes_to_read = min (len, devbufend - devbufstart);
debug_printf ("read %d bytes from buffer (rest %d)",
bytes_to_read,
devbufend - devbufstart - bytes_to_read);
memcpy (p, devbuf + devbufstart, bytes_to_read);
len -= bytes_to_read;
p += bytes_to_read;
bytes_read += bytes_to_read;
devbufstart += bytes_to_read;
if (lastblk_to_read ())
{
lastblk_to_read (false);
break;
}
}
if (len > 0)
{
if (len >= devbufsiz)
{
bytes_to_read = (len / bytes_per_sector) * bytes_per_sector;
tgt = p;
}
else
{
tgt = devbuf;
bytes_to_read = devbufsiz;
}
_off64_t current_position = get_current_position ();
if (current_position + bytes_to_read >= drive_size)
bytes_to_read = drive_size - current_position;
if (!bytes_to_read)
{
eom_detected (true);
break;
}
debug_printf ("read %d bytes %s", bytes_to_read,
len < devbufsiz ? "into buffer" : "directly");
if (!read_file (tgt, bytes_to_read, &read2, &ret))
{
if (!IS_EOM (ret))
{
__seterrno ();
goto err;
}
eom_detected (true);
if (!read2)
{
if (!bytes_read)
{
debug_printf ("return -1, set errno to ENOSPC");
set_errno (ENOSPC);
goto err;
}
break;
}
lastblk_to_read (true);
}
if (!read2)
break;
if (tgt == devbuf)
{
devbufstart = 0;
devbufend = read2;
}
else
{
len -= read2;
p += read2;
bytes_read += read2;
}
}
}
}
else if (!read_file (p, len, &bytes_read, &ret))
{
if (!IS_EOM (ret))
{
__seterrno ();
goto err;
}
if (bytes_read)
eom_detected (true);
else
{
debug_printf ("return -1, set errno to ENOSPC");
set_errno (ENOSPC);
goto err;
}
}
ulen = (size_t) bytes_read;
return;
err:
ulen = (size_t) -1;
}
int
fhandler_dev_floppy::raw_write (const void *ptr, size_t len)
{
DWORD bytes_written = 0;
char *p = (char *) ptr;
int ret;
/* Checking a previous end of media on tape */
if (eom_detected ())
{
set_errno (ENOSPC);
return -1;
}
/* Invalidate buffer. */
devbufstart = devbufend = 0;
if (len > 0)
{
if (!write_file (p, len, &bytes_written, &ret))
{
if (!IS_EOM (ret))
{
__seterrno ();
return -1;
}
eom_detected (true);
if (!bytes_written)
{
set_errno (ENOSPC);
return -1;
}
}
}
return bytes_written;
}
_off64_t _off64_t
fhandler_dev_floppy::lseek (_off64_t offset, int whence) fhandler_dev_floppy::lseek (_off64_t offset, int whence)
{ {
char buf[512]; char buf[512];
_off64_t lloffset = offset; _off64_t lloffset = offset;
_off64_t sector_aligned_offset; LARGE_INTEGER sector_aligned_offset;
_off64_t bytes_left; _off64_t bytes_left;
DWORD low;
LONG high = 0;
if (whence == SEEK_END && drive_size > 0) if (whence == SEEK_END)
{ {
lloffset = offset + drive_size; lloffset += drive_size;
whence = SEEK_SET;
}
else if (whence == SEEK_CUR)
{
lloffset += get_current_position () - (devbufend - devbufstart);
whence = SEEK_SET; whence = SEEK_SET;
} }
if (whence == SEEK_CUR) if (whence != SEEK_SET || lloffset < 0 || lloffset >= drive_size)
{
lloffset += current_position - (devbufend - devbufstart);
whence = SEEK_SET;
}
if (whence != SEEK_SET
|| lloffset < 0
|| drive_size > 0 && lloffset >= drive_size)
{ {
set_errno (EINVAL); set_errno (EINVAL);
return -1; return -1;
} }
sector_aligned_offset = (lloffset / bytes_per_sector) * bytes_per_sector; sector_aligned_offset.QuadPart = (lloffset / bytes_per_sector)
bytes_left = lloffset - sector_aligned_offset; * bytes_per_sector;
bytes_left = lloffset - sector_aligned_offset.QuadPart;
/* Invalidate buffer. */ /* Invalidate buffer. */
devbufstart = devbufend = 0; devbufstart = devbufend = 0;
low = sector_aligned_offset & UINT32_MAX; sector_aligned_offset.LowPart =
high = sector_aligned_offset >> 32; SetFilePointer (get_handle (),
if (SetFilePointer (get_handle (), low, &high, FILE_BEGIN) sector_aligned_offset.LowPart,
== INVALID_SET_FILE_POINTER && GetLastError ()) &sector_aligned_offset.HighPart,
FILE_BEGIN);
if (sector_aligned_offset.LowPart == INVALID_SET_FILE_POINTER
&& GetLastError ())
{ {
__seterrno (); __seterrno ();
return -1; return -1;
} }
eom_detected (false); eom_detected (false);
current_position = sector_aligned_offset;
if (bytes_left) if (bytes_left)
{ {
size_t len = bytes_left; size_t len = bytes_left;
raw_read (buf, len); raw_read (buf, len);
} }
return current_position + bytes_left; return sector_aligned_offset.QuadPart + bytes_left;
} }
int int
@ -257,6 +457,18 @@ fhandler_dev_floppy::ioctl (unsigned int cmd, void *buf)
*(int *)buf = bytes_per_sector; *(int *)buf = bytes_per_sector;
return 0; return 0;
} }
case RDSETBLK:
/* Just check the restriction that blocksize must be a multiple
of the sector size of the underlying volume sector size,
then fall through to fhandler_dev_raw::ioctl. */
struct rdop *op = (struct rdop *) buf;
if (op->rd_parm % bytes_per_sector)
{
SetLastError (ERROR_INVALID_PARAMETER);
__seterrno ();
return -1;
}
/*FALLTHRUGH*/
default: default:
return fhandler_dev_raw::ioctl (cmd, buf); return fhandler_dev_raw::ioctl (cmd, buf);
} }

View File

@ -27,52 +27,6 @@
/**********************************************************************/ /**********************************************************************/
/* fhandler_dev_raw */ /* fhandler_dev_raw */
int
fhandler_dev_raw::is_eom (int win_error)
{
return 0;
}
int
fhandler_dev_raw::is_eof (int)
{
return 0;
}
/* Wrapper functions to simplify error handling. */
BOOL
fhandler_dev_raw::write_file (const void *buf, DWORD to_write,
DWORD *written, int *err)
{
BOOL ret;
*err = 0;
if (!(ret = WriteFile (get_handle (), buf, to_write, written, 0)))
*err = GetLastError ();
else
current_position += *written;
syscall_printf ("%d (err %d) = WriteFile (%d, %d, write %d, written %d, 0)",
ret, *err, get_handle (), buf, to_write, *written);
return ret;
}
BOOL
fhandler_dev_raw::read_file (void *buf, DWORD to_read, DWORD *read, int *err)
{
BOOL ret;
*err = 0;
if (!(ret = ReadFile (get_handle (), buf, to_read, read, 0)))
*err = GetLastError ();
else
current_position += *read;
syscall_printf ("%d (err %d) = ReadFile (%d, %d, to_read %d, read %d, 0)",
ret, *err, get_handle (), buf, to_read, *read);
return ret;
}
fhandler_dev_raw::fhandler_dev_raw () fhandler_dev_raw::fhandler_dev_raw ()
: fhandler_base (), status () : fhandler_base (), status ()
{ {
@ -140,186 +94,6 @@ fhandler_dev_raw::open (int flags, mode_t)
return res; return res;
} }
void
fhandler_dev_raw::raw_read (void *ptr, size_t& ulen)
{
DWORD bytes_read = 0;
DWORD read2;
DWORD bytes_to_read;
int ret;
size_t len = ulen;
char *tgt;
char *p = (char *) ptr;
/* Checking a previous end of file */
if (eof_detected () && !lastblk_to_read ())
{
eof_detected (false);
ulen = 0;
return;
}
/* Checking a previous end of media */
if (eom_detected () && !lastblk_to_read ())
{
set_errno (ENOSPC);
goto err;
}
if (devbuf)
{
while (len > 0)
{
if (devbufstart < devbufend)
{
bytes_to_read = min (len, devbufend - devbufstart);
debug_printf ("read %d bytes from buffer (rest %d)",
bytes_to_read,
devbufend - devbufstart - bytes_to_read);
memcpy (p, devbuf + devbufstart, bytes_to_read);
len -= bytes_to_read;
p += bytes_to_read;
bytes_read += bytes_to_read;
devbufstart += bytes_to_read;
if (lastblk_to_read ())
{
lastblk_to_read (false);
break;
}
}
if (len > 0)
{
if (len >= devbufsiz)
{
bytes_to_read = (len / bytes_per_sector) * bytes_per_sector;
if (current_position + bytes_to_read >= drive_size)
bytes_to_read = drive_size - current_position;
tgt = p;
debug_printf ("read %d bytes direct from file",bytes_to_read);
}
else
{
tgt = devbuf;
bytes_to_read = devbufsiz;
if (current_position + bytes_to_read >= drive_size)
bytes_to_read = drive_size - current_position;
debug_printf ("read %d bytes from file into buffer",
bytes_to_read);
}
if (!bytes_to_read)
{
eom_detected (true);
break;
}
if (!read_file (tgt, bytes_to_read, &read2, &ret))
{
if (!is_eof (ret) && !is_eom (ret))
{
__seterrno ();
goto err;
}
if (is_eof (ret))
eof_detected (true);
else
eom_detected (true);
if (!read2)
{
if (!bytes_read && is_eom (ret))
{
debug_printf ("return -1, set errno to ENOSPC");
set_errno (ENOSPC);
goto err;
}
break;
}
lastblk_to_read (true);
}
if (!read2)
break;
if (tgt == devbuf)
{
devbufstart = 0;
devbufend = read2;
}
else
{
len -= read2;
p += read2;
bytes_read += read2;
}
}
}
}
else if (!read_file (p, len, &bytes_read, &ret))
{
if (!is_eof (ret) && !is_eom (ret))
{
__seterrno ();
goto err;
}
if (bytes_read)
{
if (is_eof (ret))
eof_detected (true);
else
eom_detected (true);
}
else if (is_eom (ret))
{
debug_printf ("return -1, set errno to ENOSPC");
set_errno (ENOSPC);
goto err;
}
}
ulen = (size_t) bytes_read;
return;
err:
ulen = (size_t) -1;
}
int
fhandler_dev_raw::raw_write (const void *ptr, size_t len)
{
DWORD bytes_written = 0;
char *p = (char *) ptr;
int ret;
/* Checking a previous end of media on tape */
if (eom_detected ())
{
set_errno (ENOSPC);
return -1;
}
/* Invalidate buffer. */
devbufstart = devbufend = 0;
if (len > 0)
{
if (!write_file (p, len, &bytes_written, &ret))
{
if (!is_eom (ret))
{
__seterrno ();
return -1;
}
eom_detected (true);
if (!bytes_written)
{
set_errno (ENOSPC);
return -1;
}
}
}
return bytes_written;
}
int int
fhandler_dev_raw::dup (fhandler_base *child) fhandler_dev_raw::dup (fhandler_base *child)
{ {
@ -329,16 +103,11 @@ fhandler_dev_raw::dup (fhandler_base *child)
{ {
fhandler_dev_raw *fhc = (fhandler_dev_raw *) child; fhandler_dev_raw *fhc = (fhandler_dev_raw *) child;
fhc->drive_size = drive_size;
fhc->current_position = current_position;
fhc->bytes_per_sector = bytes_per_sector;
fhc->devbufsiz = devbufsiz; fhc->devbufsiz = devbufsiz;
if (devbufsiz > 1L) if (devbufsiz > 1L)
fhc->devbuf = new char [devbufsiz]; fhc->devbuf = new char [devbufsiz];
fhc->devbufstart = 0; fhc->devbufstart = 0;
fhc->devbufend = 0; fhc->devbufend = 0;
fhc->eom_detected (eom_detected ());
fhc->eof_detected (eof_detected ());
fhc->lastblk_to_read (false); fhc->lastblk_to_read (false);
} }
return ret; return ret;
@ -385,8 +154,6 @@ fhandler_dev_raw::ioctl (unsigned int cmd, void *buf)
mop.mt_count = op->rd_parm; mop.mt_count = op->rd_parm;
ret = ioctl (MTIOCTOP, &mop); ret = ioctl (MTIOCTOP, &mop);
} }
else if (op->rd_parm % bytes_per_sector)
ret = ERROR_INVALID_PARAMETER;
else if (devbuf && op->rd_parm < devbufend - devbufstart) else if (devbuf && op->rd_parm < devbufend - devbufstart)
ret = ERROR_INVALID_PARAMETER; ret = ERROR_INVALID_PARAMETER;
else if (!devbuf || op->rd_parm != devbufsiz) else if (!devbuf || op->rd_parm != devbufsiz)

View File

@ -59,7 +59,8 @@ static NO_COPY wincaps wincap_unknown = {
has_extended_priority_class:false, has_extended_priority_class:false,
has_guid_volumes:false, has_guid_volumes:false,
detect_win16_exe:true, detect_win16_exe:true,
has_null_console_handler_routine:false has_null_console_handler_routine:false,
has_disk_ex_ioctls:false
}; };
static NO_COPY wincaps wincap_95 = { static NO_COPY wincaps wincap_95 = {
@ -110,7 +111,8 @@ static NO_COPY wincaps wincap_95 = {
has_extended_priority_class:false, has_extended_priority_class:false,
has_guid_volumes:false, has_guid_volumes:false,
detect_win16_exe:true, detect_win16_exe:true,
has_null_console_handler_routine:false has_null_console_handler_routine:false,
has_disk_ex_ioctls:false
}; };
static NO_COPY wincaps wincap_95osr2 = { static NO_COPY wincaps wincap_95osr2 = {
@ -161,7 +163,8 @@ static NO_COPY wincaps wincap_95osr2 = {
has_extended_priority_class:false, has_extended_priority_class:false,
has_guid_volumes:false, has_guid_volumes:false,
detect_win16_exe:true, detect_win16_exe:true,
has_null_console_handler_routine:false has_null_console_handler_routine:false,
has_disk_ex_ioctls:false
}; };
static NO_COPY wincaps wincap_98 = { static NO_COPY wincaps wincap_98 = {
@ -212,7 +215,8 @@ static NO_COPY wincaps wincap_98 = {
has_extended_priority_class:false, has_extended_priority_class:false,
has_guid_volumes:false, has_guid_volumes:false,
detect_win16_exe:true, detect_win16_exe:true,
has_null_console_handler_routine:false has_null_console_handler_routine:false,
has_disk_ex_ioctls:false
}; };
static NO_COPY wincaps wincap_98se = { static NO_COPY wincaps wincap_98se = {
@ -263,7 +267,8 @@ static NO_COPY wincaps wincap_98se = {
has_extended_priority_class:false, has_extended_priority_class:false,
has_guid_volumes:false, has_guid_volumes:false,
detect_win16_exe:true, detect_win16_exe:true,
has_null_console_handler_routine:false has_null_console_handler_routine:false,
has_disk_ex_ioctls:false
}; };
static NO_COPY wincaps wincap_me = { static NO_COPY wincaps wincap_me = {
@ -314,7 +319,8 @@ static NO_COPY wincaps wincap_me = {
has_extended_priority_class:false, has_extended_priority_class:false,
has_guid_volumes:false, has_guid_volumes:false,
detect_win16_exe:true, detect_win16_exe:true,
has_null_console_handler_routine:false has_null_console_handler_routine:false,
has_disk_ex_ioctls:false
}; };
static NO_COPY wincaps wincap_nt3 = { static NO_COPY wincaps wincap_nt3 = {
@ -365,7 +371,8 @@ static NO_COPY wincaps wincap_nt3 = {
has_extended_priority_class:false, has_extended_priority_class:false,
has_guid_volumes:false, has_guid_volumes:false,
detect_win16_exe:false, detect_win16_exe:false,
has_null_console_handler_routine:true has_null_console_handler_routine:true,
has_disk_ex_ioctls:false
}; };
static NO_COPY wincaps wincap_nt4 = { static NO_COPY wincaps wincap_nt4 = {
@ -416,7 +423,8 @@ static NO_COPY wincaps wincap_nt4 = {
has_extended_priority_class:false, has_extended_priority_class:false,
has_guid_volumes:false, has_guid_volumes:false,
detect_win16_exe:false, detect_win16_exe:false,
has_null_console_handler_routine:true has_null_console_handler_routine:true,
has_disk_ex_ioctls:false
}; };
static NO_COPY wincaps wincap_nt4sp4 = { static NO_COPY wincaps wincap_nt4sp4 = {
@ -467,7 +475,8 @@ static NO_COPY wincaps wincap_nt4sp4 = {
has_extended_priority_class:false, has_extended_priority_class:false,
has_guid_volumes:false, has_guid_volumes:false,
detect_win16_exe:false, detect_win16_exe:false,
has_null_console_handler_routine:true has_null_console_handler_routine:true,
has_disk_ex_ioctls:false
}; };
static NO_COPY wincaps wincap_2000 = { static NO_COPY wincaps wincap_2000 = {
@ -518,7 +527,8 @@ static NO_COPY wincaps wincap_2000 = {
has_extended_priority_class:true, has_extended_priority_class:true,
has_guid_volumes:true, has_guid_volumes:true,
detect_win16_exe:false, detect_win16_exe:false,
has_null_console_handler_routine:true has_null_console_handler_routine:true,
has_disk_ex_ioctls:false
}; };
static NO_COPY wincaps wincap_xp = { static NO_COPY wincaps wincap_xp = {
@ -569,7 +579,8 @@ static NO_COPY wincaps wincap_xp = {
has_extended_priority_class:true, has_extended_priority_class:true,
has_guid_volumes:true, has_guid_volumes:true,
detect_win16_exe:false, detect_win16_exe:false,
has_null_console_handler_routine:true has_null_console_handler_routine:true,
has_disk_ex_ioctls:true
}; };
static NO_COPY wincaps wincap_2003 = { static NO_COPY wincaps wincap_2003 = {
@ -620,7 +631,60 @@ static NO_COPY wincaps wincap_2003 = {
has_extended_priority_class:true, has_extended_priority_class:true,
has_guid_volumes:true, has_guid_volumes:true,
detect_win16_exe:false, detect_win16_exe:false,
has_null_console_handler_routine:true has_null_console_handler_routine:true,
has_disk_ex_ioctls:true
};
static NO_COPY wincaps wincap_vista = {
lock_file_highword:UINT32_MAX,
chunksize:0,
shared:FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
is_winnt:true,
is_server:true,
access_denied_on_delete:false,
has_delete_on_close:true,
has_page_guard:true,
has_security:true,
has_security_descriptor_control:true,
has_get_process_times:true,
has_lseek_bug:false,
has_lock_file_ex:true,
has_signal_object_and_wait:true,
has_eventlog:true,
has_ip_helper_lib:true,
has_set_handle_information:true,
has_set_handle_information_on_console_handles:true,
supports_smp:true,
map_view_of_file_ex_sucks:false,
altgr_is_ctrl_alt:true,
has_physical_mem_access:true,
has_working_copy_on_write:true,
share_mmaps_only_by_name:false,
virtual_protect_works_on_shared_pages:true,
has_hard_links:true,
can_open_directories:true,
has_move_file_ex:true,
has_negative_pids:false,
has_unreliable_pipes:false,
has_named_pipes:true,
has_try_enter_critical_section:true,
has_raw_devices:true,
has_valid_processorlevel:true,
has_64bit_file_access:true,
has_process_io_counters:true,
supports_reading_modem_output_lines:true,
needs_memory_protection:true,
pty_needs_alloc_console:true,
has_terminal_services:true,
has_switch_to_thread:true,
cant_debug_dll_entry:false,
has_ioctl_storage_get_media_types_ex:true,
start_proc_suspended:false,
has_extended_priority_class:true,
has_guid_volumes:true,
detect_win16_exe:false,
has_null_console_handler_routine:true,
has_disk_ex_ioctls:true
}; };
wincapc wincap; wincapc wincap;
@ -676,6 +740,11 @@ wincapc::init ()
caps = &wincap_2003; caps = &wincap_2003;
} }
break; break;
case 6:
os = "NT";
has_osversioninfoex = true;
caps = &wincap_vista;
break;
default: default:
os = "??"; os = "??";
caps = &wincap_unknown; caps = &wincap_unknown;

View File

@ -61,6 +61,7 @@ struct wincaps
unsigned has_guid_volumes : 1; unsigned has_guid_volumes : 1;
unsigned detect_win16_exe : 1; unsigned detect_win16_exe : 1;
unsigned has_null_console_handler_routine : 1; unsigned has_null_console_handler_routine : 1;
unsigned has_disk_ex_ioctls : 1;
}; };
class wincapc class wincapc
@ -126,6 +127,7 @@ public:
bool IMPLEMENT (has_guid_volumes) bool IMPLEMENT (has_guid_volumes)
bool IMPLEMENT (detect_win16_exe) bool IMPLEMENT (detect_win16_exe)
bool IMPLEMENT (has_null_console_handler_routine) bool IMPLEMENT (has_null_console_handler_routine)
bool IMPLEMENT (has_disk_ex_ioctls)
#undef IMPLEMENT #undef IMPLEMENT
}; };