//****************************************************************************************************************** struct iso_dirtree *iso9660::FindFolder( char *Folder ) { char *work; work = (char *)malloc(from_723(m_info.iso.logical_block_size)); char *temp; struct iso_directories *lastpath = NULL; if ( strpbrk(Folder, ":") ) strcpy(work, strpbrk(Folder, ":") + 1); else strcpy(work, Folder); temp = work + 1; while ( strlen( temp ) > 1 && strpbrk( temp + 1, "\\" ) ) temp = strpbrk( temp + 1, "\\" ); if ( strlen( work ) > 1 && work[ strlen(work) - 1 ] == '*' ) { work[ strlen(work) - 1 ] = 0; } if ( strlen( work ) > 2 ) if ( work[ strlen(work) - 1 ] == '\\' ) work[ strlen(work) - 1 ] = 0; if (m_paths) lastpath = m_paths->next; while ( lastpath ) { if ( !stricmp( lastpath->path, work)) { free ( work ); return lastpath->dir; } lastpath = lastpath->next; } free ( work ); return 0; }
int iso9660_get_pvd_block_size(const iso9660_pvd_t *pvd) { if (NULL == pvd) return 0; return from_723(pvd->logical_block_size); }
void iso9660::Scan() { if (m_hCDROM != NULL) return ; m_hCDROM = CIoSupport::OpenCDROM(); CIoSupport::AllocReadBuffer(); m_paths = 0; m_lastpath = 0; memset(&m_info, 0, sizeof(m_info)); m_info.ISO_HANDLE = m_hCDROM ; m_info.Curr_dir_cache = 0; m_info.Curr_dir = (char*)malloc( 4096 ); strcpy( m_info.Curr_dir, "\\" ); CSingleLock lock(m_critSection); DWORD lpNumberOfBytesRead = 0; ::SetFilePointer( m_info.ISO_HANDLE, 0x8000, 0, FILE_BEGIN ); ::ReadFile( m_info.ISO_HANDLE, &m_info.iso, sizeof(m_info.iso), &lpNumberOfBytesRead, NULL ); if (strncmp(m_info.iso.szSignature, "CD001", 5)) { CIoSupport::CloseCDROM( m_info.ISO_HANDLE); CIoSupport::FreeReadBuffer(); m_info.ISO_HANDLE = NULL; m_hCDROM = NULL; m_info.iso9660 = 0; return ; } else { m_info.iso9660 = 1; m_info.joliet = 0; m_info.HeaderPos = 0x8000; int current = 0x8000; WORD wSectorSize = from_723(m_info.iso.logical_block_size); // first check if first file in the current VD has a rock-ridge NM. if it has, disable joliet iso9660_Directory *dirPointer = reinterpret_cast<iso9660_Directory*>(&m_info.iso.szRootDir); ::SetFilePointer( m_info.ISO_HANDLE, wSectorSize * from_733(dirPointer->extent), 0, FILE_BEGIN ); DWORD lpNumberOfBytesRead; char* pCurr_dir_cache = (char*)malloc( 16*wSectorSize ); iso9660_Directory isodir; BOOL bResult = ::ReadFile( m_info.ISO_HANDLE, pCurr_dir_cache, wSectorSize, &lpNumberOfBytesRead, NULL ); memcpy( &isodir, pCurr_dir_cache, sizeof(isodir)); int iso9660searchpointer=0; if ( isodir.ucRecordLength ) iso9660searchpointer += isodir.ucRecordLength; else iso9660searchpointer = (iso9660searchpointer - (iso9660searchpointer % wSectorSize)) + wSectorSize; memcpy( &isodir, pCurr_dir_cache + iso9660searchpointer, std::min(sizeof(isodir), sizeof(m_info.isodir))); free(pCurr_dir_cache); if (bResult && lpNumberOfBytesRead == wSectorSize) bResult = IsRockRidge(isodir); while ( m_info.iso.byOne != 255) { if ( ( m_info.iso.byZero3[0] == 0x25 ) && ( m_info.iso.byZero3[1] == 0x2f ) && !bResult ) { switch ( m_info.iso.byZero3[2] ) { case 0x45 : case 0x40 : case 0x43 : m_info.HeaderPos = current; m_info.joliet = 1; } // 25 2f 45 or 25 2f 40 or 25 2f 43 = jouliet, and best fitted for reading } current += 0x800; ::SetFilePointer( m_info.ISO_HANDLE, current, 0, FILE_BEGIN ); ::ReadFile( m_info.ISO_HANDLE, &m_info.iso, sizeof(m_info.iso), &lpNumberOfBytesRead, NULL ); } ::SetFilePointer( m_info.ISO_HANDLE, m_info.HeaderPos, 0, FILE_BEGIN ); ::ReadFile( m_info.ISO_HANDLE, &m_info.iso, sizeof(m_info.iso), &lpNumberOfBytesRead, NULL ); memcpy( &m_info.isodir, m_info.iso.szRootDir, sizeof(m_info.isodir)); } memcpy( &m_info.isodir, &m_info.iso.szRootDir, sizeof(m_info.isodir) ); ReadRecursiveDirFromSector( from_733(m_info.isodir.extent), "\\" ); }
//****************************************************************************************************************** struct iso_dirtree *iso9660::ReadRecursiveDirFromSector( DWORD sector, const char *path ) { struct iso_dirtree* pDir = NULL; struct iso_dirtree* pFile_Pointer = NULL; char* pCurr_dir_cache = NULL; DWORD iso9660searchpointer; struct iso9660_Directory isodir; struct iso9660_Directory curr_dir; WORD wSectorSize = from_723(m_info.iso.logical_block_size); struct iso_directories *point = m_lastpath; if (point) { while ( point->next ) { if (strcmp(path, point->path) == 0) return NULL; point = point->next; } } #ifdef _DEBUG_OUTPUT std::string strTmp; strTmp = StringUtils::Format("****************** Adding dir : %s\r", path); OutputDebugString( strTmp.c_str() ); #endif pDir = (struct iso_dirtree *)malloc(sizeof(struct iso_dirtree)); if (!pDir) return NULL; pDir->next = NULL; pDir->path = NULL; pDir->name = NULL; pDir->dirpointer = NULL; pFile_Pointer = pDir; m_vecDirsAndFiles.push_back(pDir); ::SetFilePointer( m_info.ISO_HANDLE, wSectorSize * sector, 0, FILE_BEGIN ); DWORD lpNumberOfBytesRead = 0; pCurr_dir_cache = (char*)malloc( 16*wSectorSize ); if (!pCurr_dir_cache ) return NULL; BOOL bResult = ::ReadFile( m_info.ISO_HANDLE, pCurr_dir_cache, wSectorSize, &lpNumberOfBytesRead, NULL ); if (!bResult || lpNumberOfBytesRead != wSectorSize) { CLog::Log(LOGERROR, "%s: unable to read", __FUNCTION__); free(pCurr_dir_cache); return NULL; } memcpy( &isodir, pCurr_dir_cache, sizeof(isodir) ); memcpy( &curr_dir, pCurr_dir_cache, sizeof(isodir) ); DWORD curr_dirSize = from_733(curr_dir.size); if ( curr_dirSize > wSectorSize ) { free( pCurr_dir_cache ); pCurr_dir_cache = (char*)malloc( 16 * from_733(isodir.size) ); if (!pCurr_dir_cache ) return NULL; ::SetFilePointer( m_info.ISO_HANDLE, wSectorSize * sector, 0, FILE_BEGIN ); bResult = ::ReadFile( m_info.ISO_HANDLE, pCurr_dir_cache , curr_dirSize, &lpNumberOfBytesRead, NULL ); if (!bResult || lpNumberOfBytesRead != curr_dirSize) { CLog::Log(LOGERROR, "%s: unable to read", __FUNCTION__); free(pCurr_dir_cache); return NULL; } } iso9660searchpointer = 0; if (!m_lastpath) { m_lastpath = m_paths; if ( !m_lastpath ) { m_paths = (struct iso_directories *)malloc(sizeof(struct iso_directories)); if (!m_paths ) { free(pCurr_dir_cache); return NULL; } m_paths->path = NULL; m_paths->dir = NULL; m_paths->next = NULL; m_lastpath = m_paths; } else { while ( m_lastpath->next ) m_lastpath = m_lastpath->next; } } m_lastpath->next = ( struct iso_directories *)malloc( sizeof( struct iso_directories ) ); if (!m_lastpath->next ) { free(pCurr_dir_cache); return NULL; } m_lastpath = m_lastpath->next; m_lastpath->next = NULL; m_lastpath->dir = pDir; m_lastpath->path = (char *)malloc(strlen(path) + 1); if (!m_lastpath->path ) { free(pCurr_dir_cache); return NULL; } strcpy( m_lastpath->path, path ); while ( 1 ) { if ( isodir.ucRecordLength ) iso9660searchpointer += isodir.ucRecordLength; else { iso9660searchpointer = (iso9660searchpointer - (iso9660searchpointer % wSectorSize)) + wSectorSize; } if ( curr_dirSize <= iso9660searchpointer ) { break; } int isize = std::min(sizeof(isodir), sizeof(m_info.isodir)); memcpy( &isodir, pCurr_dir_cache + iso9660searchpointer, isize); if (!isodir.ucRecordLength) continue; if ( !(isodir.byFlags & Flag_NotExist) ) { if ( (!( isodir.byFlags & Flag_Directory )) && ( isodir.Len_Fi > 1) ) { std::string temp_text ; bool bContinue = false; if ( m_info.joliet ) { bContinue = true; isodir.FileName[isodir.Len_Fi] = isodir.FileName[isodir.Len_Fi + 1] = 0; //put terminator by its length temp_text = GetThinText(isodir.FileName, isodir.Len_Fi ); // temp_text.resize(isodir.Len_Fi); } if (!m_info.joliet && isodir.FileName[0] >= 0x20 ) { temp_text = ParseName(isodir); bContinue = true; } if (bContinue) { int semipos = temp_text.find(";", 0); if (semipos >= 0) temp_text.erase(semipos, temp_text.length() - semipos); pFile_Pointer->next = (struct iso_dirtree *)malloc(sizeof(struct iso_dirtree)); if (!pFile_Pointer->next) break; m_vecDirsAndFiles.push_back(pFile_Pointer->next); pFile_Pointer = pFile_Pointer->next; pFile_Pointer->next = 0; pFile_Pointer->dirpointer = NULL; pFile_Pointer->path = (char *)malloc(strlen(path) + 1); if (!pFile_Pointer->path) { free(pCurr_dir_cache); return NULL; } strcpy( pFile_Pointer->path, path ); pFile_Pointer->name = (char *)malloc( temp_text.length() + 1); if (!pFile_Pointer->name) { free(pCurr_dir_cache); return NULL; } strcpy( pFile_Pointer->name , temp_text.c_str()); #ifdef _DEBUG_OUTPUT //std::string strTmp; //strTmp = StringUtils::Format("adding sector : %X, File : %s size = %u pos = %x\r",sector,temp_text.c_str(), isodir.dwFileLengthLE, isodir.dwFileLocationLE ); //OutputDebugString( strTmp.c_str()); #endif pFile_Pointer->Location = from_733(isodir.extent); pFile_Pointer->dirpointer = NULL; pFile_Pointer ->Length = from_733(isodir.size); IsoDateTimeToFileTime(&isodir.DateTime, &pFile_Pointer->filetime); pFile_Pointer->type = 1; } } } } iso9660searchpointer = 0; memcpy( &curr_dir, pCurr_dir_cache, sizeof(isodir) ); memcpy( &isodir, pCurr_dir_cache, sizeof(isodir) ); while ( 1 ) { if ( isodir.ucRecordLength ) iso9660searchpointer += isodir.ucRecordLength; else { iso9660searchpointer = (iso9660searchpointer - (iso9660searchpointer % wSectorSize)) + wSectorSize; } if ( from_733(curr_dir.size) <= iso9660searchpointer ) { free( pCurr_dir_cache ); pCurr_dir_cache = NULL; return pDir; } memcpy( &isodir, pCurr_dir_cache + iso9660searchpointer, std::min(sizeof(isodir), sizeof(m_info.isodir))); if (!isodir.ucRecordLength) continue; if ( !(isodir.byFlags & Flag_NotExist) ) { if ( (( isodir.byFlags & Flag_Directory )) && ( isodir.Len_Fi > 1) ) { std::string temp_text ; bool bContinue = false; if ( m_info.joliet ) { bContinue = true; isodir.FileName[isodir.Len_Fi] = isodir.FileName[isodir.Len_Fi + 1] = 0; //put terminator by its length temp_text = GetThinText(isodir.FileName, isodir.Len_Fi); // temp_text.resize(isodir.Len_Fi); } if (!m_info.joliet && isodir.FileName[0] >= 0x20 ) { temp_text = ParseName(isodir); bContinue = true; } if (bContinue) { // int semipos = temp_text.find(";",0); //the directory is not seperate by ";",but by its length // if (semipos >= 0) // temp_text.erase(semipos,temp_text.length()-semipos); pFile_Pointer->next = (struct iso_dirtree *)malloc(sizeof(struct iso_dirtree)); if (!pFile_Pointer->next) { free(pCurr_dir_cache); return NULL; } m_vecDirsAndFiles.push_back(pFile_Pointer->next); pFile_Pointer = pFile_Pointer->next; pFile_Pointer->next = 0; pFile_Pointer->dirpointer = NULL; pFile_Pointer->path = (char *)malloc(strlen(path) + 1); if (!pFile_Pointer->path) { free(pCurr_dir_cache); return NULL; } strcpy( pFile_Pointer->path, path ); pFile_Pointer->name = (char *)malloc( temp_text.length() + 1); if (!pFile_Pointer->name) { free(pCurr_dir_cache); return NULL; } strcpy( pFile_Pointer->name , temp_text.c_str()); DWORD dwFileLocation = from_733(isodir.extent); #ifdef _DEBUG_OUTPUT std::string strTmp; strTmp = StringUtils::Format("adding directory sector : %X, File : %s size = %u pos = %x\r", sector, temp_text.c_str(), from_733(isodir.size), dwFileLocation ); OutputDebugString( strTmp.c_str()); #endif pFile_Pointer->Location = dwFileLocation; pFile_Pointer->dirpointer = NULL; pFile_Pointer->Length = from_733(isodir.size); IsoDateTimeToFileTime(&isodir.DateTime, &pFile_Pointer->filetime); std::string strPath = path; if ( strlen( path ) > 1 ) strPath += "\\"; strPath += temp_text; pFile_Pointer->dirpointer = ReadRecursiveDirFromSector( dwFileLocation, strPath.c_str() ); pFile_Pointer->type = 2; } } } } return NULL; }