无忧启动论坛

 找回密码
 注册
搜索
系统gho:最纯净好用系统下载站广告联系 微信:wuyouceo QQ:184822951
查看: 3178|回复: 8

[求助] ISO 9660文件系统,有详细资料吗?

[复制链接]
发表于 2020-1-31 18:24:38 | 显示全部楼层 |阅读模式
研究了两天,没找到详细的资料,大神有详细资料没?
最近想研究下ISO内文件列表。
发表于 2020-1-31 18:37:56 | 显示全部楼层
想通过API创建还是

点评

解析已存在的ISO文件内部文件列表。 ---------------------------- Windows有API可以创建ISO吗?  详情 回复 发表于 2020-1-31 18:46
回复

使用道具 举报

 楼主| 发表于 2020-1-31 18:46:12 | 显示全部楼层

解析已存在的ISO文件内部文件列表。
----------------------------
Windows有API可以创建ISO吗?
回复

使用道具 举报

发表于 2020-1-31 18:46:52 | 显示全部楼层
红毛樱木 发表于 2020-1-31 18:46
解析已存在的ISO文件内部文件列表。
----------------------------
Windows有API可以创建ISO吗?

就是判断ISO是 ISO 9660还是UDF?还是想获取 ISO 9660格式的ISO里的文件内容?

点评

就是解析ISO文件系统。 简单说就是想获取ISO文件里的文件列表。 比如获取A.ISO文件里的文件列表  详情 回复 发表于 2020-1-31 18:53
回复

使用道具 举报

 楼主| 发表于 2020-1-31 18:53:29 | 显示全部楼层
2012jiashanni 发表于 2020-1-31 18:46
就是判断ISO是 ISO 9660还是UDF?还是想获取 ISO 9660格式的ISO里的文件内容?

就是解析ISO文件系统。
简单说就是想获取ISO文件里的文件列表。
比如获取A.ISO文件里的文件列表
回复

使用道具 举报

发表于 2020-1-31 19:13:12 | 显示全部楼层
本帖最后由 sunsea 于 2020-1-31 19:14 编辑

当年参考https://blog.csdn.net/goodqt/article/details/17202109这个帖子写的一个小程序,提取ISO内文件的,现在可能还对你有参考价值吧。

  1. #include <stdio.h>
  2. #include <tchar.h>
  3. #include <locale.h>
  4. #include <tchar.h>
  5. #include <string>
  6. #include <vector>
  7. #include <mbstring.h>
  8. #include <stdlib.h>  

  9. using namespace std;
  10. #ifdef _UNICODE
  11. typedef wstring _tstring;

  12. #else
  13. typedef string _tstring;

  14. #endif



  15. #define ATAPI_SECTOR_SIZE 2048 //一个CD扇区2048Byte
  16. #define LBA_TO_BYTE(x) (x*ATAPI_SECTOR_SIZE)
  17. //用法isodr.exe <iso文件> <光盘内路径> <输出路径>
  18. //例:isodr.exe C:\abc.iso /boot/boot.sdi C:\abc.tmp
  19. //例:isodr.exe C:\abc.iso /bootmgr C:\bootmgr //输出根目录下的bootmgr
  20. //直接运行程序显示本帮助。

  21. struct FILE_ITEM{
  22.         unsigned long lba;
  23.         string FileName;
  24.         unsigned long size;
  25. };

  26. int _t_real_main(int argc, _TCHAR* argv[]);
  27. int PraseFileSystemAndFind(FILE* isofile,unsigned long lba,FILE_ITEM &item,int depth,const vector<string> &NeedFileName,bool &isfound);

  28. int _tmain(int argc, _TCHAR* argv[])
  29. {
  30.         _TCHAR *help_txt = _T("ISO文件直接读取工具\t作者:sunsea\t参考网上部分代码改编而成\n高歌酹酒,来者相候,唤我今日,长缨在手。\n\n用法isodr.exe <iso文件> <光盘内路径> <输出路径>\n例:isodr.exe C:\\abc.iso /boot/boot.sdi C:\\abc.tmp\n例:isodr.exe C:\\abc.iso /bootmgr C:\\bootmgr 输出根目录下的bootmgr\n\n直接运行程序显示本帮助。");
  31.         setlocale(LC_ALL,"chs");

  32.         if (argc==1) {
  33.                 _tprintf(help_txt);
  34.         }
  35.         if (argc>1){
  36.                 return _t_real_main(argc,argv);
  37.         }
  38.         return 0;
  39. }

  40. inline size_t seek_and_read(FILE* file,void* buf,unsigned long offest,unsigned long length){
  41.         fseek(file,offest,SEEK_SET);
  42.         return fread(buf,length,1,file);
  43. }


  44. int _t_real_main(int argc, _TCHAR* argv[]){
  45. //这里是真正做事情的代码。
  46.         //先检查源文件是否存在。
  47.         _TCHAR *source_filename=argv[1];
  48.         FILE * source_iso=NULL;
  49.         FILE_ITEM myFile;//目标文件
  50.         source_iso=_tfopen(source_filename,_T("rb"));
  51.         if (source_iso==NULL)
  52.         {
  53.                 _ftprintf(stderr,_T("源ISO镜像打开失败!请检查文件。"));
  54.                 return -1;
  55.         }
  56.         FILE *output=_tfopen(argv[3],_T("wb"));
  57.         if (output==NULL){
  58.                 _ftprintf(stderr,_T("目标文件打开失败!请检查文件。"));

  59.                 return -1;
  60.         }

  61.         char buf_sector_1[ATAPI_SECTOR_SIZE];
  62.         /* iso的前32768字节被保留,检查CD001标志*/
  63.         unsigned long lba = (0x8000 / 0x800); /*从0x8000的地方开始寻找.*/
  64.         for(;;++lba)
  65.         {
  66.                 //ISO9660最大允许整个iso 2G大小。
  67.                 if(!seek_and_read(source_iso,buf_sector_1,LBA_TO_BYTE(lba),ATAPI_SECTOR_SIZE)) { //读一个扇区
  68.                         _ftprintf(stderr,_T("源ISO镜像读取错误!请检查文件。"));
  69.                         return -1;
  70.                 }
  71.                 /*Identifier is always "CD001".*/
  72.                 if(buf_sector_1[1] != 'C' ||
  73.                         buf_sector_1[2] != 'D' ||
  74.                         buf_sector_1[3] != '0' ||
  75.                         buf_sector_1[4] != '0' ||
  76.                         buf_sector_1[5] != '1' ) /*判断CD001 不符合直接返回.*/

  77.                 {
  78.                         _ftprintf(stderr,_T("源ISO镜像非法!"));
  79.                         return -1;
  80.                 }
  81.                 if(buf_sector_1[0] == 0xff) /*Volume Descriptor Set Terminator.*/
  82.                         return -1; /*如果这是最后一个 也返回.*/
  83.                 if(buf_sector_1[0] != 0x01 /*Primary Volume Descriptor.*/)
  84.                         continue; /*不是Primary Volume Descriptor就继续*/

  85.                 /*Directory entry for the root directory.*/
  86.                 if(buf_sector_1[156] != 0x22 /*Msut 34.*/)
  87.                         return -1;

  88.                 /*Location of extent (LBA) in both-endian format.*/
  89.                 lba = *(unsigned long *)(buf_sector_1 + 156 + 2);
  90.                 break; /*读LBA,跳出.*/
  91.         }
  92.     //分析文件名。分解出目录
  93.         string Temp;
  94.         vector<string> WantedFileName;
  95.         char *token = NULL;
  96.         char *next_token = NULL;
  97.         char *Wanted;
  98.         bool isfound=false;

  99. #ifdef _UNICODE
  100.         int need=0;
  101.         need=wcstombs(NULL,argv[2],0)+1;
  102.         Wanted = new char[need];
  103.         wcstombs(Wanted,argv[2],need);
  104. #else
  105.         Wanted = new char[strlen(argv[1])+1];
  106.         strcpy(Wanted,argv[1]);
  107. #endif
  108.         token=strtok_s(Wanted,"/",&next_token);
  109.         
  110.         while (token != NULL)
  111.         {
  112.                 if (token != NULL)
  113.                 {
  114.                         Temp=token;
  115.                         WantedFileName.push_back(Temp);
  116.                         token = strtok_s(NULL,"/", &next_token);
  117.                         
  118.                 }
  119.         }

  120.         delete [] Wanted;//切分完毕
  121.         PraseFileSystemAndFind(source_iso,lba,myFile,0,WantedFileName,isfound);
  122.         if (!isfound){
  123.                 _ftprintf(stderr,_T("没找到你要的文件!"));
  124.         }else{
  125.                 _tprintf(_T("找到目标文件,大小%d,LBA %d\n"),myFile.size,myFile.lba);
  126.                 fseek(source_iso,LBA_TO_BYTE(myFile.lba),SEEK_SET);
  127.                 char buffer[4096]; //按4K一块
  128.                 for (unsigned int i=0;i<=(myFile.size/4096);i++){
  129.                         if (i==(myFile.size/4096)){
  130.                                 //最后一块
  131.                                 fread(buffer,myFile.size-i*4096,1,source_iso);
  132.                                 fwrite(buffer,myFile.size-i*4096,1,output);
  133.                                 _tprintf(_T("输出完毕。"));
  134.                         }else{
  135.                                 fread(buffer,4096,1,source_iso);
  136.                                 fwrite(buffer,4096,1,output);
  137.                         }
  138.                 }
  139.         }
  140.         fclose(output);
  141.         fclose(source_iso);
  142.         if (!isfound){
  143.                 _tremove(argv[3]);
  144.         }
  145.         
  146.         return 0;
  147. }

  148. int PraseFileSystemAndFind(FILE* isofile,unsigned long lba,FILE_ITEM &item,int depth,const vector<string> &NeedFileName,bool &isfound){
  149.         
  150. isfound=false;


  151.         char SectorBuf[ATAPI_SECTOR_SIZE];
  152.         seek_and_read(isofile,SectorBuf,LBA_TO_BYTE(lba),ATAPI_SECTOR_SIZE);

  153.    unsigned long offset = 0; /*要读的文件(夹)的信息结构的偏移.*/
  154.    bool isDir = 0; /*是否是文件夹.*/
  155.    bool needRead = 0; /*需不需要重新读.*/

  156.    for(;;offset += SectorBuf[offset + 0x0] /*Length of Directory Record.*/)
  157.    {
  158.       while(offset >= ATAPI_SECTOR_SIZE)
  159.       {
  160.          offset -= ATAPI_SECTOR_SIZE;
  161.          ++lba;
  162.          needRead = 1;
  163.          /*Read again.*/
  164.       } /*偏移超出这个扇区的范围就修正一下.*/
  165.       if(needRead)
  166.         seek_and_read(isofile,SectorBuf,LBA_TO_BYTE(lba),ATAPI_SECTOR_SIZE);
  167.       needRead = 0;
  168.       
  169.       if(SectorBuf[offset + 0x0] == 0x0) /*No more.*/
  170.          break; /*大小是0说明结束了,退出.*/
  171.       
  172.       /*Location of extent (LBA) in both-endian format.*/
  173.       unsigned long fileLBA = *(unsigned long *)(SectorBuf + offset + 0x2);
  174.       if(fileLBA <= lba)
  175.         continue; /*获取文件LBA,小于就继续吧.*/


  176.       isDir = SectorBuf[offset + 25] & 0x2; /*Is it a dir?*/

  177.       unsigned long filesize = *(unsigned long *)(SectorBuf + offset + 10);

  178.       /*Length of file identifier (file name).
  179.        * This terminates with a ';' character
  180.        * followed by the file ID number in ASCII coded decimal ('1').*/
  181.       unsigned long filenameLength = SectorBuf[offset + 32];
  182.       //if(!isDir) /*如果是文件就要删掉最后的";1".*/
  183.       //   filenameLength -= 2; /*Remove ';' and '1'.*/

  184.       char *filename =new char[filenameLength + 1]; /*Add 1 for '\0'.*/
  185.       memcpy(filename,
  186.          (const void *)(SectorBuf + offset + 33),
  187.          filenameLength); /*把文件名复制过来.*/

  188.       if((!isDir) && (filename[0] == '_'))
  189.          filename[0] = '.';
  190.       if((!isDir) && (filename[filenameLength - 1] == '.'))
  191.          filename[filenameLength - 1] = '\0';
  192.       else
  193.          filename[filenameLength] = '\0'; /*做一些修正.*/

  194.       string _filename_safe = filename;
  195. delete [] filename;

  196.       if(!isDir)
  197.       {

  198.                   if(filesize != 0)
  199.                   {
  200.                           if (!stricmp(NeedFileName[depth].c_str(),_filename_safe.c_str())) //找到了!
  201.                           {
  202.                                   item.FileName=_filename_safe;
  203.                                   item.lba=fileLBA;
  204.                                   item.size=filesize;
  205.                                   isfound=true;
  206.                                   return 1;
  207.                           }
  208.                   }

  209.       }
  210.       else
  211.       {
  212.                   if (!stricmp(NeedFileName[depth].c_str(),_filename_safe.c_str()))
  213.                         PraseFileSystemAndFind(isofile,fileLBA,item,depth+1,NeedFileName,isfound); /*对的就递归.*/

  214.       }
  215.    }
  216.          

  217.           return 0;
  218. }
复制代码

编译结果就不放了,VS2005下编译通过,注意,输出的LBA是2048字节大扇区式的LBA。
回复

使用道具 举报

 楼主| 发表于 2020-1-31 19:14:28 来自手机 | 显示全部楼层
sunsea 发表于 2020-1-31 19:13
当年参考https://blog.csdn.net/goodqt/article/details/17202109这个帖子写的一个小程序,提取ISO内文件的 ...

我也是看这里的,这里不全
回复

使用道具 举报

发表于 2020-1-31 19:16:49 | 显示全部楼层
红毛樱木 发表于 2020-1-31 19:14
我也是看这里的,这里不全

能按路径找到文件应该就能列出所有文件吧?或许可以试试能不能改造下这个程序列出所有文件和它们的LBA和长度,而且ISO9660还有个很棒的特点——所有文件都是连续的。

https://blog.csdn.net/perry_peng/article/details/7698673另外这里似乎还有个Python程序也能有帮助。

回复

使用道具 举报

 楼主| 发表于 2020-2-6 15:39:59 | 显示全部楼层
决定放弃了,ISO文件的文件系统太多了。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|Archiver|捐助支持|无忧启动 ( 闽ICP备05002490号-1 )

闽公网安备 35020302032614号

GMT+8, 2024-3-29 18:27

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表