revert between 56095 -> 55830 in arch
[AROS.git] / workbench / devs / diskimage / plugins / xpk.c
blob6961b2e4d16ad311082861e44c24cedcdce2bee0
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 #define USED_PLUGIN_API_VERSION 8
28 #include <devices/diskimage.h>
29 #include <gadgets/fuelgauge.h>
30 #include <xpk/xpk.h>
31 #include <proto/exec.h>
32 #include <proto/dos.h>
33 #include <proto/xpkmaster.h>
34 #include <string.h>
35 #include "device_locale.h"
36 #include <SDI_compiler.h>
37 #include "rev/diskimage.device_rev.h"
39 PLUGIN_VERSTAG("XPK")
41 extern struct DiskImagePlugin xpk_plugin;
43 PLUGIN_TABLE(&xpk_plugin)
45 BOOL XPK_Init (struct DiskImagePlugin *Self, const struct PluginData *data);
46 void XPK_Exit (struct DiskImagePlugin *Self);
47 BOOL XPK_CheckImage (struct DiskImagePlugin *Self, BPTR file, CONST_STRPTR name, QUAD file_size,
48 const UBYTE *test, LONG testsize);
49 APTR XPK_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 XpkProgress *xp));
52 static LONG XPKError (LONG error, LONG *error_string);
54 struct DiskImagePlugin xpk_plugin = {
55 PLUGIN_NODE(-1, "XPK"),
56 PLUGIN_FLAG_M68K,
58 ZERO,
59 NULL,
60 XPK_Init,
61 XPK_Exit,
62 XPK_CheckImage,
63 XPK_OpenImage,
64 NULL,
65 NULL,
66 NULL,
67 NULL,
68 NULL,
69 NULL,
70 NULL,
71 NULL
74 struct Library *SysBase;
75 struct Library *DOSBase;
76 static struct DIPluginIFace *IPlugin;
77 static struct Library *XpkBase;
79 BOOL XPK_Init (struct DiskImagePlugin *Self, const struct PluginData *data) {
80 SysBase = data->SysBase;
81 DOSBase = data->DOSBase;
82 IPlugin = data->IPlugin;
83 return TRUE;
86 void XPK_Exit (struct DiskImagePlugin *Self) {
87 if (XpkBase) CloseLibrary(XpkBase);
90 BOOL XPK_CheckImage (struct DiskImagePlugin *Self, BPTR file, CONST_STRPTR name, QUAD file_size,
91 const UBYTE *test, LONG testsize)
93 struct XpkFib *xf;
94 BOOL is_xpk = FALSE;
96 if (!XpkBase) {
97 XpkBase = OpenLibrary("xpkmaster.library", 0);
98 if (!XpkBase) return FALSE;
101 xf = XpkAllocObject(XPKOBJ_FIB, NULL);
102 if (xf) {
103 if (XpkExamineTags(xf, XPK_InFH, file, TAG_DONE) == XPKERR_OK) {
104 if (xf->xf_Type == XPKTYPE_PACKED) is_xpk = TRUE;
106 XpkFreeObject(XPKOBJ_FIB, xf);
107 ChangeFilePosition(file, 0, OFFSET_BEGINNING);
109 return is_xpk;
112 APTR XPK_OpenImage (struct DiskImagePlugin *Self, APTR unit, BPTR file,
113 CONST_STRPTR name)
115 LONG done = FALSE;
116 LONG error = NO_ERROR;
117 LONG error_string = NO_ERROR_STRING;
118 IPTR error_args[4] = {0};
119 APTR image = NULL;
120 BPTR outfile;
121 CONST_STRPTR ext;
122 BPTR tmpdir;
123 CONST_STRPTR tmpname;
125 if (!XpkBase) {
126 XpkBase = OpenLibrary("xpkmaster.library", 0);
127 if (!XpkBase) {
128 error = ERROR_OBJECT_NOT_FOUND;
129 error_string = MSG_REQ;
130 error_args[0] = (IPTR)"xpkmaster.library";
131 goto error;
135 ext = strrchr(FilePart(name), '.');
136 if (ext) ext++;
138 error = IPlugin_CreateTempFile(unit, ext, &tmpdir, &tmpname);
139 if (error) goto error;
141 outfile = IPlugin_OpenTempFile(unit, MODE_NEWFILE);
142 if (!outfile) {
143 error = IoErr();
144 goto error;
145 } else {
146 struct Hook progresshook = {0};
147 LONG xpk_err;
149 progresshook.h_Entry = ProgressHookFunc;
150 progresshook.h_Data = IPlugin_CreateProgressBar(unit, TRUE);
152 xpk_err = XpkUnpackTags(
153 XPK_InFH, file,
154 XPK_OutFH, outfile,
155 XPK_ChunkHook, &progresshook,
156 TAG_END);
157 if (xpk_err == XPKERR_NEEDPASSWD) {
158 CONST_STRPTR passwd;
159 passwd = IPlugin_RequestPassword(unit);
160 if (passwd) {
161 xpk_err = XpkUnpackTags(
162 XPK_Password, passwd,
163 XPK_InFH, file,
164 XPK_OutFH, outfile,
165 XPK_ChunkHook, &progresshook,
166 TAG_END);
167 FreeVec(passwd);
168 } else {
169 error = ERROR_NO_FREE_STORE;
172 IPlugin_DeleteProgressBar(progresshook.h_Data);
173 Close(outfile);
174 Close(file);
175 file = ZERO;
176 if (error != NO_ERROR) goto error;
178 error = XPKError(xpk_err, &error_string);
179 if (error != NO_ERROR) goto error;
181 outfile = IPlugin_OpenTempFile(unit, MODE_OLDFILE);
182 if (!outfile) {
183 error = IoErr();
184 goto error;
187 done = TRUE;
188 tmpdir = CurrentDir(tmpdir);
189 image = IPlugin_OpenImage(unit, outfile, tmpname);
190 CurrentDir(tmpdir);
193 error:
194 Close(file);
195 if (!done) {
196 IPlugin_SetDiskImageErrorA(unit, error, error_string, error_args);
198 return image;
201 static ULONG ProgressHookFunc (REG(a0, struct Hook *hook), REG(a2, void *unused),
202 REG(a1, struct XpkProgress *xp))
204 APTR pb = hook->h_Data;
205 if (pb) {
206 IPlugin_SetProgressBarAttrs(pb,
207 FUELGAUGE_Percent, TRUE,
208 FUELGAUGE_Max, 100,
209 FUELGAUGE_Level, xp->xp_Done,
210 TAG_END);
212 return IPlugin_ProgressBarInput(pb) ? 1 : 0;
215 static LONG XPKError (LONG error, LONG *error_string) {
216 switch (error) {
217 case XPKERR_OK:
218 return NO_ERROR;
219 case XPKERR_NOMEM:
220 return ERROR_NO_FREE_STORE;
221 case XPKERR_ABORTED:
222 *error_string = MSG_CANCELED;
223 return ERROR_BREAK;
224 case XPKERR_NEEDPASSWD:
225 *error_string = MSG_NOPASSWD;
226 return ERROR_REQUIRED_ARG_MISSING;
227 case XPKERR_WRONGPW:
228 *error_string = MSG_WRONGPASSWD;
229 return ERROR_REQUIRED_ARG_MISSING;
230 default:
231 *error_string = MSG_XPKERR;
232 return ERROR_OBJECT_WRONG_TYPE;