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 #define USED_PLUGIN_API_VERSION 8
28 #include <devices/diskimage.h>
29 #include <gadgets/fuelgauge.h>
30 #include <libraries/xadmaster.h>
31 #include <proto/exec.h>
32 #include <proto/dos.h>
33 #include <proto/xadmaster.h>
35 #include "device_locale.h"
36 #include <SDI_compiler.h>
37 #include "rev/diskimage.device_rev.h"
41 extern struct DiskImagePlugin xad_plugin
;
43 PLUGIN_TABLE(&xad_plugin
)
45 BOOL
XAD_Init (struct DiskImagePlugin
*Self
, const struct PluginData
*data
);
46 void XAD_Exit (struct DiskImagePlugin
*Self
);
47 BOOL
XAD_CheckImage (struct DiskImagePlugin
*Self
, BPTR file
, CONST_STRPTR name
, QUAD file_size
,
48 const UBYTE
*test
, LONG testsize
);
49 APTR
XAD_OpenImage (struct DiskImagePlugin
*Self
, APTR unit
, BPTR file
, CONST_STRPTR name
);
50 static ULONG
ProgressHookFunc (REG(a0
, struct Hook
*hook
), REG(a2
, void *unused
),
51 REG(a1
, struct xadProgressInfo
*pi
));
52 static LONG
XADError (LONG error
, LONG
*error_string
);
54 struct DiskImagePlugin xad_plugin
= {
55 PLUGIN_NODE(-1, "XAD"),
74 struct Library
*SysBase
;
75 struct Library
*DOSBase
;
76 static struct DIPluginIFace
*IPlugin
;
77 static struct xadMasterBase
*xadMasterBase
;
79 BOOL
XAD_Init (struct DiskImagePlugin
*Self
, const struct PluginData
*data
) {
80 SysBase
= data
->SysBase
;
81 DOSBase
= data
->DOSBase
;
82 IPlugin
= data
->IPlugin
;
86 void XAD_Exit (struct DiskImagePlugin
*Self
) {
87 if (xadMasterBase
) CloseLibrary((struct Library
*)xadMasterBase
);
90 BOOL
XAD_CheckImage (struct DiskImagePlugin
*Self
, BPTR file
, CONST_STRPTR name
, QUAD file_size
,
91 const UBYTE
*test
, LONG testsize
)
93 struct xadArchiveInfo
*xai
;
97 xadMasterBase
= (struct xadMasterBase
*)OpenLibrary("xadmaster.library", 0);
98 if (!xadMasterBase
) return FALSE
;
101 xai
= xadAllocObjectA(XADOBJ_ARCHIVEINFO
, NULL
);
103 if (xadGetInfo(xai
, XAD_INFILEHANDLE
, file
, TAG_END
) == XADERR_OK
) {
104 if (xai
->xai_FileInfo
) is_xad
= TRUE
;
107 xadFreeObjectA(xai
, NULL
);
108 ChangeFilePosition(file
, 0, OFFSET_BEGINNING
);
113 static CONST TEXT match_str1
[] = "#?.(adf|b5i|bin|cdi|cso|d64|daa|dax|"
114 "dmg|img|iso|mdf|nrg|pdi|raw|sad|toast|uif)";
115 static CONST TEXT match_str2
[] = "~(#?(displayme|readme|liesmich)#?|"
116 "#?.(diz|info|doc|dok|txt|text|exe|lst|cue|mds|nfo|pdf))";
118 static CONST CONST_STRPTR match_strs
[] = {
119 match_str1
, match_str2
, NULL
122 APTR
XAD_OpenImage (struct DiskImagePlugin
*Self
, APTR unit
, BPTR file
,
126 LONG error
= NO_ERROR
;
127 LONG error_string
= NO_ERROR_STRING
;
128 IPTR error_args
[4] = {0};
130 struct xadArchiveInfo
*xai
;
133 struct xadFileInfo
*xfi
, *chosen
= NULL
;
134 CONST CONST_STRPTR
*match_str
;
138 CONST_STRPTR tmpname
;
140 if (!xadMasterBase
) {
141 xadMasterBase
= (struct xadMasterBase
*)OpenLibrary("xadmaster.library", 0);
142 if (!xadMasterBase
) {
143 error
= ERROR_OBJECT_NOT_FOUND
;
144 error_string
= MSG_REQ
;
145 error_args
[0] = (IPTR
)"xadmaster.library";
150 xai
= xadAllocObjectA(XADOBJ_ARCHIVEINFO
, NULL
);
151 patbuf_size
= 2*max(sizeof(match_str1
), sizeof(match_str2
))+2;
152 patbuf
= AllocVec(patbuf_size
, MEMF_ANY
);
153 if (!xai
|| !patbuf
) {
154 error
= ERROR_NO_FREE_STORE
;
158 if (xadGetInfo(xai
, XAD_INFILEHANDLE
, file
, TAG_END
) != XADERR_OK
) {
159 error
= ERROR_OBJECT_WRONG_TYPE
;
163 match_str
= match_strs
;
164 while (!chosen
&& *match_str
) {
165 ParsePatternNoCase(*match_str
++, patbuf
, patbuf_size
);
166 for (xfi
= xai
->xai_FileInfo
; xfi
; xfi
= xfi
->xfi_Next
) {
167 if (MatchPatternNoCase(patbuf
, FilePart(xfi
->xfi_FileName
))) {
176 chosen
= xai
->xai_FileInfo
;
178 error
= ERROR_OBJECT_NOT_FOUND
;
183 ext
= strrchr(FilePart(chosen
->xfi_FileName
), '.');
186 error
= IPlugin_CreateTempFile(unit
, ext
, &tmpdir
, &tmpname
);
187 if (error
!= NO_ERROR
) goto error
;
189 outfile
= IPlugin_OpenTempFile(unit
, MODE_NEWFILE
);
194 struct Hook progresshook
= {0};
197 progresshook
.h_Entry
= ProgressHookFunc
;
198 progresshook
.h_Data
= IPlugin_CreateProgressBar(unit
, TRUE
);
200 xad_err
= xadFileUnArc(xai
,
201 XAD_OUTFILEHANDLE
, outfile
,
203 XAD_ENTRYNUMBER
, chosen
->xfi_EntryNumber
,
204 XAD_PROGRESSHOOK
, &progresshook
,
206 if (xad_err
== XADERR_PASSWORD
) {
208 passwd
= IPlugin_RequestPassword(unit
);
210 xad_err
= xadFileUnArc(xai
,
211 XAD_PASSWORD
, passwd
,
212 XAD_OUTFILEHANDLE
, outfile
,
214 XAD_ENTRYNUMBER
, chosen
->xfi_EntryNumber
,
215 XAD_PROGRESSHOOK
, &progresshook
,
219 error
= ERROR_NO_FREE_STORE
;
222 IPlugin_DeleteProgressBar(progresshook
.h_Data
);
224 xadFreeObjectA(xai
, NULL
);
228 if (error
!= NO_ERROR
) goto error
;
230 error
= XADError(xad_err
, &error_string
);
231 if (error
!= NO_ERROR
) goto error
;
233 outfile
= IPlugin_OpenTempFile(unit
, MODE_OLDFILE
);
240 tmpdir
= CurrentDir(tmpdir
);
241 image
= IPlugin_OpenImage(unit
, outfile
, tmpname
);
246 if (xai
) xadFreeObjectA(xai
, NULL
);
250 IPlugin_SetDiskImageErrorA(unit
, error
, error_string
, error_args
);
255 static ULONG
ProgressHookFunc (REG(a0
, struct Hook
*hook
), REG(a2
, void *unused
),
256 REG(a1
, struct xadProgressInfo
*pi
))
258 APTR pb
= hook
->h_Data
;
260 switch (pi
->xpi_Mode
) {
261 case XADPMODE_PROGRESS
:
262 if (pi
->xpi_FileInfo
->xfi_Flags
& XADFIF_NOUNCRUNCHSIZE
) {
263 hook
->h_SubEntry
= (void *)(pi
->xpi_CurrentSize
>> 10);
264 IPlugin_SetProgressBarAttrs(pb
,
265 FUELGAUGE_Percent
, FALSE
,
268 FUELGAUGE_VarArgs
, &hook
->h_SubEntry
,
271 IPlugin_SetProgressBarAttrs(pb
,
272 FUELGAUGE_Percent
, TRUE
,
273 FUELGAUGE_Max
, pi
->xpi_FileInfo
->xfi_Size
,
274 FUELGAUGE_Level
, pi
->xpi_CurrentSize
,
280 return IPlugin_ProgressBarInput(pb
) ? 0 : XADPIF_OK
;
283 static LONG
XADError (LONG error
, LONG
*error_string
) {
289 return ERROR_BUFFER_OVERFLOW
;
290 case XADERR_NOMEMORY
:
291 return ERROR_NO_FREE_STORE
;
293 *error_string
= MSG_CANCELED
;
295 case XADERR_PASSWORD
:
296 *error_string
= MSG_WRONGPASSWD
;
297 return ERROR_REQUIRED_ARG_MISSING
;
299 *error_string
= MSG_XADERR
;
300 return ERROR_OBJECT_WRONG_TYPE
;