Develop and Download Open Source Software

Browse CVS Repository

Contents of /enbanfukusyaya/EnbanKensa/common/check.c

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


Revision 1.14 - (show annotations) (download) (as text)
Sat Dec 2 14:00:19 2006 UTC (17 years, 4 months ago) by bananajinn
Branch: MAIN
CVS Tags: HEAD
Changes since 1.13: +10 -10 lines
File MIME type: text/x-csrc
*** empty log message ***

1 /**
2 * ‰~”Ő•ĄŽĘ‰Ž - EnbanKensa
3 * Copyright (C) 2005 Kagetani Hideto
4 * check.c - ŒŸ¸
5 * $Date: 2006/05/27 16:04:59 $
6 * $Revision: 1.13 $
7 */
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #if defined(__APPLE__) && defined(__MACH__)
12 # include <Carbon/Carbon.h>
13 #else
14 # include <sys/timeb.h>
15 #endif
16
17 #include "check.h"
18 #include "drive.h"
19 #include "cmd.h"
20 #include "struct.h"
21 #include "option.h"
22 #include "ui.h"
23 #include "text.h"
24 #include "ebstring.h"
25
26 #if defined(WIN32)
27 # define snprintf _snprintf
28 #endif
29
30 #define D_MARGIN_LEFT (8*4)
31 #define D_MARGIN_RIGHT (8*6)
32 #define D_MARGIN_TOP (8*2)
33 #define D_MARGIN_BOTTOM (8*2)
34
35 #define D_COL_BASELINE 0xffff, 0xffff, 0xffff
36 #define D_COL_TRANSRATE 0x0000, 0x7fff, 0xffff
37 #define D_COL_TRANSRATE_GRID 0x0000, 0x3fff, 0x7fff
38 #define D_COL_ERRORRATE 0x7fff, 0xffff, 0x0000
39 #define D_COL_ERRORRATE_GRID 0x3fff, 0x7fff, 0x0000
40 #define D_COL_ERRORLINE 0xffff, 0x0000, 0x0000
41 #define D_COL_ADDRESSLINE 0x7fff, 0x7fff, 0x7fff
42 #define D_COL_TEXT 0xffff, 0xffff, 0xffff
43 #define D_COL_BACK 0x0000, 0x0000, 0x0000
44 #define D_COL_DISABLED 0x2fff, 0x4fff, 0x4fff
45
46 typedef struct {
47 WORD track;
48 WORD session;
49 DWORD start_lba;
50 DWORD end_lba;
51 DWORD blocks;
52 BYTE track_mode;
53 BYTE data_mode;
54 BYTE fp:1;
55 BYTE packet:1;
56 BYTE damage;
57 BYTE blank:1;
58 BYTE res:4;
59 DWORD packet_size;
60 } TRACKINFO;
61
62 typedef struct {
63 TRACKINFO *tracks;
64 WORD num_track;
65 DWORD last_lba;
66 } DISCINFO;
67
68 typedef struct {
69 DWORD lba;
70 float trans_rate;
71 float error_rate;
72 } RATES;
73
74 typedef struct {
75 RATES *rates;
76 int num_rates;
77 } TRACKRESULT;
78
79 typedef struct {
80 TRACKRESULT *track_result;
81 int num_track;
82 float max_trans_rate; /* •\ŽŚĹ‘ĺ”{‘Ź */
83 float max_error_rate; /* •\ŽŚĹ‘ĺƒGƒ‰[—Ś(%) */
84 BOOL c2_error; /* C2ƒGƒ‰[”­ś */
85 BOOL read_error; /* “ǂݎć‚čƒGƒ‰[”­ś */
86 } RESULTINFO;
87
88 static struct _DRAWAREA {
89 int width;
90 int height;
91 } g_drawArea;
92
93 static BYTE g_zero294[294];
94
95 static int OpenDevice(CMDDRIVE *drive, DRIVEID *id, BOOL bWaitDisc)
96 {
97 int ret;
98 DWORD timeout=5*60;
99
100 ret = InitializeCmdDrive(drive, 0x10000);
101 if(ret!=RET_OK){
102 return ret;
103 }
104 ret = SetDriveAspiSetting(drive, &id->hid, &id->tid, &timeout);
105 if(ret!=RET_OK){
106 return ret;
107 }
108
109 ret = GetDiscType(drive, &drive->disc_type, bWaitDisc);
110 if(ret!=RET_OK){
111 if(ret!=RET_ABORT && bWaitDisc){
112 UIDispMessage(MSG_CANT_GET_DISC_TYPE
113 /*"ƒfƒBƒXƒNƒ^ƒCƒvŽć“ž‚ÉŽ¸”s‚ľ‚Ü‚ľ‚˝B"*/, UIDMT_ERROR);
114 }
115 FreeCmdDrive(drive);
116 return ret;
117 }
118 ret = SendPreventAllow(drive, 1);
119 if(ret!=RET_OK){
120 DispCommandError(drive);
121 FreeCmdDrive(drive);
122 return ret;
123 }
124
125 return RET_OK;
126 }
127
128 static void CloseDevice(CMDDRIVE *drive)
129 {
130 SendPreventAllow(drive, 0);
131 FreeCmdDrive(drive);
132 }
133
134 static DWORD GetEndLbaByTrackInfo(CMDDRIVE *drive, struct _TRACKINFO *ti)
135 {
136 int ret;
137 DWORD start_lba;
138 DWORD end_lba;
139
140 start_lba = Get4bytes(ti->track_start);
141
142 if(ti->blank != 0){
143 end_lba = start_lba;
144 }
145 else{
146 end_lba =
147 Get4bytes(ti->track_start) +
148 Get4bytes(ti->track_size) -
149 Get4bytes(ti->free_blocks) -1;
150
151 if(DT_CD_FAMILY(drive->disc_type)){
152 /* CD‚Ěę‡AĹŒă‚Ě2ƒuƒƒbƒN‚đ READ ‚ľ‚Ä Run-out ‚Š‚Ç‚¤‚Š‚đŠm”F */
153 ret = SendReadCD(drive, end_lba-1, 2);
154 if(ret == RET_CMDERR){
155 end_lba -= 2;
156 }
157 }
158 }
159
160 return end_lba;
161 }
162
163 static RESULTINFO *FreeResultInfo(RESULTINFO *resultInfo)
164 {
165 WORD track;
166
167 if(resultInfo == NULL){
168 return NULL;
169 }
170
171 for(track=0; track<resultInfo->num_track; track++){
172 if(resultInfo->track_result[track].rates != NULL){
173 free(resultInfo->track_result[track].rates);
174 }
175 }
176 free(resultInfo->track_result);
177 free(resultInfo);
178 return NULL;
179 }
180
181 static RESULTINFO *AllocInitResultInfo(DISCINFO *discInfo, DWORD readBlock)
182 {
183 RESULTINFO *resultInfo;
184 WORD trackIndex;
185 TRACKINFO *trackInfo;
186 RATES *rates;
187 int numRates;
188
189 resultInfo = (RESULTINFO *)malloc(sizeof(RESULTINFO));
190 if(resultInfo == NULL){
191 return NULL;
192 }
193
194 memset(resultInfo, 0, sizeof(RESULTINFO));
195
196 resultInfo->track_result =
197 (TRACKRESULT *)malloc(sizeof(TRACKRESULT)*discInfo->num_track);
198 if(resultInfo->track_result == NULL){
199 free(resultInfo);
200 return NULL;
201 }
202 memset(resultInfo->track_result, 0, sizeof(TRACKRESULT)*discInfo->num_track);
203 resultInfo->num_track = discInfo->num_track;
204
205 for(trackIndex=0; trackIndex<discInfo->num_track; trackIndex++){
206 trackInfo = &discInfo->tracks[trackIndex];
207 if(trackInfo->start_lba < trackInfo->end_lba){
208 numRates =
209 ((trackInfo->end_lba-trackInfo->start_lba)+readBlock-1)/readBlock;
210 /* 1‚‘˝‚߂Ƀƒ‚ƒŠŠm•Ű‚ľ‚Ä‚¨‚ą‚¤‚Á‚Ć */
211 rates = (RATES *)malloc(sizeof(RATES)*(numRates+1));
212 if(rates == NULL){
213 FreeResultInfo(resultInfo);
214 return NULL;
215 }
216 memset(rates, 0, sizeof(RATES)*numRates);
217
218 resultInfo->track_result[trackIndex].rates = rates;
219 resultInfo->track_result[trackIndex].num_rates = numRates;
220 }
221 }
222
223 return resultInfo;
224 }
225
226
227 static DISCINFO *FreeDiscInfo(DISCINFO *discInfo)
228 {
229 if(discInfo == NULL){
230 return NULL;
231 }
232
233 if(discInfo->tracks != NULL){
234 free(discInfo->tracks);
235 }
236
237 free(discInfo);
238 return NULL;
239 }
240
241 static DISCINFO *AllocInitDiscInfo()
242 {
243 DISCINFO *discInfo;
244
245 discInfo = (DISCINFO *)malloc(sizeof(DISCINFO));
246 if(discInfo == NULL){
247 return NULL;
248 }
249
250 memset(discInfo, 0, sizeof(DISCINFO));
251
252 return discInfo;
253 }
254
255 static int MakeDiscInfo(CMDDRIVE *drive, DISCINFO **discInfoRet)
256 {
257 int ret;
258 DISCINFO *discInfo;
259 TRACKINFO *trackInfo;
260 struct _DISCINFO *di;
261 struct _TRACKINFO ti;
262 WORD last_track;
263 WORD curr_track;
264
265 discInfo = AllocInitDiscInfo();
266 if(discInfo==NULL){
267 return RET_MEMERR;
268 }
269
270 *discInfoRet = discInfo;
271
272 ret = SendReadDiscInfo(drive);
273 if(ret != RET_OK){
274 return ret;
275 }
276 di = (struct _DISCINFO *)drive->data_buf;
277 if(di->disc_status == DISCSTAT_EMPTY){
278 UIDispMessage(MSG_INS_MEDIA_IS_BLANK
279 /*"‘}“ü‚ł‚ę‚˝ƒfƒBƒXƒN‚Í–˘‹L˜^ƒfƒBƒXƒN‚Ĺ‚ˇB"*/, UIDMT_ERROR);
280 return RET_ABORT;
281 }
282 last_track =
283 ((WORD)di->last_track_ls_msb << 8) |
284 (WORD)di->last_track_ls_lsb;
285 trackInfo = (TRACKINFO *)malloc(sizeof(TRACKINFO)*last_track);
286 if(trackInfo == NULL){
287 *discInfoRet = FreeDiscInfo(discInfo);
288 return RET_MEMERR;
289 }
290 memset(trackInfo, 0, sizeof(TRACKINFO)*last_track);
291 discInfo->num_track = last_track;
292 discInfo->tracks = trackInfo;
293
294 for(curr_track=1; curr_track<=last_track; curr_track++){
295 UIDispInfo(MSG_MAKING_DISCINFO_, curr_track, last_track);
296 if(UICheckAbort()){
297 *discInfoRet = FreeDiscInfo(discInfo);
298 return RET_ABORT;
299 }
300 ret = SendReadTrackInfo(drive, curr_track);
301 if(ret != RET_OK){
302 *discInfoRet = FreeDiscInfo(discInfo);
303 return RET_MEMERR;
304 }
305 memcpy(&ti, drive->data_buf, sizeof(struct _TRACKINFO));
306 trackInfo[curr_track-1].session =
307 ((WORD)ti.session_number_msb << 8) |
308 (WORD)ti.session_number_lsb;
309 trackInfo[curr_track-1].track =
310 ((WORD)ti.track_number_msb << 8) |
311 (WORD)ti.track_number_lsb;
312 trackInfo[curr_track-1].start_lba = Get4bytes(ti.track_start);
313 trackInfo[curr_track-1].end_lba = GetEndLbaByTrackInfo(drive, &ti);
314 trackInfo[curr_track-1].blocks = Get4bytes(ti.track_size);
315 trackInfo[curr_track-1].track_mode = ti.track_mode;
316 trackInfo[curr_track-1].data_mode = ti.data_mode;
317 trackInfo[curr_track-1].fp = ti.fp;
318 trackInfo[curr_track-1].packet = ti.packet;
319 trackInfo[curr_track-1].damage = ti.damage;
320 trackInfo[curr_track-1].blank = ti.blank;
321 trackInfo[curr_track-1].packet_size = Get4bytes(ti.packet_size);
322 if(trackInfo[curr_track-1].start_lba < trackInfo[curr_track-1].end_lba){
323 discInfo->last_lba = trackInfo[curr_track-1].end_lba;
324 }
325 }
326
327 return RET_OK;
328 }
329
330 static void DrawGridLines(CMDDRIVE *drive, DISCINFO *discInfo,
331 float maxTransRate, float maxErrorRate)
332 {
333 DWORD maxAddress = discInfo->last_lba;
334 int x0, y0, x1, y1;
335 int width;
336 int xx, yy;
337 int i, skipMask;
338 char textBuf[16];
339 UICOLOR baseLineColor = { D_COL_BASELINE };
340 UICOLOR transRateColor = { D_COL_TRANSRATE_GRID };
341 UICOLOR errorRateColor = { D_COL_ERRORRATE_GRID };
342 UICOLOR addressLineColor = { D_COL_ADDRESSLINE };
343 UICOLOR textColor = { D_COL_TEXT };
344 UICOLOR backColor = { D_COL_BACK };
345 UICOLOR disableColor = { D_COL_DISABLED };
346
347 /* ‘SÁ‹Ž */
348 UIDrawBox(0, 0, g_drawArea.width-1, g_drawArea.height-1, &backColor, TRUE);
349
350 /* Šî–{Ŕ•WÝ’č */
351 x0 = D_MARGIN_LEFT;
352 y0 = D_MARGIN_TOP;
353 x1 = g_drawArea.width-D_MARGIN_RIGHT;
354 y1 = g_drawArea.height-D_MARGIN_BOTTOM;
355 width = g_drawArea.width-D_MARGIN_LEFT-D_MARGIN_RIGHT;
356
357 /* READ•s‰Â—Ěˆć‚Ě•\ŽŚ */
358 for(i=1; i<discInfo->num_track; i++){
359 if((discInfo->tracks[i-1].end_lba+1 < discInfo->tracks[i].start_lba) &&
360 (discInfo->tracks[i].start_lba < discInfo->tracks[i].end_lba)){
361 UIDrawBox(x0+width*discInfo->tracks[i-1].end_lba/maxAddress, y0,
362 x0+width*discInfo->tracks[i].start_lba/maxAddress, y1,
363 &disableColor, TRUE);
364 }
365 }
366
367 /* X•űŒü‚̖ڐˇ‚č */
368 for(i=1; i<=4; i++){
369 xx = x0+(x1-x0)*i/4;
370 UIDrawLine(xx, y0, xx, y1, &addressLineColor);
371 }
372 /* “]‘—‘Ź“x‚̖ڐˇ‚č */
373 if(maxTransRate > 64){
374 skipMask = 7;
375 }
376 else if(maxTransRate > 32){
377 skipMask = 3;
378 }
379 else if(maxTransRate > 16){
380 skipMask = 1;
381 }
382 else{
383 skipMask = 0;
384 }
385 for(i=1; i<=maxTransRate; i++){
386 if((i&skipMask) != 0){
387 continue;
388 }
389 yy = (int)(y1-i*(y1-y0)/maxTransRate);
390 UIDrawLine(x0, yy, x1, yy, &transRateColor);
391 sprintf(textBuf, "%2dx", i);
392 UIDrawText(0, yy, &textColor, textBuf);
393 }
394 if(maxErrorRate > 0){
395 /* ƒGƒ‰[ƒŒ[ƒg‚̖ڐˇ‚č */
396 for(i=1; i<=4; i++){
397 yy = y1-(y1-y0)*i/4;
398 UIDrawLine(x0, yy, x1, yy, &errorRateColor);
399 sprintf(textBuf, "%.3f%%", maxErrorRate*i/4);
400 UIDrawText(x1, yy, &textColor, textBuf);
401 }
402 }
403
404 /* Šî–{ޞ */
405 UIDrawLine(x0, y1, x1, y1, &baseLineColor);
406 UIDrawLine(x0, y0, x0, y1, &baseLineColor);
407
408 UIDrawText(x0-8, y1, &textColor, "0");
409 sprintf(textBuf, "0x%08lX", maxAddress);
410 UIDrawText(x1-80, y1, &textColor, textBuf);
411
412 }
413
414 static void DrawTransRateLine(RATES *r1, RATES *r2,
415 float maxTransRate, DWORD maxAddress)
416 {
417 int x0, y0, x1, y1;
418 int baseY = g_drawArea.height-D_MARGIN_BOTTOM;
419 int width, height;
420 UICOLOR color = { D_COL_TRANSRATE };
421 UICOLOR errColor = { D_COL_ERRORLINE };
422
423 if((r1->lba == 0) || (r2->lba == 0)){
424 return;
425 }
426
427 width = g_drawArea.width-D_MARGIN_LEFT-D_MARGIN_RIGHT;
428 height = g_drawArea.height-D_MARGIN_TOP-D_MARGIN_BOTTOM;
429 x0 = (int)(D_MARGIN_LEFT + width*r1->lba/maxAddress);
430 x1 = (int)(D_MARGIN_LEFT + width*r2->lba/maxAddress);
431 y0 = (int)(baseY - height*r1->trans_rate/maxTransRate);
432 y1 = (int)(baseY - height*r2->trans_rate/maxTransRate);
433 UIDrawLine(x0, y0, x1, y1,
434 (r2->trans_rate==0) ? &errColor : &color);
435 }
436
437 static void DrawErrorRateLine(RATES *r1, RATES *r2,
438 float maxErrorRate, DWORD maxAddress)
439 {
440 int x0, y0, x1, y1;
441 int baseY = g_drawArea.height-D_MARGIN_BOTTOM;
442 int width, height;
443 UICOLOR color = { D_COL_ERRORRATE };
444 UICOLOR errColor = { D_COL_ERRORLINE };
445
446 if(maxErrorRate==0){
447 return;
448 }
449 if((r1->lba == 0) || (r2->lba == 0)){
450 return;
451 }
452
453 width = g_drawArea.width-D_MARGIN_LEFT-D_MARGIN_RIGHT;
454 height = g_drawArea.height-D_MARGIN_TOP-D_MARGIN_BOTTOM;
455
456 x0 = (int)(D_MARGIN_LEFT + width*r1->lba/maxAddress);
457 x1 = (int)(D_MARGIN_LEFT + width*r2->lba/maxAddress);
458 y0 = (int)(baseY - height*r1->error_rate/maxErrorRate);
459 y1 = (int)(baseY - height*r2->error_rate/maxErrorRate);
460 UIDrawLine(x0, y0, x1, y1,
461 (r2->trans_rate==0) ? &errColor : &color);
462 }
463
464 static void DrawTransRateLineTrack(RATES *rates, int count,
465 float maxTransRate, DWORD maxAddress)
466 {
467 int i;
468
469 for(i=0; i<count; i++){
470 DrawTransRateLine(&rates[i], &rates[i+1], maxTransRate, maxAddress);
471 }
472 }
473
474 static void DrawTransRateLineAll(RESULTINFO *resultInfo, WORD trackCount,
475 DWORD maxAddress)
476 {
477 WORD trackIndex;
478
479 for(trackIndex=0; trackIndex<trackCount; trackIndex++){
480 DrawTransRateLineTrack(resultInfo->track_result[trackIndex].rates,
481 resultInfo->track_result[trackIndex].num_rates-1,
482 resultInfo->max_trans_rate, maxAddress);
483 }
484 }
485
486 static void DrawErrorRateLineTrack(RATES *rates, int count,
487 float maxErrorRate, DWORD maxAddress)
488 {
489 int i;
490
491 if(maxErrorRate==0){
492 return;
493 }
494
495 for(i=0; i<count; i++){
496 DrawErrorRateLine(&rates[i], &rates[i+1], maxErrorRate, maxAddress);
497 }
498 }
499
500 static void DrawErrorRateLineAll(RESULTINFO *resultInfo, WORD trackCount,
501 DWORD maxAddress)
502 {
503 WORD trackIndex;
504
505 for(trackIndex=0; trackIndex<trackCount; trackIndex++){
506 DrawErrorRateLineTrack(resultInfo->track_result[trackIndex].rates,
507 resultInfo->track_result[trackIndex].num_rates-1,
508 resultInfo->max_error_rate, maxAddress);
509 }
510 }
511
512 static void UpdateScreen(CMDDRIVE *drive, DISCINFO *discInfo,
513 RESULTINFO *resultInfo,
514 WORD trackIndex, int current, BOOL drawCurrent)
515 {
516 DWORD maxAddress = discInfo->last_lba;
517 BOOL resetGrids = FALSE;
518 RATES *rates = resultInfo->track_result[trackIndex].rates;
519
520 if(rates[current].trans_rate > resultInfo->max_trans_rate){
521 /* ‰ć–Ęă•”‚đ‚͂ݏo‚éę‡ */
522 resultInfo->max_trans_rate = (float)((int)rates[current].trans_rate + 2);
523 resetGrids = TRUE;
524 }
525 if(resultInfo->max_error_rate > 0){
526 if(rates[current].error_rate > resultInfo->max_error_rate){
527 /* ‰ć–Ęă•”‚đ‚͂ݏo‚éę‡ */
528 resultInfo->max_error_rate = (float)(rates[current].error_rate + 0.01);
529 resetGrids = TRUE;
530 }
531 }
532
533 if(resetGrids){
534 DrawGridLines(drive, discInfo,
535 resultInfo->max_trans_rate, resultInfo->max_error_rate);
536 DrawTransRateLineAll(resultInfo, trackIndex, maxAddress);
537 DrawTransRateLineTrack(rates, current,
538 resultInfo->max_trans_rate, maxAddress);
539 if(resultInfo->max_error_rate > 0){
540 DrawErrorRateLineAll(resultInfo, trackIndex, maxAddress);
541 DrawErrorRateLineTrack(rates, current,
542 resultInfo->max_error_rate, maxAddress);
543 }
544 }
545 else{
546 if((current > 0) && drawCurrent){
547 DrawTransRateLine(&rates[current-1], &rates[current],
548 resultInfo->max_trans_rate, maxAddress);
549 if(resultInfo->max_error_rate > 0){
550 DrawErrorRateLine(&rates[current-1], &rates[current],
551 resultInfo->max_error_rate, maxAddress);
552 }
553 }
554 }
555 }
556
557 static DWORD GetMilliSec()
558 {
559 #if defined(__APPLE__) && defined(__MACH__)
560 UnsignedWide gms;
561 Microseconds(&gms);
562 return gms.lo/1000;
563 #elif defined(WIN32)
564 return timeGetTime();
565 #else
566 struct timeb t;
567 ftime(&t);
568 return (DWORD)t.time*1000+t.millitm;
569 #endif
570 }
571
572 static DWORD CountC2ErrorBits(const BYTE *ptr)
573 {
574 DWORD count=0;
575 int index;
576 const BYTE bitCount[] = {
577 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
578 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
579 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
580 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
581 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
582 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
583 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
584 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
585 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
586 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
587 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
588 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
589 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
590 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
591 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
592 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
593 };
594
595 for(index=0; index<294; index++, ptr++){
596 count += bitCount[*ptr];
597 }
598
599 return count;
600 }
601
602 static int GetErrorRate(CMDDRIVE *drive, DWORD lba, DWORD len,
603 float *errorRate)
604 {
605 int ret;
606 DWORD block;
607 BYTE cdb[12];
608 DWORD errorCount=0;
609
610 *errorRate = 0.0;
611 memset(cdb, 0, sizeof(cdb));
612 cdb[0] = CMD_READ_CD;
613 Set4bytes(cdb+2, lba);
614 Set3bytes(cdb+6, len);
615 cdb[9] = 0x04;
616 ret = SendCmd(drive, cdb, len*296, REQ_DATAIN);
617 if(ret == RET_OK){
618 for(block=0; block<len; block++){
619 #if 0
620 if(memcmp(drive->data_buf+294*block+2, g_zero294, 294)!=0){
621 errorCount += 2352;
622 }
623 #else
624 errorCount += CountC2ErrorBits(drive->data_buf+294*block+2);
625 #endif
626 }
627 if(errorCount > 0){
628 *errorRate = (float)(100.0*errorCount/(len*2352));
629 }
630 }
631
632 return ret;
633 }
634
635 static int ReadCheck(CMDDRIVE *drive, DWORD lba, DWORD blocks,
636 DWORD *readTime, float *errorRate, DWORD *lastTime)
637 {
638 int ret;
639 DWORD startTime;
640 BOOL measureErrorRate=(DT_CD_FAMILY(drive->disc_type) && (errorRate!=NULL));
641 DWORD len = 20;
642 DWORD totalBlocks = blocks;
643 float totalErrorRate = 0;
644
645 if(*lastTime != 0){
646 startTime = *lastTime;
647 }
648 else{
649 startTime = GetMilliSec();
650 }
651
652 while(blocks > 0){
653 if(blocks < len){
654 len = blocks;
655 }
656 if(measureErrorRate){
657 ret = GetErrorRate(drive, lba, len, errorRate);
658 if(ret != RET_OK){
659 return ret;
660 }
661 totalErrorRate += (*errorRate) * len;
662 }
663 else if(DT_CD_FAMILY(drive->disc_type)){
664 ret = SendReadCD(drive, lba, len);
665 if(ret != RET_OK){
666 return ret;
667 }
668 }
669 else{
670 ret = SendRead10(drive, lba, (WORD)len, len*2048);
671 if(ret != RET_OK){
672 return ret;
673 }
674 }
675
676 lba += len;
677 blocks -= len;
678 }
679
680 *lastTime = GetMilliSec();
681 *readTime = *lastTime-startTime;
682
683 if(measureErrorRate){
684 *errorRate = totalErrorRate/totalBlocks;
685 }
686
687 return RET_OK;
688 }
689
690
691 static int ReadLoopRange(CMDDRIVE *drive,
692 DISCINFO *discInfo, RESULTINFO *resultInfo,
693 WORD trackIndex, int start_pos,
694 DWORD startLba, DWORD endLba, DWORD readBlockParam,
695 DWORD dummyStart)
696 {
697 int ret;
698 DWORD readBlock = readBlockParam;
699 DWORD lba = startLba;
700 float errorRate=0;
701 int baseRateKBS = DT_CD_FAMILY(drive->disc_type) ? 150 : 1385;
702 TRACKINFO *trackInfo = &discInfo->tracks[trackIndex];
703 TRACKRESULT *trackResult = &resultInfo->track_result[trackIndex];
704 RATES *rates = trackResult->rates;
705 DWORD readTime, lastTime=0;
706 char buf[80];
707 int current = start_pos;
708
709 ret = ReadCheck(drive, dummyStart,
710 ((dummyStart < lba) ? lba-dummyStart : 1),
711 &readTime, &errorRate, &lastTime);
712 if(dummyStart >= lba){
713 lastTime=0;
714 }
715 for(; current<trackResult->num_rates; current++){
716 if(UICheckAbort()){
717 return RET_ABORT;
718 }
719 if(lba >= endLba){
720 trackResult->num_rates = current;
721 break;
722 }
723
724 if((endLba-lba) < readBlock){
725 readBlock = endLba-lba;
726 }
727 else if((endLba-lba-readBlock) < readBlock/2){
728 /*
729 * Žc‚肪’ʏí“ǂݎć‚čƒTƒCƒY‚Ě”ź•Ş–˘–ž‚ɂȂéę‡A
730 * Žc‚č‚đ‘S‚ēǂݍž‚ށB
731 */
732 readBlock = endLba-lba;
733 }
734
735 ret = ReadCheck(drive, lba, readBlock, &readTime, &errorRate, &lastTime);
736 if((ret != RET_OK) && (ret != RET_CMDERR)){
737 return ret;
738 }
739 rates[current].lba = lba+readBlock/2;
740 if(ret == RET_CMDERR){
741 rates[current].trans_rate = 0;
742 readTime = 0;
743 resultInfo->read_error = TRUE;
744 }
745 else{
746 if((current > 0) && (readBlock < readBlockParam/16)){
747 /* “ǂݎć‚č•‚Ş‹ˇ‚ˇ‚Ź‚éę‡‚ÍŒëˇ‚Ş‘ĺ‚Ť‚˘‚Ě‚ĹŒë–‚‰ť‚ˇ */
748 rates[current].trans_rate = rates[current-1].trans_rate;
749 }
750 else{
751 rates[current].trans_rate =
752 (float)(readBlock*2.0*1000/readTime/baseRateKBS);
753 }
754 }
755 rates[current].error_rate = errorRate;
756 if(errorRate > 0){
757 resultInfo->c2_error = TRUE;
758 }
759 UpdateScreen(drive, discInfo,
760 resultInfo, trackIndex, current, (current>start_pos));
761
762 /* “ǂݎć‚čŒ‹‰Ę‚É‚ć‚Á‚Ä•\ŽŚî•ń•śŽš—ń‚đěŹ‚ˇ‚é */
763 if(ret != RET_OK){
764 snprintf(buf, sizeof(buf), MSG_STATUS_STRING_READ_NG_
765 /*"ƒgƒ‰ƒbƒN=%d ”Ô’n=0x%08lX “ǂݎć‚莸”s"*/,
766 trackInfo->track, rates[current].lba);
767 }
768 else{
769 snprintf(buf, sizeof(buf), MSG_STATUS_STRING_
770 /*"ƒgƒ‰ƒbƒN=%d ”Ô’n=0x%08lX %.1f”{‘Ź “ǎ掞ŠÔ=%ldms"*/,
771 trackInfo->track,
772 rates[current].lba,
773 rates[current].trans_rate, readTime);
774 if(rates[current].error_rate > 0){
775 snprintf(buf+strlen(buf), sizeof(buf)-strlen(buf), " C2Error=%.2f",
776 rates[current].error_rate);
777 }
778 }
779
780 UIDispInfo(buf);
781
782 lba += readBlock;
783 }
784
785 return RET_OK;
786 }
787
788 static int ReadLoop(CMDDRIVE *drive,
789 DISCINFO *discInfo, RESULTINFO *resultInfo,
790 WORD trackIndex, DWORD readBlock)
791 {
792 int ret;
793 TRACKINFO *trackInfo;
794 TRACKRESULT *trackResult, *lastTrackResult;
795 /* DWORD maxAddress = discInfo->last_lba;*/
796 DWORD lba, dummyStart;
797 int current;
798 int rangeIndex;
799 struct _LBARANGE {
800 DWORD start, end;
801 int start_pos; /* RATES”z—ń‚ĚˆĘ’u */
802 } lbaRange[3];
803
804 if(trackIndex >= discInfo->num_track){
805 return RET_OK;
806 }
807 if(trackIndex >= resultInfo->num_track){
808 return RET_OK;
809 }
810 trackInfo = &discInfo->tracks[trackIndex];
811 trackResult = &resultInfo->track_result[trackIndex];
812 if(trackInfo->start_lba >= trackInfo->end_lba){
813 return RET_OK;
814 }
815 lba = trackInfo->start_lba;
816
817 memset(g_zero294, 0, sizeof(g_zero294));
818
819 current=0;
820 if(trackIndex > 0){
821 /* ’ź‘O‚Ěƒgƒ‰ƒbƒN‚Ć‚Â‚Č‚Ş‚Á‚Ä‚˘‚邊‚Ç‚¤‚ŠŠm”F‚ˇ‚é */
822 if(trackInfo->start_lba == (discInfo->tracks[trackIndex-1].end_lba+1)){
823 /*
824 * ˜A‘ą‚ľ‚ÄREAD‰Â”\‚Č‚çA•\ŽŚă‚͐ü‚ĹŒ‹‚Ô‚˝‚ß‚É
825 * ’ź‘Oƒgƒ‰ƒbƒN‚̍ŏIŒ‹‰Ę‚đĄ‰ń‚̍ŏ‰‚ĚŒ‹‰Ę‚Ć‚ˇ‚éB
826 */
827 lastTrackResult = &resultInfo->track_result[trackIndex-1];
828 if(lastTrackResult->num_rates > 0){
829 memcpy(&trackResult->rates[current],
830 &lastTrackResult->rates[lastTrackResult->num_rates-1],
831 sizeof(RATES));
832 current++;
833 }
834 }
835 }
836
837 if(GetOption()->out2in){
838 lbaRange[0].start = trackInfo->start_lba;
839 lbaRange[0].end =
840 (trackInfo->end_lba - trackInfo->start_lba)/3/readBlock*readBlock-1;
841 lbaRange[0].start_pos = current;
842 lbaRange[1].start = lbaRange[0].end+1;
843 lbaRange[1].end =
844 (trackInfo->end_lba - trackInfo->start_lba)*2/3/readBlock*readBlock-1;
845 lbaRange[1].start_pos = (lbaRange[1].start-trackInfo->start_lba)/readBlock;
846 lbaRange[2].start = lbaRange[1].end+1;
847 lbaRange[2].end = trackInfo->end_lba;
848 lbaRange[2].start_pos = (lbaRange[2].start-trackInfo->start_lba)/readBlock;
849 /* overlap */
850 lbaRange[0].end += readBlock;
851 lbaRange[1].end += readBlock;
852
853 for(rangeIndex=2; rangeIndex>=0; rangeIndex--){
854 if(rangeIndex == 0){
855 dummyStart = lbaRange[rangeIndex].start;
856 }
857 else if((lbaRange[rangeIndex].start - trackInfo->start_lba) > 0x200){
858 dummyStart = lbaRange[rangeIndex].start-0x200;
859 }
860 else{
861 dummyStart = trackInfo->start_lba;
862 }
863
864 ret = ReadLoopRange(drive, discInfo, resultInfo, trackIndex,
865 lbaRange[rangeIndex].start_pos,
866 lbaRange[rangeIndex].start,
867 lbaRange[rangeIndex].end,
868 readBlock, dummyStart);
869 if(ret != RET_OK){
870 return ret;
871 }
872 }
873 }
874 else{
875 ret = ReadLoopRange(drive, discInfo, resultInfo, trackIndex, current,
876 trackInfo->start_lba, trackInfo->end_lba, readBlock,
877 trackInfo->start_lba);
878 if(ret != RET_OK){
879 return ret;
880 }
881 }
882
883 return RET_OK;
884 }
885
886 static int SetReadRetryCount(CMDDRIVE *drive,
887 BYTE count, BYTE *currentCountReturn)
888 {
889 int ret;
890 struct _MODEPAGE01 *mp01;
891
892 ret = SendModeSense(drive, MSPC_CURRENT, 1);
893 if(ret != RET_OK){
894 return ret;
895 }
896 mp01 = (struct _MODEPAGE01 *)
897 (drive->data_buf + (drive->cmd_type==CMDDRVCTYPE_ATAPI ? 8 : 16));
898 if(currentCountReturn != NULL){
899 *currentCountReturn = mp01->rd_retry_count;
900 }
901 mp01->rd_retry_count = count;
902 ret = SendModeSelect(drive, 1);
903 if(ret != RET_OK){
904 return ret;
905 }
906
907 return RET_OK;
908 }
909
910
911 /**
912 * ƒ`ƒFƒbƒNŽŔs
913 * @param[in] drive ‘•’u
914 * @param[out] c2Error C2ƒGƒ‰[‚Ş‚ ‚Á‚˝‚Š‚Ç‚¤‚Š
915 * @param[out] readError “ǂݎć‚čƒGƒ‰[‚Ş‚ ‚Á‚˝‚Š‚Ç‚¤‚Š
916 * @retval RET_OK łíI—š
917 * @retval ‚ť‚Ě‘ź ƒGƒ‰[
918 */
919 static int ExecCheck(CMDDRIVE *drive, BOOL *c2Error, BOOL *readError)
920 {
921 int ret;
922 int width, height;
923 BYTE oldRetryCount;
924 DISCINFO *discInfo=NULL;
925 RESULTINFO *resultInfo=NULL;
926 WORD trackIndex;
927 DWORD readBlock;
928
929 /* ƒfƒBƒXƒNî•ń\‘˘‘Ě‚Ě€”ő */
930 ret = MakeDiscInfo(drive, &discInfo);
931 if(ret != RET_OK){
932 return ret;
933 }
934
935 ret = SetOption(drive, discInfo->num_track);
936 if(ret != RET_OK){
937 discInfo = FreeDiscInfo(discInfo);
938 return ret;
939 }
940
941 readBlock = DT_CD_FAMILY(drive->disc_type) ? 1024 : 4096;
942
943 /* Œv‘ŞŒ‹‰ĘŠi”[—Ěˆć‚̏€”ő */
944 resultInfo = AllocInitResultInfo(discInfo, readBlock);
945 if(resultInfo == NULL){
946 discInfo = FreeDiscInfo(discInfo);
947 return RET_MEMERR;
948 }
949
950 /* Y•űŒüĹ‘ĺ’l‚̏‰Šú’lŒˆ’č */
951 if(DT_CD_FAMILY(drive->disc_type)){
952 resultInfo->max_trans_rate = 24/*16*/;
953 resultInfo->max_error_rate = (float)0.01;
954 }
955 else {
956 resultInfo->max_trans_rate = 5;
957 resultInfo->max_error_rate = (float)0.0; /* Œv‘Ş‚ľ‚Č‚˘ */
958 }
959
960 UIGetDrawableSize(&width, &height);
961 g_drawArea.width = width;
962 g_drawArea.height = height;
963
964 /* “ǎ摏“xĹ‘ĺÝ’č */
965 if(DT_CD_FAMILY(drive->disc_type)){
966 SendSetCdSpeed(drive, 0xffff, 0xffff, 0);
967 }
968
969 /* “ÇŽćƒŠƒgƒ‰ƒC‰ń”Ý’č */
970 ret = SetReadRetryCount(drive, GetOption()->read_retry, &oldRetryCount);
971 if(ret != RET_OK){
972 discInfo = FreeDiscInfo(discInfo);
973 resultInfo = FreeResultInfo(resultInfo);
974 return ret;
975 }
976
977 /* ƒOƒŠƒbƒh•`‰ć */
978 DrawGridLines(drive, discInfo,
979 resultInfo->max_trans_rate, resultInfo->max_error_rate);
980
981 for(trackIndex=0; trackIndex<discInfo->num_track; trackIndex++){
982 ret = ReadLoop(drive, discInfo, resultInfo, trackIndex, readBlock);
983 if(ret != RET_OK){
984 discInfo = FreeDiscInfo(discInfo);
985 resultInfo = FreeResultInfo(resultInfo);
986 SetReadRetryCount(drive, oldRetryCount, NULL);
987 return ret;
988 }
989 }
990
991 *c2Error = resultInfo->c2_error;
992 *readError = resultInfo->read_error;
993
994 discInfo = FreeDiscInfo(discInfo);
995 resultInfo = FreeResultInfo(resultInfo);
996 SetReadRetryCount(drive, oldRetryCount, NULL); /* “ÇŽćƒŠƒgƒ‰ƒC‰ń”‚đ–ß‚ˇ */
997
998 return RET_OK;
999 }
1000
1001
1002 static void DispEndMessage(CMDDRIVE *drive, int retcode,
1003 BOOL c2Error, BOOL readError)
1004 {
1005 char *msg;
1006
1007 if(retcode==RET_OK){
1008 if(readError){
1009 /*"łí‚ÉŠŽ—š‚ľ‚Ü‚ľ‚˝‚ށA“ǂݎć‚č‚ÉŽ¸”s‚ľ‚˝•”•ނނ ‚č‚Ü‚ˇB\n \
1010 ޏ”s•”•ނޏ­‚Č‚˘ę‡‚Í‚ŕ‚Á‚Ɠǂݎć‚萍”\‚Ě—Ç‚˘‘•’u‚ĹƒoƒbƒNƒAƒbƒv‚É
1011 ’§í‚ľ‚Ü‚ľ‚傤B\
1012 ޏ”s•”•ނޏ­‚Č‚­‚Č‚˘ę‡‚ÍŽc”O‚Č‚Ş‚çŽč’x‚ę‚̉”\Ť‚ލ‚‚˘‚Ĺ‚ˇB";*/
1013 msg = MSG_COMPLETE_WITH_READ_ERROR;
1014 }
1015 else if(c2Error){
1016 msg = MSG_COMPLETE_WITH_C2_ERROR;
1017 /*"łí‚ÉŠŽ—š‚ľ‚Ü‚ľ‚˝B“ǂݎć‚莸”s‚Í‚ ‚č‚Ü‚š‚ń‚ށAC2ƒGƒ‰[‚Ş \
1018 ”­ś‚ľ‚Ä‚˘‚é•”•ނނ ‚č‚Ü‚ˇB \
1019 ó‘ԂލX‚ɈŤ‰ť‚ľ‚Č‚˘‚¤‚ż‚ɃoƒbƒNƒAƒbƒv‚đ‚¨ŠŠ‚ß‚ľ‚Ü‚ˇB";*/
1020 }
1021 else{
1022 msg = MSG_COMPLETE_WITHOUT_ERROR;
1023 /*"łí‚ÉŠŽ—š‚ľ‚Ü‚ľ‚˝B‘S‚­–â‘č‚Č‚­“ǂݎć‚肪‚Ĺ‚Ť‚Ü‚ˇB";*/
1024 }
1025 UIDispMessage(msg, UIDMT_INFORMATION);
1026 }
1027 else if(retcode==RET_ABORT){
1028 UIDispMessage(MSG_ABORTED/*"’†’f‚ł‚ę‚Ü‚ľ‚˝B"*/, UIDMT_INFORMATION);
1029 }
1030 else if(retcode==RET_CMDERR){
1031 DispCommandError(drive);
1032 }
1033 else{
1034 UIDispMessage(MSG_ABORTED_BECAUSE_ERROR
1035 /*"ƒGƒ‰[‚É‚ć‚č’†’f‚ł‚ę‚Ü‚ľ‚˝B"*/, UIDMT_ERROR);
1036 }
1037 }
1038
1039
1040 int CheckDisc(DRIVEID *driveid)
1041 {
1042 CMDDRIVE drv;
1043 int ret;
1044 BOOL c2Error=FALSE, readError=FALSE;
1045
1046 if(UICheckAbort()){
1047 return RET_ABORT;
1048 }
1049
1050 memset(&drv, 0, sizeof(drv));
1051 ret = OpenDevice(&drv, driveid, TRUE);
1052 if(ret != RET_OK){
1053 if(ret != RET_ABORT){
1054 UIDispMessage(MSG_DRIVE_INIT_ERROR
1055 /*"‘•’u‚̏‰Šú‰ť‚ÉŽ¸”s‚ľ‚Ü‚ľ‚˝B"*/, UIDMT_ERROR);
1056 }
1057 UIDispInfo("");
1058 return ret;
1059 }
1060
1061 ret = ExecCheck(&drv, &c2Error, &readError);
1062 DispEndMessage(&drv, ret, c2Error, readError);
1063
1064 CloseDevice(&drv);
1065 UIDispInfo("");
1066 return RET_OK;
1067 }
1068
1069 /**
1070 * Volumeî•ń•śŽš—ń˜AŒ‹
1071 */
1072 static char *AppendVolumeInfo(char *string, const char *label,
1073 const char *buf, int len)
1074 {
1075 char *tmp;
1076 tmp = EbStringGetString(buf, len, ' ');
1077 if(tmp==NULL){
1078 return string;
1079 }
1080
1081 if(strlen(tmp) == 0){
1082 free(tmp);
1083 return string;
1084 }
1085
1086 if(string!=NULL){
1087 if(strlen(string) > 0){
1088 string = EbStringAppend(string, "\n");
1089 }
1090 }
1091 string = EbStringAppend(string, label);
1092 string = EbStringAppend(string, "=");
1093 string = EbStringAppend(string, tmp);
1094 tmp = EbStringFree(tmp);
1095
1096 return string;
1097 }
1098
1099 /**
1100 * Volumeî•ń“úŽž•śŽš—ń˜AŒ‹
1101 * “úŽžŒ`ŽŽ:YYYYmmddHHMMSS
1102 * TZ: -48(-1200)`52(+1300)
1103 */
1104 static char *AppendVolumeInfoDateTime(char *string, const char *label,
1105 const char *buf)
1106 {
1107 char *tmp;
1108 char tz[6];
1109 char datetime[23]; /* YYYY/mm/dd HH:MM:SS.FF */
1110 int n;
1111
1112 tmp = EbStringGetString(buf, 17, '\0');
1113 if(tmp==NULL){
1114 return string;
1115 }
1116
1117 if(string!=NULL){
1118 if(strlen(string) > 0){
1119 string = EbStringAppend(string, "\n");
1120 }
1121 }
1122 string = EbStringAppend(string, label);
1123 string = EbStringAppend(string, "=");
1124
1125 /* date & time */
1126 memcpy(datetime+0, tmp+0, 4);
1127 datetime[4] = '/';
1128 memcpy(datetime+5, tmp+4, 2);
1129 datetime[7] = '/';
1130 memcpy(datetime+8, tmp+6, 2);
1131 datetime[10] = ' ';
1132 memcpy(datetime+11, tmp+8, 2);
1133 datetime[13] = ':';
1134 memcpy(datetime+14, tmp+10, 2);
1135 datetime[16] = ':';
1136 memcpy(datetime+17, tmp+12, 2);
1137 datetime[19] = '.';
1138 memcpy(datetime+20, tmp+14, 2);
1139 datetime[22] = '\0';
1140
1141 /* TZ */
1142 tz[0] = (tmp[16] < 0) ? '-' : '+';
1143 n = (int)((tmp[16] < 0) ? -tmp[16] : tmp[16]);
1144 snprintf(tz+1, 5, "%02d%02d", n/4, (n%4)*15);
1145 string = EbStringAppend(string, datetime);
1146 string = EbStringAppend(string, tz);
1147 tmp = EbStringFree(tmp);
1148
1149 return string;
1150 }
1151
1152
1153 /**
1154 * VolumeŽć“ž
1155 */
1156 static char *GetVolume(CMDDRIVE *drive, WORD track, DWORD start_lba)
1157 {
1158 int ret;
1159 char *vol=NULL;
1160
1161 ret = SendRead10(drive, start_lba+16, 1, 2048);
1162 if(ret != RET_OK){
1163 return NULL;
1164 }
1165 if(drive->data_buf[0] != 0x01){
1166 return NULL;
1167 }
1168 if(strncmp(drive->data_buf+1, "CD001", 5) != 0){
1169 return NULL;
1170 }
1171
1172 /* System */
1173 vol = AppendVolumeInfo(vol, MSG_SYSTEM, drive->data_buf+0x08, 0x20);
1174 /* Volume */
1175 vol = AppendVolumeInfo(vol, MSG_VOLUME, drive->data_buf+0x28, 0x20);
1176 /* ƒ{ƒŠƒ…[ƒ€W‡ */
1177 vol = AppendVolumeInfo(vol, MSG_VOLUMESET, drive->data_buf+0xbe, 0x80);
1178 /* o”ĹŽŇ */
1179 vol = AppendVolumeInfo(vol, MSG_PUBLISHER, drive->data_buf+0x13e, 0x80);
1180 /* •ҏWŽŇ */
1181 vol = AppendVolumeInfo(vol, MSG_PREPARER, drive->data_buf+0x1be, 0x80);
1182 /* ‰ž—pƒVƒXƒeƒ€ */
1183 vol = AppendVolumeInfo(vol, MSG_APPLICATION, drive->data_buf+0x23e, 0x80);
1184 /* ěŹ“úŽž */
1185 vol = AppendVolumeInfoDateTime(vol, MSG_CREATION_DATE_TIME, drive->data_buf+0x32d);
1186 /* ‚ť‚Ě‘ź */
1187 vol = AppendVolumeInfo(vol, MSG_OTHER, drive->data_buf+0x374, 0x1ff);
1188
1189 return vol;
1190 }
1191
1192 /**
1193 * ƒf[ƒ^ƒ‚[ƒhŽć“ž
1194 */
1195 static char *GetDataMode(CMDDRIVE *drive, TRACKINFO *trackInfo)
1196 {
1197 int ret;
1198 char *mode=NULL;
1199
1200 if((trackInfo->data_mode==1) || (trackInfo->data_mode==2)){
1201 mode = EbStringNewWithFormat("Mode%d", trackInfo->data_mode);
1202 }
1203 else if(DT_CD_FAMILY(drive->disc_type)){
1204 ret = SendReadCD(drive, trackInfo->start_lba, 1);
1205 if(ret == RET_OK){
1206 mode = EbStringNewWithFormat("Mode%d", drive->data_buf[15]);
1207 }
1208 }
1209
1210 if(mode == NULL){
1211 mode = EbStringNew("Data");
1212 }
1213
1214 return mode;
1215 }
1216
1217
1218 /**
1219 * ISRCŽć“ž
1220 */
1221 static char *GetISRC(CMDDRIVE *drive, BYTE track)
1222 {
1223 int ret;
1224 char *isrc;
1225
1226 ret = SendReadSubchannel(drive, track, 0, 1, 3/*ISRC*/);
1227 if(ret != RET_OK){
1228 return NULL;
1229 }
1230 isrc = (char *)malloc(13);
1231 if(isrc == NULL){
1232 UIDispMessage(MSG_MEM_ALLOC_ERROR, UIDMT_ERROR);
1233 return NULL;
1234 }
1235 memcpy(isrc, drive->data_buf+9, 12);
1236 isrc[12] = '\0';
1237
1238 return isrc;
1239 }
1240
1241 /**
1242 * ƒhƒ‰ƒCƒu‚Š‚çƒfƒBƒXƒNî•ń‚đŽć“ž‚ľ‚Ä•\ŽŚ‚ˇ‚é
1243 */
1244 int DisplayDiscInformation(DRIVEID *driveid)
1245 {
1246 CMDDRIVE drv;
1247 DISCINFO *discInfo=NULL;
1248 UITRACKINFO *uiTrackInfo=NULL, *uiInfo;
1249 TRACKINFO *trackInfo;
1250 WORD trackIdx;
1251 int ret;
1252 BOOL aborted=FALSE;
1253
1254 if(UICheckAbort()){
1255 return RET_ABORT;
1256 }
1257
1258 memset(&drv, 0, sizeof(drv));
1259 ret = OpenDevice(&drv, driveid, TRUE);
1260 if(ret != RET_OK){
1261 if(ret != RET_ABORT){
1262 UIDispMessage(MSG_DRIVE_INIT_ERROR, UIDMT_ERROR);
1263 }
1264 UIDispInfo("");
1265 return ret;
1266 }
1267
1268 ret = MakeDiscInfo(&drv, &discInfo);
1269 if(ret != RET_OK){
1270 CloseDevice(&drv);
1271 UIDispInfo("");
1272 return ret;
1273 }
1274
1275 uiTrackInfo = (UITRACKINFO *)malloc(discInfo->num_track *
1276 sizeof(UITRACKINFO));
1277 if(uiTrackInfo == NULL){
1278 UIDispMessage(MSG_MEM_ALLOC_ERROR, UIDMT_ERROR);
1279 FreeDiscInfo(discInfo);
1280 CloseDevice(&drv);
1281 UIDispInfo("");
1282 return RET_NG;
1283 }
1284
1285 memset(uiTrackInfo, 0, discInfo->num_track * sizeof(UITRACKINFO));
1286 for(trackIdx=0; trackIdx<discInfo->num_track; trackIdx++){
1287 UIDispInfo(MSG_READING_TRACK_, trackIdx+1, discInfo->num_track);
1288 if(UICheckAbort()){
1289 aborted = TRUE;
1290 break;
1291 }
1292
1293 uiInfo = &uiTrackInfo[trackIdx];
1294 trackInfo = &discInfo->tracks[trackIdx];
1295 if(trackInfo->blank){
1296 continue;
1297 }
1298 uiInfo->session = trackInfo->session;
1299 uiInfo->track = trackInfo->track;
1300 uiInfo->start_lba = trackInfo->start_lba;
1301 uiInfo->end_lba = trackInfo->end_lba;
1302 uiInfo->blocks = trackInfo->blocks;
1303 uiInfo->packet_size = trackInfo->packet_size;
1304 if((trackInfo->track_mode & 0x0c) == 4){
1305 /* Data Track */
1306 char *vol;
1307 uiInfo->mode = GetDataMode(&drv, trackInfo);
1308 vol = GetVolume(&drv, uiInfo->track, trackInfo->start_lba);
1309 if(vol != NULL){
1310 uiInfo->comment = EbStringNew(vol);
1311 free(vol);
1312 }
1313 }
1314 else{
1315 /* Audio Track */
1316 DWORD blocks = uiInfo->end_lba-uiInfo->start_lba+1;
1317 char *isrc;
1318 uiInfo->mode = EbStringNew("Audio");
1319 uiInfo->comment = EbStringNewWithFormat("Time=%ld:%02ld",
1320 blocks/75/60,
1321 (blocks/75)%60);
1322 isrc = GetISRC(&drv, (BYTE)uiInfo->track);
1323 if(isrc != NULL){
1324 uiInfo->comment = EbStringAppendWithFormat(uiInfo->comment,
1325 "\nISRC=%s", isrc);
1326 free(isrc);
1327 }
1328 }
1329
1330 /* Damage? */
1331 if(trackInfo->damage){
1332 if(uiInfo->comment != NULL){
1333 uiInfo->comment = EbStringAppend(uiInfo->comment, " ");
1334 }
1335 uiInfo->comment = EbStringAppend(uiInfo->comment, "Damage!!");
1336 }
1337 }
1338
1339 UIDispInfo("");
1340 if(aborted == FALSE){
1341 UIDispDiscInfo(uiTrackInfo, (int)discInfo->num_track);
1342 }
1343
1344 for(trackIdx=0; trackIdx<discInfo->num_track; trackIdx++){
1345 EbStringFree(uiTrackInfo[trackIdx].mode);
1346 EbStringFree(uiTrackInfo[trackIdx].comment);
1347 }
1348 free(uiTrackInfo);
1349 uiTrackInfo = NULL;
1350
1351 discInfo = FreeDiscInfo(discInfo);
1352 CloseDevice(&drv);
1353 UIDispInfo("");
1354 return RET_OK;
1355 }

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