Develop and Download Open Source Software

Browse CVS Repository

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

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


Revision 1.11 - (show annotations) (download) (as text)
Tue Nov 2 15:23:51 2010 UTC (13 years, 5 months ago) by bananajinn
Branch: MAIN
CVS Tags: HEAD
Changes since 1.10: +18 -4 lines
File MIME type: text/x-csrc
*** empty log message ***

1 /**
2 * @file discinfo.c
3 * @brief ディスク情報取得関連
4 * @author BananaJinn
5 * @version $Id: discinfo.c,v 1.10 2010/11/01 14:34:11 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 #if defined(WIN32)
13 # include <io.h>
14 #endif
15
16 #include "mem.h"
17 #include "aspi.h"
18 #include "struct.h"
19 #include "cmd.h"
20 #include "ui.h"
21 #include "text.h"
22 #include "log.h"
23 #include "discinfo.h"
24 #include "emg.h"
25 #include "ebstring.h"
26
27 /**
28 * ディスク情報を設定(イメージファイルに記録する)
29 * @param[in] drive 書込装置構造体
30 * @param[in] discinfo ディスク情報
31 * @retval RET_OK 正常終了
32 * @retval RET_NG エラー
33 */
34 int SetDiscInformation(CMDDRIVE *drive, CPDISCINFO *discinfo)
35 {
36 int ret;
37
38 if(drive->type == CMDDRVTYPE_ISO){
39 /* ISOイメージの場合は、1トラック/1セッションのみ */
40 if(discinfo->tracks > 1){
41 UIDispMessage(MSG_CANT_CREATE_MULTITRACK_ISO,
42 UIDMT_ERROR);
43 return RET_NG;
44 }
45 }
46 else if(drive->type == CMDDRVTYPE_IMAGE){
47 /* 円盤複写屋オリジナルイメージ */
48 /* イメージファイルにディスク情報を書き込む */
49 ret = EmgWriteDiscInformation(&drive->u.image, discinfo);
50 if(ret!=RET_OK)
51 return ret;
52 }
53
54 return RET_OK;
55 }
56
57
58 /**
59 * TAO記録すべきかどうかを判別する
60 * @param[in] drive ドライブ構造体
61 * @param[in] discinfo ディスク情報構造体
62 * @param[in] sess_num セッション番号
63 * @param[out] result 判別結果(TAO=TRUE)
64 * @retval RET_OK 正常終了
65 * @retval RET_NG エラー
66 */
67 static int JudgeTAO(CMDDRIVE *drive, CPDISCINFO *discinfo,
68 WORD sess_num, BOOL *result)
69 {
70 if(!REALDRIVE(drive))
71 return RET_OK;
72
73 *result = FALSE;
74 if(!DT_CD_FAMILY(drive->disc_type)){
75 *result = TRUE; /* DVD系の場合はTAOとする */
76 DebugLog("JudgeTAO: TAO(Disc is not CD.)\n");
77 return RET_OK;
78 }
79
80 if(sess_num == discinfo->sessions){
81 /* 最終セッションの場合はオープンセッションかどうかを確認 */
82 if(discinfo->last_sess_stat == SESSSTAT_EMPTY){
83 *result = FALSE;
84 DebugLog("JudgeTAO: Session is empty.\n");
85 return RET_OK;
86 }
87 else if(discinfo->last_sess_stat == SESSSTAT_INCOMPLETE){
88 /* 未完了セッションの場合はTAOとする */
89 *result = TRUE;
90 DebugLog("JudgeTAO: TAO(Last session is incomplete.)\n");
91 return RET_OK;
92 }
93 }
94
95 /*
96 * 以前はセッションの最後に Run-out があるかどうかを判別していたが、
97 * もはや Run-out がリードエラーにならないドライブもあり、判別が不可能!?
98 * セッションがクローズされているなら、SAOで記録することにする。
99 */
100 *result = FALSE;
101 return RET_OK;
102 }
103
104 /**
105 * 指定されたセッションのリードアウト開始アドレスを求める。
106 * @param[in] drive ドライブ構造体
107 * @param[in] discinfo ディスク情報構造体
108 * @param[in] sess_num セッション番号
109 * @param[out] lout_start Lead-out開始アドレス
110 * @retval RET_OK 正常終了
111 * @retval RET_NG エラー
112 */
113 static int GetLeadOutStart(CMDDRIVE *drive, CPDISCINFO *discinfo,
114 WORD sess_num, DWORD *lout_start)
115 {
116 int ret;
117 int i;
118 struct _FULLTOCDESC *ftd;
119 DWORD lba=0UL;
120 WORD tno;
121 WORD sno;
122 CPTRACKINFO *cpti;
123
124 /* TOC情報から該当セッションのリードアウト開始アドレスを求める */
125 ret = SendReadToc(drive, sess_num, 1, RTF_FULLTOC);
126 if(ret==RET_OK){
127 for(i=sizeof(struct _TOCHEADER); i<drive->bufsize; i+=sizeof(struct _FULLTOCDESC)){
128 ftd = (struct _FULLTOCDESC *)(drive->data_buf+i);
129 if(ftd->point == 0xa2){
130 lba = MSF2LBA(ftd->pmin, ftd->psec, ftd->pframe, FALSE);
131 break;
132 }
133 }
134 }
135 else{
136 /* ReadTOCがエラーになる場合はトラック情報から求める */
137 for(tno=1; tno<=discinfo->tracks; tno++){
138 cpti = &discinfo->trackinfo[tno-1];
139 sno = (WORD)cpti->trackinfo.session_number_msb<<8 |
140 cpti->trackinfo.session_number_lsb;
141 if(sno == sess_num){
142 lba = Get4bytes(cpti->trackinfo.track_start) +
143 Get4bytes(cpti->trackinfo.track_size);
144 }
145 }
146 /*
147 * Run-outがあると仮定しておいて +2 する。
148 * 実際に読んでアドレスエラーなら Run-out は無かったことにする。
149 */
150 lba += 2;
151 }
152
153 if(lba==0UL){
154 /* 取得できなかった */
155 *lout_start = lba;
156 return RET_OK;
157 }
158
159 /* リードアウト開始アドレスの直前2ブロックを読んでみる */
160 ret = SendReadCD(drive, lba-2, 2);
161 if(ret != RET_OK){
162 if(SD_ASC(drive)==0x21){
163 /* Run-out は無かった */
164 lba -= 2;
165 }
166 }
167
168 *lout_start = lba;
169
170 return RET_OK;
171 }
172
173 /**
174 * 読取装置の指定トラックのプリギャップ長を取得する
175 * @param[in] drive 読取装置構造体
176 * @param[in/out] cpti トラック情報
177 * @retval RET_OK 正常終了
178 * @retval RET_NG エラー
179 */
180 static int GetGapLen(CMDDRIVE *drive, CPTRACKINFO *cpti)
181 {
182 int ret;
183 DWORD search_start, search_end, lba=0, track_start;
184 DWORD real_start;
185 BYTE track_num = cpti->trackinfo.track_number_lsb;
186
187 track_start = Get4bytes(cpti->trackinfo.track_start);
188 search_end = track_start;
189 search_start = search_end - 151; /* GAP長=150が一般的なので、その手前から検索 */
190 real_start = search_start;
191
192 while(TRUE){
193 /*
194 * 2分探索するよりもシーケンシャルでアクセスした方がたぶん速い
195 */
196 for(lba=search_start; lba<search_end; lba++){
197 ret = GetSubQ(drive, lba, 1);
198 if(ret!=RET_OK){
199 search_start++;
200 continue;
201 }
202 if((drive->data_buf[0] & 0x0f)!=0x01){
203 /* たぶんISRCかMediaCatalogNumberが記録されている */
204 search_start++;
205 continue;
206 }
207 if(track_num==drive->data_buf[1]){
208 break;
209 }
210 }
211 if(lba==real_start){
212 /* 検索した先頭が既にギャップなら、もっと前から検索する */
213 search_end = search_start;
214 search_start -= 150;
215 real_start = search_start;
216 continue;
217 }
218 break;
219 }
220 if(lba >= track_start)
221 cpti->pause_len = 0;
222 else if(track_start-lba > 0xffff)
223 cpti->pause_len = 0xffff;
224 else
225 cpti->pause_len = (WORD)(track_start - lba);
226
227 if(cpti->pause_len>0){
228 /* 念のため、ギャップの最後も確認する */
229 ret = GetSubQ(drive, Get4bytes(cpti->trackinfo.track_start)-1, 1);
230 if(ret==RET_OK){
231 if((drive->data_buf[0] & 0x0f)==0x01 &&
232 drive->data_buf[1]==track_num &&
233 drive->data_buf[2]>0){
234 cpti->pause_len--;
235 }
236 }
237 }
238
239 return RET_OK;
240 }
241
242 /**
243 * トラック情報取得
244 * @param[in] drive 読取装置構造体
245 * @param[in] track_num トラック番号
246 * @param[out] cpti トラック情報
247 * @retval RET_OK 正常終了
248 * @retval RET_NG エラー
249 */
250 static int GetTrackInformation(CMDDRIVE *drive, WORD track_num, CPTRACKINFO *cpti)
251 {
252 int ret;
253
254 ret = SendReadTrackInfo(drive, track_num);
255 if(ret!=RET_OK){
256 DispCommandError(drive);
257 return ret;
258 }
259 memcpy(&cpti->trackinfo, drive->data_buf, sizeof(struct _TRACKINFO));
260 cpti->mode2 = 0;
261 cpti->pause_len = 0;
262 if(cpti->trackinfo.blank)
263 return RET_OK;
264 if(DT_CD_FAMILY(drive->disc_type)){
265 memset(cpti->isrc, 0, 12+1);
266 if(IS_TRACKMODE_DATA(cpti->trackinfo.track_mode)){
267 /* MODE2かどうかを調べる */
268 ret = SendReadCD(drive, Get4bytes(cpti->trackinfo.track_start), 1);
269 if(ret!=RET_OK){
270 DispCommandError(drive);
271 return ret;
272 }
273 if(drive->data_buf[15]==2)
274 cpti->mode2 = 1;
275 }
276 else{
277 ret = SendReadSubchannel(drive, (BYTE)track_num, 0, 1, RSCF_ISRC);
278 if(ret!=RET_OK){
279 DispCommandError(drive);
280 return ret;
281 }
282 if(drive->data_buf[8] & 0x80){
283 memcpy(cpti->isrc, drive->data_buf+9, 12);
284 }
285 if(track_num>1){
286 /* ギャップ長を調べる */
287 ret = GetGapLen(drive, cpti);
288 if(ret!=RET_OK){
289 return ret;
290 }
291 }
292 }
293 }
294
295 DebugLog("GetTrackInformation: start=0x%08lX size=0x%08lX tmode=0x%X mode2=%d gap=0x%X\n",
296 Get4bytes(cpti->trackinfo.track_start),
297 Get4bytes(cpti->trackinfo.track_size),
298 cpti->trackinfo.track_mode,
299 cpti->mode2, cpti->pause_len);
300
301 return RET_OK;
302 }
303
304 /**
305 * トラックサイズを調整する
306 * @param[in] drive 読取装置構造体
307 * @param[in/out] discinfo ディスク情報
308 * @param[in] track_num トラック番号
309 * @param[in] lout_start Lead-out開始アドレス
310 * @retval RET_OK 正常終了
311 * @retval RET_NG エラー
312 */
313 static int AdjustTrackSize(CMDDRIVE *drive, CPDISCINFO *discinfo,
314 WORD track_num, DWORD lout_start)
315 {
316 DWORD next_start=0;
317 CPTRACKINFO *cpti, *ncpti=NULL;
318 DWORD lba, track_size;
319 int ret;
320 #if 0
321 char buf[80];
322 #endif
323
324 if(!REALDRIVE(drive))
325 return RET_OK;
326
327 if(DT_DVD_FAMILY(drive->disc_type))
328 return RET_OK;
329
330 next_start = lout_start;
331 cpti = &discinfo->trackinfo[track_num-1];
332 if(cpti->tao){
333 /* 完了トラックならトラックの最後2ブロックを読んでみる */
334 if(Get4bytes(cpti->trackinfo.free_blocks)==0){
335 lba = Get4bytes(cpti->trackinfo.track_start) +
336 Get4bytes(cpti->trackinfo.track_size) -2;
337 ret = SendReadCD(drive, lba, 2);
338 if(ret!=RET_OK){
339 /* 読めないならたぶん Run-out でしょう */
340 track_size = Get4bytes(cpti->trackinfo.track_size) -2;
341 Set4bytes(cpti->trackinfo.track_size, track_size);
342 }
343 }
344 return RET_OK;
345 }
346 if(track_num < discinfo->tracks){
347 ncpti = &discinfo->trackinfo[track_num];
348 if(((WORD)cpti->trackinfo.session_number_msb<<8 | cpti->trackinfo.session_number_lsb)==
349 ((WORD)ncpti->trackinfo.session_number_msb<<8 | ncpti->trackinfo.session_number_lsb)){
350 /* 次のトラックも同じセッション */
351 next_start = Get4bytes(ncpti->trackinfo.track_start);
352 if(IS_TRACKMODE_DATA(ncpti->trackinfo.track_mode)){
353 next_start -= 150;
354 if(!IS_TRACKMODE_DATA(cpti->trackinfo.track_mode) ||
355 ncpti->mode2 != cpti->mode2){
356 /* 2part */
357 next_start -= 75;
358 }
359 }
360 else{
361 next_start -= ncpti->pause_len;
362 }
363 }
364 }
365 if(next_start==0)
366 return RET_OK;
367
368 /* 実際に読めるとこまで読んでみる? */
369 for(lba=next_start-4; lba<next_start; lba++){
370 ret = SendReadCD(drive, lba, 1);
371 if(ret!=RET_OK)
372 break;
373 }
374
375 track_size = lba-Get4bytes(cpti->trackinfo.track_start);
376 #if 0
377 if(track_size != Get4bytes(cpti->trackinfo.track_size)){
378 sprintf(buf, "トラック%d のサイズは 0x%08lX から 0x%08lX に変更されました。",
379 track_num, Get4bytes(cpti->trackinfo.track_size), track_size);
380 UIDispMessage(buf, UIDMT_INFORMATION);
381 }
382 #endif
383 Set4bytes(cpti->trackinfo.track_size, track_size);
384
385 return RET_OK;
386 }
387
388 /**
389 * CD-TEXT情報取得
390 * @param[in] drive 読取装置構造体
391 * @param[out] discinfo ディスク情報
392 * @retval RET_OK 正常終了
393 * @retval RET_NG エラー
394 */
395 static int GetCDText(CMDDRIVE *drive, CPDISCINFO *discinfo)
396 {
397 int ret;
398 WORD len;
399
400 ret = SendReadToc(drive, 0, 0, RTF_CDTEXT);
401 if(ret!=RET_OK){
402 return RET_OK;
403 }
404 len = Get2bytes(drive->data_buf);
405 if(len<=2){ /* header(4bytes) - length field(2bytes) */
406 /* CD-TEXTなし */
407 return RET_OK;
408 }
409 len -= 2;
410 discinfo->cdtext = (BYTE *)MemNew(len);
411 if(discinfo->cdtext==NULL)
412 return RET_MEMERR;
413 memcpy(discinfo->cdtext, drive->data_buf+4, len);
414 discinfo->cdtext_size = len;
415 return RET_OK;
416 }
417
418 /**
419 * @brief 1セッション1トラックのディスク情報を作成する
420 * @param[in] track_size トラックサイズ
421 * @param[out] discinfo ディスク情報
422 * @retval RET_OK 正常終了
423 * @retval RET_MEMERR メモリ確保エラー
424 */
425 static int CreateDummyDiscInformation(DWORD track_size, CPDISCINFO *discinfo)
426 {
427 /* ディスク情報設定 */
428 discinfo->disc_stat = DISCSTAT_COMPLETE;
429 discinfo->last_sess_stat = SESSSTAT_COMPLETE;
430 discinfo->last_addr = (DWORD)(track_size > 0 ? track_size-1 : 0);
431 discinfo->sessions = 1;
432 discinfo->tracks = 1;
433 discinfo->trackinfo = (CPTRACKINFO *)MemNew(sizeof(CPTRACKINFO));
434 if(discinfo->trackinfo==NULL){
435 return RET_MEMERR;
436 }
437 memset(discinfo->trackinfo, 0, sizeof(CPTRACKINFO));
438 discinfo->trackinfo->mode2 = 0;
439 discinfo->trackinfo->tao = FALSE;
440 discinfo->trackinfo->trackinfo.track_number_lsb = 1;
441 discinfo->trackinfo->trackinfo.session_number_lsb = 1;
442 discinfo->trackinfo->trackinfo.track_mode = 4;
443 discinfo->trackinfo->trackinfo.data_mode = 0x0f;
444 Set4bytes(discinfo->trackinfo->trackinfo.track_start, 0);
445 Set4bytes(discinfo->trackinfo->trackinfo.track_size, track_size);
446 return RET_OK;
447 }
448
449 /**
450 * @brief ディスク情報取得(mkisofs)
451 * @param[in] drive 読取装置構造体
452 * @param[in] discinfo ディスク情報
453 * @retval RET_OK 正常終了
454 * @retval RET_NG エラー
455 * @retval RET_MEMERR メモリ確保エラー
456 */
457 static int GetDiscInformationMkisofs(CMDDRIVE *drive, CPDISCINFO *discinfo)
458 {
459 DWORD track_size = 0;
460 UIDispInfo(MSG_READING);
461 if(UICheckAbort()){
462 return RET_ABORT;
463 }
464 track_size = MIFGetBlockCount(&drive->u.mkisofs);
465 if(track_size == 0){
466 char *message = EbStringNewWithFormat(
467 MSG_MKISOFS_ERROR_,
468 MIFGetErrorMessage(&drive->u.mkisofs));
469 UIDispMessage(message, UIDMT_ERROR);
470 EbStringFree(message);
471 return RET_NG;
472 }
473 UIDispInfo("");
474 return CreateDummyDiscInformation(track_size, discinfo);
475 }
476
477 /**
478 * ディスク情報取得(ISOイメージ)
479 * @param[in] drive 読取装置構造体
480 * @param[out] discinfo ディスク情報
481 * @retval RET_OK 正常終了
482 * @retval RET_NG エラー
483 */
484 static int GetDiscInformationISO(CMDDRIVE *drive, CPDISCINFO *discinfo)
485 {
486 DWORD track_size;
487 #ifdef WIN32
488 __int64 file_size;
489 #else
490 off_t file_size;
491 #endif
492
493 /* ファイルサイズ取得 */
494 #ifdef WIN32
495 file_size = _lseeki64(_fileno(drive->u.image.fp), 0, SEEK_END);
496 _lseeki64(_fileno(drive->u.image.fp), 0, SEEK_SET);
497 #else
498 fseeko(drive->u.image.fp, 0, SEEK_END);
499 file_size = ftello(drive->u.image.fp);
500 fseeko(drive->u.image.fp, 0, SEEK_SET);
501 #endif
502 track_size = (DWORD)((file_size+2047)/2048);
503
504 return CreateDummyDiscInformation(track_size, discinfo);
505 }
506
507 /**
508 * ディスク情報取得(イメージファイル)
509 * @param[in] drive 読取装置構造体
510 * @param[out] discinfo ディスク情報
511 * @retval RET_OK 正常終了
512 * @retval RET_NG エラー
513 */
514 static int GetDiscInformationImage(CMDDRIVE *drive, CPDISCINFO *discinfo)
515 {
516 int ret;
517
518 ret = EmgReadDiscInformation(&drive->u.image, discinfo);
519 if(ret!=RET_OK)
520 return ret;
521
522 return RET_OK;
523 }
524
525 /**
526 * ディスク情報取得(実ドライブ)
527 * @param[in] drive 読取装置構造体
528 * @param[out] discinfo ディスク情報
529 * @retval RET_OK 正常終了
530 * @retval RET_NG エラー
531 */
532 static int GetDiscInformationDrive(CMDDRIVE *drive, CPDISCINFO *discinfo)
533 {
534 WORD track_num;
535 WORD sess_num, last_sess_num;
536 BOOL tao=FALSE;
537 struct _DISCINFO *di;
538 CPTRACKINFO *cpti;
539 DWORD last_addr=0, lout_start=0;
540 int ret;
541
542 ret = SendReadDiscInfo(drive);
543 if(ret!=RET_OK){
544 DispCommandError(drive);
545 return ret;
546 }
547 di = (struct _DISCINFO *)drive->data_buf;
548 discinfo->disc_stat = di->disc_status;
549 discinfo->last_sess_stat = di->sess_status;
550 discinfo->sessions = (WORD)di->numsess_msb<<8 | di->numsess_lsb;
551 discinfo->tracks = (WORD)di->last_track_ls_msb<<8 | di->last_track_ls_lsb;
552 discinfo->disc_type = di->disc_type;
553
554 DebugLog("GetDiscInformationDrive: disc_status=%d\n",
555 discinfo->disc_stat);
556 DebugLog("GetDiscInformationDrive: last_sess_status=%d\n",
557 discinfo->last_sess_stat);
558 DebugLog("GetDiscInformationDrive: tracks=%d\n",
559 discinfo->tracks);
560 DebugLog("GetDiscInformationDrive: disc_type=%d\n",
561 discinfo->disc_type);
562
563 if(discinfo->disc_stat == DISCSTAT_EMPTY){
564 UIDispMessage(MSG_SOURCE_IS_BLANK
565 /*"複写元ディスクはブランクです。複写できません。"*/,
566 UIDMT_INFORMATION);
567 return RET_ABORT;
568 }
569 discinfo->cdtext = NULL;
570 discinfo->cdtext_size = 0;
571 memset(discinfo->media_catalog_number, 0, 13+1);
572 if(DT_CD_FAMILY(drive->disc_type)){
573 ret = SendReadSubchannel(drive, 0, 0, 1, RSCF_MCN);
574 if(ret!=RET_OK){
575 DispCommandError(drive);
576 return ret;
577 }
578 if(drive->data_buf[8] & 0x80){
579 memcpy(discinfo->media_catalog_number, drive->data_buf+9, 13);
580 }
581 /* CD-TEXT */
582 ret = GetCDText(drive, discinfo);
583 if(ret!=RET_OK){
584 return ret;
585 }
586 }
587
588 /* トラックごとに情報を取得 */
589 UIMeter1Initialize(MSG_READING);
590 if(drive->type==CMDDRVTYPE_NET){
591 NAUIMeter1Initialize(&drive->u.net, MSG_READING);
592 }
593 discinfo->trackinfo = (CPTRACKINFO *)MemNew(sizeof(CPTRACKINFO)*discinfo->tracks);
594 for(track_num=1; track_num<=discinfo->tracks; track_num++){
595 UIMeter1Update((float)track_num*100/discinfo->tracks/2);
596 if(drive->type==CMDDRVTYPE_NET){
597 NAUIMeter1Update(&drive->u.net, (float)track_num*100/discinfo->tracks/2);
598 }
599 if(UICheckAbort()){
600 MemFree(discinfo->cdtext);
601 discinfo->cdtext = NULL;
602 MemFree(discinfo->trackinfo);
603 discinfo->trackinfo = NULL;
604 return RET_ABORT;
605 }
606 cpti = &discinfo->trackinfo[track_num-1];
607 ret = GetTrackInformation(drive, track_num, cpti);
608 if(ret!=RET_OK){
609 MemFree(discinfo->cdtext);
610 discinfo->cdtext = NULL;
611 MemFree(discinfo->trackinfo);
612 discinfo->trackinfo = NULL;
613 return ret;
614 }
615 }
616
617 last_sess_num = 0;
618 for(track_num=1; track_num<=discinfo->tracks; track_num++){
619 UIMeter1Update((float)track_num*100/discinfo->tracks/2+50);
620 if(drive->type==CMDDRVTYPE_NET){
621 NAUIMeter1Update(&drive->u.net, (float)track_num*100/discinfo->tracks/2+50);
622 }
623 if(UICheckAbort()){
624 MemFree(discinfo->cdtext);
625 discinfo->cdtext = NULL;
626 MemFree(discinfo->trackinfo);
627 discinfo->trackinfo = NULL;
628 return RET_ABORT;
629 }
630 cpti = &discinfo->trackinfo[track_num-1];
631 /* セッションがTAO記録かどうかを調べる */
632 sess_num = (WORD)cpti->trackinfo.session_number_msb<<8 |
633 cpti->trackinfo.session_number_lsb;
634 if(sess_num != last_sess_num){
635 /* TAOかSAOか判断 */
636 ret = JudgeTAO(drive, discinfo, sess_num, &tao);
637 if(ret!=RET_OK){
638 MemFree(discinfo->cdtext);
639 discinfo->cdtext = NULL;
640 MemFree(discinfo->trackinfo);
641 discinfo->trackinfo = NULL;
642 return ret;
643 }
644 /* リードアウト開始アドレスを取得 */
645 ret = GetLeadOutStart(drive, discinfo, sess_num, &lout_start);
646 if(ret!=RET_OK){
647 MemFree(discinfo->cdtext);
648 discinfo->cdtext = NULL;
649 MemFree(discinfo->trackinfo);
650 discinfo->trackinfo = NULL;
651 return ret;
652 }
653 last_sess_num = sess_num;
654 }
655 cpti->tao = tao;
656 /* セッションの最終トラックサイズ調整 */
657 ret = AdjustTrackSize(drive, discinfo, track_num, lout_start);
658 if(ret!=RET_OK){
659 MemFree(discinfo->cdtext);
660 discinfo->cdtext = NULL;
661 MemFree(discinfo->trackinfo);
662 discinfo->trackinfo = NULL;
663 return ret;
664 }
665 /* ディスク最終アドレス更新 */
666 if(cpti->trackinfo.nwa_valid){
667 if(Get4bytes(cpti->trackinfo.next_writable_addr) > Get4bytes(cpti->trackinfo.track_start))
668 last_addr = Get4bytes(cpti->trackinfo.next_writable_addr);
669 }
670 else{
671 last_addr = Get4bytes(cpti->trackinfo.track_start) +
672 Get4bytes(cpti->trackinfo.track_size);
673 }
674 }
675 discinfo->last_addr = last_addr;
676
677 if(DT_DVD_FAMILY(drive->disc_type) && discinfo->tracks>1){
678 /* DVDのDAOでは複数トラック記録できない */
679 if(GetOption()->dao){
680 /* トラックが複数存在するので DAO 記録できません。\nTAO で記録を続行しますか?" */
681 ret = UIDispMessage(MSG_CANT_DAO,
682 UIDMT_QUESTION);
683 if(ret!=UIDMRET_OK){
684 MemFree(discinfo->cdtext);
685 discinfo->cdtext = NULL;
686 MemFree(discinfo->trackinfo);
687 discinfo->trackinfo = NULL;
688 return RET_ABORT;
689 }
690 GetOption()->dao = FALSE;
691 }
692 }
693
694 UIMeter1Initialize(MSG_TOTAL /*"全体"*/);
695 if(drive->type==CMDDRVTYPE_NET){
696 NAUIMeter1Initialize(&drive->u.net, MSG_TOTAL /*"全体"*/);
697 }
698
699 return RET_OK;
700 }
701
702 /**
703 * ディスク情報取得
704 * @param[in] drive 読取装置構造体
705 * @param[out] discinfo ディスク情報
706 * @retval RET_OK 正常終了
707 * @retval RET_NG エラー
708 */
709 int GetDiscInformation(CMDDRIVE *drive, CPDISCINFO *discinfo)
710 {
711 int ret;
712
713 memset(discinfo, 0, sizeof(CPDISCINFO));
714 if(!REALDRIVE(drive)){
715 if(drive->type == CMDDRVTYPE_MKISOFS){
716 /* フォルダからのISOイメージ(mkisofs)の場合 */
717 ret = GetDiscInformationMkisofs(drive, discinfo);
718 if(ret != RET_OK){
719 return ret;
720 }
721 }
722 else if(drive->type == CMDDRVTYPE_ISO){
723 /* ISOイメージファイルの場合 */
724 ret = GetDiscInformationISO(drive, discinfo);
725 if(ret != RET_OK){
726 return ret;
727 }
728 }
729 else if(drive->type == CMDDRVTYPE_IMAGE){
730 /* イメージファイル(emg)からディスク情報を得る */
731 ret = GetDiscInformationImage(drive, discinfo);
732 if(ret != RET_OK){
733 return ret;
734 }
735 }
736 }
737 else{
738 /* 実ドライブから情報取得 */
739 ret = GetDiscInformationDrive(drive, discinfo);
740 if(ret != RET_OK){
741 return ret;
742 }
743 }
744
745 return RET_OK;
746 }

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