nLBA = pDisc->SCSI.nAllLength;
if (!ExecReadCD(pExtArg, pDevice, lpCmd, nLBA - 1, aBuf,
CD_RAW_SECTOR_SIZE, _T(__FUNCTION__), __LINE__)
|| byScsiStatus >= SCSISTAT_CHECK_CONDITION) {
}
Ok. I didn't see this line
Anyway I have some good news. After some coding and experimenting with F1 command I can enable reading more sectors from cache.
Current situation:
1) You call ExecReadCD with nLBA -1 which read single sector into cache.
I have extended F1 command function to show the cache:
static int lineno = 0;
static int cacheline = 0;
BOOL ReadCacheForLgAsus(
PEXT_ARG pExtArg,
PDEVICE pDevice,
PDISC pDisc,
INT nLBA
) {
//DWORD dwSize = 0xb00;
DWORD dwSize = 0xb00 * 1;
LPBYTE lpBuf = NULL;
if (!GetAlignedCallocatedBuffer(pDevice, &pDisc->lpCachedBuf,
(UINT)dwSize, &lpBuf, _T(__FUNCTION__), __LINE__)) {
return FALSE;
}
// http://forum.redump.org/post/72629/#p72629
// F1 06 xx xx xx xx yy yy yy yy
// xx - address to read
// yy - length of data to return
//
// 0x000-0x92F - Main Channel (Scrambled)
// 0x930-0x98F - P-W Subchannel
// 0x990-0x99F - Q Subchannel
// 0x9A0-0x9A3 - (unknown)
// 0x9A4-0xAC9 - C2 Error Bits
// 0xACA-0xB00 - (unknown)
CDB::_CDB10 cdb = {};
cdb.OperationCode = 0xf1;
cdb.Reserved1 = 3;
//nLBA = 0;
cdb.LogicalBlockByte0 = BYTE((0xb00 * nLBA >> 24) & 0xff);
cdb.LogicalBlockByte1 = BYTE((0xb00 * nLBA >> 16) & 0xff);
cdb.LogicalBlockByte2 = BYTE((0xb00 * nLBA >> 8) & 0xff);
cdb.LogicalBlockByte3 = BYTE(0xb00 * nLBA & 0xff);
//cdb.LogicalBlockByte0 = BYTE((nLBA >> 24) & 0xff);
//cdb.LogicalBlockByte1 = BYTE((nLBA >> 16) & 0xff);
//cdb.LogicalBlockByte2 = BYTE((nLBA >> 8) & 0xff);
//cdb.LogicalBlockByte3 = BYTE(nLBA & 0xff);
//cdb.TransferBlocksLsb = 0x0b;
//cdb.Control = 0x00;
cdb.Reserved2 = BYTE((dwSize >> 24) & 0xff);
cdb.TransferBlocksMsb = BYTE((dwSize >> 16) & 0xff);
cdb.TransferBlocksLsb = BYTE((dwSize >> 8) & 0xff);
cdb.Control = BYTE(dwSize & 0xff);
#ifdef _WIN32
INT direction = SCSI_IOCTL_DATA_IN;
#else
INT direction = SG_DXFER_FROM_DEV;
#endif
BYTE byScsiStatus = 0;
if (!ScsiPassThroughDirect(pExtArg, pDevice, &cdb, CDB10GENERIC_LENGTH
, lpBuf, direction, dwSize, &byScsiStatus, _T(__FUNCTION__), __LINE__)
|| byScsiStatus >= SCSISTAT_CHECK_CONDITION) {
return FALSE;
}
FILE *a = fopen("f1cache", "wb");
fwrite(lpBuf, dwSize, 1, a);
fclose(a);
UCHAR sync[] = {0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ,0};
for(DWORD x = 0; x < dwSize - 16; ++x) {
if(!memcmp(sync, lpBuf + x, sizeof(sync))) {
// 1 80 0 60
UCHAR m = lpBuf[x + 0xC] ^ 0x1;
UCHAR s = lpBuf[x + 0xD] ^ 0x80;
UCHAR f = lpBuf[x + 0xE] ^ 0;
UCHAR mode = lpBuf[x + 0xF] ^ 0x60;
UCHAR md = BcdToDec(m);
UCHAR sd = BcdToDec(s);
UCHAR fd = BcdToDec(f);
ULONG lsn = fd + 75 * (sd + 60 * md) - 150;
if(!cacheline) {
cacheline = lsn;
} else if(lsn != cacheline + 1) {
fprintf(stdout, "=====================================\n");
fprintf(stdout, "Cache SIZE: %lu\n", lineno);
fprintf(stdout, "=====================================\n");
cacheline = lsn;
Sleep(3000);
} else {
cacheline = lsn;
}
fprintf(stdout, "%lu Cache MSF: %02x %02x %02x %lu %06lu\n", lineno++, m, s, f, mode, lsn);
OutputDiscLog("%lu Cache MSF: %02x %02x %02x %lu %06lu\n", lineno, m, s, f, mode, lsn);
}
}
// OutputCDMain(fileMainInfo, lpBuf, nLBA, dwSize);
return TRUE;
}
and in caller function I call it like this:
DWORD ct = 10;
OutputDiscLog("Reading %lu - %lu INTO CACHE\n", nLBA - 1 - ct, nLBA - 1);
fprintf(stdout, "Reading %lu - %lu INTO CACHE\n", nLBA - 1 - ct, nLBA - 1);
for(DWORD x = nLBA - 1 - ct; x <= nLBA - 1; ++x) {
if(!ExecReadCD(pExtArg, pDevice, lpCmd, x, aBuf,
CD_RAW_SECTOR_SIZE, _T(__FUNCTION__), __LINE__)
|| byScsiStatus >= SCSISTAT_CHECK_CONDITION) {
}
}
DWORD xx = 0;
for(; xx < 10000; ++xx) {
if(!ReadCacheForLgAsus(pExtArg, pDevice, pDisc, xx)) {
break;
}
}
Result:
Reading 326657 - 326657 INTO CACHE
0 Cache MSF: 72 37 30 1 326655
1 Cache MSF: 72 37 31 1 326656
=====================================
Cache SIZE: 2
=====================================
2 Cache MSF: 00 02 00 1 000000
3 Cache MSF: 00 02 01 1 000001
4 Cache MSF: 00 02 02 1 000002
So you get 2 sectors into cache none of which are related to Lead-Out.
However when you read more sectors into cache (change 'ct' to for example 10) things get more interesting:
Reading 326637 - 326657 INTO CACHE
0 Cache MSF: 72 37 10 1 326635
1 Cache MSF: 72 37 11 1 326636
2 Cache MSF: 72 37 12 1 326637
3 Cache MSF: 72 37 13 1 326638
4 Cache MSF: 72 37 14 1 326639
5 Cache MSF: 72 37 15 1 326640
6 Cache MSF: 72 37 16 1 326641
7 Cache MSF: 72 37 17 1 326642
8 Cache MSF: 72 37 18 1 326643
9 Cache MSF: 72 37 19 1 326644
10 Cache MSF: 72 37 20 1 326645
11 Cache MSF: 72 37 21 1 326646
12 Cache MSF: 72 37 22 1 326647
13 Cache MSF: 72 37 23 1 326648
14 Cache MSF: 72 37 24 1 326649
15 Cache MSF: 72 37 25 1 326650
16 Cache MSF: 72 37 26 1 326651
17 Cache MSF: 72 37 27 1 326652
18 Cache MSF: 72 37 28 1 326653
19 Cache MSF: 72 37 29 1 326654
20 Cache MSF: 72 37 30 1 326655
21 Cache MSF: 72 37 31 1 326656
22 Cache MSF: 72 37 32 1 326657
23 Cache MSF: 72 37 33 1 326658
24 Cache MSF: 72 37 34 1 326659
25 Cache MSF: 72 37 35 1 326660
26 Cache MSF: 72 37 36 1 326661
27 Cache MSF: 72 37 37 1 326662
28 Cache MSF: 72 37 38 1 326663
29 Cache MSF: 72 37 39 1 326664
30 Cache MSF: 72 37 40 1 326665
31 Cache MSF: 72 37 41 1 326666
32 Cache MSF: 72 37 42 1 326667
=====================================
Cache SIZE: 33
=====================================
33 Cache MSF: 00 02 31 1 000031
34 Cache MSF: 00 02 32 1 000032
35 Cache MSF: 00 02 33 1 000033
36 Cache MSF: 00 02 34 1 000034
33 sectors are read from cache until it wraps. Lead out starts at entry no 23.
When you specify 'ct' = 1000, even more sectors are read into cache:
992 Cache MSF: 72 37 22 1 326647
993 Cache MSF: 72 37 23 1 326648
994 Cache MSF: 72 37 24 1 326649
995 Cache MSF: 72 37 25 1 326650
996 Cache MSF: 72 37 26 1 326651
997 Cache MSF: 72 37 27 1 326652
998 Cache MSF: 72 37 28 1 326653
999 Cache MSF: 72 37 29 1 326654
1000 Cache MSF: 72 37 30 1 326655
1001 Cache MSF: 72 37 31 1 326656
1002 Cache MSF: 72 37 32 1 326657
1003 Cache MSF: 72 37 33 1 326658 Lead out
1004 Cache MSF: 72 37 34 1 326659
1005 Cache MSF: 72 37 35 1 326660
1006 Cache MSF: 72 37 36 1 326661
1007 Cache MSF: 72 37 37 1 326662
1008 Cache MSF: 72 37 38 1 326663
1009 Cache MSF: 72 37 39 1 326664
1010 Cache MSF: 72 37 40 1 326665
1011 Cache MSF: 72 37 41 1 326666
1012 Cache MSF: 72 37 42 1 326667
1013 Cache MSF: 72 37 43 1 326668
1014 Cache MSF: 72 37 44 1 326669
1015 Cache MSF: 72 37 45 1 326670
1016 Cache MSF: 72 37 46 1 326671
1017 Cache MSF: 72 37 47 1 326672
1018 Cache MSF: 72 37 48 1 326673
1019 Cache MSF: 72 37 49 1 326674
1020 Cache MSF: 72 37 50 1 326675
1021 Cache MSF: 72 37 51 1 326676
The results differ from run to run. You have to parse the cache buffer and manually extract data from there (skipping wrong cache entries). I saw that after few hundreds cache reads device's buffer wraps up and starts giving data from the beginning (it looks like cyclic buffer).
The critical thing here is to read sectors in batch to fill the cache. I think ct = 20 looks like a sweet spot and allows to read discs with big offsets.
Please implement the changes.