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