blob: 4dfef5a3357ab031937a41110a12754ab2a6322d [file] [log] [blame]
Yi Kong39bbd962022-01-09 19:41:38 +08001/* 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
18Buffer 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 */
48Stream_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