void IosBackupAdapter::SeparateDir(const std::wstring& dataDir) { std::wstring findStr = std::wstring(dataDir) + L"\\*.*"; WIN32_FIND_DATAW fd = {0}; HANDLE hf = FindFirstFile(findStr.c_str(), &fd); if ( INVALID_HANDLE_VALUE == hf ) return; do { if ( ! (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ) continue; if ( 0 == wcscmp(fd.cFileName, L".") || 0 == wcscmp(fd.cFileName, L"..") ) continue; if ( ProcessDir(std::wstring(dataDir) + L"\\" + fd.cFileName) ) HackCaseInfo(dataDir, std::wstring(dataDir) + L"\\" + fd.cFileName + L"(Backup)"); } while ( FindNextFileW(hf, &fd) ); FindClose(hf); }
IFXRESULT IFXOSFileIterator::GetPlugins( IFXString *subPath ) { IFXRESULT result = IFX_OK; WIN32_FIND_DATA data; BOOL res = FALSE; HANDLE hdl; IFXString tempPath; // find and store all files in this dir ProcessDir( subPath ); // now process subdirs IFXString localPath( m_pluginLocation ); localPath.Concatenate( subPath ); localPath.Concatenate( IFXOSFI_EXTALL ); hdl = FindFirstFile( localPath.Raw(), &data ); // if there are no any file/directory then skip next block if( INVALID_HANDLE_VALUE != hdl ) { // keep searching while there are any files/directories do { // create full path to the found object tempPath.Assign( &m_pluginLocation ); tempPath.Concatenate( subPath ); tempPath.Concatenate( data.cFileName ); // we already found and stored all files we wanted, so check if found object is // a) a directory, // b) its nesting doesn't exceed the limitation (IFXOSFI_MAXDEPTH), // c) its name isn't a "." or ".." if( IsDir( &tempPath ) > 0 && m_depth < IFXOSFI_MAXDEPTH && wcscmp( data.cFileName, IFXOSFI_CURRDIR ) && wcscmp( data.cFileName, IFXOSFI_UPPRDIR ) ) { // we have found a directory and we want to look in it, so // create its relative path: tempPath.Assign( subPath ); tempPath.Concatenate( data.cFileName ); tempPath.Concatenate( L"\\" ); // increment the depth (nesting) m_depth++; // step inside GetPlugins( &tempPath ); // decrement the depth (nesting) m_depth--; } // find next file/directory res = FindNextFile( hdl, &data ); } while( res ); // close handle FindClose( hdl ); } return result; }
bool CBrowseDir::BrowseDir (const char *dir,const char *filespec) { _chdir(dir); //首先查找dir中符合要求的文件 long hFile; _finddata_t fileinfo; if ((hFile=_findfirst(filespec,&fileinfo)) != -1) { do { //检查是不是目录 //如果不是,则进行处理 if (!(fileinfo.attrib & _A_SUBDIR)) { char filename[_MAX_PATH]; strcpy(filename,dir); strcat(filename,fileinfo.name); if (!ProcessFile(filename)) return false; } } while (_findnext(hFile,&fileinfo) == 0); _findclose(hFile); } //查找dir中的子目录 //因为在处理dir中的文件时,派生类的ProcessFile有可能改变了 //当前目录,因此还要重新设置当前目录为dir。 //执行过_findfirst后,可能系统记录下了相关信息,因此改变目录 //对_findnext没有影响。 _chdir(dir); if ((hFile=_findfirst("*.*",&fileinfo)) != -1) { do { //检查是不是目录 //如果是,再检查是不是 . 或 .. //如果不是,进行迭代 if ((fileinfo.attrib & _A_SUBDIR)) { if (strcmp(fileinfo.name,".") != 0 && strcmp (fileinfo.name,"..") != 0) { char subdir[_MAX_PATH]; strcpy(subdir,dir); strcat(subdir,fileinfo.name); strcat(subdir,"\\"); ProcessDir(subdir,dir); if (!BrowseDir(subdir,filespec)) return false; } } } while (_findnext(hFile,&fileinfo) == 0); _findclose(hFile); } return true; }
void K3b::Iso9660Directory::expand() { if( !m_bExpanded ) { archive()->dirent = this; if( ProcessDir( &K3b::Iso9660::read_callback, m_startSector, m_size, &K3b::Iso9660::isofs_callback, archive() ) ) qDebug() << "(K3b::Iso9660) failed to expand dir: " << name() << " with size: " << m_size; m_bExpanded = true; } }
bool BiopMessage::Process(DSMCCCacheModuleData *cachep, DSMCCCache *filecache, unsigned char *data, unsigned long *curp) { // Parse header if (! ProcessMsgHdr(data, curp)) { VERBOSE(VB_DSMCC,"[biop] Invalid biop header, " "dropping rest of module"); /* not valid, skip rest of data */ return false; } // Handle each message type if (strcmp(m_objkind, "fil") == 0) { VERBOSE(VB_DSMCC,"[biop] Processing file"); return ProcessFile(cachep, filecache, data, curp); } else if (strcmp(m_objkind, "dir") == 0) { VERBOSE(VB_DSMCC,"[biop] Processing directory"); return ProcessDir(false, cachep, filecache, data, curp); } else if (strcmp(m_objkind, "srg") == 0) { VERBOSE(VB_DSMCC,"[biop] Processing gateway"); return ProcessDir(true, cachep, filecache, data, curp); } else { /* Error */ VERBOSE(VB_DSMCC, QString("Unknown or unsupported format %1%2%3%4") .arg(m_objkind[0]).arg(m_objkind[1]) .arg(m_objkind[2]).arg(m_objkind[3])); return false; } }
/* * 搜索指定的jre环境 */ char* LocateJRE(manifest_info* info) { char *path; char *home; char *target = NULL; char *dp; char *cp; /* * Start by getting JAVA_VERSION_PATH */ if (info->jre_restrict_search) { path = JLI_StringDup(system_dir); } else if ((path = getenv("JAVA_VERSION_PATH")) != NULL) { path = JLI_StringDup(path); } else { if ((home = getenv("HOME")) != NULL) { path = (char *)JLI_MemAlloc(JLI_StrLen(home) + \ JLI_StrLen(system_dir) + JLI_StrLen(user_dir) + 2); sprintf(path, "%s%s:%s", home, user_dir, system_dir); } else { path = JLI_StringDup(system_dir); } } /* * Step through each directory on the path. Terminate the scan with * the first directory with an acceptable JRE. */ cp = dp = path; while (dp != NULL) { cp = JLI_StrChr(dp, (int)':'); if (cp != NULL) *cp = '\0'; if ((target = ProcessDir(info, dp)) != NULL) break; dp = cp; if (dp != NULL) dp++; } JLI_MemFree(path); return (target); }
/* * This is the global entry point. It examines the host for the optimal * JRE to be used by scanning a set of registry entries. This set of entries * is hardwired on Windows as "Software\JavaSoft\Java Runtime Environment" * under the set of roots "{ HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE }". * * This routine simply opens each of these registry directories before passing * control onto ProcessDir(). */ char * LocateJRE(manifest_info* info) { HKEY key = NULL; char *path; int key_index; HKEY root_keys[2] = { HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE }; for (key_index = 0; key_index <= 1; key_index++) { if (RegOpenKeyEx(root_keys[key_index], JRE_KEY, 0, KEY_READ, &key) == ERROR_SUCCESS) if ((path = ProcessDir(info, key)) != NULL) { if (key != NULL) RegCloseKey(key); return (path); } if (key != NULL) RegCloseKey(key); } return NULL; }
//-------------------------------------------------------------------------- // Process a EXIF marker // Describes all the drivel that most digital cameras include... //-------------------------------------------------------------------------- bool CExifParse::Process (const unsigned char* const ExifSection, const unsigned short length, ExifInfo_t *info) { m_ExifInfo = info; // EXIF signature: "Exif\0\0" // Check EXIF signatures const char ExifHeader[] = "Exif\0\0"; const char ExifAlignment0[] = "II"; const char ExifAlignment1[] = "MM"; const char ExifExtra = 0x2a; const char* pos = (const char*)(ExifSection + sizeof(short)); // position data pointer after length field if (memcmp(pos, ExifHeader,6)) { printf("ExifParse: incorrect Exif header"); return false; } pos += 6; if (memcmp(pos, ExifAlignment0, strlen(ExifAlignment0)) == 0) { m_MotorolaOrder = false; } else if (memcmp(pos, ExifAlignment1, strlen(ExifAlignment1)) == 0) { m_MotorolaOrder = true; } else { printf("ExifParse: invalid Exif alignment marker"); return false; } pos += strlen(ExifAlignment0); // Check the next value for correctness. if (Get16((const void*)(pos), m_MotorolaOrder) != ExifExtra) { printf("ExifParse: invalid Exif start (1)"); return false; } pos += sizeof(short); unsigned long FirstOffset = (unsigned)Get32((const void*)pos, m_MotorolaOrder); if (FirstOffset < 8 || FirstOffset > 16) { // Usually set to 8, but other values valid too. // CLog::Log(LOGERROR, "ExifParse: suspicious offset of first IFD value"); } // First directory starts 16 bytes in. All offset are relative to 8 bytes in. ProcessDir(ExifSection+8+FirstOffset, ExifSection+8, length-8, 0); m_ExifInfo->ThumbnailAtEnd = m_ExifInfo->ThumbnailOffset >= m_LargestExifOffset; // Compute the CCD width, in millimeters. if (m_FocalPlaneXRes != 0) { // Note: With some cameras, its not possible to compute this correctly because // they don't adjust the indicated focal plane resolution units when using less // than maximum resolution, so the CCDWidth value comes out too small. Nothing // that Jhead can do about it - its a camera problem. m_ExifInfo->CCDWidth = (float)(m_ExifImageWidth * m_FocalPlaneUnits / m_FocalPlaneXRes); } if (m_ExifInfo->FocalLength) { if (m_ExifInfo->FocalLength35mmEquiv == 0) { // Compute 35 mm equivalent focal length based on sensor geometry if we haven't // already got it explicitly from a tag. if (m_ExifInfo->CCDWidth != 0.0) { m_ExifInfo->FocalLength35mmEquiv = (int)(m_ExifInfo->FocalLength/m_ExifInfo->CCDWidth*36 + 0.5); } } } return true; }
//-------------------------------------------------------------------------- // Process one of the nested EXIF directories. //-------------------------------------------------------------------------- void CExifParse::ProcessDir(const unsigned char* const DirStart, const unsigned char* const OffsetBase, const unsigned ExifLength, int NestingLevel) { if (NestingLevel > 4) { ErrNonfatal("Maximum directory nesting exceeded (corrupt exif header)", 0,0); return; } char IndentString[25]; memset(IndentString, ' ', 25); IndentString[NestingLevel * 4] = '\0'; int NumDirEntries = Get16((const void*)DirStart, m_MotorolaOrder); const unsigned char* const DirEnd = DIR_ENTRY_ADDR(DirStart, NumDirEntries); if (DirEnd+4 > (OffsetBase+ExifLength)) { if (DirEnd+2 == OffsetBase+ExifLength || DirEnd == OffsetBase+ExifLength) { // Version 1.3 of jhead would truncate a bit too much. // This also caught later on as well. } else { ErrNonfatal("Illegally sized directory", 0,0); return; } } for (int de=0;de<NumDirEntries;de++) { int Tag, Format, Components; unsigned char* ValuePtr; int ByteCount; const unsigned char* const DirEntry = DIR_ENTRY_ADDR(DirStart, de); Tag = Get16(DirEntry, m_MotorolaOrder); Format = Get16(DirEntry+2, m_MotorolaOrder); Components = Get32(DirEntry+4, m_MotorolaOrder); if (Format <= 0 || Format > NUM_FORMATS) { ErrNonfatal("Illegal number format %d for tag %04x", Format, Tag); continue; } if ((unsigned)Components > 0x10000) { ErrNonfatal("Illegal number of components %d for tag %04x", Components, Tag); continue; } ByteCount = Components * BytesPerFormat[Format - 1]; if (ByteCount > 4) { unsigned OffsetVal; OffsetVal = (unsigned)Get32(DirEntry+8, m_MotorolaOrder); // If its bigger than 4 bytes, the dir entry contains an offset. if (OffsetVal+ByteCount > ExifLength) { // Bogus pointer offset and / or bytecount value ErrNonfatal("Illegal value pointer for tag %04x", Tag,0); continue; } ValuePtr = (unsigned char*)(const_cast<unsigned char*>(OffsetBase)+OffsetVal); if (OffsetVal > m_LargestExifOffset) { m_LargestExifOffset = OffsetVal; } } else { // 4 bytes or less and value is in the dir entry itself ValuePtr = (unsigned char*)(const_cast<unsigned char*>(DirEntry)+8); } // Extract useful components of tag switch(Tag) { case TAG_DESCRIPTION: { int length = max(ByteCount, 0); length = min(length, MAX_COMMENT); strncpy(m_ExifInfo->Description, (char *)ValuePtr, length); m_ExifInfo->Description[length] = '\0'; break; } case TAG_MAKE: { int space = sizeof(m_ExifInfo->CameraMake); if (space > 0) { strncpy(m_ExifInfo->CameraMake, (char *)ValuePtr, space - 1); m_ExifInfo->CameraMake[space - 1] = '\0'; } break; } case TAG_MODEL: { int space = sizeof(m_ExifInfo->CameraModel); if (space > 0) { strncpy(m_ExifInfo->CameraModel, (char *)ValuePtr, space - 1); m_ExifInfo->CameraModel[space - 1] = '\0'; } break; } // case TAG_SOFTWARE: strncpy(m_ExifInfo->Software, ValuePtr, 5); break; case TAG_FOCALPLANEXRES: m_FocalPlaneXRes = ConvertAnyFormat(ValuePtr, Format); break; case TAG_THUMBNAIL_OFFSET: m_ExifInfo->ThumbnailOffset = (unsigned)ConvertAnyFormat(ValuePtr, Format); break; case TAG_THUMBNAIL_LENGTH: m_ExifInfo->ThumbnailSize = (unsigned)ConvertAnyFormat(ValuePtr, Format); break; case TAG_MAKER_NOTE: continue; break; case TAG_DATETIME_ORIGINAL: { int space = sizeof(m_ExifInfo->DateTime); if (space > 0) { strncpy(m_ExifInfo->DateTime, (char *)ValuePtr, space - 1); m_ExifInfo->DateTime[space - 1] = '\0'; // If we get a DATETIME_ORIGINAL, we use that one. m_DateFound = true; } break; } case TAG_DATETIME_DIGITIZED: case TAG_DATETIME: { if (!m_DateFound) { // If we don't already have a DATETIME_ORIGINAL, use whatever // time fields we may have. int space = sizeof(m_ExifInfo->DateTime); if (space > 0) { strncpy(m_ExifInfo->DateTime, (char *)ValuePtr, space - 1); m_ExifInfo->DateTime[space - 1] = '\0'; } } break; } case TAG_USERCOMMENT: { // The UserComment allows comments without the charset limitations of ImageDescription. // Therefore the UserComment field is prefixed by a CharacterCode field (8 Byte): // - ASCII: 'ASCII\0\0\0' // - Unicode: 'UNICODE\0' // - JIS X208-1990: 'JIS\0\0\0\0\0' // - Unknown: '\0\0\0\0\0\0\0\0' (application specific) m_ExifInfo->CommentsCharset = EXIF_COMMENT_CHARSET_UNKNOWN; const int EXIF_COMMENT_CHARSET_LENGTH = 8; if (ByteCount >= EXIF_COMMENT_CHARSET_LENGTH) { // As some implementations use spaces instead of \0 for the padding, // we're not so strict and check only the prefix. if (memcmp(ValuePtr, "ASCII", 5) == 0) m_ExifInfo->CommentsCharset = EXIF_COMMENT_CHARSET_ASCII; else if (memcmp(ValuePtr, "UNICODE", 7) == 0) m_ExifInfo->CommentsCharset = EXIF_COMMENT_CHARSET_UNICODE; else if (memcmp(ValuePtr, "JIS", 3) == 0) m_ExifInfo->CommentsCharset = EXIF_COMMENT_CHARSET_JIS; int length = ByteCount - EXIF_COMMENT_CHARSET_LENGTH; length = min(length, MAX_COMMENT); memcpy(m_ExifInfo->Comments, ValuePtr + EXIF_COMMENT_CHARSET_LENGTH, length); m_ExifInfo->Comments[length] = '\0'; // FixComment(comment); // Ensure comment is printable } } break; case TAG_XP_COMMENT: { // The XP user comment field is always unicode (UCS-2) encoded m_ExifInfo->XPCommentsCharset = EXIF_COMMENT_CHARSET_UNICODE; size_t length = min(ByteCount, MAX_COMMENT); memcpy(m_ExifInfo->XPComment, ValuePtr, length); m_ExifInfo->XPComment[length] = '\0'; } break; case TAG_FNUMBER: // Simplest way of expressing aperture, so I trust it the most. // (overwrite previously computd value if there is one) m_ExifInfo->ApertureFNumber = (float)ConvertAnyFormat(ValuePtr, Format); break; case TAG_APERTURE: case TAG_MAXAPERTURE: // More relevant info always comes earlier, so only use this field if we don't // have appropriate aperture information yet. if (m_ExifInfo->ApertureFNumber == 0) { m_ExifInfo->ApertureFNumber = (float)exp(ConvertAnyFormat(ValuePtr, Format)*log(2.0)*0.5); } break; case TAG_FOCALLENGTH: // Nice digital cameras actually save the focal length as a function // of how far they are zoomed in. m_ExifInfo->FocalLength = (float)ConvertAnyFormat(ValuePtr, Format); break; case TAG_SUBJECT_DISTANCE: // Inidcates the distacne the autofocus camera is focused to. // Tends to be less accurate as distance increases. { float distance = (float)ConvertAnyFormat(ValuePtr, Format); m_ExifInfo->Distance = distance; } break; case TAG_EXPOSURETIME: { // Simplest way of expressing exposure time, so I trust it most. // (overwrite previously computd value if there is one) float expTime = (float)ConvertAnyFormat(ValuePtr, Format); if (expTime) m_ExifInfo->ExposureTime = expTime; } break; case TAG_SHUTTERSPEED: // More complicated way of expressing exposure time, so only use // this value if we don't already have it from somewhere else. if (m_ExifInfo->ExposureTime == 0) { m_ExifInfo->ExposureTime = (float)(1/exp(ConvertAnyFormat(ValuePtr, Format)*log(2.0))); } break; case TAG_FLASH: m_ExifInfo->FlashUsed = (int)ConvertAnyFormat(ValuePtr, Format); break; case TAG_ORIENTATION: m_ExifInfo->Orientation = (int)ConvertAnyFormat(ValuePtr, Format); if (m_ExifInfo->Orientation < 0 || m_ExifInfo->Orientation > 8) { ErrNonfatal("Undefined rotation value %d", m_ExifInfo->Orientation, 0); m_ExifInfo->Orientation = 0; } break; case TAG_EXIF_IMAGELENGTH: case TAG_EXIF_IMAGEWIDTH: // Use largest of height and width to deal with images that have been // rotated to portrait format. { int a = (int)ConvertAnyFormat(ValuePtr, Format); if (m_ExifImageWidth < a) m_ExifImageWidth = a; } break; case TAG_FOCALPLANEUNITS: switch((int)ConvertAnyFormat(ValuePtr, Format)) { // According to the information I was using, 2 means meters. // But looking at the Cannon powershot's files, inches is the only // sensible value. case 1: m_FocalPlaneUnits = 25.4; break; // inch case 2: m_FocalPlaneUnits = 25.4; break; case 3: m_FocalPlaneUnits = 10; break; // centimeter case 4: m_FocalPlaneUnits = 1; break; // millimeter case 5: m_FocalPlaneUnits = .001; break; // micrometer } break; case TAG_EXPOSURE_BIAS: m_ExifInfo->ExposureBias = (float)ConvertAnyFormat(ValuePtr, Format); break; case TAG_WHITEBALANCE: m_ExifInfo->Whitebalance = (int)ConvertAnyFormat(ValuePtr, Format); break; case TAG_LIGHT_SOURCE: //Quercus: 17-1-2004 Added LightSource, some cams return this, whitebalance or both m_ExifInfo->LightSource = (int)ConvertAnyFormat(ValuePtr, Format); break; case TAG_METERING_MODE: m_ExifInfo->MeteringMode = (int)ConvertAnyFormat(ValuePtr, Format); break; case TAG_EXPOSURE_PROGRAM: m_ExifInfo->ExposureProgram = (int)ConvertAnyFormat(ValuePtr, Format); break; case TAG_EXPOSURE_INDEX: if (m_ExifInfo->ISOequivalent == 0) { // Exposure index and ISO equivalent are often used interchangeably, // so we will do the same. // http://photography.about.com/library/glossary/bldef_ei.htm m_ExifInfo->ISOequivalent = (int)ConvertAnyFormat(ValuePtr, Format); } break; case TAG_ISO_EQUIVALENT: m_ExifInfo->ISOequivalent = (int)ConvertAnyFormat(ValuePtr, Format); if (m_ExifInfo->ISOequivalent < 50) m_ExifInfo->ISOequivalent *= 200; // Fixes strange encoding on some older digicams. break; case TAG_EXPOSURE_MODE: m_ExifInfo->ExposureMode = (int)ConvertAnyFormat(ValuePtr, Format); break; case TAG_DIGITALZOOMRATIO: m_ExifInfo->DigitalZoomRatio = (float)ConvertAnyFormat(ValuePtr, Format); break; case TAG_EXIF_OFFSET: case TAG_INTEROP_OFFSET: { const unsigned char* const SubdirStart = OffsetBase + (unsigned)Get32(ValuePtr, m_MotorolaOrder); if (SubdirStart < OffsetBase || SubdirStart > OffsetBase+ExifLength) { ErrNonfatal("Illegal exif or interop ofset directory link",0,0); } else { ProcessDir(SubdirStart, OffsetBase, ExifLength, NestingLevel+1); } continue; } break; case TAG_GPSINFO: { const unsigned char* const SubdirStart = OffsetBase + (unsigned)Get32(ValuePtr, m_MotorolaOrder); if (SubdirStart < OffsetBase || SubdirStart > OffsetBase+ExifLength) { ErrNonfatal("Illegal GPS directory link",0,0); } else { ProcessGpsInfo(SubdirStart, ByteCount, OffsetBase, ExifLength); } continue; } break; case TAG_FOCALLENGTH_35MM: // The focal length equivalent 35 mm is a 2.2 tag (defined as of April 2002) // if its present, use it to compute equivalent focal length instead of // computing it from sensor geometry and actual focal length. m_ExifInfo->FocalLength35mmEquiv = (unsigned)ConvertAnyFormat(ValuePtr, Format); break; } } // In addition to linking to subdirectories via exif tags, // there's also a potential link to another directory at the end of each // directory. this has got to be the result of a committee! unsigned Offset; if (DIR_ENTRY_ADDR(DirStart, NumDirEntries) + 4 <= OffsetBase+ExifLength) { Offset = (unsigned)Get32(DirStart+2+12*NumDirEntries, m_MotorolaOrder); if (Offset) { const unsigned char* const SubdirStart = OffsetBase + Offset; if (SubdirStart > OffsetBase+ExifLength || SubdirStart < OffsetBase) { if (SubdirStart > OffsetBase && SubdirStart < OffsetBase+ExifLength+20) { // Jhead 1.3 or earlier would crop the whole directory! // As Jhead produces this form of format incorrectness, // I'll just let it pass silently } else { ErrNonfatal("Illegal subdirectory link",0,0); } } else { if (SubdirStart <= OffsetBase+ExifLength) { ProcessDir(SubdirStart, OffsetBase, ExifLength, NestingLevel+1); } } if (Offset > m_LargestExifOffset) { m_LargestExifOffset = Offset; } } } else { // The exif header ends before the last next directory pointer. } if (m_ExifInfo->ThumbnailOffset) { m_ExifInfo->ThumbnailAtEnd = false; if (m_ExifInfo->ThumbnailOffset <= ExifLength) { if (m_ExifInfo->ThumbnailSize > ExifLength - m_ExifInfo->ThumbnailOffset) { // If thumbnail extends past exif header, only save the part that // actually exists. Canon's EOS viewer utility will do this - the // thumbnail extracts ok with this hack. m_ExifInfo->ThumbnailSize = ExifLength - m_ExifInfo->ThumbnailOffset; } } } }
bool CBrowseDir::BeginBrowse(const char *filespec) { ProcessDir(m_szInitDir,NULL); return BrowseDir(m_szInitDir,filespec); }
bool K3b::Iso9660::open() { if( d->isOpen ) return true; if( !d->backend ) { // create a backend if( !m_filename.isEmpty() ) d->backend = new K3b::Iso9660FileBackend( m_filename ); else if( d->fd > 0 ) d->backend = new K3b::Iso9660FileBackend( d->fd ); else if( d->cdDevice ) { // now check if we have a scrambled video dvd if( d->cdDevice->copyrightProtectionSystemType() == K3b::Device::COPYRIGHT_PROTECTION_CSS ) { qDebug() << "(K3b::Iso9660) found encrypted dvd. using libdvdcss."; // open the libdvdcss stuff d->backend = new K3b::Iso9660LibDvdCssBackend( d->cdDevice ); if( !d->backend->open() ) { // fallback to devicebackend delete d->backend; d->backend = new K3b::Iso9660DeviceBackend( d->cdDevice ); } } else d->backend = new K3b::Iso9660DeviceBackend( d->cdDevice ); } else return false; } 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; // TODO implement win32 support /* 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( &K3b::Iso9660::read_callback, d->startSector, this ); if (!desc) { qDebug() << "K3b::Iso9660::openArchive no volume descriptors"; 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 K3b::Iso9660Directory( this, path, path, access | S_IFDIR, buf.st_mtime, buf.st_atime, buf.st_ctime, uid, gid, QString() ); 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 K3b::Iso9660Directory( this, path, path, access | S_IFDIR, buf.st_mtime, buf.st_atime, buf.st_ctime, uid, gid, QString() ); // expand the root entry ProcessDir( &K3b::Iso9660::read_callback, isonum_733(idr->extent),isonum_733(idr->size),&K3b::Iso9660::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; }
/* callback function for libisofs */ static int mycallb(struct iso_directory_record *idr, void *udata) { KISOFUNC; KIso *iso = static_cast<KIso*>(udata); QString path, user, group, symlink; int i; int access; int time, cdate, adate; rr_entry rr; bool special = false; KArchiveEntry *entry = NULL, *oldentry = NULL; char z_algo[2], z_params[2]; long long z_size = 0; if ((idr->flags[0] & 1) && !iso->showhidden) return 0; if (iso->level) { if (isonum_711(idr->name_len) == 1) { switch (idr->name[0]) { case 0: path += ("."); special = true; break; case 1: path += (".."); special = true; break; } } if (iso->showrr && ParseRR(idr, &rr) > 0) { if (!special) path = rr.name; symlink = rr.sl; access = rr.mode; time = rr.t_mtime; adate = rr.t_atime; cdate = rr.t_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->joliet) { 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 { for (i = 0;i < isonum_711(idr->name_len);++i) { if (idr->name[i] == ';') break; if (idr->name[i]) path += (idr->name[i]); } } if (path.endsWith('.')) path.resize(path.length() - 1); } } if (iso->showrr) FreeRR(&rr); if (idr->flags[0] & 2) { entry = new KIsoDirectory(iso, path, access | S_IFDIR, time, adate, cdate, user, group, symlink); } else { entry = new KIsoFile(iso, path, access, time, adate, cdate, user, group, symlink, (long long)(isonum_733(idr->extent)) << (long long)11, isonum_733(idr->size)); if (z_size)(static_cast <KIsoFile*>(entry))->setZF(z_algo, z_params, z_size); } iso->dirent->addEntry(entry); } if ((idr->flags[0] & 2) && (iso->level == 0 || !special)) { if (iso->level) { oldentry = iso->dirent; iso->dirent = static_cast<KIsoDirectory*>(entry); } iso->level++; ProcessDir(&readf, isonum_733(idr->extent), isonum_733(idr->size), &mycallb, udata); iso->level--; if (iso->level) iso->dirent = static_cast<KIsoDirectory*>(oldentry); } return 0; }