summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorJordan K. Hubbard <jkh@FreeBSD.org>1997-02-10 21:09:18 +0000
committerJordan K. Hubbard <jkh@FreeBSD.org>1997-02-10 21:09:18 +0000
commit00647e5628e6ead9c0a86c701a4e064b46293f4b (patch)
treebacf6017ec505d79da410c53af5cdf1a8e99541d /sys
parent582231348c205000612c979ff84b7d781653e6c9 (diff)
Notes
Diffstat (limited to 'sys')
-rw-r--r--sys/i386/isa/wcd.c33
1 files changed, 23 insertions, 10 deletions
diff --git a/sys/i386/isa/wcd.c b/sys/i386/isa/wcd.c
index 8c23421001f2..9e97f889f51b 100644
--- a/sys/i386/isa/wcd.c
+++ b/sys/i386/isa/wcd.c
@@ -41,6 +41,8 @@
#define F_DEBUG 0x0004 /* The media have changed since open */
#define F_NOPLAYCD 0x0008 /* The PLAY_CD op not supported */
+#define WCD_LASTPLUS1 170 /* Don't ask, xcdplayer uses this */
+
/*
* Disc table of contents.
*/
@@ -732,18 +734,31 @@ int wcdioctl (dev_t dev, int cmd, caddr_t addr, int flags, struct proc *p)
struct toc *toc = &t->toc;
struct toc buf;
u_long len;
+ u_char starting_track = te->starting_track;
if (! t->toc.hdr.ending_track)
return (EIO);
- if (te->starting_track < toc->hdr.starting_track ||
- te->starting_track > toc->hdr.ending_track)
+
+ if ( te->data_len < sizeof(toc->tab[0])
+ || (te->data_len % sizeof(toc->tab[0])) != 0
+ || te->address_format != CD_MSF_FORMAT
+ && te->address_format != CD_LBA_FORMAT
+ )
+ return (EINVAL);
+
+ if (starting_track == 0)
+ starting_track = toc->hdr.starting_track;
+ else if (starting_track == WCD_LASTPLUS1)
+ starting_track = toc->hdr.ending_track + 1;
+ else if (starting_track < toc->hdr.starting_track ||
+ starting_track > toc->hdr.ending_track + 1)
return (EINVAL);
- len = (toc->hdr.ending_track - te->starting_track + 2) *
+ len = (toc->hdr.ending_track + 2 - starting_track) *
sizeof(toc->tab[0]);
if (te->data_len < len)
len = te->data_len;
- if (len <= 0)
+ if (len > sizeof(toc->tab))
return (EINVAL);
/* Convert to MSF format, if needed. */
@@ -752,16 +767,14 @@ int wcdioctl (dev_t dev, int cmd, caddr_t addr, int flags, struct proc *p)
buf = t->toc;
toc = &buf;
- e = toc->tab + toc->hdr.ending_track -
- te->starting_track + 2;
+ e = toc->tab + toc->hdr.ending_track + 2 -
+ toc->hdr.starting_track;
while (--e >= toc->tab)
lba2msf (e->addr.lba, &e->addr.msf.minute,
&e->addr.msf.second, &e->addr.msf.frame);
}
- if (copyout (toc->tab + te->starting_track -
- toc->hdr.starting_track, te->data, len) != 0)
- error = EFAULT;
- break;
+ return copyout (toc->tab + starting_track -
+ toc->hdr.starting_track, te->data, len);
}
case CDIOCREADSUBCHANNEL: {
struct ioc_read_subchannel *args =