1 /*
2 * ADF Library
3 *
4 * adf_dump.c
5 *
6 * $Id$
7 *
8 * Amiga Dump File specific routines
9 *
10 * This file is part of ADFLib.
11 *
12 * ADFLib is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * ADFLib is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with Foobar; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 *
26 */
27
28 #include<stdio.h>
29 #include<stdlib.h>
30 #include<errno.h>
31
32 #include"adf_defs.h"
33 #include"adf_str.h"
34 #include"adf_disk.h"
35 #include"adf_nativ.h"
36 #include"adf_err.h"
37
38 extern struct Env adfEnv;
39
40 /*
41 * adfInitDumpDevice
42 *
43 */
adfInitDumpDevice(struct Device * dev,char * name,BOOL ro)44 RETCODE adfInitDumpDevice(struct Device* dev, char* name, BOOL ro)
45 {
46 struct nativeDevice* nDev;
47 int32_t size;
48
49 nDev = (struct nativeDevice*)dev->nativeDev;
50
51 nDev = (struct nativeDevice*)malloc(sizeof(struct nativeDevice));
52 if (!nDev) {
53 (*adfEnv.eFct)("adfInitDumpDevice : malloc");
54 return RC_MALLOC;
55 }
56 dev->nativeDev = nDev;
57
58 dev->readOnly = ro;
59 errno = 0;
60 if (!ro) {
61 nDev->fd = fopen(name,"rb+");
62 /* force read only */
63 if (!nDev->fd && (errno==EACCES || errno==EROFS) ) {
64 nDev->fd = fopen(name,"rb");
65 dev->readOnly = TRUE;
66 if (nDev->fd)
67 (*adfEnv.wFct)("myInitDevice : fopen, read-only mode forced");
68 }
69 }
70 else
71 /* read only requested */
72 nDev->fd = fopen(name,"rb");
73
74 if (!nDev->fd) {
75 free(nDev);
76 (*adfEnv.eFct)("myInitDevice : fopen");
77 return RC_ERROR;
78 }
79
80 /* determines size */
81 fseek(nDev->fd, 0, SEEK_END);
82 size = ftell(nDev->fd);
83 fseek(nDev->fd, 0, SEEK_SET);
84
85 dev->size = size;
86
87 return RC_OK;
88 }
89
90
91 /*
92 * adfReadDumpSector
93 *
94 */
adfReadDumpSector(struct Device * dev,int32_t n,int size,uint8_t * buf)95 RETCODE adfReadDumpSector(struct Device *dev, int32_t n, int size, uint8_t* buf)
96 {
97 struct nativeDevice* nDev;
98 int r;
99 /*puts("adfReadDumpSector");*/
100 nDev = (struct nativeDevice*)dev->nativeDev;
101 r = fseek(nDev->fd, 512*n, SEEK_SET);
102 /*printf("nnn=%ld size=%d\n",n,size);*/
103 if (r==-1)
104 return RC_ERROR;
105 /*puts("123");*/
106 if ((r=fread(buf, 1, size, nDev->fd))!=size) {
107 /*printf("rr=%d\n",r);*/
108 return RC_ERROR;
109 }
110 /*puts("1234");*/
111
112 return RC_OK;
113 }
114
115
116 /*
117 * adfWriteDumpSector
118 *
119 */
adfWriteDumpSector(struct Device * dev,int32_t n,int size,uint8_t * buf)120 RETCODE adfWriteDumpSector(struct Device *dev, int32_t n, int size, uint8_t* buf)
121 {
122 struct nativeDevice* nDev;
123 int r;
124
125 nDev = (struct nativeDevice*)dev->nativeDev;
126
127 r=fseek(nDev->fd, 512*n, SEEK_SET);
128 if (r==-1)
129 return RC_ERROR;
130
131 if ( fwrite(buf, 1, size, nDev->fd)!=(unsigned int)(size) )
132 return RC_ERROR;
133 /*puts("adfWriteDumpSector");*/
134 return RC_OK;
135 }
136
137
138 /*
139 * adfReleaseDumpDevice
140 *
141 */
adfReleaseDumpDevice(struct Device * dev)142 RETCODE adfReleaseDumpDevice(struct Device *dev)
143 {
144 struct nativeDevice* nDev;
145
146 if (!dev->nativeDev)
147 return RC_ERROR;
148
149 nDev = (struct nativeDevice*)dev->nativeDev;
150 fclose(nDev->fd);
151
152 free(nDev);
153
154 return RC_OK;
155 }
156
157
158 /*
159 * adfCreateHdFile
160 *
161 */
adfCreateHdFile(struct Device * dev,char * volName,int volType)162 RETCODE adfCreateHdFile(struct Device* dev, char* volName, int volType)
163 {
164
165 if (dev==NULL) {
166 (*adfEnv.eFct)("adfCreateHdFile : dev==NULL");
167 return RC_ERROR;
168 }
169 dev->volList =(struct Volume**) malloc(sizeof(struct Volume*));
170 if (!dev->volList) {
171 (*adfEnv.eFct)("adfCreateHdFile : unknown device type");
172 return RC_ERROR;
173 }
174
175 dev->volList[0] = adfCreateVol( dev, 0L, (int32_t)dev->cylinders, volName, volType );
176 if (dev->volList[0]==NULL) {
177 free(dev->volList);
178 return RC_ERROR;
179 }
180
181 dev->nVol = 1;
182 dev->devType = DEVTYPE_HARDFILE;
183
184 return RC_OK;
185 }
186
187
188 /*
189 * adfCreateDumpDevice
190 *
191 * returns NULL if failed
192 */
193 struct Device*
adfCreateDumpDevice(char * filename,int32_t cylinders,int32_t heads,int32_t sectors)194 adfCreateDumpDevice(char* filename, int32_t cylinders, int32_t heads, int32_t sectors)
195 {
196 struct Device* dev;
197 uint8_t buf[LOGICAL_BLOCK_SIZE];
198 struct nativeDevice* nDev;
199 /* int32_t i;*/
200 int r;
201
202 dev=(struct Device*)malloc(sizeof(struct Device));
203 if (!dev) {
204 (*adfEnv.eFct)("adfCreateDumpDevice : malloc dev");
205 return NULL;
206 }
207 nDev = (struct nativeDevice*)malloc(sizeof(struct nativeDevice));
208 if (!nDev) {
209 free(dev);
210 (*adfEnv.eFct)("adfCreateDumpDevice : malloc nDev");
211 return NULL;
212 }
213 dev->nativeDev = nDev;
214
215 nDev->fd = (FILE*)fopen(filename,"wb");
216 if (!nDev->fd) {
217 free(nDev); free(dev);
218 (*adfEnv.eFct)("adfCreateDumpDevice : fopen");
219 return NULL;
220 }
221
222 /* for(i=0; i<cylinders*heads*sectors; i++)
223 fwrite(buf, sizeof(uint8_t), 512 , nDev->fd);
224 */
225 r=fseek(nDev->fd, ((cylinders*heads*sectors)-1)*LOGICAL_BLOCK_SIZE, SEEK_SET);
226 if (r==-1) {
227 fclose(nDev->fd); free(nDev); free(dev);
228 (*adfEnv.eFct)("adfCreateDumpDevice : fseek");
229 return NULL;
230 }
231
232 fwrite(buf, LOGICAL_BLOCK_SIZE, 1, nDev->fd);
233
234 fclose(nDev->fd);
235
236 nDev->fd=(FILE*)fopen(filename,"rb+");
237 if (!nDev->fd) {
238 free(nDev); free(dev);
239 (*adfEnv.eFct)("adfCreateDumpDevice : fopen");
240 return NULL;
241 }
242 dev->cylinders = cylinders;
243 dev->heads = heads;
244 dev->sectors = sectors;
245 dev->size = cylinders*heads*sectors* LOGICAL_BLOCK_SIZE;
246
247 if (dev->size==80*11*2*LOGICAL_BLOCK_SIZE)
248 dev->devType = DEVTYPE_FLOPDD;
249 else if (dev->size==80*22*2*LOGICAL_BLOCK_SIZE)
250 dev->devType = DEVTYPE_FLOPHD;
251 else
252 dev->devType = DEVTYPE_HARDDISK;
253
254 dev->nVol = 0;
255 dev->isNativeDev = FALSE;
256 dev->readOnly = FALSE;
257
258 return(dev);
259 }
260
261 /*##################################################################################*/
262
263