Check for SYS/GL during library init. Reason is that
[AROS.git] / workbench / devs / diskimage / cmd / mounthdf.c
blob8fe0521e0be241b8d6ce1e9f4ae6fe7912a7aaae
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 #include <exec/exec.h>
28 #include <dos/dos.h>
29 #include <workbench/startup.h>
30 #include <libraries/expansion.h>
31 #include <devices/diskimage.h>
32 #include <proto/exec.h>
33 #include <proto/dos.h>
34 #include <proto/icon.h>
35 #include <proto/expansion.h>
36 #include <proto/diskimage.h>
37 #ifdef __AROS__
38 #include <libraries/mui.h>
39 #include <proto/muimaster.h>
40 #else
41 #include <reaction/reaction_macros.h>
42 #include <classes/requester.h>
43 #include <proto/intuition.h>
44 #include <proto/requester.h>
45 #include <clib/alib_protos.h>
46 #endif
47 #include "support.h"
48 #include "endian.h"
49 #include "rev/MountHDF_rev.h"
51 CONST TEXT USED verstag[] = VERSTAG;
53 #define PROGNAME "MountHDF"
54 #define TEMPLATE "U=UNIT/N/A,HDF=HARDFILE/A,WP=WRITEPROTECT/S," \
55 "TRKSIZ=BLOCKSPERTRACK/N,HEADS=SIDES=SURFACES/N,BLKSIZ=BLOCKSIZE/N," \
56 "RESERVED=BOOTBLOCKS/N"
58 enum {
59 ARG_UNIT,
60 ARG_HDF,
61 ARG_WRITEPROTECT,
62 ARG_BLOCKSPERTRACK,
63 ARG_SURFACES,
64 ARG_BLOCKSIZE,
65 ARG_RESERVED,
66 MAX_ARGS
69 struct WBStartup *WBMsg;
70 #ifndef __AROS__
71 struct Library *IconBase;
72 struct IntuitionBase *IntuitionBase;
73 struct Library *RequesterBase;
74 #endif
75 extern struct IOStdReq *DiskImageIO;
77 LONG DoReq (Object *req);
78 void IoErrRequester (LONG error, CONST_STRPTR header);
79 void ErrorStringRequester (CONST_STRPTR error_string);
81 int main (int argc, char **argv) {
82 int rc = RETURN_FAIL;
83 BPTR stderr = ZERO;
84 struct DiskObject *icon = NULL;
85 struct RDArgs *rdargs = NULL;
86 BPTR filedir = ZERO;
87 CONST_STRPTR filename = NULL;
88 LONG unit = -1;
89 BOOL writeprotect = FALSE;
90 ULONG blockspertrack = 32;
91 ULONG surfaces = 1;
92 ULONG blocksize = 512;
93 ULONG reserved = 2;
94 LONG error = NO_ERROR;
95 LONG error2 = NO_ERROR;
96 TEXT error_buffer[256];
97 UBYTE *block_buffer = NULL;
98 struct DriveGeometry dg;
99 UQUAD filesize;
100 ULONG cylindersize;
101 TEXT drivename[20];
102 IPTR parampkt[21];
103 struct DeviceNode *device;
105 stderr = Output();
107 if (argc == 0) {
108 BPTR currdir;
109 WBMsg = (struct WBStartup *)argv;
110 #ifndef __AROS__
111 if (!(IconBase = OpenLibrary("icon.library", MIN_OS_VERSION)) ||
112 !(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", MIN_OS_VERSION)) ||
113 !(RequesterBase = OpenLibrary("requester.class", MIN_OS_VERSION)))
115 goto error;
117 #endif
118 if (WBMsg->sm_NumArgs < 2) {
119 IoErrRequester(ERROR_REQUIRED_ARG_MISSING, NULL);
120 goto error;
122 filedir = WBMsg->sm_ArgList[1].wa_Lock;
123 filename = WBMsg->sm_ArgList[1].wa_Name;
124 currdir = CurrentDir(filedir);
125 icon = GetDiskObjectNew((STRPTR)filename);
126 CurrentDir(currdir);
127 if (!icon) {
128 IoErrRequester(IoErr(), NULL);
129 goto error;
131 unit = TTInteger(icon, "UNIT", -1);
132 writeprotect = TTBoolean(icon, "WP") || TTBoolean(icon, "WRITEPROTECT");
133 blockspertrack = TTInteger(icon, "BLOCKSPERTRACK", blockspertrack);
134 surfaces = TTInteger(icon, "SURFACES", surfaces);
135 blocksize = TTInteger(icon, "BLOCKSIZE", blocksize);
136 reserved = TTInteger(icon, "RESERVED", TTInteger(icon, "BOOTBLOCKS", reserved));
137 } else {
138 IPTR args[MAX_ARGS];
139 ClearMem(args, sizeof(args));
140 rdargs = ReadArgs(TEMPLATE, args, NULL);
141 if (!rdargs) {
142 PrintFault(IoErr(), PROGNAME);
143 goto error;
145 filedir = GetCurrentDir();
146 filename = (CONST_STRPTR)args[ARG_HDF];
147 if (args[ARG_UNIT]) unit = *(LONG *)args[ARG_UNIT];
148 writeprotect = args[ARG_WRITEPROTECT] ? TRUE : FALSE;
149 if (args[ARG_BLOCKSPERTRACK]) blockspertrack = *(ULONG *)args[ARG_BLOCKSPERTRACK];
150 if (args[ARG_SURFACES]) surfaces = *(ULONG *)args[ARG_SURFACES];
151 if (args[ARG_BLOCKSIZE]) blocksize = *(ULONG *)args[ARG_BLOCKSIZE];
152 if (args[ARG_RESERVED]) reserved = *(ULONG *)args[ARG_RESERVED];
155 if (unit == -1) {
156 if (WBMsg)
157 IoErrRequester(ERROR_REQUIRED_ARG_MISSING, NULL);
158 else
159 PrintFault(ERROR_REQUIRED_ARG_MISSING, PROGNAME);
160 goto error;
163 if (!OpenDiskImageDevice(unit)) {
164 SNPrintf(error_buffer, sizeof(error_buffer),
165 "failed to open diskimage.device");
166 if (WBMsg)
167 ErrorStringRequester(error_buffer);
168 else
169 FPrintf(stderr, "%s: %s\n", PROGNAME, error_buffer);
170 goto error;
173 error_buffer[0] = 0;
174 error = UnitControl(unit,
175 DITAG_Error, (IPTR)&error2,
176 DITAG_ErrorString, (IPTR)error_buffer,
177 DITAG_ErrorStringLength, sizeof(error_buffer),
178 DITAG_CurrentDir, (IPTR)filedir,
179 DITAG_Filename, (IPTR)filename,
180 DITAG_WriteProtect, writeprotect,
181 TAG_END);
182 if (error == NO_ERROR) error = error2;
183 if (error_buffer[0]) {
184 if (WBMsg)
185 ErrorStringRequester(error_buffer);
186 else
187 FPrintf(stderr, "%s: %s\n", filename, error_buffer);
188 goto error;
189 } else if (error) {
190 if (WBMsg)
191 IoErrRequester(error, NULL);
192 else
193 PrintFault(error, filename);
194 goto error;
197 block_buffer = AllocVec(blocksize, MEMF_ANY);
198 if (!block_buffer) {
199 if (WBMsg)
200 IoErrRequester(ERROR_NO_FREE_STORE, NULL);
201 else
202 PrintFault(ERROR_NO_FREE_STORE, PROGNAME);
203 goto error;
206 DiskImageIO->io_Command = TD_GETGEOMETRY;
207 DiskImageIO->io_Data = &dg;
208 DiskImageIO->io_Length = sizeof(dg);
209 if (DoIO((struct IORequest *)DiskImageIO) != IOERR_SUCCESS) {
210 SNPrintf(error_buffer, sizeof(error_buffer), "disk geometry error");
211 if (WBMsg)
212 ErrorStringRequester(error_buffer);
213 else
214 FPrintf(stderr, "%s: %s\n", PROGNAME, error_buffer);
215 goto error;
217 filesize = (UQUAD)dg.dg_TotalSectors * dg.dg_SectorSize;
218 cylindersize = blockspertrack * surfaces * blocksize;
220 DiskImageIO->io_Command = CMD_READ;
221 DiskImageIO->io_Data = block_buffer;
222 DiskImageIO->io_Offset = 0;
223 DiskImageIO->io_Length = blocksize;
224 if (DoIO((struct IORequest *)DiskImageIO) != IOERR_SUCCESS) {
225 SNPrintf(error_buffer, sizeof(error_buffer), "read error on block 0");
226 if (WBMsg)
227 ErrorStringRequester(error_buffer);
228 else
229 FPrintf(stderr, "%s: %s\n", PROGNAME, error_buffer);
230 goto error;
233 SNPrintf(drivename, sizeof(drivename), "IHD%ld", unit);
234 parampkt[0] = (IPTR)drivename;
235 parampkt[1] = (IPTR)"diskimage.device";
236 parampkt[2] = unit;
237 parampkt[3] = 0;
238 parampkt[4] = 16;
239 parampkt[5] = blocksize >> 2;
240 parampkt[6] = 0;
241 parampkt[7] = surfaces;
242 parampkt[8] = 1;
243 parampkt[9] = blockspertrack;
244 parampkt[10] = reserved;
245 parampkt[11] = 0;
246 parampkt[12] = 0;
247 parampkt[13] = 0;
248 parampkt[14] = (filesize / cylindersize) - 1;
249 parampkt[15] = 5;
250 parampkt[16] = MEMF_ANY;
251 parampkt[17] = 0x7fffffffUL;
252 parampkt[18] = 0xfffffffcUL;
253 parampkt[19] = 0;
254 parampkt[20] = rbe32(block_buffer);
255 device = MakeDosNode(parampkt);
256 if (!device) {
257 if (WBMsg)
258 IoErrRequester(ERROR_NO_FREE_STORE, NULL);
259 else
260 PrintFault(ERROR_NO_FREE_STORE, PROGNAME);
261 goto error;
263 if (!AddBootNode(0, ADNF_STARTPROC, device, NULL)) {
264 if (WBMsg)
265 IoErrRequester(ERROR_DEVICE_NOT_MOUNTED, NULL);
266 else
267 PrintFault(ERROR_DEVICE_NOT_MOUNTED, PROGNAME);
268 goto error;
271 rc = RETURN_OK;
273 error:
274 FreeVec(block_buffer);
275 CloseDiskImageDevice();
276 if (WBMsg) {
277 if (icon) FreeDiskObject(icon);
278 #ifndef __AROS__
279 if (RequesterBase) CloseLibrary(RequesterBase);
280 if (IntuitionBase) CloseLibrary((struct Library *)IntuitionBase);
281 if (IconBase) CloseLibrary(IconBase);
282 #endif
283 } else {
284 FreeArgs(rdargs);
287 return rc;
290 #ifdef __AROS__
292 void IoErrRequester (LONG error, CONST_STRPTR header) {
293 TEXT bodytext[80];
294 if (error == NO_ERROR) {
295 return;
297 Fault(error, (STRPTR)header, bodytext, sizeof(bodytext));
298 MUI_Request(NULL, NULL, 0, "Error - "PROGNAME, "Ok", "%s", bodytext);
301 void ErrorStringRequester (CONST_STRPTR error_string) {
302 MUI_Request(NULL, NULL, 0, "Error - "PROGNAME, "Ok", "%s", (STRPTR)error_string);
305 #else
307 LONG DoReq (Object *req) {
308 LONG res = 0;
309 if (req) {
310 res = DoMethod(req, RM_OPENREQ, NULL, NULL, NULL);
311 DisposeObject(req);
313 return res;
316 void IoErrRequester (LONG error, CONST_STRPTR header) {
317 TEXT bodytext[80];
318 Object *req;
319 if (error == NO_ERROR) {
320 return;
322 Fault(error, (STRPTR)header, bodytext, sizeof(bodytext));
323 req = RequesterObject,
324 REQ_TitleText, "Error - "PROGNAME,
325 REQ_BodyText, bodytext,
326 REQ_GadgetText, "_Ok",
327 End;
328 DoReq(req);
331 void ErrorStringRequester (CONST_STRPTR error_string) {
332 Object *req;
333 req = RequesterObject,
334 REQ_TitleText, "Error - "PROGNAME,
335 REQ_BodyText, error_string,
336 REQ_GadgetText, "_Ok",
337 End;
338 DoReq(req);
341 #endif