initial check in

This commit is contained in:
2012-12-06 21:43:03 +04:00
commit 4bc273824d
179 changed files with 29415 additions and 0 deletions

View File

@@ -0,0 +1,699 @@
// testDeviceIOWin32.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <stdio.h>
#include <tchar.h>
#include <iostream>
#include <windows.h>
#include <winioctl.h>
#include <ntddcdrm.h>
/*
CD
Every byte == 14bit (EFM) ??
Small Frame == 588bit == 24 byte <== this is the unit of read. Can't read smaller portions.
+-----------+------------+--------------+-----------+--------------+-----------+
| Sync code | Subchannel | Main Channel | CIRC code | Main Channel | CIRC code |
| | byte | data | | data | |
bit | 24+3 | 14+3 | 12x(14+3) | 4x(14+3) | 12x(14+3) | 4x(14+3) |
+-----------+------------+--------------+-----------+--------------+-----------+
Frame == 98 Small Frames == 2352 bytes <== this is reachable form soft.
+98 byte of subchannel ( 2 sync bytes + 96 bytes of data )
The first 2 small frames containe sync bytes and then the rest of small frames
containe data bytes.
Session == Lead-in + Program Area + Lead-out
Lead-in == TOC in Q-Subchannel
Program Area == Logical Tracks (at least containes one logical track)
Address format is MSF (Minute/Second/Frame) M=60*S S=75*F
1 Audio Sec = 4(Stereo 16bit)*44100(Hz)=176400 byte = 75 * 2352 byte = 75 Frame
0<= F <= 74
0<= S <= 59
0<= M <= 99
*/
enum {
ADDR_SEC2FRAME = 75,
ADDR_MIN2SEC = 60,
CTRL_COPYPROT_MASK = 0x02, // 0010
CTRL_TYPE_MASK = 0x0C, // 1100
CTRL_AUDIO2CH_TRACK = 0x00, //
CTRL_DATA_TRACK = 0x04, //
CTRL_AUDIO4CH_TRACK = 0x06, //
CTRL_RESERVED_TRACK = 0x0C, //
CTRL_DATA_INCREMENTAL = 0x01, //
CTRL_AUDIO_50_15 = 0x01, //
FRAME_DATA = 2352,
};
#define MAXIMUM_NUMBER_TRACKS 100
#define NSECTORS 13
#define UNDERSAMPLING 1
#define CB_CDDASECTOR 2368
#define CB_QSUBCHANNEL 16
#define CB_CDROMSECTOR 2048
#define CB_AUDIO (CB_CDDASECTOR-CB_QSUBCHANNEL)
/* The code of interest is in the subroutine GetDriveGeometry. The
code in main shows how to interpret the results of the call. */
class device
{
protected:
// Handle to the drive to be examined.
HANDLE hDevice;
DISK_GEOMETRY dg;
CDROM_TOC toc;
bool m_bLocked;
public:
device()
{
hDevice = INVALID_HANDLE_VALUE;
m_bLocked = false;
}
~device()
{
if ( hDevice != INVALID_HANDLE_VALUE )
{
if ( m_bLocked )
storageMediaUnlock();
close();
}
}
bool create( const TCHAR* pszDevice )
{
hDevice = ::CreateFile(pszDevice, // drive to open
GENERIC_READ |
GENERIC_WRITE , // no access to the drive
FILE_SHARE_READ | // share mode
FILE_SHARE_WRITE,
NULL, // default security attributes
OPEN_EXISTING, // disposition
0, // file attributes
NULL); // do not copy file attributes
if (hDevice == INVALID_HANDLE_VALUE) // cannot open the drive
{
printErr("CreateFile");
return false;
}
return true;
}
bool close()
{
if ( hDevice != INVALID_HANDLE_VALUE )
{
::CloseHandle(hDevice);
hDevice = INVALID_HANDLE_VALUE;
}
return true;
}
static void printErr( char* szMsg = "" )
{
printf ("%s Error %ld. ", szMsg, GetLastError ());
char szMsgBfr[ 1024 ];
::FormatMessageA(
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError (),
0, // Default language
szMsgBfr,
sizeof( szMsgBfr ),
NULL );
szMsgBfr[sizeof( szMsgBfr )-1] = 0;
puts ( szMsgBfr );
}
bool diskGetDriveGeometry()
{
DWORD junk; // discard results
printf("IOCTL_DISK_GET_DRIVE_GEOMETRY\n");
if ( !DeviceIoControl( hDevice, // device to be queried
IOCTL_DISK_GET_DRIVE_GEOMETRY, // operation to perform
NULL, 0, // no input buffer
&dg, sizeof(dg), // output buffer
&junk, // # bytes returned
(LPOVERLAPPED) NULL) ) // synchronous I/O
{
printErr("");
return false;
}
else
{
printf("MediaType = %d\n", dg.MediaType);
printf("Cylinders = %I64d\n", dg.Cylinders);
printf("Tracks/cylinder = %ld\n", (ULONG) dg.TracksPerCylinder);
printf("Sectors/track = %ld\n", (ULONG) dg.SectorsPerTrack);
printf("Bytes/sector = %ld\n", (ULONG) dg.BytesPerSector);
ULONGLONG DiskSize = dg.Cylinders.QuadPart * (ULONG)dg.TracksPerCylinder *
(ULONG)dg.SectorsPerTrack * (ULONG)dg.BytesPerSector;
printf("Disk size = %I64d (Bytes) = %I64d (Gb)\n", DiskSize,
DiskSize / (1024 * 1024 * 1024));
}
puts("");
return true;
}
bool diskGetCacheInformation()
{
DWORD junk; // discard results
DISK_CACHE_INFORMATION dci;
printf("IOCTL_DISK_GET_CACHE_INFORMATION\n");
if ( !DeviceIoControl( hDevice, // device to be queried
IOCTL_DISK_GET_CACHE_INFORMATION, // operation to perform
NULL, 0, // no input buffer
&dci, sizeof(dci), // output buffer
&junk, // # bytes returned
(LPOVERLAPPED) NULL) ) // synchronous I/O
{
printErr("");
return false;
}
else
{
printf("ParametersSavable = %d\n", dci.ParametersSavable);
printf("ReadCacheEnabled = %d\n", dci.ReadCacheEnabled);
printf("WriteCacheEnabled = %d\n", dci.WriteCacheEnabled);
printf("ReadRetentionPriority = %d\n", dci.ReadRetentionPriority);
printf("WriteRetentionPriority = %d\n", dci.WriteRetentionPriority);
printf("DisablePrefetchTransferLength = %d\n", dci.DisablePrefetchTransferLength);
if ( dci.PrefetchScalar )
{
printf("ScalarPrefetch.Minimum = %d\n", dci.ScalarPrefetch.Minimum);
printf("ScalarPrefetch.Maximum = %d\n", dci.ScalarPrefetch.Maximum);
printf("ScalarPrefetch.MaximumBlocks = %d\n", dci.ScalarPrefetch.MaximumBlocks);
}
else
{
printf("BlockPrefetch.Minimum = %d\n", dci.BlockPrefetch.Minimum);
printf("BlockPrefetch.Maximum = %d\n", dci.BlockPrefetch.Maximum);
}
}
puts("");
return true;
}
bool diskPerformance()
{
DWORD junk; // discard results
DISK_PERFORMANCE dp;
printf("IOCTL_DISK_PERFORMANCE\n");
if ( !DeviceIoControl( hDevice, // device to be queried
IOCTL_DISK_PERFORMANCE, // operation to perform
NULL, 0, // no input buffer
&dp, sizeof(dp), // output buffer
&junk, // # bytes returned
(LPOVERLAPPED) NULL) ) // synchronous I/O
{
printErr("");
return false;
}
else
{
printf("BytesRead = %I64d\n", dp.BytesRead);
printf("BytesWritten = %I64d\n", dp.BytesWritten);
printf("ReadTime = %I64d\n", dp.ReadTime);
printf("WriteTime = %I64d\n", dp.WriteTime);
printf("IdleTime = %I64d\n", dp.IdleTime);
printf("ReadCount = %d\n", dp.ReadCount);
printf("WriteCount = %d\n", dp.WriteCount);
printf("QueueDepth = %d\n", dp.QueueDepth);
printf("SplitCount = %d\n", dp.SplitCount);
printf("QueryTime = %I64d\n", dp.QueryTime);
printf("StorageDeviceNumber = %d\n", dp.StorageDeviceNumber);
printf("StorageManagerName = %c%c%c%c%c%c%c%c\n",
dp.StorageManagerName[0], dp.StorageManagerName[1],
dp.StorageManagerName[2], dp.StorageManagerName[3],
dp.StorageManagerName[4], dp.StorageManagerName[5],
dp.StorageManagerName[6], dp.StorageManagerName[7]);
}
puts("");
//////////////////////////////////////////////////////////////////////////////
printf("IOCTL_DISK_PERFORMANCE_OFF\n");
if ( !DeviceIoControl( hDevice, // device to be queried
IOCTL_DISK_PERFORMANCE_OFF, // operation to perform
NULL, 0, // no input buffer
0, 0, // output buffer
&junk, // # bytes returned
(LPOVERLAPPED) NULL) ) // synchronous I/O
{
printErr("");
return false;
}
puts("");
return true;
}
bool diskVerify()
{
DWORD junk; // discard results
VERIFY_INFORMATION vi;
printf("IOCTL_DISK_VERIFY\n");
vi.StartingOffset.QuadPart = 0;
vi.Length = 2048;
if ( !DeviceIoControl( hDevice, // device to be queried
IOCTL_DISK_VERIFY, // operation to perform
&vi, sizeof(vi), // no input buffer
0, 0, // output buffer
&junk, // # bytes returned
(LPOVERLAPPED) NULL) ) // synchronous I/O
{
printErr("");
return false;
}
puts("");
return true;
}
bool storageMediaLock()
{
DWORD junk; // discard results
PREVENT_MEDIA_REMOVAL pmr;
pmr.PreventMediaRemoval = 1;
printf("IOCTL_STORAGE_MEDIA_REMOVAL lock\n");
if ( !::DeviceIoControl( hDevice,
IOCTL_STORAGE_MEDIA_REMOVAL,
&pmr, sizeof( pmr ),
0, 0,
&junk,
(LPOVERLAPPED)0 ) )
{
printErr("");
return false;
}
m_bLocked = true;
return true;
}
bool storageMediaUnlock()
{
DWORD junk; // discard results
PREVENT_MEDIA_REMOVAL pmr;
pmr.PreventMediaRemoval = 0;
printf("IOCTL_STORAGE_MEDIA_REMOVAL unlock\n");
if ( !::DeviceIoControl( hDevice,
IOCTL_STORAGE_MEDIA_REMOVAL,
&pmr, sizeof( pmr ),
0, 0,
&junk,
(LPOVERLAPPED)0 ) )
{
printErr("");
return false;
}
m_bLocked = false;
return true;
}
bool storageLoadMedia()
{
DWORD junk; // discard results
printf("IOCTL_STORAGE_LOAD_MEDIA\n");
if ( !::DeviceIoControl( hDevice,
IOCTL_STORAGE_LOAD_MEDIA,
0, 0,
0, 0,
&junk,
(LPOVERLAPPED)0 ) )
{
printErr("");
return false;
}
else
{
// printf("");
}
return true;
}
bool storageCheckVerify()
{
DWORD junk; // discard results
printf("IOCTL_STORAGE_CHECK_VERIFY\n");
if ( !::DeviceIoControl( hDevice,
IOCTL_STORAGE_CHECK_VERIFY,
0, 0,
0, 0,
&junk,
(LPOVERLAPPED)0 ) )
{
printErr("");
return false;
}
else
{
// printf("");
}
return true;
}
bool storageEjectMedia()
{
DWORD junk; // discard results
printf("IOCTL_STORAGE_EJECT_MEDIA\n");
if ( !::DeviceIoControl( hDevice,
IOCTL_STORAGE_EJECT_MEDIA,
0, 0,
0, 0,
&junk,
(LPOVERLAPPED)0 ) )
{
printErr("");
return false;
}
else
{
// printf("");
}
return true;
}
bool storageReadCapacity()
{
// 2003
#if 0
DWORD junk; // discard results
STORAGE_READ_CAPACITY src;
printf("IOCTL_STORAGE_READ_CAPACITY\n");
if ( !DeviceIoControl( hDevice, // device to be queried
IOCTL_STORAGE_READ_CAPACITY, // operation to perform
NULL, 0, // no input buffer
&src, sizeof(src), // output buffer
&junk, // # bytes returned
(LPOVERLAPPED) NULL) ) // synchronous I/O
{
printErr("");
return false;
}
else
{
printf("Version = %d\n", src.Version);
printf("Size = %d\n", src.Size);
printf("BlockLength = %d\n", src.BlockLength);
printf("NumberOfBlocks = %I64d\n", dg.NumberOfBlocks);
printf("DiskLength = %I64d\n", dg.DiskLength);
}
puts("");
#endif
return true;
}
bool cdromDiskInfo()
{
#if 0
DWORD junk; // discard results
printf("IOCTL_CDROM_DISC_INFO\n");
CDROM_DISCINFO cdi;
if ( !DeviceIoControl( hDevice, // device to be queried
IOCTL_CDROM_DISC_INFO, // operation to perform
0, 0, // no input buffer
&cdi, sizeof( cdi ), // output buffer
&junk, // # bytes returned
(LPOVERLAPPED) NULL) ) // synchronous I/O
{
printErr("");
}
else
{
printf("Reserved = %I64d\n", cdi.Reserved );
printf("FirstTrack = %I64d\n", cdi.FirstTrack );
printf("LastTrack = %I64d\n", cdi.LastTrack );
printf("LastTrack = %I64d\n", cdi.LeadOutTrackAddr );
printf("FirstSession = %I64d\n", cdi.FirstSession );
printf("LastSession = %I64d\n", cdi.LastSession );
printf("ReqSession = %I64d\n", cdi.ReqSession );
printf("RetSession = %I64d\n", cdi.RetSession );
printf("LogicStartAddr = %I64d\n", cdi.LogicStartAddr );
}
puts("");
#endif
}
bool cdromReadTOC()
{
DWORD junk; // discard results
printf("IOCTL_CDROM_READ_TOC\n");
if ( !::DeviceIoControl( hDevice,
IOCTL_CDROM_READ_TOC,
0, 0,
&toc, sizeof(toc),
&junk,
(LPOVERLAPPED)0 ) )
{
printErr("");
return false;
}
else
{
std::cout << "Length = " << (USHORT&)toc.Length << std::endl;
std::cout << "FirstTrack = " << int(toc.FirstTrack) << std::endl;
std::cout << "LastTrack = " << int(toc.LastTrack) << std::endl;
for ( int i = 0; i < (toc.LastTrack - toc.FirstTrack +1); ++i )
{
std::cout << "track " << i << " {" << std::endl;
if ( toc.TrackData[i].Control & CTRL_COPYPROT_MASK )
std::cout << " No copy protection" << std::endl;
else
std::cout << " Copy protected" << std::endl;
int n = toc.TrackData[i].Control & CTRL_TYPE_MASK;
if ( n == CTRL_AUDIO2CH_TRACK )
std::cout << " 2 channel audio track" << std::endl;
else if ( n == CTRL_AUDIO4CH_TRACK )
std::cout << " 4 channel audio track" << std::endl;
else if ( n == CTRL_DATA_TRACK )
std::cout << " Data track" << std::endl;
else
std::cout << " Unknown type of track" << std::endl;
if ( n == CTRL_DATA_TRACK )
{
if ( toc.TrackData[i].Control & CTRL_DATA_INCREMENTAL )
std::cout << " Incremental record" << std::endl;
else
std::cout << " Continuous record" << std::endl;
}
else
{
if ( toc.TrackData[i].Control & CTRL_AUDIO_50_15 )
std::cout << " Predistortion 50/15 mks" << std::endl;
else
std::cout << " No predistortion" << std::endl;
}
std::cout << " Adr = " << int(toc.TrackData[i].Adr) << std::endl;
std::cout << " TrackNumber = " << int(toc.TrackData[i].TrackNumber) << std::endl;
std::cout << " Address[0] = " << int(toc.TrackData[i].Address[0]) << std::endl;
std::cout << " Minute = " << int(toc.TrackData[i].Address[1]) << std::endl;
std::cout << " Second = " << int(toc.TrackData[i].Address[2]) << std::endl;
std::cout << " Frame = " << int(toc.TrackData[i].Address[3]) << std::endl;
std::cout << " Start Sector = " << toc.TrackData[i].Address[1] * ADDR_MIN2SEC * ADDR_SEC2FRAME
+ toc.TrackData[i].Address[2] * ADDR_SEC2FRAME
+ toc.TrackData[i].Address[3] << std::endl;
std::cout << "}" << std::endl;
}
}
return true;
}
virtual int cdromRawRead( int sector, int num, char* buf, int buf_size );
};
int device::cdromRawRead( int sector, int num, char* buf, int buf_size )
{
DWORD nBytsRead = 0;
RAW_READ_INFO rri;
// rri.TrackMode = CDDA;
rri.TrackMode = YellowMode2;
rri.SectorCount = num;
rri.DiskOffset.QuadPart = sector*CB_CDROMSECTOR;
memset ( buf, 0, buf_size );
#if 1
// std::cout << "IOCTL_CDROM_RAW_READ" << std::endl;
if ( !::DeviceIoControl( hDevice,
IOCTL_CDROM_RAW_READ,
&rri, sizeof(rri),
buf, buf_size,
&nBytsRead,
(LPOVERLAPPED)0 ) )
{
int i = 0;
char tmp[32];
for ( ; i < buf_size && !buf[i]; ++i );
if ( i < buf_size )
_snprintf( tmp, sizeof( tmp), "Sector %d buf!=0", sector );
else
_snprintf( tmp, sizeof( tmp), "Sector %d", sector );
printErr( tmp );
return false;
}
else
#endif
{
#if 0
std::cout << " Read " << nBytsRead << " bytes" << std::endl;
const int cCol = 16;
for ( int i = 0; i < int(nBytsRead) ; )
{
int k = i;
for ( int j = 0; j < cCol && k < int(nBytsRead); ++k, ++j )
{
std::cout << std::hex << (((unsigned)( buf[k] ) >> 4) & 0xF ) << ((unsigned)( buf[k] ) & 0x0F ) << " ";
}
for ( int j = 0; j < cCol && i < int(nBytsRead); ++i, ++j )
{
if ( 32 < buf[i] && buf[i] < 255 )
std::cout << buf[i];
else
std::cout << ' ';
}
std::cout << std::endl;
}
#endif
}
// CB_CDROMSECTOR
#if 0
if (m_bTocValid && ((sector + NumSectors) <= GetEndSector(m_TOC.LastTrack)))
{
RAW_READ_INFO rri;
rri.TrackMode = CDDA;
rri.SectorCount = (DWORD)NumSectors;
rri.DiskOffset.QuadPart = sector*CB_CDROMSECTOR;
DWORD charsRead = 0;
if (::DeviceIoControl(m_hDrive, IOCTL_CDROM_RAW_READ, &rri, sizeof(rri), Buffer, (DWORD)NumSectors * CB_AUDIO, &charsRead, NULL) != 0)
return true;
else
return false;
}
else
return false;
#endif
return nBytsRead;
}
int _tmain(int argc, _TCHAR* argv[])
{
//TCHAR szDevice[] = L"\\\\.\\PhysicalDrive0";
//TCHAR szDevice[] = L"\\\\.\\PhysicalDrive2";
TCHAR szDevice[] = L"\\\\.\\E:";
FILE* f = fopen( "dump.txt", "wb" );
device d;
if ( !d.create( szDevice ) )
{
std::cerr << "Cannot open device." << std::endl;
return 1;
}
if ( !d.storageCheckVerify() )
{
std::cerr << "Media is not accessable." << std::endl;
return 2;
}
if ( !d.storageMediaLock() )
{
std::cerr << "Cannot lock the media." << std::endl;
return 3;
}
// d.diskGetDriveGeometry();
// d.storageReadCapacity();
// d.diskGetCacheInformation();
// d.diskPerformance();
// d.cdromDiskInfo();
d.cdromReadTOC();
const int nStart = 000;
const int nAmount = nStart + 350000;
int i = nStart;
char buf[ 2*FRAME_DATA ];
for ( ; i < nAmount; ++i )
{
int n = d.cdromRawRead( i, 1, buf, sizeof( buf ) );
// fwrite( buf, 1, n, f );
}
d.storageMediaUnlock();
d.storageMediaUnlock();
d.storageMediaUnlock();
d.storageMediaUnlock();
d.storageMediaUnlock();
d.storageMediaUnlock();
// d.storageEjectMedia();
d.close();
fclose( f );
return 0;
}