isofs.cpp revision c7814cf6e1240a519cbec0441e033d0e2470ed00
/* $Id$ */
/** @file
* IPRT - ISO 9660 file system handling.
*/
/*
* Copyright (C) 2010-2011 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*
* The contents of this file may alternatively be used under the terms
* of the Common Development and Distribution License Version 1.0
* (CDDL) only, as it comes in the "COPYING.CDDL" file of the
* VirtualBox OSE distribution, in which case the provisions of the
* CDDL are applicable instead of those of the GPL.
*
* You may elect to license modified versions of this file under the
* terms and conditions of either the GPL or the CDDL or both.
*/
/*******************************************************************************
* Header Files *
*******************************************************************************/
/**
* Destroys the path cache.
*
* @param pFile ISO handle.
*/
{
while (pNode)
{
if (fLast)
break;
}
}
/**
* Adds a path entry to the path table list.
*
* @return IPRT status code.
* @param pList Path table list to add the path entry to.
* @param pszPath Path to add.
* @param pHeader Path header information to add.
*/
{
return VERR_NO_MEMORY;
{
return VINF_SUCCESS;
}
return VERR_NO_MEMORY;
}
/**
* Retrieves the parent path of a given node, assuming that the path table
* (still) is in sync with the node's index.
*
* @return IPRT status code.
* @param pList Path table list to use.
* @param pNode Node of path table entry to lookup the full path for.
* @param pszPathNode Current (partial) parent path; needed for recursion.
* @param ppszPath Pointer to a pointer to store the retrieved full path to.
*/
char *pszPathNode, char **ppszPath)
{
int rc = VINF_SUCCESS;
/* Do we have a parent? */
{
/* Get the parent of our current node (pNode) */
/* Construct intermediate path (parent + current path). */
if (pszPath)
{
/* ... and do the same with the parent's parent until we reached the root. */
}
else
}
else /* No parent (left), this must be the root path then. */
return rc;
}
/**
* Updates the path table cache of an ISO file.
*
* @return IPRT status code.
* @param pFile ISO handle.
*/
{
/* Seek to path tables. */
int rc = VINF_SUCCESS;
/*
* Since this is a sequential format, for performance it's best to read the
* complete path table (every entry can have its own level (directory depth) first
* and the actual directories of the path table afterwards.
*/
/* Read in the path table ... */
{
rc = RTFileRead(pFile->file, (RTISOFSPATHTABLEHEADER*)&header, sizeof(RTISOFSPATHTABLEHEADER), &cbRead);
if (RT_FAILURE(rc))
break;
{
/* Allocate and read in the actual path name. */
if (RT_SUCCESS(rc))
{
/* Add entry to cache ... */
}
/* Read padding if required ... */
{
cbLeft--;
}
}
}
/* Transform path names into full paths. This is a bit ugly right now. */
while ( pNode
&& RT_SUCCESS(rc))
{
if (RT_SUCCESS(rc))
}
return rc;
}
{
#if 0
int l = sizeof(RTISOFSDIRRECORD);
RTPrintf("RTISOFSDIRRECORD=%ld\n", l);
Assert(l == 33);
/* Each volume descriptor exactly occupies one sector. */
l = sizeof(RTISOFSPRIVOLDESC);
RTPrintf("RTISOFSPRIVOLDESC=%ld\n", l);
Assert(l == RTISOFS_SECTOR_SIZE);
#endif
int rc = RTFileOpen(&pFile->file, pszFileName, RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_WRITE);
if (RT_SUCCESS(rc))
{
if ( RT_SUCCESS(rc)
{
bool fFoundPrimary = false;
bool fIsValid = false;
{
/* Get primary descriptor. */
break;
{
fFoundPrimary = true;
}
{
if (fFoundPrimary)
fIsValid = true;
break;
}
cbOffset += sizeof(RTISOFSPRIVOLDESC);
}
if (fIsValid)
else
}
if (RT_FAILURE(rc))
}
return rc;
}
{
if (pFile)
{
}
}
/**
* Parses an extent given at the specified sector + size and
* searches for a file name to return an allocated directory record.
*
* @return IPRT status code.
* @param pFile ISO handle.
* @param pszFileName Absolute file name to search for.
* @param uExtentSector Sector of extent.
* @param cbExtent Size (in bytes) of extent.
* @param ppRec Pointer to a pointer to return the
* directory record. Must be free'd with
* rtIsoFsFreeDirectoryRecord().
*/
{
if (RT_SUCCESS(rc))
{
{
{
if (pCurRecord->record_length == 0)
break;
&& pszName[0] == 0x0)
{
/* This is a "." directory (self). */
}
&& pszName[0] == 0x1)
{
/* This is a ".." directory (parent). */
}
else /* Regular directory or file */
{
{
/* We don't recursively go into directories
* because we already have the cached path table. */
/*rc = rtIsoFsParseDir(pFile, pszFileName,
pDirHdr->extent_location, pDirHdr->extent_data_length);*/
}
else /* File */
{
/* Get last occurrence of ";" and cut it off. */
if (pTerm)
/* Don't use case sensitive comparison here, in IS0 9660 all
* file / directory names are UPPERCASE. */
{
if (pRec)
{
rc = VINF_SUCCESS;
}
else
rc = VERR_NO_MEMORY;
break;
}
}
}
}
}
}
return rc;
}
/**
* Retrieves the sector of a file extent given by the
* full file path within the ISO.
*
* @return IPRT status code.
* @param pFile ISO handle.
* @param pszPath File path to resolve.
* @param puSector Pointer where to store the found sector to.
*/
{
int rc = VERR_FILE_NOT_FOUND;
if (pszTemp)
{
bool bFound = false;
{
if (pNode)
bFound = true;
}
else
{
{
{
bFound = true;
break;
}
}
}
if (bFound)
{
rc = VINF_SUCCESS;
}
else
}
else
rc = VERR_NO_MEMORY;
return rc;
}
/**
* Allocates a new directory record.
*
* @return Pointer to the newly allocated directory record.
*/
static PRTISOFSDIRRECORD rtIsoFsCreateDirectoryRecord(void)
{
return pRecord;
}
/**
* Frees a previously allocated directory record.
*
* @return IPRT status code.
*/
{
}
/**
* Returns an allocated directory record for a given file.
*
* @return IPRT status code.
* @param pFile ISO handle.
* @param pszPath File path to resolve.
* @param ppRecord Pointer to a pointer to return the
* directory record. Must be free'd with
* rtIsoFsFreeDirectoryRecord().
*/
{
if (RT_SUCCESS(rc))
{
/* Seek and read the directory record of given file. */
if (RT_SUCCESS(rc))
{
if (pRecord)
{
if (RT_SUCCESS(rc))
{
}
if (RT_FAILURE(rc))
}
else
rc = VERR_NO_MEMORY;
}
}
return rc;
}
{
if (RT_SUCCESS(rc))
{
/* Get actual file record. */
&pFileRecord);
if (RT_SUCCESS(rc))
{
}
}
return rc;
}
const char *pszDest)
{
if (RT_SUCCESS(rc))
{
if (RT_SUCCESS(rc))
{
if (RT_SUCCESS(rc))
{
while ( cbLength > 0
&& RT_SUCCESS(rc))
{
if (RT_FAILURE(rc))
break;
if (RT_FAILURE(rc))
break;
}
}
}
}
return rc;
}