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