VirtualBox

Changeset 32997 in vbox for trunk


Ignore:
Timestamp:
Oct 8, 2010 8:26:59 AM (14 years ago)
Author:
vboxsync
Message:

IPRT: Added ISO 9660 FS support.

Location:
trunk
Files:
2 added
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManageGuestCtrl.cpp

    r32976 r32997  
    3535#include <VBox/HostServices/GuestControlSvc.h> /* for PROC_STS_XXX */
    3636
    37 #include <VBox/log.h>
    3837#include <iprt/asm.h>
    39 #include <iprt/assert.h>
    40 #include <iprt/file.h>
     38#include <iprt/isofs.h>
    4139#include <iprt/getopt.h>
    42 #include <iprt/list.h>
    43 #include <iprt/path.h>
    44 #include <iprt/stream.h>
    45 #include <iprt/string.h>
    46 #include <iprt/time.h>
    47 #include <iprt/thread.h>
    4840
    4941#ifdef USE_XPCOM_QUEUE
     
    558550}
    559551
    560 #ifdef VBOX_WITH_COPYTOGUEST
    561 
    562 #define VBOX_ISO9660_MAX_SYSTEM_ID 32
    563 #define VBOX_ISO9660_MAX_VOLUME_ID 32
    564 #define VBOX_ISO9660_MAX_PUBLISHER_ID   128
    565 #define VBOX_ISO9660_MAX_VOLUME_ID   32
    566 #define VBOX_ISO9660_MAX_VOLUMESET_ID   128
    567 #define VBOX_ISO9660_MAX_PREPARER_ID   128
    568 #define VBOX_ISO9660_MAX_APPLICATION_ID   128
    569 #define VBOX_ISO9660_STANDARD_ID "CD001"
    570 #define VBOX_ISO9660_SECTOR_SIZE 2048
    571 
    572 #pragma pack(1)
    573 typedef struct VBoxISO9660DateShort
    574 {
    575     uint8_t year;
    576     uint8_t month;
    577     uint8_t day;
    578     uint8_t hour;
    579     uint8_t minute;
    580     uint8_t second;
    581     int8_t      gmt_offset;
    582 } VBoxISO9660DateShort;
    583 
    584 typedef struct VBoxISO9660DateLong
    585 {
    586     char year[4];
    587     char month[2];
    588     char day[2];
    589     char hour[2];
    590     char minute[2];
    591     char second[2];
    592     char hseconds[2];
    593     int8_t gmt_offset;
    594 } VBoxISO9660DateLong;
    595 
    596 typedef struct VBoxISO9660DirRecord
    597 {
    598         uint8_t record_length;
    599         uint8_t extented_attr_length;
    600         uint32_t extent_location;
    601     uint32_t extent_location_big;
    602         uint32_t extent_data_length; /* Number of bytes (file) / len (directory). */
    603     uint32_t extent_data_length_big;
    604     VBoxISO9660DateShort date;
    605         uint8_t flags;
    606         uint8_t interleave_unit_size;
    607     uint8_t interleave_gap_size;
    608         uint16_t volume_sequence_number;
    609     uint16_t volume_sequence_number_big;
    610         uint8_t name_len;
    611     /* Starting here there will be the actual directory entry name
    612      * and a padding of 1 byte if name_len is odd. */
    613 } VBoxISO9660DirRecord;
    614 
    615 typedef struct VBoxISO9660PriVolDesc
    616 {
    617         uint8_t type;
    618         char name_id[6];
    619         uint8_t version;
    620         char system_id[VBOX_ISO9660_MAX_SYSTEM_ID];
    621         char volume_id[VBOX_ISO9660_MAX_VOLUME_ID];
    622         uint8_t unused2[8];
    623         uint32_t volume_space_size; /* Number of sectors, Little Endian. */
    624         uint32_t volume_space_size_big; /* Number of sectors Big Endian. */
    625     uint8_t unused3[32];
    626         uint16_t volume_set_size;
    627     uint16_t volume_set_size_big;
    628     uint16_t volume_sequence_number;
    629     uint16_t volume_sequence_number_big;
    630     uint16_t logical_block_size; /* 2048. */
    631     uint16_t logical_block_size_big;
    632         uint32_t path_table_size; /* Size in bytes. */
    633         uint32_t path_table_size_big; /* Size in bytes. */
    634     uint32_t path_table_start_first;
    635     uint32_t path_table_start_second;
    636     uint32_t path_table_start_first_big;
    637     uint32_t path_table_start_second_big;
    638     VBoxISO9660DirRecord root_directory_record;
    639     uint8_t directory_padding;
    640     char volume_set_id[VBOX_ISO9660_MAX_VOLUMESET_ID];
    641     char publisher_id[VBOX_ISO9660_MAX_PUBLISHER_ID];
    642     char preparer_id[VBOX_ISO9660_MAX_PREPARER_ID];
    643     char application_id[VBOX_ISO9660_MAX_APPLICATION_ID];
    644     char copyright_file_id[37];
    645     char abstract_file_id[37];
    646     char bibliographic_file_id[37];
    647     VBoxISO9660DateLong creation_date;
    648     VBoxISO9660DateLong modification_date;
    649     VBoxISO9660DateLong expiration_date;
    650     VBoxISO9660DateLong effective_date;
    651     uint8_t file_structure_version;
    652     uint8_t unused4[1];
    653     char application_data[512];
    654     uint8_t unused5[653];
    655 } VBoxISO9660PriVolDesc;
    656 
    657 typedef struct VBoxISO9660PathTableHeader
    658 {
    659     uint8_t length;
    660     uint8_t extended_attr_sectors;
    661     /** Sector of starting directory table. */
    662     uint32_t sector_dir_table;
    663     /** Index of parent directory (1 for the root). */
    664     uint16_t parent_index;
    665     /* Starting here there will be the name of the directory,
    666      * specified by length above. */
    667 } VBoxISO9660PathTableHeader;
    668 
    669 typedef struct VBoxISO9660PathTableEntry
    670 {
    671     char       *path;
    672     char       *path_full;
    673     VBoxISO9660PathTableHeader header;
    674     RTLISTNODE  Node;
    675 } VBoxISO9660PathTableEntry;
    676 
    677 typedef struct VBoxISO9660File
    678 {
    679     RTFILE file;
    680     RTLISTNODE listPaths;
    681     VBoxISO9660PriVolDesc priVolDesc;
    682 } VBoxISO9660File;
    683 #pragma pack()
    684 
    685 void rtISO9660DestroyPathCache(VBoxISO9660File *pFile)
    686 {
    687     VBoxISO9660PathTableEntry *pNode = RTListNodeGetFirst(&pFile->listPaths, VBoxISO9660PathTableEntry, Node);
    688     while (pNode)
    689     {
    690         VBoxISO9660PathTableEntry *pNext = RTListNodeGetNext(&pNode->Node, VBoxISO9660PathTableEntry, Node);
    691         bool fLast = RTListNodeIsLast(&pFile->listPaths, &pNode->Node);
    692 
    693         if (pNode->path)
    694             RTStrFree(pNode->path);
    695         if (pNode->path_full)
    696             RTStrFree(pNode->path_full);
    697         RTListNodeRemove(&pNode->Node);
    698         RTMemFree(pNode);
    699 
    700         if (fLast)
    701             break;
    702 
    703         pNode = pNext;
    704     }
    705 }
    706 
    707 void RTISO9660Close(VBoxISO9660File *pFile)
    708 {
    709     if (pFile)
    710     {
    711         rtISO9660DestroyPathCache(pFile);
    712         RTFileClose(pFile->file);
    713     }
    714 }
    715 
    716 int rtISO9660AddToPathCache(PRTLISTNODE pList, const char *pszPath,
    717                             VBoxISO9660PathTableHeader *pHeader)
    718 {
    719     AssertPtrReturn(pList, VERR_INVALID_PARAMETER);
    720     AssertPtrReturn(pszPath, VERR_INVALID_PARAMETER);
    721     AssertPtrReturn(pHeader, VERR_INVALID_PARAMETER);
    722 
    723     VBoxISO9660PathTableEntry *pNode = (VBoxISO9660PathTableEntry*)RTMemAlloc(sizeof(VBoxISO9660PathTableEntry));
    724     if (pNode == NULL)
    725         return VERR_NO_MEMORY;
    726 
    727     pNode->path = NULL;
    728     if (RT_SUCCESS(RTStrAAppend(&pNode->path, pszPath)))
    729     {
    730         memcpy((VBoxISO9660PathTableHeader*)&pNode->header,
    731                (VBoxISO9660PathTableHeader*)pHeader, sizeof(pNode->header));
    732 
    733         pNode->path_full = NULL;
    734         pNode->Node.pPrev = NULL;
    735         pNode->Node.pNext = NULL;
    736         RTListAppend(pList, &pNode->Node);
    737         return VINF_SUCCESS;
    738     }
    739     return VERR_NO_MEMORY;
    740 }
    741 
    742 int rtISO9660GetParentPathSub(PRTLISTNODE pList, VBoxISO9660PathTableEntry *pNode,
    743                               char *pszPathNode, char **ppszPath)
    744 {
    745     int rc = VINF_SUCCESS;
    746     if (pNode->header.parent_index > 1)
    747     {
    748         uint16_t idx = 1;
    749         VBoxISO9660PathTableEntry *pNodeParent = RTListNodeGetFirst(pList, VBoxISO9660PathTableEntry, Node);
    750         while (idx++ < pNode->header.parent_index)
    751             pNodeParent =  RTListNodeGetNext(&pNodeParent->Node, VBoxISO9660PathTableEntry, Node);
    752         char *pszPath;
    753         if (RTStrAPrintf(&pszPath, "%s/%s", pNodeParent->path, pszPathNode))
    754         {
    755             rc = rtISO9660GetParentPathSub(pList, pNodeParent, pszPath, ppszPath);
    756             RTStrFree(pszPath);
    757         }
    758         else
    759             rc = VERR_NO_MEMORY;
    760     }
    761     else
    762     {
    763         char *pszPath = RTStrDup(pszPathNode);
    764         *ppszPath = pszPath;
    765     }
    766     return rc;
    767 }
    768 
    769 /* Is a *flat* structure! */
    770 int rtISO9660UpdatePathCache(VBoxISO9660File *pFile)
    771 {
    772     AssertPtrReturn(pFile, VERR_INVALID_PARAMETER);
    773     rtISO9660DestroyPathCache(pFile);
    774 
    775     RTListInit(&pFile->listPaths);
    776 
    777     /* Seek to path tables. */
    778     int rc = VINF_SUCCESS;
    779     Assert(pFile->priVolDesc.path_table_start_first > 16);
    780     uint64_t uTableStart = (pFile->priVolDesc.path_table_start_first * VBOX_ISO9660_SECTOR_SIZE);
    781     Assert(uTableStart % VBOX_ISO9660_SECTOR_SIZE == 0); /* Make sure it's aligned. */
    782     if (RTFileTell(pFile->file) != uTableStart)
    783         rc = RTFileSeek(pFile->file, uTableStart, RTFILE_SEEK_BEGIN, &uTableStart);
    784 
    785     /*
    786      * Since this is a sequential format, for performance it's best to read the
    787      * complete path table (every entry can have its own level (directory depth) first
    788      * and the actual directories of the path table afterwards.
    789      */
    790 
    791     /* Read in the path table ... */
    792     uint32_t cbLeft = pFile->priVolDesc.path_table_size;
    793     VBoxISO9660PathTableHeader header;
    794     while ((cbLeft > 0) && RT_SUCCESS(rc))
    795     {
    796         size_t cbRead;
    797         rc = RTFileRead(pFile->file, (VBoxISO9660PathTableHeader*)&header, sizeof(VBoxISO9660PathTableHeader), &cbRead);
    798         if (RT_FAILURE(rc))
    799             break;
    800         cbLeft -= cbRead;
    801         if (header.length)
    802         {
    803             Assert(cbLeft >= header.length);
    804             Assert(header.length <= 31);
    805             /* Allocate and read in the actual path name. */
    806             char *pszName = RTStrAlloc(header.length + 1);
    807             rc = RTFileRead(pFile->file, (char*)pszName, header.length, &cbRead);
    808             if (RT_SUCCESS(rc))
    809             {
    810                 cbLeft -= cbRead;
    811                 pszName[cbRead] = '\0'; /* Terminate string. */
    812                 /* Add entry to cache ... */
    813                 rc = rtISO9660AddToPathCache(&pFile->listPaths, pszName, &header);
    814             }
    815             RTStrFree(pszName);
    816             /* Read padding if required ... */
    817             if ((header.length % 2) != 0) /* If we have an odd length, read/skip the padding byte. */
    818             {
    819                 rc = RTFileSeek(pFile->file, 1, RTFILE_SEEK_CURRENT, NULL);
    820                 cbLeft--;
    821             }
    822         }
    823     }
    824 
    825     /* Transform path names into full paths. This is a bit ugly right now. */
    826     VBoxISO9660PathTableEntry *pNode = RTListNodeGetLast(&pFile->listPaths, VBoxISO9660PathTableEntry, Node);
    827     while (   pNode
    828            && !RTListNodeIsFirst(&pFile->listPaths, &pNode->Node)
    829            && RT_SUCCESS(rc))
    830     {
    831         rc = rtISO9660GetParentPathSub(&pFile->listPaths, pNode,
    832                                        pNode->path, &pNode->path_full);
    833         if (RT_SUCCESS(rc))
    834             pNode = RTListNodeGetPrev(&pNode->Node, VBoxISO9660PathTableEntry, Node);
    835     }
    836 
    837     return rc;
    838 }
    839 
    840 int RTISO9660Open(const char *pszFileName, VBoxISO9660File *pFile)
    841 {
    842     AssertPtrReturn(pszFileName, VERR_INVALID_PARAMETER);
    843     AssertPtrReturn(pFile, VERR_INVALID_PARAMETER);
    844 
    845     RTListInit(&pFile->listPaths);
    846 #if 1
    847     Assert(sizeof(VBoxISO9660DateShort) == 7);
    848     Assert(sizeof(VBoxISO9660DateLong) == 17);
    849     int l = sizeof(VBoxISO9660DirRecord);
    850     RTPrintf("VBoxISO9660DirRecord=%ld\n", l);
    851     Assert(l == 33);
    852     /* Each volume descriptor exactly occupies one sector. */
    853     l = sizeof(VBoxISO9660PriVolDesc);
    854     RTPrintf("VBoxISO9660PriVolDesc=%ld\n", l);
    855     Assert(l == VBOX_ISO9660_SECTOR_SIZE);
    856 #endif
    857     int rc = RTFileOpen(&pFile->file, pszFileName, RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_WRITE);
    858     if (RT_SUCCESS(rc))
    859     {
    860         uint64_t cbSize;
    861         rc = RTFileGetSize(pFile->file, &cbSize);
    862         if (   RT_SUCCESS(rc)
    863             && cbSize > 16 * VBOX_ISO9660_SECTOR_SIZE)
    864         {
    865             uint64_t cbOffset = 16 * VBOX_ISO9660_SECTOR_SIZE; /* Start reading at 32k. */
    866             size_t cbRead;
    867             VBoxISO9660PriVolDesc volDesc;
    868             bool fFoundPrimary = false;
    869             bool fIsValid = false;
    870             while (cbOffset < _1M)
    871             {
    872                 /* Get primary descriptor. */
    873                 rc = RTFileRead(pFile->file, (VBoxISO9660PriVolDesc*)&volDesc, sizeof(VBoxISO9660PriVolDesc), &cbRead);
    874                 if (RT_FAILURE(rc) || cbRead < sizeof(VBoxISO9660PriVolDesc))
    875                     break;
    876                 if (   RTStrStr((char*)volDesc.name_id, VBOX_ISO9660_STANDARD_ID)
    877                     && volDesc.type    == 0x1 /* Primary Volume Descriptor */)
    878                 {
    879                     memcpy((VBoxISO9660PriVolDesc*)&pFile->priVolDesc,
    880                            (VBoxISO9660PriVolDesc*)&volDesc, sizeof(VBoxISO9660PriVolDesc));
    881                     fFoundPrimary = true;
    882                 }
    883                 else if(volDesc.type == 0xff /* Termination Volume Descriptor */)
    884                 {
    885                     if (fFoundPrimary)
    886                         fIsValid = true;
    887                     break;
    888                 }
    889                 cbOffset += sizeof(VBoxISO9660PriVolDesc);
    890             }
    891 
    892             if (fIsValid)
    893                 rc = rtISO9660UpdatePathCache(pFile);
    894             else
    895                 rc = VERR_INVALID_PARAMETER;
    896         }
    897         if (RT_FAILURE(rc))
    898             RTISO9660Close(pFile);
    899     }
    900     return rc;
    901 }
    902 
    903 /* Parses the extent content given at a specified sector. */
    904 int rtISO9660FindEntry(VBoxISO9660File *pFile, const char *pszFileName,
    905                        uint32_t uExtentSector, uint32_t cbExtent /* Bytes */,
    906                        VBoxISO9660DirRecord **ppRec)
    907 {
    908     AssertPtrReturn(pFile, VERR_INVALID_PARAMETER);
    909     Assert(uExtentSector > 16);
    910 
    911     int rc = RTFileSeek(pFile->file, uExtentSector * VBOX_ISO9660_SECTOR_SIZE,
    912                         RTFILE_SEEK_BEGIN, NULL);
    913     if (RT_SUCCESS(rc))
    914     {
    915         rc = VERR_FILE_NOT_FOUND;
    916 
    917         uint8_t uBuffer[VBOX_ISO9660_SECTOR_SIZE];
    918         uint32_t cbLeft = cbExtent;
    919         while (!RT_SUCCESS(rc) && cbLeft > 0)
    920         {
    921             size_t cbRead;
    922             int rc2 = RTFileRead(pFile->file, (void*)&uBuffer, sizeof(uBuffer), &cbRead);
    923             Assert(RT_SUCCESS(rc2) && cbRead == VBOX_ISO9660_SECTOR_SIZE);
    924             cbLeft -= cbRead;
    925 
    926             uint32_t idx = 0;
    927             while (idx < cbRead)
    928             {
    929                 VBoxISO9660DirRecord *pCurRecord = (VBoxISO9660DirRecord*)&uBuffer[idx];
    930                 if (pCurRecord->record_length == 0)
    931                     break;
    932 
    933                 Assert(pCurRecord->name_len > 0);
    934                 char *pszName = RTStrAlloc(pCurRecord->name_len + 1);
    935                 AssertPtr(pszName);
    936                 Assert(idx + sizeof(VBoxISO9660DirRecord) < cbRead);
    937                 memcpy(pszName, &uBuffer[idx + sizeof(VBoxISO9660DirRecord)], pCurRecord->name_len);
    938 
    939                 if (   pCurRecord->name_len == 1
    940                     && pszName[0] == 0x0)
    941                 {
    942                     /* This is a "." directory (self). */
    943                 }
    944                 else if (   pCurRecord->name_len == 1
    945                          && pszName[0] == 0x1)
    946                 {
    947                     /* This is a ".." directory (parent). */
    948                 }
    949                 else /* Regular directory or file */
    950                 {
    951                     if (pCurRecord->flags & RT_BIT(1)) /* Directory */
    952                     {
    953                         /* We don't recursively go into directories
    954                          * because we already have the cached path table. */
    955                         pszName[pCurRecord->name_len] = 0;
    956                         /*rc = rtISO9660ParseDir(pFile, pszFileName,
    957                                                  pDirHdr->extent_location, pDirHdr->extent_data_length);*/
    958                     }
    959                     else /* File */
    960                     {
    961                         /* Get last occurence of ";" and cut it off. */
    962                         char *pTerm = strrchr(pszName, ';');
    963                         if (pTerm)
    964                             pszName[pTerm - pszName] = 0;
    965 
    966                         /* Don't use case sensitive comparison here, in IS0 9660 all
    967                          * file / directory names are UPPERCASE. */
    968                         if (!RTStrICmp(pszName, pszFileName))
    969                         {
    970                             VBoxISO9660DirRecord *pRec = (VBoxISO9660DirRecord*)RTMemAlloc(sizeof(VBoxISO9660DirRecord));
    971                             if (pRec)
    972                             {
    973                                 memcpy(pRec, pCurRecord, sizeof(VBoxISO9660DirRecord));
    974                                 *ppRec = pRec;
    975                                 rc = VINF_SUCCESS;
    976                                 break;
    977                             }
    978                             else
    979                                 rc = VERR_NO_MEMORY;
    980                         }
    981                     }
    982                 }
    983                 idx += pCurRecord->record_length;
    984             }
    985         }
    986     }
    987     return rc;
    988 }
    989 
    990 int rtISO9660ResolvePath(VBoxISO9660File *pFile, const char *pszPath, uint32_t *puSector)
    991 {
    992     AssertPtrReturn(pFile, VERR_INVALID_PARAMETER);
    993     AssertPtrReturn(pszPath, VERR_INVALID_PARAMETER);
    994     AssertPtrReturn(puSector, VERR_INVALID_PARAMETER);
    995 
    996     int rc = VERR_FILE_NOT_FOUND;
    997     char *pszTemp = RTStrDup(pszPath);
    998     if (pszTemp)
    999     {
    1000         RTPathStripFilename(pszTemp);
    1001 
    1002         bool bFound = false;
    1003         VBoxISO9660PathTableEntry *pNode;
    1004         if (!RTStrCmp(pszTemp, ".")) /* Root directory? Use first node! */
    1005         {
    1006             pNode = RTListNodeGetFirst(&pFile->listPaths, VBoxISO9660PathTableEntry, Node);
    1007             bFound = true;
    1008         }
    1009         else
    1010         {
    1011             RTListForEach(&pFile->listPaths, pNode, VBoxISO9660PathTableEntry, Node)
    1012             {
    1013                 if (   pNode->path_full != NULL /* Root does not have a path! */
    1014                     && !RTStrICmp(pNode->path_full, pszTemp))
    1015                 {
    1016                     bFound = true;
    1017                     break;
    1018                 }
    1019             }
    1020         }
    1021         if (bFound)
    1022         {
    1023             *puSector = pNode->header.sector_dir_table;
    1024             rc = VINF_SUCCESS;
    1025         }
    1026         RTStrFree(pszTemp);
    1027     }
    1028     else
    1029         rc = VERR_NO_MEMORY;
    1030     return rc;
    1031 }
    1032 
    1033 int rtISO9660GetDirectoryRecord(VBoxISO9660File *pFile, const char *pszPath,
    1034                                 VBoxISO9660DirRecord **ppRecord)
    1035 {
    1036     AssertPtrReturn(pFile, VERR_INVALID_PARAMETER);
    1037     AssertPtrReturn(pszPath, VERR_INVALID_PARAMETER);
    1038     AssertPtrReturn(ppRecord, VERR_INVALID_PARAMETER);
    1039 
    1040     uint32_t uSector;
    1041     int rc = rtISO9660ResolvePath(pFile, pszPath, &uSector);
    1042     if (RT_SUCCESS(rc))
    1043     {
    1044         /* Seek and read the directory record of given file. */
    1045         rc = RTFileSeek(pFile->file, uSector * VBOX_ISO9660_SECTOR_SIZE,
    1046                         RTFILE_SEEK_BEGIN, NULL);
    1047         if (RT_SUCCESS(rc))
    1048         {
    1049             size_t cbRead;
    1050             VBoxISO9660DirRecord *pRecord = (VBoxISO9660DirRecord*)RTMemAlloc(sizeof(VBoxISO9660DirRecord));
    1051             if (pRecord)
    1052             {
    1053                 rc = RTFileRead(pFile->file, (VBoxISO9660DirRecord*)pRecord, sizeof(VBoxISO9660DirRecord), &cbRead);
    1054                 if (RT_SUCCESS(rc))
    1055                 {
    1056                     Assert(cbRead == sizeof(VBoxISO9660DirRecord));
    1057                     *ppRecord = pRecord;
    1058                 }
    1059                 if (RT_FAILURE(rc))
    1060                     RTMemFree(pRecord);
    1061             }
    1062             else
    1063                 rc = VERR_NO_MEMORY;
    1064         }
    1065     }
    1066     return rc;
    1067 }
    1068 
    1069 int RTISO9660GetFileInfo(VBoxISO9660File *pFile, const char *pszPath,
    1070                          uint32_t *pcbOffset, uint32_t *pcbLength)
    1071 {
    1072     AssertPtrReturn(pFile, VERR_INVALID_PARAMETER);
    1073     AssertPtrReturn(pszPath, VERR_INVALID_PARAMETER);
    1074     AssertPtrReturn(pcbOffset, VERR_INVALID_PARAMETER);
    1075 
    1076     VBoxISO9660DirRecord *pDirRecord;
    1077     int rc = rtISO9660GetDirectoryRecord(pFile, pszPath, &pDirRecord);
    1078     if (RT_SUCCESS(rc))
    1079     {
    1080         /* Get actual file record. */
    1081         VBoxISO9660DirRecord *pFileRecord;
    1082         rc = rtISO9660FindEntry(pFile,
    1083                                 RTPathFilename(pszPath),
    1084                                 pDirRecord->extent_location,
    1085                                 pDirRecord->extent_data_length,
    1086                                 &pFileRecord);
    1087         if (RT_SUCCESS(rc))
    1088         {
    1089             *pcbOffset = pFileRecord->extent_location * VBOX_ISO9660_SECTOR_SIZE;
    1090             *pcbLength = pFileRecord->extent_data_length;
    1091             RTMemFree(pFileRecord);
    1092         }
    1093         RTMemFree(pDirRecord);
    1094     }
    1095     return rc;
    1096 }
    1097 
    1098 int RTISO9660ExtractFile(VBoxISO9660File *pFile, const char *pszSource,
    1099                          const char *pszDest)
    1100 {
    1101     uint32_t cbOffset, cbLength;
    1102     int rc = RTISO9660GetFileInfo(pFile, pszSource, &cbOffset, &cbLength);
    1103     if (RT_SUCCESS(rc))
    1104     {
    1105         rc = RTFileSeek(pFile->file, cbOffset, RTFILE_SEEK_BEGIN, NULL);
    1106         if (RT_SUCCESS(rc))
    1107         {
    1108             RTFILE fileDest;
    1109             rc = RTFileOpen(&fileDest, pszDest, RTFILE_O_CREATE | RTFILE_O_WRITE | RTFILE_O_DENY_WRITE);
    1110             if (RT_SUCCESS(rc))
    1111             {
    1112                 size_t cbToRead, cbRead, cbWritten;
    1113                 uint8_t byBuffer[_4K];
    1114                 while (   cbLength > 0
    1115                        && RT_SUCCESS(rc))
    1116                 {
    1117                     cbToRead = RT_MIN(cbLength, _4K);
    1118                     rc = RTFileRead(pFile->file, (uint8_t*)byBuffer, cbToRead, &cbRead);
    1119                     if (RT_FAILURE(rc))
    1120                         break;
    1121                     rc = RTFileWrite(fileDest, (uint8_t*)byBuffer, cbRead, &cbWritten);
    1122                     if (RT_FAILURE(rc))
    1123                         break;
    1124                     cbLength -= cbRead;
    1125                 }
    1126                 RTFileClose(fileDest);
    1127             }
    1128         }
    1129     }
    1130     return rc;
    1131 }
    1132 
    1133 #endif
    1134 
    1135552static int handleCtrlCopyTo(HandlerArg *a)
    1136553{
    1137     VBoxISO9660File file;
    1138     int vrc = RTISO9660Open("c:\\Downloads\\VBoxGuestAdditions_3.2.8.iso", &file);
     554    RTISOFSFILE file;
     555    int vrc = RTIsoFsOpen(&file, "c:\\Downloads\\VBoxGuestAdditions_3.2.8.iso");
    1139556    if (RT_SUCCESS(vrc))
    1140557    {
    1141         //vrc = RTISO9660ExtractFile(&file, "VBOXWINDOWSADDITIONS_X86.EXE", "C:\\VBOXWINDOWSADDITIONS_X86.EXE");
    1142         vrc = RTISO9660ExtractFile(&file, "32BIT/OS2/README.TXT", "C:\\OS2-Readme.txt");
    1143         RTISO9660Close(&file);
     558        vrc = RTIsoFsExtractFile(&file, "VBOXWINDOWSADDITIONS_X86.EXE", "C:\\VBOXWINDOWSADDITIONS_X86.EXE");
     559        vrc = RTIsoFsExtractFile(&file, "FOO.EXE", "C:\\FOO.EXE");
     560        vrc = RTIsoFsExtractFile(&file, "32BIT/OS2/README.TXT", "C:\\OS2-Readme.txt");
     561        RTIsoFsClose(&file);
    1144562    }
    1145563    return vrc;
  • trunk/src/VBox/Runtime/Makefile.kmk

    r32990 r32997  
    387387        r3/fs.cpp \
    388388        r3/init.cpp \
     389        r3/isofs.cpp \
    389390        r3/path.cpp \
    390391        r3/process.cpp \
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette