1 /* Copyright 2007-2012 Fredrik Wikstrom. All rights reserved.
3 ** Redistribution and use in source and binary forms, with or without
4 ** modification, are permitted provided that the following conditions
7 ** 1. Redistributions of source code must retain the above copyright
8 ** notice, this list of conditions and the following disclaimer.
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>
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>
38 #include <libraries/mui.h>
39 #include <proto/muimaster.h>
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>
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"
69 struct WBStartup
*WBMsg
;
71 struct Library
*IconBase
;
72 struct IntuitionBase
*IntuitionBase
;
73 struct Library
*RequesterBase
;
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
) {
84 struct DiskObject
*icon
= NULL
;
85 struct RDArgs
*rdargs
= NULL
;
87 CONST_STRPTR filename
= NULL
;
89 BOOL writeprotect
= FALSE
;
90 ULONG blockspertrack
= 32;
92 ULONG blocksize
= 512;
94 LONG error
= NO_ERROR
;
95 LONG error2
= NO_ERROR
;
96 TEXT error_buffer
[256];
97 UBYTE
*block_buffer
= NULL
;
98 struct DriveGeometry dg
;
103 struct DeviceNode
*device
;
109 WBMsg
= (struct WBStartup
*)argv
;
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
)))
118 if (WBMsg
->sm_NumArgs
< 2) {
119 IoErrRequester(ERROR_REQUIRED_ARG_MISSING
, NULL
);
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
);
128 IoErrRequester(IoErr(), NULL
);
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
));
139 ClearMem(args
, sizeof(args
));
140 rdargs
= ReadArgs(TEMPLATE
, args
, NULL
);
142 PrintFault(IoErr(), PROGNAME
);
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
];
157 IoErrRequester(ERROR_REQUIRED_ARG_MISSING
, NULL
);
159 PrintFault(ERROR_REQUIRED_ARG_MISSING
, PROGNAME
);
163 if (!OpenDiskImageDevice(unit
)) {
164 SNPrintf(error_buffer
, sizeof(error_buffer
),
165 "failed to open diskimage.device");
167 ErrorStringRequester(error_buffer
);
169 FPrintf(stderr
, "%s: %s\n", PROGNAME
, error_buffer
);
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
,
182 if (error
== NO_ERROR
) error
= error2
;
183 if (error_buffer
[0]) {
185 ErrorStringRequester(error_buffer
);
187 FPrintf(stderr
, "%s: %s\n", filename
, error_buffer
);
191 IoErrRequester(error
, NULL
);
193 PrintFault(error
, filename
);
197 block_buffer
= AllocVec(blocksize
, MEMF_ANY
);
200 IoErrRequester(ERROR_NO_FREE_STORE
, NULL
);
202 PrintFault(ERROR_NO_FREE_STORE
, PROGNAME
);
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");
212 ErrorStringRequester(error_buffer
);
214 FPrintf(stderr
, "%s: %s\n", PROGNAME
, error_buffer
);
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");
227 ErrorStringRequester(error_buffer
);
229 FPrintf(stderr
, "%s: %s\n", PROGNAME
, error_buffer
);
233 SNPrintf(drivename
, sizeof(drivename
), "IHD%ld", unit
);
234 parampkt
[0] = (IPTR
)drivename
;
235 parampkt
[1] = (IPTR
)"diskimage.device";
239 parampkt
[5] = blocksize
>> 2;
241 parampkt
[7] = surfaces
;
243 parampkt
[9] = blockspertrack
;
244 parampkt
[10] = reserved
;
248 parampkt
[14] = (filesize
/ cylindersize
) - 1;
250 parampkt
[16] = MEMF_ANY
;
251 parampkt
[17] = 0x7fffffffUL
;
252 parampkt
[18] = 0xfffffffcUL
;
254 parampkt
[20] = rbe32(block_buffer
);
255 device
= MakeDosNode(parampkt
);
258 IoErrRequester(ERROR_NO_FREE_STORE
, NULL
);
260 PrintFault(ERROR_NO_FREE_STORE
, PROGNAME
);
263 if (!AddBootNode(0, ADNF_STARTPROC
, device
, NULL
)) {
265 IoErrRequester(ERROR_DEVICE_NOT_MOUNTED
, NULL
);
267 PrintFault(ERROR_DEVICE_NOT_MOUNTED
, PROGNAME
);
274 FreeVec(block_buffer
);
275 CloseDiskImageDevice();
277 if (icon
) FreeDiskObject(icon
);
279 if (RequesterBase
) CloseLibrary(RequesterBase
);
280 if (IntuitionBase
) CloseLibrary((struct Library
*)IntuitionBase
);
281 if (IconBase
) CloseLibrary(IconBase
);
292 void IoErrRequester (LONG error
, CONST_STRPTR header
) {
294 if (error
== NO_ERROR
) {
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
);
307 LONG
DoReq (Object
*req
) {
310 res
= DoMethod(req
, RM_OPENREQ
, NULL
, NULL
, NULL
);
316 void IoErrRequester (LONG error
, CONST_STRPTR header
) {
319 if (error
== NO_ERROR
) {
322 Fault(error
, (STRPTR
)header
, bodytext
, sizeof(bodytext
));
323 req
= RequesterObject
,
324 REQ_TitleText
, "Error - "PROGNAME
,
325 REQ_BodyText
, bodytext
,
326 REQ_GadgetText
, "_Ok",
331 void ErrorStringRequester (CONST_STRPTR error_string
) {
333 req
= RequesterObject
,
334 REQ_TitleText
, "Error - "PROGNAME
,
335 REQ_BodyText
, error_string
,
336 REQ_GadgetText
, "_Ok",