Develop and Download Open Source Software

Browse CVS Repository

Contents of /enbanfukusyaya/EnbanFukusyaYa/DriveAccess/offsetiso.c

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.6 - (show annotations) (download) (as text)
Mon Nov 1 14:34:11 2010 UTC (13 years, 5 months ago) by bananajinn
Branch: MAIN
CVS Tags: HEAD
Changes since 1.5: +68 -68 lines
File MIME type: text/x-csrc
*** empty log message ***

1 /**
2 * @file offsetiso.c
3 * @brief ISOイメージを外側にずらす
4 * @author BananaJinn
5 * @version $Id: offsetiso.c,v 1.5 2007/01/30 15:49:27 bananajinn Exp $
6 * 円盤複写屋
7 * Copyright (C) 2004-2006 BananaJinn<banana@mxh.mesh.ne.jp>.
8 */
9 #include <stdio.h>
10 #include <string.h>
11 #include <stdlib.h>
12 #include "mem.h"
13 #include "cmd.h"
14 #include "ui.h"
15 #include "text.h"
16 #include "log.h"
17
18 #define BLOCKKIND_VOLUME 0
19 #define BLOCKKIND_PATHTABLE_L_PVD 1
20 #define BLOCKKIND_PATHTABLE_M_PVD 2
21 #define BLOCKKIND_PATHTABLE_L_SVD 3
22 #define BLOCKKIND_PATHTABLE_M_SVD 4
23 #define BLOCKKIND_DIRECTORY 5
24
25 #define GET4BYTES(p,l) (l) ? Get4bytesLE(p) : Get4bytes(p)
26 #define GET2BYTES(p,l) (l) ? Get4bytesLE(p) : Get4bytes(p)
27 #define SET4BYTES(p,v,l) (l) ? Set4bytesLE(p,v) : Set4bytes(p,v)
28 #define SET2BYTES(p,v,l) (l) ? Set2bytesLE(p,v) : Set2bytes(p,v)
29
30
31 /**
32 * @brief 置き換えアドレス保持構造体
33 */
34 typedef struct {
35 int kind; /**< データの種類 */
36 DWORD lba; /**< アドレス */
37 DWORD size; /**< サイズ */
38 } REPLBA;
39
40
41 static DWORD gOffset = 0; /**< 外側にずらすブロック数 */
42 static REPLBA *gRepLBA = NULL; /**< 置き換えアドレス配列 */
43 static int gNumRepLBA = 0; /**< 置き換えアドレス配列サイズ */
44 static int gNext = -1; /**< 次に参照する置き換えアドレス */
45 static BYTE gVolumeDesc = 0; /**< ボリューム記述子の種別 */
46
47
48 /**
49 * @brief 置き換えアドレス配列に追加
50 * @param[in] kind データの種類
51 * @param[in] lba アドレス
52 * @param[in] size サイズ
53 * @retval RET_OK 正常終了
54 * @retval RET_NG エラー
55 * @retval RET_MEMERR メモリエラー
56 */
57 static int AddRepLBA(int kind, DWORD lba, DWORD size)
58 {
59 int i;
60
61 lba += gOffset;
62
63 gRepLBA = MemResize(gRepLBA, sizeof(REPLBA)*(gNumRepLBA+1));
64 if(gRepLBA == NULL){
65 return RET_MEMERR;
66 }
67 for(i=0; i<gNumRepLBA; i++){
68 if(lba < gRepLBA[i].lba){
69 break;
70 }
71 else if(lba == gRepLBA[i].lba){
72 return RET_OK;
73 }
74 }
75
76 if((gNumRepLBA-i) > 0){
77 memmove(gRepLBA+i+1, gRepLBA+i, (gNumRepLBA-i)*sizeof(REPLBA));
78 }
79 gRepLBA[i].kind = kind;
80 gRepLBA[i].lba = lba;
81 gRepLBA[i].size = size;
82 gNumRepLBA++;
83
84 if(gNext < 0){
85 gNext = 0;
86 }
87 return RET_OK;
88 }
89
90
91 /**
92 * @brief 置き換えアドレス配列を解放
93 */
94 static void FreeRepLBA()
95 {
96 MemFree(gRepLBA);
97 gRepLBA = NULL;
98 gNumRepLBA = 0;
99 }
100
101 /**
102 * @brief ディレクトリレコードをOFFSET
103 * @param[in] top ブロック先頭ポインタ
104 * @retval RET_OK 正常終了
105 * @retval RET_NG エラー
106 */
107 static int OffsetLbaAtDirectoryRecord(BYTE *top)
108 {
109 DWORD lba;
110 DWORD size;
111 int ret;
112 int i;
113
114 lba = Get4bytesLE(top+0x02);
115 size = Get4bytesLE(top+0x0a);
116 if(top[0x19] & 0x02){
117 /* ファイルフラグがディレクトリの場合 */
118 i = 0;
119 while(size > 0){
120 ret = AddRepLBA(BLOCKKIND_DIRECTORY, lba+i,
121 size>0x800 ? 0x800:size);
122 if(ret != RET_OK)
123 return ret;
124 size -= size>0x800 ? 0x800:size;
125 i++;
126 }
127 }
128 Set4bytesLE(top+0x02, lba+gOffset);
129 Set4bytes(top+0x06, lba+gOffset);
130
131 return RET_OK;
132 }
133
134
135 /**
136 * @brief パステーブルレコードをOFFSET
137 * @param[in] top ブロック先頭ポインタ
138 * @param[in] kind ブロック種別(BLOCKKIND_PATHTABLE_[LM]_[PS]VD)
139 * @retval RET_OK 正常終了
140 * @retval RET_NG エラー
141 */
142 static int OffsetLbaAtPathTableRecord(BYTE *top, int kind)
143 {
144 DWORD lba;
145 //int ret;
146 BOOL le = FALSE;
147
148 le = (kind==BLOCKKIND_PATHTABLE_L_PVD) || (kind==BLOCKKIND_PATHTABLE_L_SVD);
149 lba = GET4BYTES(top+0x02, le);
150 #if 0
151 ret = AddRepLBA(BLOCKKIND_DIRECTORY, lba);
152 if(ret != RET_OK)
153 return ret;
154 #endif
155 SET4BYTES(top+0x02, lba+gOffset, le);
156
157 return RET_OK;
158 }
159
160
161 /**
162 * @brief ボリュームブロックをOFFSET
163 * @param[in] top ブロック先頭ポインタ
164 * @retval RET_OK 正常終了
165 * @retval RET_NG エラー
166 */
167 static int OffsetLbaAtVolume(BYTE *top)
168 {
169 DWORD size;
170 DWORD blocks, i;
171 DWORD lba;
172 int ret;
173
174 if(top[0] == 0x03){
175 /* ?? */
176 lba = Get4bytesLE(top+0x48);
177 Set4bytesLE(top+0x48, lba+gOffset);
178 Set4bytes(top+0x4c, lba+gOffset);
179 }
180 else if((top[0] == 0x01) || (top[0] == 0x02)){
181 /* PVD/SVD */
182
183 /* パステーブルサイズ(bytes) */
184 size = Get4bytes(top+0x88);
185 blocks = (size+2047)/2048;
186
187 /* L形パステーブルLBA */
188 lba = Get4bytesLE(top+0x8c);
189 for(i=0; i<blocks; i++){
190 ret = AddRepLBA(top[0] == 1 ?
191 BLOCKKIND_PATHTABLE_L_PVD : BLOCKKIND_PATHTABLE_L_SVD,
192 lba+i, size);
193 if(ret != RET_OK)
194 return ret;
195 }
196 Set4bytesLE(top+0x8c, lba+gOffset);
197 DebugLog("L type PathTable : 0x%08lX -> 0x%08lX\n",
198 lba, lba+gOffset);
199
200 /* 任意L型パステーブルLBA */
201 lba = Get4bytesLE(top+0x90);
202 if(lba != 0x00000000){
203 for(i=0; i<blocks; i++){
204 ret = AddRepLBA(top[0] == 1 ?
205 BLOCKKIND_PATHTABLE_L_PVD : BLOCKKIND_PATHTABLE_L_SVD,
206 lba+i, size);
207 if(ret != RET_OK)
208 return ret;
209 }
210 Set4bytesLE(top+0x90, lba+gOffset);
211 DebugLog("L type PathTable2 : 0x%08lX -> 0x%08lX\n",
212 lba, lba+gOffset);
213 }
214
215 /* M形パステーブルLBA */
216 lba = Get4bytes(top+0x94);
217 for(i=0; i<blocks; i++){
218 ret = AddRepLBA(top[0] == 1 ?
219 BLOCKKIND_PATHTABLE_M_PVD : BLOCKKIND_PATHTABLE_M_SVD,
220 lba+i, size);
221 if(ret != RET_OK)
222 return ret;
223 }
224 Set4bytes(top+0x94, lba+gOffset);
225 DebugLog("M type PathTable : 0x%08lX -> 0x%08lX\n",
226 lba, lba+gOffset);
227
228 /* 任意M型パステーブルLBA */
229 lba = Get4bytes(top+0x98);
230 if(lba != 0x00000000){
231 for(i=0; i<blocks; i++){
232 ret = AddRepLBA(top[0] == 1 ?
233 BLOCKKIND_PATHTABLE_M_PVD : BLOCKKIND_PATHTABLE_M_SVD,
234 lba+i, size);
235 if(ret != RET_OK)
236 return ret;
237 }
238 Set4bytes(top+0x98, lba+gOffset);
239 DebugLog("M type PathTable2 : 0x%08lX -> 0x%08lX\n",
240 lba, lba+gOffset);
241 }
242
243 ret = OffsetLbaAtDirectoryRecord(top+0x9c);
244 if(ret != RET_OK)
245 return ret;
246 }
247
248 return RET_OK;
249 }
250
251 /**
252 * @brief パステーブルブロックをOFFSET
253 * @param[in] top ブロック先頭ポインタ
254 * @param[in] kind ブロック種別(BLOCKKIND_PATHTABLE_[LM]_[PS]VD)
255 * @param[in] size パステーブルサイズ(バイト数)
256 * @retval RET_OK 正常終了
257 * @retval RET_NG エラー
258 */
259 static int OffsetLbaAtPathTable(BYTE *top, int kind, DWORD size)
260 {
261 DWORD reclen = 0;
262 DWORD i = 0;
263 int ret;
264
265 while(i < size){
266 ret = OffsetLbaAtPathTableRecord(top+i, kind);
267 if(ret != RET_OK){
268 return ret;
269 }
270 reclen = top[i]+8;
271 if(reclen & 1) reclen++;
272 i += reclen;
273 }
274
275 return RET_OK;
276 }
277
278 /**
279 * @brief ディレクトリブロックをOFFSET
280 * @param[in] top ブロック先頭ポインタ
281 * @param[in] size ディレクトリサイズ(バイト数)
282 * @retval RET_OK 正常終了
283 * @retval RET_NG エラー
284 */
285 static int OffsetLbaAtDirectory(BYTE *top, DWORD size)
286 {
287 DWORD reclen = 0;
288 DWORD i = 0;
289 int ret;
290
291 while(i < size){
292 reclen = top[i];
293 if(reclen == 0){
294 break;
295 }
296 ret = OffsetLbaAtDirectoryRecord(top+i);
297 if(ret != RET_OK){
298 return ret;
299 }
300 i += reclen;
301 }
302
303 return RET_OK;
304 }
305
306 /**
307 * @brief 種類に応じて分岐
308 * @param[in] top 1ブロックの先頭ポインタ
309 * @param[in] 種類
310 * @param[in] size サイズ(バイト数)
311 * @retval RET_OK 正常終了
312 * @retval RET_NG エラー
313 */
314 static int OffsetLBA(BYTE *top, int kind, DWORD size)
315 {
316 int ret;
317
318 switch(kind){
319 case BLOCKKIND_VOLUME:
320 ret = OffsetLbaAtVolume(top);
321 break;
322 case BLOCKKIND_PATHTABLE_L_PVD:
323 case BLOCKKIND_PATHTABLE_L_SVD:
324 case BLOCKKIND_PATHTABLE_M_PVD:
325 case BLOCKKIND_PATHTABLE_M_SVD:
326 ret = OffsetLbaAtPathTable(top, kind, size);
327 break;
328 case BLOCKKIND_DIRECTORY:
329 ret = OffsetLbaAtDirectory(top, size);
330 break;
331 default:
332 return RET_NG;
333 }
334 return ret;
335 }
336
337
338 /**
339 * @brief ISO9660イメージを外側にずらすブロック数を設定する。
340 * @param[in] offset ブロック数
341 */
342 void SetOffset(DWORD offset)
343 {
344 gOffset = offset;
345
346 /* 初期化 */
347 FreeRepLBA();
348 gNext = -1;
349 gVolumeDesc = 0;
350 }
351
352
353 /**
354 * @brief ISO9660イメージを外側にずらすブロック数を取得する。
355 * @return ブロック数
356 */
357 DWORD GetOffset()
358 {
359 return gOffset;
360 }
361
362
363 /**
364 * @brief ISO9660イメージを外側にずらす
365 * @param[in] data データ
366 * @param[in] lba データのアドレス
367 * @param[in] blocksize 1ブロックのバイト数(2048)
368 * @param[in] len データの長さ(ブロック数)
369 */
370 int OffsetISO(BYTE *data, DWORD lba, DWORD blocksize, DWORD len)
371 {
372 DWORD i;
373 DWORD curr_lba;
374 BYTE *top;
375 int ret;
376
377 if(gOffset == 0){
378 return RET_OK;
379 }
380
381 for(i=0; i<len; i++){
382 top = data+i*blocksize;
383 if(gVolumeDesc < 0xff){
384 if(!memcmp(top+1, "CD001", 5)){
385 gVolumeDesc = top[0];
386 ret = OffsetLBA(top, BLOCKKIND_VOLUME, 0);
387 if(ret != RET_OK){
388 FreeRepLBA();
389 return ret;
390 }
391 }
392 }
393 else if(gNext >= 0){
394 curr_lba = lba+i;
395 while(curr_lba > gRepLBA[gNext].lba){
396 if(gNext >= gNumRepLBA-1){
397 /* 終了(これ以降のデータにはアドレス置き換えがない) */
398 gNext = -1;
399 return RET_OK;
400 }
401 gNext++;
402 }
403 if(curr_lba == gRepLBA[gNext].lba){
404 ret = OffsetLBA(top, gRepLBA[gNext].kind, gRepLBA[gNext].size);
405 if(ret != RET_OK){
406 FreeRepLBA();
407 return ret;
408 }
409 if(gNext >= gNumRepLBA-1){
410 /* 終了(これ以降のデータにはアドレス置き換えがない) */
411 gNext = -1;
412 return RET_OK;
413 }
414 }
415 }
416 }
417
418 return RET_OK;
419 }

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26