/* Copyright 2021 Alain Knaff. * This file is part of mtools. * * Mtools is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Mtools is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Mtools. If not, see . * * Open filesystem image or device, and push any remapping and/or partitioning layers on it Buffer read/write module */ #include "sysincludes.h" #include "mtools.h" #include "lba.h" #include "open_image.h" #include "plain_io.h" #include "floppyd_io.h" #include "xdf_io.h" #include "scsi_io.h" #include "remap.h" #include "partition.h" #include "offset.h" #include "swap.h" /* * Open filesystem image * out_dev: device descriptor, adapted to current media and context * dev: initial template device descriptor (not modified) * name: file name (if applicable) * maxSize: if set, max size will be returned here * geomFailureP: if set, geometry failure will be returned here. This means * that caller should retry again opening the same image read/write * skip: a bitmask of intermediary layers to skip * errmsg: any error messages will be returned here */ Stream_t *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, #ifdef USE_XDF struct xdf_info *xdf_info #else void *dummy UNUSEDP #endif ) { Stream_t *Stream=NULL; int geomFailure=0; if(out_dev->misc_flags & FLOPPYD_FLAG) { #ifdef USE_FLOPPYD Stream = FloppydOpen(out_dev, name, mode, errmsg, maxSize); #endif } else { #ifdef USE_XDF Stream = XdfOpen(out_dev, name, mode, errmsg, xdf_info); if(Stream) { out_dev->use_2m = 0x7f; if(maxSize) *maxSize = max_off_t_31; } #endif #ifdef HAVE_SCSI if (!Stream) { Stream = OpenScsi(out_dev, name, mode, errmsg, flags, 0, lockMode, maxSize); } #endif if (!Stream) { Stream = SimpleFileOpenWithLm(out_dev, dev, name, mode, errmsg, flags, 0, lockMode, maxSize, &geomFailure); } if(geomFailure) { if(*geomFailureP) *geomFailureP=geomFailure; return NULL; } } if( !Stream) return NULL; if(dev->data_map) { Stream_t *Remapped = Remap(Stream, out_dev, errmsg); if(Remapped == NULL) goto exit_0; Stream = Remapped; } if(dev->offset) { Stream_t *Offset = OpenOffset(Stream, out_dev, dev->offset, errmsg, maxSize); if(Offset == NULL) goto exit_0; Stream = Offset; } if(DO_SWAP(dev)) { Stream_t *Swap = OpenSwap(Stream); if(Swap == NULL) goto exit_0; Stream = Swap; } if((flags & ALWAYS_GET_GEOMETRY) && compute_lba_geom_from_tot_sectors(out_dev) < 0) goto exit_0; if(dev->partition && !(flags & SKIP_PARTITION)) { Stream_t *Partition = OpenPartition(Stream, out_dev, errmsg, maxSize); if(Partition == NULL) goto exit_0; Stream = Partition; } return Stream; exit_0: FREE(&Stream); return NULL; }