xref: /aosp_15_r20/external/mtools/open_image.c (revision d5c9a868b113e0ec0db2f27bc2ce8a253e77c4b0)
1 /*  Copyright 2021 Alain Knaff.
2  *  This file is part of mtools.
3  *
4  *  Mtools is free software: you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation, either version 3 of the License, or
7  *  (at your option) any later version.
8  *
9  *  Mtools is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with Mtools.  If not, see <http://www.gnu.org/licenses/>.
16  *
17  * Open filesystem image or device, and push any remapping and/or partitioning layers on it
18 Buffer read/write module
19  */
20 
21 #include "sysincludes.h"
22 #include "msdos.h"
23 #include "mtools.h"
24 #include "lba.h"
25 
26 #include "open_image.h"
27 
28 #include "plain_io.h"
29 #include "floppyd_io.h"
30 #include "xdf_io.h"
31 #include "scsi_io.h"
32 #include "remap.h"
33 #include "partition.h"
34 #include "offset.h"
35 #include "swap.h"
36 
37 /*
38  * Open filesystem image
39  *   out_dev: device descriptor, adapted to current media and context
40  *   dev: initial template device descriptor (not modified)
41  *   name: file name (if applicable)
42  *   maxSize: if set, max size will be returned here
43  *   geomFailureP: if set, geometry failure will be returned here. This means
44  *     that caller should retry again opening the same image read/write
45  *   skip: a bitmask of intermediary layers to skip
46  *   errmsg: any error messages will be returned here
47  */
OpenImage(struct device * out_dev,struct device * dev,const char * name,int mode,char * errmsg,int flags,int lockMode,mt_off_t * maxSize,int * geomFailureP,struct xdf_info * xdf_info)48 Stream_t *OpenImage(struct device *out_dev, struct device *dev,
49 		    const char *name, int mode, char *errmsg,
50 		    int flags, int lockMode,
51 		    mt_off_t *maxSize, int *geomFailureP,
52 #ifdef USE_XDF
53 		    struct xdf_info *xdf_info
54 #else
55 		    void *dummy UNUSEDP
56 #endif
57 		    )
58 {
59 	Stream_t *Stream=NULL;
60 	int geomFailure=0;
61 	if(out_dev->misc_flags & FLOPPYD_FLAG) {
62 #ifdef USE_FLOPPYD
63 		Stream = FloppydOpen(out_dev, name, mode,
64 				     errmsg, maxSize);
65 #endif
66 	} else {
67 
68 #ifdef USE_XDF
69 		Stream = XdfOpen(out_dev, name, mode, errmsg, xdf_info);
70 		if(Stream) {
71 			out_dev->use_2m = 0x7f;
72 			if(maxSize)
73 				*maxSize = max_off_t_31;
74 		}
75 #endif
76 
77 		if (!Stream) {
78 			Stream = OpenScsi(out_dev, name,
79 					  mode,
80 					  errmsg, flags, 0,
81 					  lockMode,
82 					  maxSize);
83 		}
84 
85 		if (!Stream) {
86 			Stream = SimpleFileOpenWithLm(out_dev, dev, name,
87 						      mode,
88 						      errmsg, flags, 0,
89 						      lockMode,
90 						      maxSize,
91 						      &geomFailure);
92 		}
93 
94 		if(geomFailure) {
95 			if(*geomFailureP)
96 				*geomFailureP=geomFailure;
97 			return NULL;
98 		}
99 	}
100 
101 	if( !Stream)
102 		return NULL;
103 
104 	if(dev->data_map) {
105 		Stream_t *Remapped = Remap(Stream, out_dev, errmsg);
106 		if(Remapped == NULL)
107 			goto exit_0;
108 		Stream = Remapped;
109 	}
110 
111 	if(dev->offset) {
112 		Stream_t *Offset = OpenOffset(Stream, out_dev, dev->offset,
113 					      errmsg, maxSize);
114 		if(Offset == NULL)
115 			goto exit_0;
116 		Stream = Offset;
117 	}
118 
119 	if(DO_SWAP(dev)) {
120 		Stream_t *Swap = OpenSwap(Stream);
121 		if(Swap == NULL)
122 			goto exit_0;
123 		Stream = Swap;
124 	}
125 
126 	if((flags & ALWAYS_GET_GEOMETRY) &&
127 	   compute_lba_geom_from_tot_sectors(out_dev) < 0)
128 		goto exit_0;
129 
130 	if(dev->partition && !(flags & SKIP_PARTITION)) {
131 		Stream_t *Partition = OpenPartition(Stream, out_dev,
132 						    errmsg, maxSize);
133 		if(Partition == NULL)
134 			goto exit_0;
135 		Stream = Partition;
136 	}
137 
138 	return Stream;
139  exit_0:
140 	FREE(&Stream);
141 	return NULL;
142 }
143 
144