From 50b48aec6ddd451a6d1709c0942477b503457663 Mon Sep 17 00:00:00 2001 From: tpearson Date: Wed, 3 Feb 2010 02:15:56 +0000 Subject: Added abandoned KDE3 version of K3B git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/k3b@1084400 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- libk3b/tools/k3biso9660.cpp | 899 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 899 insertions(+) create mode 100644 libk3b/tools/k3biso9660.cpp (limited to 'libk3b/tools/k3biso9660.cpp') diff --git a/libk3b/tools/k3biso9660.cpp b/libk3b/tools/k3biso9660.cpp new file mode 100644 index 0000000..84edc4b --- /dev/null +++ b/libk3b/tools/k3biso9660.cpp @@ -0,0 +1,899 @@ +/* + * + * $Id: k3biso9660.cpp 690529 2007-07-21 10:51:47Z trueg $ + * Copyright (C) 2003 Sebastian Trueg + * + * This file is part of the K3b project. + * Copyright (C) 1998-2007 Sebastian Trueg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * See the file "COPYING" for the exact licensing terms. + */ + +#include +#include + +#include "k3biso9660.h" +#include "k3biso9660backend.h" + +#include + +#include "libisofs/isofs.h" + +#include +#include +#include +#include + +#include + + +/* callback function for libisofs */ +int K3bIso9660::read_callback( char* buf, sector_t start, int len, void* udata ) +{ + K3bIso9660* isoF = static_cast(udata); + + return isoF->read( start, buf, len ); +} + +/* callback function for libisofs */ +int K3bIso9660::isofs_callback( struct iso_directory_record *idr, void *udata ) +{ + K3bIso9660 *iso = static_cast (udata); + QString path, isoPath,user,group,symlink; + int i; + int access; + int time,cdate,adate; + rr_entry rr; + bool special=false; + K3bIso9660Entry *entry=0; + //K3bIso9660Entry *oldentry=0; + char z_algo[2],z_params[2]; + int z_size=0; + + if (isonum_711(idr->name_len)==1) { + switch (idr->name[0]) { + case 0: + path+=("."); + special=true; + break; + case 1: + path+=(".."); + special=true; + break; + } + } + // + // First extract the raw iso9660 name + // + if( !special ) { + for( i = 0; i < isonum_711( idr->name_len ); i++ ) { + if( idr->name[i] ) + isoPath += idr->name[i]; + } + } + else + isoPath = path; + + // + // Now see if we have RockRidge + // + if( !iso->plainIso9660() && ParseRR(idr,&rr) > 0 ) { + iso->m_rr = true; + if (!special) + path = QString::fromLocal8Bit( rr.name ); + symlink=rr.sl; + access=rr.mode; + time=0;//rr.st_mtime; + adate=0;//rr.st_atime; + cdate=0;//rr.st_ctime; + user.setNum(rr.uid); + group.setNum(rr.gid); + z_algo[0]=rr.z_algo[0];z_algo[1]=rr.z_algo[1]; + z_params[0]=rr.z_params[0];z_params[1]=rr.z_params[1]; + z_size=rr.z_size; + } + else { + access=iso->dirent->permissions() & ~S_IFMT; + adate=cdate=time=isodate_915(idr->date,0); + user=iso->dirent->user(); + group=iso->dirent->group(); + if (idr->flags[0] & 2) access |= S_IFDIR; else access |= S_IFREG; + if (!special) { + if( !iso->plainIso9660() && iso->jolietLevel() ) { + for (i=0;i<(isonum_711(idr->name_len)-1);i+=2) { + QChar ch( be2me_16(*((ushort*)&(idr->name[i]))) ); + if (ch==';') break; + path+=ch; + } + } + else { + // no RR, no Joliet, just plain iso9660 + path = isoPath; + + // remove the version field + int pos = path.find( ';' ); + if( pos > 0 ) + path.truncate( pos ); + } + if (path.endsWith(".")) path.setLength(path.length()-1); + } + } + + if( !iso->plainIso9660() ) + FreeRR(&rr); + + if (idr->flags[0] & 2) { + entry = new K3bIso9660Directory( iso, isoPath, path, access | S_IFDIR, time, adate, cdate, + user, group, symlink, + special ? 0 : isonum_733(idr->extent), + special ? 0 : isonum_733(idr->size) ); + } + else { + entry = new K3bIso9660File( iso, isoPath, path, access, time, adate, cdate, + user, group, symlink, isonum_733(idr->extent), isonum_733(idr->size) ); + if (z_size) + (static_cast(entry))->setZF( z_algo, z_params, z_size ); + } + iso->dirent->addEntry(entry); + + return 0; +} + + + +K3bIso9660Entry::K3bIso9660Entry( K3bIso9660* archive, + const QString& isoName, + const QString& name, + int access, + int date, + int adate, + int cdate, + const QString& user, + const QString& group, + const QString& symlink ) + : m_adate( adate ), + m_cdate( cdate ), + m_name( name ), + m_isoName( isoName ), + m_date( date ), + m_access( access ), + m_user( user ), + m_group( group ), + m_symlink( symlink ), + m_archive( archive ) +{ +} + + +K3bIso9660Entry::~K3bIso9660Entry() +{ +} + + + + + + +K3bIso9660File::K3bIso9660File( K3bIso9660* archive, + const QString& isoName, + const QString& name, + int access, + int date, + int adate, + int cdate, + const QString& user, + const QString& group, + const QString& symlink, + unsigned int pos, + unsigned int size ) + : K3bIso9660Entry( archive, isoName, name, access, date, adate, cdate, user, group, symlink ), + m_startSector(pos), + m_size(size) +{ + m_algo[0] = 0; + m_algo[1] = 0; + m_parms[0] = 0; + m_parms[1] = 0; + m_realsize = 0; +} + +K3bIso9660File::~K3bIso9660File() +{ +} + +void K3bIso9660File::setZF(char algo[2],char parms[2],int realsize) +{ + m_algo[0]=algo[0];m_algo[1]=algo[1]; + m_parms[0]=parms[0];m_parms[1]=parms[1]; + m_realsize=realsize; +} + + +int K3bIso9660File::read( unsigned int pos, char* data, int maxlen ) const +{ + if( pos >= size() ) + return 0; + + unsigned long startSec = m_startSector + pos/2048; + int startSecOffset = pos%2048; + char* buffer = data; + bool buffered = false; + unsigned long bufferLen = maxlen+startSecOffset; + + // cut to size + if( pos + maxlen > size() ) + bufferLen = size() - pos + startSecOffset; + + // pad to 2048 + if( bufferLen%2048 ) + bufferLen += (2048-(bufferLen%2048)); + + // we need to buffer if we changed the startSec or need a bigger buffer + if( startSecOffset || bufferLen > (unsigned int)maxlen ) { + buffered = true; + buffer = new char[bufferLen]; + } + + int read = archive()->read( startSec, buffer, bufferLen/2048 )*2048; + + if( buffered ) { + if( read > 0 ) { + // cut to requested data + read -= startSecOffset; + if( read + pos > size() ) + read = size() - pos; + if( read > maxlen ) + read = maxlen; + + ::memcpy( data, buffer+startSecOffset, read ); + } + delete [] buffer; + + return read; + } + else { + // cut read data + if( read + pos > size() ) + read = size() - pos; + + return read; + } +} + + +bool K3bIso9660File::copyTo( const QString& url ) const +{ + QFile of( url ); + if( of.open( IO_WriteOnly ) ) { + char buffer[2048*10]; + unsigned int pos = 0; + int r = 0; + while( ( r = read( pos, buffer, 2048*10 ) ) > 0 ) { + of.writeBlock( buffer, r ); + pos += r; + } + + return !r; + } + else { + kdDebug() << "(K3bIso9660File) could not open " << url << " for writing." << endl; + return false; + } +} + + +K3bIso9660Directory::K3bIso9660Directory( K3bIso9660* archive, + const QString& isoName, + const QString& name, + int access, + int date, + int adate, + int cdate, + const QString& user, + const QString& group, + const QString& symlink, + unsigned int pos, + unsigned int size ) + : K3bIso9660Entry( archive, isoName, name, access, date, adate, cdate, user, group, symlink ), + m_bExpanded( size == 0 ), // we can only expand entries that represent an actual directory + m_startSector(pos), + m_size(size) +{ + m_entries.setAutoDelete( true ); +} + +K3bIso9660Directory::~K3bIso9660Directory() +{ +} + + +void K3bIso9660Directory::expand() +{ + if( !m_bExpanded ) { + archive()->dirent = this; + if( ProcessDir( &K3bIso9660::read_callback, m_startSector, m_size, &K3bIso9660::isofs_callback, archive() ) ) + kdDebug() << "(K3bIso9660) failed to expand dir: " << name() << " with size: " << m_size << endl; + + m_bExpanded = true; + } +} + + +QStringList K3bIso9660Directory::entries() const +{ + // create a fake const method to fool the user ;) + const_cast(this)->expand(); + + QStringList l; + + QDictIterator it( m_entries ); + for( ; it.current(); ++it ) + l.append( it.currentKey() ); + + return l; +} + + +QStringList K3bIso9660Directory::iso9660Entries() const +{ + // create a fake const method to fool the user ;) + const_cast(this)->expand(); + + QStringList l; + + QDictIterator it( m_iso9660Entries ); + for( ; it.current(); ++it ) + l.append( it.currentKey() ); + + return l; +} + + +K3bIso9660Entry* K3bIso9660Directory::entry( const QString& n ) +{ + if( n.isEmpty() ) + return 0; + + expand(); + + QString name(n); + + // trailing slash ? -> remove + if( name.length() > 1 && name[name.length()-1] == '/' ) { + name.truncate( name.length()-1 ); + } + + int pos = name.find( '/' ); + while( pos == 0 ) { + if( name.length() > 1 ) { + name = name.mid( 1 ); // remove leading slash + pos = name.find( '/' ); // look again + } + else // "/" + return this; + } + + if ( pos != -1 ) { + QString left = name.left( pos ); + QString right = name.mid( pos + 1 ); + + K3bIso9660Entry* e = m_entries[ left ]; + if ( !e || !e->isDirectory() ) + return 0; + return static_cast(e)->entry( right ); + } + + return m_entries[ name ]; +} + + +K3bIso9660Entry* K3bIso9660Directory::iso9660Entry( const QString& n ) +{ + if( n.isEmpty() ) + return 0; + + expand(); + + QString name(n); + + // trailing slash ? -> remove + if( name.length() > 1 && name[name.length()-1] == '/' ) { + name.truncate( name.length()-1 ); + } + + int pos = name.find( '/' ); + while( pos == 0 ) { + if( name.length() > 1 ) { + name = name.mid( 1 ); // remove leading slash + pos = name.find( '/' ); // look again + } + else // "/" + return this; + } + + if ( pos != -1 ) { + QString left = name.left( pos ); + QString right = name.mid( pos + 1 ); + + K3bIso9660Entry* e = m_iso9660Entries[ left ]; + if ( !e || !e->isDirectory() ) + return 0; + return static_cast(e)->iso9660Entry( right ); + } + + return m_iso9660Entries[ name ]; +} + + +const K3bIso9660Entry* K3bIso9660Directory::entry( const QString& name ) const +{ + return const_cast(this)->entry( name ); +} + + +const K3bIso9660Entry* K3bIso9660Directory::iso9660Entry( const QString& name ) const +{ + return const_cast(this)->iso9660Entry( name ); +} + + +void K3bIso9660Directory::addEntry( K3bIso9660Entry* entry ) +{ + m_entries.insert( entry->name(), entry ); + m_iso9660Entries.insert( entry->isoName(), entry ); +} + + + + + +class K3bIso9660::Private +{ +public: + Private() + : cdDevice(0), + fd(-1), + isOpen(false), + startSector(0), + plainIso9660(false), + backend(0) { + } + + QPtrList elToritoDirs; + QPtrList jolietDirs; + QPtrList isoDirs; + QPtrList rrDirs; // RockRidge + + K3bIso9660SimplePrimaryDescriptor primaryDesc; + + K3bDevice::Device* cdDevice; + int fd; + + bool isOpen; + + // only used for direkt K3bDevice::Device access + unsigned int startSector; + + bool plainIso9660; + + K3bIso9660Backend* backend; +}; + + +K3bIso9660::K3bIso9660( const QString& filename ) + : m_filename( filename ) +{ + d = new Private(); +} + + +K3bIso9660::K3bIso9660( int fd ) +{ + d = new Private(); + d->fd = fd; +} + + +K3bIso9660::K3bIso9660( K3bIso9660Backend* backend ) +{ + d = new Private(); + d->backend = backend; +} + + +K3bIso9660::K3bIso9660( K3bDevice::Device* dev, unsigned int startSector ) +{ + d = new Private(); + d->cdDevice = dev; + d->startSector = startSector; +} + + +K3bIso9660::~K3bIso9660() +{ + close(); + delete d->backend; + delete d; +} + + +void K3bIso9660::setStartSector( unsigned int startSector ) +{ + d->startSector = startSector; +} + + +void K3bIso9660::setPlainIso9660( bool b ) +{ + d->plainIso9660 = b; +} + + +bool K3bIso9660::plainIso9660() const +{ + return d->plainIso9660; +} + + +int K3bIso9660::read( unsigned int sector, char* data, int count ) +{ + if( count == 0 ) + return 0; + else + return d->backend->read( sector, data, count ); +} + + +void K3bIso9660::addBoot(struct el_torito_boot_descriptor* bootdesc) +{ + int i,size; + boot_head boot; + boot_entry *be; + QString path; + K3bIso9660File *entry; + + entry=new K3bIso9660File( this, "Catalog", "Catalog", dirent->permissions() & ~S_IFDIR, + dirent->date(), dirent->adate(), dirent->cdate(), + dirent->user(), dirent->group(), QString::null, + isonum_731(bootdesc->boot_catalog), 2048 ); + dirent->addEntry(entry); + if (!ReadBootTable(&K3bIso9660::read_callback,isonum_731(bootdesc->boot_catalog),&boot,this)) { + i=1; + be=boot.defentry; + while (be) { + size=BootImageSize(&K3bIso9660::read_callback, + isonum_711(((struct default_entry*) be->data)->media), + isonum_731(((struct default_entry*) be->data)->start), + isonum_721(((struct default_entry*) be->data)->seccount), + this); + path="Default Image"; + if (i>1) path += " (" + QString::number(i) + ")"; + entry=new K3bIso9660File( this, path, path, dirent->permissions() & ~S_IFDIR, + dirent->date(), dirent->adate(), dirent->cdate(), + dirent->user(), dirent->group(), QString::null, + isonum_731(((struct default_entry*) be->data)->start), size<<9 ); + dirent->addEntry(entry); + be=be->next; + i++; + } + + FreeBootTable(&boot); + } +} + + +bool K3bIso9660::open() +{ + if( d->isOpen ) + return true; + + if( !d->backend ) { + // create a backend + + if( !m_filename.isEmpty() ) + d->backend = new K3bIso9660FileBackend( m_filename ); + + else if( d->fd > 0 ) + d->backend = new K3bIso9660FileBackend( d->fd ); + + else if( d->cdDevice ) { + // now check if we have a scrambled video dvd + if( d->cdDevice->copyrightProtectionSystemType() == 1 ) { + + kdDebug() << "(K3bIso9660) found encrypted dvd. using libdvdcss." << endl; + + // open the libdvdcss stuff + d->backend = new K3bIso9660LibDvdCssBackend( d->cdDevice ); + if( !d->backend->open() ) { + // fallback to devicebackend + delete d->backend; + d->backend = new K3bIso9660DeviceBackend( d->cdDevice ); + } + } + else + d->backend = new K3bIso9660DeviceBackend( d->cdDevice ); + } + } + + d->isOpen = d->backend->open(); + if( !d->isOpen ) + return false; + + iso_vol_desc *desc; + QString path,tmp,uid,gid; + k3b_struct_stat buf; + int access,c_i,c_j; + struct el_torito_boot_descriptor* bootdesc; + + + /* We'll use the permission and user/group of the 'host' file except + * in Rock Ridge, where the permissions are stored on the file system + */ + if ( k3b_stat( QFile::encodeName(m_filename), &buf ) < 0 ) { + /* defaults, if stat fails */ + memset(&buf,0,sizeof(k3b_struct_stat)); + buf.st_mode=0777; + } + uid.setNum(buf.st_uid); + gid.setNum(buf.st_gid); + access = buf.st_mode & ~S_IFMT; + + + int c_b=1; + c_i=1;c_j=1; + + desc = ReadISO9660( &K3bIso9660::read_callback, d->startSector, this ); + + if (!desc) { + kdDebug() << "K3bIso9660::openArchive no volume descriptors" << endl; + close(); + return false; + } + + while (desc) { + + m_rr = false; + + switch (isonum_711(desc->data.type)) { + case ISO_VD_BOOT: + + bootdesc=(struct el_torito_boot_descriptor*) &(desc->data); + if( !memcmp( EL_TORITO_ID, bootdesc->system_id, ISODCL(8,39) ) ) { + path="El Torito Boot"; + if( c_b > 1 ) + path += " (" + QString::number(c_b) + ")"; + + dirent = new K3bIso9660Directory( this, path, path, access | S_IFDIR, + buf.st_mtime, buf.st_atime, buf.st_ctime, uid, gid, QString::null ); + d->elToritoDirs.append( dirent ); + + addBoot(bootdesc); + c_b++; + } + break; + + case ISO_VD_PRIMARY: + createSimplePrimaryDesc( (struct iso_primary_descriptor*)&desc->data ); + // fall through + case ISO_VD_SUPPLEMENTARY: + { + struct iso_primary_descriptor* primaryDesc = (struct iso_primary_descriptor*)&desc->data; + struct iso_directory_record* idr = (struct iso_directory_record*)&primaryDesc->root_directory_record; + + m_joliet = JolietLevel(&desc->data); + + // skip joliet in plain iso mode + if( m_joliet && plainIso9660() ) + break; + + if (m_joliet) { + path = "Joliet level " + QString::number(m_joliet); + if( c_j > 1 ) + path += " (" + QString::number(c_j) + ")"; + } + else { + path = QString::fromLocal8Bit( primaryDesc->volume_id, 32 ); + if( c_i > 1 ) + path += " (" + QString::number(c_i) + ")"; + } + + dirent = new K3bIso9660Directory( this, path, path, access | S_IFDIR, + buf.st_mtime, buf.st_atime, buf.st_ctime, uid, gid, QString::null ); + + // expand the root entry + ProcessDir( &K3bIso9660::read_callback, isonum_733(idr->extent),isonum_733(idr->size),&K3bIso9660::isofs_callback,this); + + if (m_joliet) + c_j++; + else + c_i++; + + if( m_joliet ) + d->jolietDirs.append( dirent ); + else { + if( m_rr ) + d->rrDirs.append( dirent ); + d->isoDirs.append( dirent ); + } + + break; + } + } + desc = desc->next; + } + + FreeISO9660(desc); + + return true; +} + + +bool K3bIso9660::isOpen() const +{ + return d->isOpen; +} + + +void K3bIso9660::createSimplePrimaryDesc( struct iso_primary_descriptor* desc ) +{ + d->primaryDesc.volumeId = QString::fromLocal8Bit( desc->volume_id, 32 ).stripWhiteSpace(); + d->primaryDesc.systemId = QString::fromLocal8Bit( desc->system_id, 32 ).stripWhiteSpace(); + d->primaryDesc.volumeSetId = QString::fromLocal8Bit( desc->volume_set_id, 128 ).stripWhiteSpace(); + d->primaryDesc.publisherId = QString::fromLocal8Bit( desc->publisher_id, 128 ).stripWhiteSpace(); + d->primaryDesc.preparerId = QString::fromLocal8Bit( desc->preparer_id, 128 ).stripWhiteSpace(); + d->primaryDesc.applicationId = QString::fromLocal8Bit( desc->application_id, 128 ).stripWhiteSpace(); + d->primaryDesc.volumeSetSize = isonum_723(desc->volume_set_size); + d->primaryDesc.volumeSetNumber = isonum_723(desc->volume_set_size); + d->primaryDesc.logicalBlockSize = isonum_723(desc->logical_block_size); + d->primaryDesc.volumeSpaceSize = isonum_733(desc->volume_space_size); +} + + +void K3bIso9660::close() +{ + if( d->isOpen ) { + d->backend->close(); + + // Since the first isoDir is the KArchive + // root we must not delete it but all the + // others. + + d->elToritoDirs.setAutoDelete(true); + d->jolietDirs.setAutoDelete(true); + d->isoDirs.setAutoDelete(true); + d->elToritoDirs.clear(); + d->jolietDirs.clear(); + d->isoDirs.clear(); + + d->isOpen = false; + } +} + + +const K3bIso9660Directory* K3bIso9660::firstJolietDirEntry() const +{ + return d->jolietDirs.first(); +} + + +const K3bIso9660Directory* K3bIso9660::firstIsoDirEntry() const +{ + return d->isoDirs.first(); +} + + +const K3bIso9660Directory* K3bIso9660::firstElToritoEntry() const +{ + return d->elToritoDirs.first(); +} + + +const K3bIso9660Directory* K3bIso9660::firstRRDirEntry() const +{ + return d->rrDirs.first(); +} + + +const K3bIso9660SimplePrimaryDescriptor& K3bIso9660::primaryDescriptor() const +{ + return d->primaryDesc; +} + + +void K3bIso9660::debug() const +{ + if( isOpen() ) { + kdDebug() << "System Id: " << primaryDescriptor().systemId << endl; + kdDebug() << "Volume Id: " << primaryDescriptor().volumeId << endl; + kdDebug() << "Volume Set Id: " << primaryDescriptor().volumeSetId << endl; + kdDebug() << "Preparer Id: " << primaryDescriptor().preparerId << endl; + kdDebug() << "Publisher Id: " << primaryDescriptor().publisherId << endl; + kdDebug() << "Application Id: " << primaryDescriptor().applicationId << endl; + kdDebug() << "Volume Set Size: " << primaryDescriptor().volumeSetSize << endl; + kdDebug() << "Volume Set Number: " << primaryDescriptor().volumeSetNumber << endl; + + if( firstIsoDirEntry() ) { + kdDebug() << "First ISO Dir entry:" << endl; + kdDebug() << "----------------------------------------------" << endl; + debugEntry( firstIsoDirEntry(), 0 ); + kdDebug() << "----------------------------------------------" << endl << endl; + } + if( firstRRDirEntry() ) { + kdDebug() << "First RR Dir entry:" << endl; + kdDebug() << "----------------------------------------------" << endl; + debugEntry( firstRRDirEntry(), 0 ); + kdDebug() << "----------------------------------------------" << endl << endl; + } + if( firstJolietDirEntry() ) { + kdDebug() << "First Joliet Dir entry:" << endl; + kdDebug() << "----------------------------------------------" << endl; + debugEntry( firstJolietDirEntry(), 0 ); + kdDebug() << "----------------------------------------------" << endl << endl; + } + } +} + + +void K3bIso9660::debugEntry( const K3bIso9660Entry* entry, int depth ) const +{ + if( !entry ) { + kdDebug() << "(K3bIso9660::debugEntry) null entry." << endl; + return; + } + + QString spacer; + spacer.fill( ' ', depth*3 ); + kdDebug() << spacer << "- " << entry->name() << " (" << entry->isoName() << ")" << endl; + if( entry->isDirectory() ) { + const K3bIso9660Directory* dir = dynamic_cast(entry); + QStringList entries = dir->entries(); + for( QStringList::const_iterator it = entries.begin(); it != entries.end(); ++it ) { + debugEntry( dir->entry( *it ), depth+1 ); + } + } +} + + +K3bIso9660SimplePrimaryDescriptor::K3bIso9660SimplePrimaryDescriptor() + : volumeSetSize(0), + volumeSetNumber(0), + logicalBlockSize(0), + volumeSpaceSize(0) +{ +} + + +bool operator==( const K3bIso9660SimplePrimaryDescriptor& d1, + const K3bIso9660SimplePrimaryDescriptor& d2 ) +{ + return( d1.volumeId == d2.volumeId && + d1.systemId == d2.systemId && + d1.volumeSetId == d2.volumeSetId && + d1.publisherId == d2.publisherId && + d1.preparerId == d2.preparerId && + d1.applicationId == d2.applicationId && + d1.volumeSetSize == d2.volumeSetSize && + d1.volumeSetNumber == d2.volumeSetNumber && + d1.logicalBlockSize == d2.logicalBlockSize && + d1.volumeSpaceSize == d2.volumeSpaceSize ); +} + + +bool operator!=( const K3bIso9660SimplePrimaryDescriptor& d1, + const K3bIso9660SimplePrimaryDescriptor& d2 ) +{ + return( d1.volumeId != d2.volumeId || + d1.systemId != d2.systemId || + d1.volumeSetId != d2.volumeSetId || + d1.publisherId != d2.publisherId || + d1.preparerId != d2.preparerId || + d1.applicationId != d2.applicationId || + d1.volumeSetSize != d2.volumeSetSize || + d1.volumeSetNumber != d2.volumeSetNumber || + d1.logicalBlockSize != d2.logicalBlockSize || + d1.volumeSpaceSize != d2.volumeSpaceSize ); +} -- cgit v1.2.3