home *** CD-ROM | disk | FTP | other *** search
/ AMIGA PD 1 / AMIGA-PD-1.iso / Aminet / Tools / Useful / AmiCDROM / src / generic.c < prev    next >
C/C++ Source or Header  |  1994-10-04  |  8KB  |  382 lines

  1. /* generic.c:
  2.  *
  3.  * Generic interface to the protocol handlers.
  4.  *
  5.  * Modified by Nicola Salmoria.
  6.  *
  7.  * ----------------------------------------------------------------------
  8.  * This code is (C) Copyright 1993,1994 by Frank Munkert.
  9.  * All rights reserved.
  10.  * This software may be freely distributed and redistributed for
  11.  * non-commercial purposes, provided this notice is included.
  12.  * ----------------------------------------------------------------------
  13.  * [History removed]
  14.  */
  15.  
  16. #include <stdlib.h>
  17. #include <string.h>
  18.  
  19. #include <dos/dos.h>
  20. #include <exec/types.h>
  21. #include <exec/memory.h>
  22. #include <proto/exec.h>
  23. #include <proto/dos.h>
  24. #include <proto/intuition.h>
  25. #include <proto/utility.h>
  26. #include <proto/input.h>
  27.  
  28. #include "cdrom.h"
  29. #include "generic.h"
  30. #include "iso9660.h"
  31. #include "rock.h"
  32. #include "hfs.h"
  33.  
  34. /* note that vol may be either a VOLUME * or a CDROM_OBJ *  */
  35. #define HAN(vol,func) (*(vol)->handler->func)
  36.  
  37. #define HANX(vol,func) ((vol)->handler->func)
  38.  
  39.  
  40.  
  41. /* WhichProtocol - examines which protocol is used.
  42.  *
  43.  * Input Variables:
  44.  *  p_cdrom - CDROM descriptor
  45.  *
  46.  * Output Variables:
  47.  *  p_skip - skip length for RockRidge disks
  48.  *  p_offset - block offset of last session for multisession disks (ISO only)
  49.  *
  50.  * Result:
  51.  *  PRO_ISO, PRO_HIGH_SIERRA, PRO_RR, PRO_HFS or PRO_UNKNOWN.
  52.  */
  53.  
  54. t_protocol Which_Protocol (CDROM *p_cdrom,int *p_skip,t_ulong *p_offset)
  55. {
  56. BOOL hfs;
  57.  
  58.  
  59. if (p_cdrom->model == MODEL_TOSHIBA_3401)
  60. {
  61.     if (Is_XA_Mode_Disk(p_cdrom))
  62.         Mode_Select(p_cdrom, 0x81, 2048);
  63.     else
  64.         Mode_Select(p_cdrom, 0x00, 2048);
  65. }
  66.  
  67.  
  68. /* check for HFS first to speed up floppy access */
  69. if (hfs = Uses_HFS_Protocol(p_cdrom, p_skip))
  70. {
  71. /* if a shift key is pressed, open this partition */
  72.     if (PeekQualifier() & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
  73.         return(PRO_HFS);
  74. }
  75. /* don't waste time trying the other file systems if it failed because of an error */
  76. else if (IoErr() != ERROR_NOT_A_DOS_DISK) return(PRO_UNKNOWN);
  77.  
  78. if (Uses_Iso_Protocol(p_cdrom, p_offset))
  79. {
  80.     VOLUME tmp_vol; /* temporary volume descriptor */
  81.     t_bool rr;
  82.  
  83.  
  84.     tmp_vol.cd = p_cdrom;
  85.     tmp_vol.protocol = PRO_ISO;
  86.     Iso_Init_Vol_Info(&tmp_vol, 0, *p_offset,0);
  87.     rr = Uses_Rock_Ridge_Protocol(&tmp_vol, p_skip);
  88.     HAN(&tmp_vol, close_vol_info)(&tmp_vol);
  89.     return(rr ? PRO_ROCK : PRO_ISO);
  90. }
  91. else if (hfs)
  92. /* no ISO partition, so open the HFS partition */
  93.     return(PRO_HFS);
  94. else if (Uses_High_Sierra_Protocol(p_cdrom))
  95.     return(PRO_HIGH_SIERRA);
  96. else return(PRO_UNKNOWN);
  97. }
  98.  
  99.  
  100.  
  101. VOLUME *Open_Volume(CDROM *p_cdrom,t_bool lowercase)
  102. {
  103.   VOLUME *res;
  104.   int skip;
  105.   t_ulong offset;
  106.  
  107.   res = AllocMem (sizeof (VOLUME), MEMF_PUBLIC);
  108.   if (!res) {
  109.     SetIoErr(ERROR_NO_FREE_STORE);
  110.     return NULL;
  111.   }
  112.  
  113.   res->cd = p_cdrom;
  114.  
  115.   res->protocol = Which_Protocol (p_cdrom,&skip,&offset);
  116.  
  117.   switch (res->protocol) {
  118.   case PRO_ISO:
  119.     if (!Iso_Init_Vol_Info (res, skip, offset, lowercase)) {
  120.       FreeMem (res, sizeof (VOLUME));
  121.       return NULL;
  122.     }
  123.     break;
  124.   case PRO_ROCK:
  125.     if (!Iso_Init_Vol_Info (res, skip, offset, 0)) {
  126.       FreeMem (res, sizeof (VOLUME));
  127.       return NULL;
  128.     }
  129.     break;
  130.   case PRO_HFS:
  131.     if (!HFS_Init_Vol_Info (res, skip)) {
  132.       FreeMem (res, sizeof (VOLUME));
  133.       return NULL;
  134.     }
  135.     break;
  136.   default:
  137.     FreeMem (res, sizeof (VOLUME));
  138.     return NULL;
  139.   }
  140.  
  141.   return res;
  142. }
  143.  
  144. void Close_Volume (VOLUME *p_volume)
  145. {
  146.   HAN(p_volume, close_vol_info)(p_volume);
  147.   FreeMem (p_volume, sizeof (VOLUME));
  148. }
  149.  
  150. CDROM_OBJ *Open_Top_Level_Directory (VOLUME *p_volume)
  151. {
  152. return(HAN(p_volume, open_top_level_directory)(p_volume));
  153. }
  154.  
  155. CDROM_OBJ *Open_Object(VOLUME *p_volume,CDROM_OBJ *p_current_dir, char *p_path_name)
  156. {
  157.   char *cp = p_path_name;
  158.   CDROM_OBJ *obj, *new;
  159.   char *np;
  160.   char name[100];
  161.  
  162.   if (*cp == ':') {
  163.     obj = HAN(p_volume, open_top_level_directory)(p_volume);
  164.     cp++;
  165.   } else {
  166.     obj = Clone_Object (p_current_dir);
  167.     if (!obj) {
  168.       SetIoErr(ERROR_NO_FREE_STORE);
  169.       return NULL;
  170.     }
  171.     while (*cp == '/') {
  172.       new = HAN(p_volume, find_parent)(p_volume,obj);
  173.       if (!new)
  174.         return NULL;
  175.       Close_Object(obj);
  176.       obj = new;
  177.       cp++;
  178.     }
  179.   }
  180.  
  181.   while (*cp) {
  182.     for (np = name; *cp && *cp != '/'; )
  183.       *np++ = *cp++;
  184.     *np = 0;
  185.  
  186.     if (*cp)
  187.       cp++;
  188.  
  189.     if (new = HAN(p_volume, open_obj_in_directory)(p_volume,obj, name)) {
  190.       Close_Object(obj);
  191.       if (*cp && new->symlink_f) {
  192.     Close_Object(new);
  193.     SetIoErr(ISOERR_IS_SYMLINK);
  194.     return NULL;
  195.       }
  196.       if (*cp && !new->directory_f) {
  197.     Close_Object(new);
  198.     SetIoErr(ISOERR_NOT_FOUND);
  199.     return NULL;
  200.       }
  201.       obj = new;
  202.     } else {
  203.       Close_Object(obj);
  204.       return NULL;
  205.     }
  206.   }
  207.  
  208. return(obj);
  209. }
  210.  
  211. void Close_Object(CDROM_OBJ *p_object)
  212. {
  213. HAN(p_object,close_obj)(p_object);
  214. }
  215.  
  216. int Read_From_File (VOLUME *p_volume,CDROM_OBJ *p_file, char *p_buffer, int p_buffer_length)
  217. {
  218.   return HAN(p_volume, read_from_file)(p_volume,p_file, p_buffer, p_buffer_length);
  219. }
  220.  
  221. LONG CDROM_Info (VOLUME *p_volume,CDROM_OBJ *p_obj, CDROM_INFO *p_info)
  222. {
  223.   return HAN(p_volume, cdrom_info)(p_volume,p_obj, p_info);
  224. }
  225.  
  226. LONG Examine_Next (VOLUME *p_volume,CDROM_OBJ *p_dir, CDROM_INFO *p_info, unsigned long *p_offset)
  227. {
  228.   return HAN(p_volume, examine_next)(p_volume,p_dir, p_info, p_offset);
  229. }
  230.  
  231. CDROM_OBJ *Clone_Object (CDROM_OBJ *p_object)
  232. {
  233. CDROM_OBJ *new;
  234.  
  235.  
  236. if (!(new = AllocMem(sizeof(CDROM_OBJ),MEMF_PUBLIC)))
  237.     return NULL;
  238.  
  239. memcpy(new,p_object,sizeof(CDROM_OBJ));
  240.  
  241. if (!(new->obj_info = HAN(p_object,clone_obj_info)(p_object->obj_info)))
  242. {
  243.     FreeMem(new,sizeof(CDROM_OBJ));
  244.     return(NULL);
  245. }
  246.  
  247. return(new);
  248. }
  249.  
  250.  
  251.  
  252. CDROM_OBJ *Find_Parent (VOLUME *p_volume,CDROM_OBJ *p_object)
  253. {
  254. return(HAN(p_volume, find_parent)(p_volume,p_object));
  255. }
  256.  
  257. t_bool Is_Top_Level_Object (VOLUME *p_volume,CDROM_OBJ *p_object)
  258. {
  259.   return HAN(p_volume, is_top_level_obj)(p_volume,p_object);
  260. }
  261.  
  262. t_bool Same_Objects (CDROM_OBJ *p_object1, CDROM_OBJ *p_object2)
  263. {
  264. if (p_object1->handler != p_object2->handler) return(FALSE);
  265. else return(HAN(p_object1,same_objects)(p_object1,p_object2));
  266. }
  267.  
  268. t_ulong Volume_Creation_Date (VOLUME *p_volume)
  269. {
  270.   if (!HANX(p_volume, creation_date))
  271.     return 0;
  272.   return HAN(p_volume, creation_date)(p_volume);
  273. }
  274.  
  275. t_ulong Volume_Size (VOLUME *p_volume)
  276. {
  277.   return HAN(p_volume, volume_size)(p_volume);
  278. }
  279.  
  280. t_ulong Volume_Free (VOLUME *p_volume)
  281. {
  282.   return HAN(p_volume, volume_free)(p_volume);
  283. }
  284.  
  285. t_ulong Block_Size (VOLUME *p_volume)
  286. {
  287.   return HAN(p_volume, block_size)(p_volume);
  288. }
  289.  
  290. void Volume_ID (VOLUME *p_volume, char *p_buffer, int p_buf_length)
  291. {
  292.   HAN(p_volume, volume_id)(p_volume, p_buffer, p_buf_length);
  293. }
  294.  
  295. t_ulong Location (VOLUME *p_volume,CDROM_OBJ *p_object)
  296. {
  297.   return HAN(p_volume, location)(p_volume,p_object);
  298. }
  299.  
  300. /* Find a position in a file.
  301.  */
  302.  
  303. LONG Seek_Position (CDROM_OBJ *p_object, long p_offset, int p_mode)
  304. {
  305. t_ulong new_pos;
  306. t_ulong max_len;
  307.  
  308.  
  309. max_len = HAN(p_object,file_length)(p_object);
  310.  
  311. if (p_object->directory_f) return(ERROR_OBJECT_WRONG_TYPE);
  312.  
  313. switch (p_mode)
  314. {
  315. case OFFSET_BEGINNING:
  316.     if (p_offset < 0 || p_offset > max_len) return(ERROR_SEEK_ERROR);
  317.     new_pos = p_offset;
  318.     break;
  319.  
  320. case OFFSET_CURRENT:
  321.     if ((p_offset < 0 && -p_offset > p_object->pos) ||
  322.             (p_offset > 0 && p_object->pos + p_offset > max_len))
  323.         return(ERROR_SEEK_ERROR);
  324.     new_pos = p_object->pos + p_offset;
  325.     break;
  326.  
  327. case OFFSET_END:
  328.     if (p_offset > 0 || -p_offset > max_len) return(ERROR_SEEK_ERROR);
  329.     new_pos = max_len + p_offset;
  330.     break;
  331.  
  332. default:
  333.     return(ERROR_SEEK_ERROR);
  334.     break;
  335. }
  336.  
  337. p_object->pos = new_pos;
  338. return(0);
  339. }
  340.  
  341. /* Find path name of an object:
  342.  *
  343.  */
  344.  
  345. int Full_Path_Name (VOLUME *p_volume,CDROM_OBJ *p_obj, char *p_buf, int p_buf_length)
  346. {
  347.   int len = 0;
  348.   int free_chars = p_buf_length - 1;
  349.   CDROM_OBJ *obj = p_obj;
  350.   CDROM_OBJ *new;
  351.   CDROM_INFO info;
  352.  
  353.   while (!Is_Top_Level_Object (p_volume,obj)) {
  354.     if (!CDROM_Info (p_volume,obj, &info))
  355.       return 0;
  356.  
  357.     if (info.name_length+1 > free_chars)
  358.       return 0;
  359.  
  360.     memmove (p_buf+1+info.name_length, p_buf, len);
  361.     memcpy (p_buf+1, info.name, info.name_length);
  362.     p_buf[0] = '/';
  363.     free_chars -= info.name_length + 1;
  364.     len += info.name_length + 1;
  365.  
  366.     new = Find_Parent (p_volume,obj);
  367.     if (!new)
  368.       return 0;
  369.     if (obj != p_obj)
  370.       Close_Object(obj);
  371.     obj = new;
  372.   }
  373.  
  374.   p_buf[0] = ':';
  375.   p_buf[len ? len : 1] = 0;
  376.  
  377.   if (obj != p_obj)
  378.     Close_Object(obj);
  379.  
  380.   return 1;
  381. }
  382.