📄 cdaccess.c
字号:
/* * cdaccess.c * System-dependent code to access extended CD information * * Based on a contribution by Erik Andersen * * Copyright (c) 2003 Christoph Pfisterer * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, copy, * modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */#include "detect.h"#ifdef USE_IOCTL_LINUX#include <sys/ioctl.h>#include <linux/cdrom.h>#define DO_CDACCESS 1#endif /* USE_IOCTL_LINUX */#ifdef DO_CDACCESS/* * CDDB stuff */static int cddb_sum(int n);#define LBA_TO_SECS(lba) (((lba) + 150) / 75)/* * CD structure: * Tries to get the CD TOC using out-of-band means (i.e. ioctl()), * prints the info, and analyzes just the data tracks. Quite * system-dependent, but layed out for porability. */int analyze_cdaccess(int fd, SOURCE *s, int level) { int i; int first, last, ntracks; int cksum, totaltime, seconds; U32 diskid; U8 ctrl[100]; U32 lba[100], length; char human_readable_size[256];#ifdef USE_IOCTL_LINUX struct cdrom_tochdr tochdr; struct cdrom_tocentry tocentry;#endif /* read TOC header */#ifdef USE_IOCTL_LINUX if (ioctl(fd, CDROMREADTOCHDR, &tochdr) < 0) { return 0; } first = tochdr.cdth_trk0; last = tochdr.cdth_trk1;#else return 0;#endif ntracks = last + 1 - first; if (ntracks > 99) /* natural limit */ return 0; /* read per-track data from TOC */ for (i = 0; i <= ntracks; i++) {#ifdef USE_IOCTL_LINUX if (i == ntracks) tocentry.cdte_track = CDROM_LEADOUT; else tocentry.cdte_track = first + i; tocentry.cdte_format = CDROM_LBA; if (ioctl(fd, CDROMREADTOCENTRY, &tocentry) < 0) { //printf("CDROMREADTOCENTRY: %s: ", strerror(errno)); return 0; } ctrl[i] = tocentry.cdte_ctrl; lba[i] = tocentry.cdte_addr.lba;#endif } /* System-dependent code ends here. From now on, we use the data in first, last, ntracks, ctrl[], and lba[]. We also assume all systems treat actual data access the same way... */ /* calculate CDDB disk id */ cksum = 0; for (i = 0; i < ntracks; i++) { cksum += cddb_sum(LBA_TO_SECS(lba[i])); } totaltime = LBA_TO_SECS(lba[ntracks]) - LBA_TO_SECS(lba[0]); diskid = (U32)(cksum % 0xff) << 24 | (U32)totaltime << 8 | (U32)ntracks; /* print disk info */ print_line(level, "CD-ROM, %d track%s, CDDB disk ID %08lX", ntracks, (ntracks != 1) ? "s" : "", diskid); /* Loop over each track */ for (i = 0; i < ntracks; i++) { /* length of track in sectors */ length = lba[i+1] - lba[i]; if ((ctrl[i] & 0x4) == 0) { /* Audio track, one sector holds 2352 actual data bytes */ seconds = length / 75; format_size(human_readable_size, (U64)length * 2352); print_line(level, "Track %d: Audio track, %s, %3d min %02d sec", first + i, human_readable_size, seconds / 60, seconds % 60); } else { /* Data track, one sector holds 2048 actual data bytes */ format_size(human_readable_size, length * 2048); print_line(level, "Track %d: Data track, %s", first + i, human_readable_size); /* NOTE: we adjust the length to stay clear of padding or post-gap stuff */ analyze_source_special(s, level + 1, (U64)lba[i] * 2048, (U64)(length - 250) * 2048); } } return 1;}/* * helper function: calculate cddb disk id */static int cddb_sum(int n) { /* a number like 2344 becomes 2+3+4+4 (13) */ int ret = 0; while (n > 0) { ret = ret + (n % 10); n = n / 10; } return ret;}#else /* DO_CDACCESS *//** the system is not supported, so use a dummy function*/int analyze_cdaccess(int fd, SOURCE *s, int level) { return 0;}#endif /* DO_CDACCESS *//* EOF */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -