revert between 56095 -> 55830 in arch
[AROS.git] / workbench / devs / diskimage / plugins / generic.c
blob67a544aff1f2d488b530e84382ee1ffa6f39a0c6
1 /* Copyright 2007-2012 Fredrik Wikstrom. All rights reserved.
2 **
3 ** Redistribution and use in source and binary forms, with or without
4 ** modification, are permitted provided that the following conditions
5 ** are met:
6 **
7 ** 1. Redistributions of source code must retain the above copyright
8 ** notice, this list of conditions and the following disclaimer.
9 **
10 ** 2. Redistributions in binary form must reproduce the above copyright
11 ** notice, this list of conditions and the following disclaimer in the
12 ** documentation and/or other materials provided with the distribution.
14 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
15 ** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 ** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 ** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
18 ** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 ** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 ** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 ** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 ** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 ** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 ** POSSIBILITY OF SUCH DAMAGE.
27 #ifdef __AROS__
28 #define __EXEC_NOLIBBASE__
29 #define __DOS_NOLIBBASE__
30 #endif
32 #define USED_PLUGIN_API_VERSION 8
33 #include <devices/diskimage.h>
34 #include <proto/exec.h>
35 #include <proto/dos.h>
36 #include <string.h>
37 #include <SDI_compiler.h>
38 #include "device_locale.h"
39 #include "rev/diskimage.device_rev.h"
41 PLUGIN_VERSTAG("Generic")
43 extern struct DiskImagePlugin generic_plugin;
45 PLUGIN_TABLE(&generic_plugin)
47 struct GenericImage {
48 BPTR file;
49 ULONG block_size;
50 ULONG total_blocks;
51 UQUAD total_bytes;
54 BOOL Generic_Init (struct DiskImagePlugin *Self, const struct PluginData *data);
55 BOOL Generic_CheckImage (struct DiskImagePlugin *Self, BPTR file, CONST_STRPTR name, QUAD file_size,
56 const UBYTE *test, LONG testsize);
57 APTR Generic_OpenImage (struct DiskImagePlugin *Self, APTR unit, BPTR file, CONST_STRPTR name);
58 void Generic_CloseImage (struct DiskImagePlugin *Self, APTR image_ptr);
59 LONG Generic_Geometry (struct DiskImagePlugin *Self, APTR image_ptr, struct DriveGeometry *dg);
60 LONG Generic_Read (struct DiskImagePlugin *Self, APTR image_ptr, struct IOStdReq *io);
61 LONG Generic_Write (struct DiskImagePlugin *Self, APTR image_ptr, struct IOStdReq *io);
63 struct DiskImagePlugin generic_plugin = {
64 PLUGIN_NODE(-127, "Generic"),
65 PLUGIN_FLAG_M68K,
67 ZERO,
68 NULL,
69 Generic_Init,
70 NULL,
71 Generic_CheckImage,
72 Generic_OpenImage,
73 Generic_CloseImage,
74 Generic_Geometry,
75 Generic_Read,
76 Generic_Write,
77 NULL,
78 NULL,
79 NULL,
80 NULL
83 static struct Library *SysBase;
84 static struct Library *DOSBase;
85 static struct DIPluginIFace *IPlugin;
87 BOOL Generic_Init (struct DiskImagePlugin *Self, const struct PluginData *data) {
88 SysBase = data->SysBase;
89 DOSBase = data->DOSBase;
90 IPlugin = data->IPlugin;
91 return TRUE;
94 BOOL Generic_CheckImage (struct DiskImagePlugin *Self, BPTR file, CONST_STRPTR name, QUAD file_size,
95 const UBYTE *test, LONG testsize)
97 return TRUE;
100 APTR Generic_OpenImage (struct DiskImagePlugin *Self, APTR unit, BPTR file, CONST_STRPTR name) {
101 LONG done = FALSE;
102 LONG error = NO_ERROR;
103 QUAD file_size;
104 struct GenericImage *image = NULL;
106 file_size = GetFileSize(file);
107 if (file_size == -1) {
108 error = IoErr();
109 goto error;
112 image = AllocVec(sizeof(*image), MEMF_CLEAR);
113 if (!image) {
114 error = ERROR_NO_FREE_STORE;
115 goto error;
117 image->file = file;
118 image->total_bytes = file_size;
120 image->block_size = 512;
121 image->total_blocks = image->total_bytes >> 9;
123 done = TRUE;
125 error:
126 if (!done) {
127 if (image) {
128 Plugin_CloseImage(Self, image);
129 image = NULL;
130 } else {
131 Close(file);
133 IPlugin_SetDiskImageError(unit, error, 0);
135 return image;
138 void Generic_CloseImage (struct DiskImagePlugin *Self, APTR image_ptr) {
139 struct GenericImage *image = image_ptr;
140 if (image) {
141 Close(image->file);
142 FreeVec(image);
146 LONG Generic_Geometry (struct DiskImagePlugin *Self, APTR image_ptr, struct DriveGeometry *dg) {
147 struct GenericImage *image = image_ptr;
148 dg->dg_SectorSize = image->block_size;
149 dg->dg_Heads =
150 dg->dg_TrackSectors =
151 dg->dg_CylSectors = 1;
152 dg->dg_Cylinders =
153 dg->dg_TotalSectors = image->total_blocks;
154 return IOERR_SUCCESS;
157 LONG Generic_Read (struct DiskImagePlugin *Self, APTR image_ptr, struct IOStdReq *io) {
158 struct GenericImage *image = image_ptr;
159 BPTR file = image->file;
160 UQUAD offset;
161 UBYTE *buffer;
162 LONG size, read_size;
164 offset = ((UQUAD)io->io_Offset)|((UQUAD)io->io_Actual << 32);
165 buffer = io->io_Data;
166 size = io->io_Length;
167 io->io_Actual = 0;
169 if (!ChangeFilePosition(file, offset, OFFSET_BEGINNING)) {
170 return TDERR_SeekError;
173 io->io_Actual = size;
174 while (size) {
175 read_size = Read(file, buffer, size);
176 if (read_size == 0) {
177 io->io_Actual -= size;
178 return IOERR_BADLENGTH;
179 } else if (read_size == -1) {
180 io->io_Actual -= size;
181 return IPlugin_DOS2IOErr(IoErr());
183 buffer += read_size;
184 size -= read_size;
186 return IOERR_SUCCESS;
189 LONG Generic_Write (struct DiskImagePlugin *Self, APTR image_ptr, struct IOStdReq *io) {
190 struct GenericImage *image = image_ptr;
191 BPTR file = image->file;
192 UQUAD offset;
193 UBYTE *buffer;
194 LONG size, write_size;
196 offset = ((UQUAD)io->io_Offset)|((UQUAD)io->io_Actual << 32);
197 buffer = io->io_Data;
198 size = io->io_Length;
199 io->io_Actual = 0;
201 if (!ChangeFilePosition(file, offset, OFFSET_BEGINNING)) {
202 return TDERR_SeekError;
205 io->io_Actual = size;
206 while (size) {
207 write_size = Write(file, buffer, size);
208 if (write_size == -1) {
209 io->io_Actual -= size;
210 return IPlugin_DOS2IOErr(IoErr());
212 buffer += write_size;
213 size -= write_size;
215 return IOERR_SUCCESS;