開発環境 Microsoft Visual C++ 2010 Express (SP1)
実行環境 Microsoft Windows XP Home Edition (SP3)
プロジェクトの種類 Win32 コンソール アプリケーション
プロジェクト名 readtoc
アプリケーションの種類 コンソール アプリケーション
追加のオプション 空のプロジェクト
文字セット Unicode

Windows Driver Kit Version 7.1.0

参考

readtoc.cpp
/*
[構成プロパティ]-[VC++ ディレクトリ]-[インクルード ディレクトリ]
C:\WinDDK\7600.16385.1\src\storage\tools\spti
 
Unicode文字セット
*/
#include <Windows.h>
#include <tchar.h>
#include <locale.h>
#include <stddef.h>
 
#include <ntddscsi.h>
#include <spti.h>
 
#define REVWORD(w) (((w<<8)&0xff00)|((w>>8)&0xff))
#define REVDWORD(dw) (((dw<<24)&0xff000000)|((dw<<8)&0xff0000)|((dw>>8)&0xff00)|((dw>>24)&0xff))
 
struct READTOC {
	WORD wLen;
	BYTE byStartTrack;
	BYTE byEndTrack;
	struct TRACKDESC {
		BYTE d0;
		BYTE data;
		BYTE byTrack;
		BYTE d1;
		DWORD dwLBA;
	} td[100];
};
 
// 関数プロトタイプ宣言
int TrackList(TCHAR cDrv);
DWORD ExecCommand(
	HANDLE hDev,		// デバイスハンドル
	PUCHAR pucCdb,		// コマンド(SCSI command descriptor block)
	UCHAR ucCdbLen,		// コマンドの長さ
	PVOID pvData,		// バッファ
	ULONG ulDataLen);	// バッファの長さ
 
//==============================================================================
int _tmain(int argc, LPTSTR argv[])
{
	TCHAR szDrv[] = _T("@:\\");
	UINT ur;
 
	_tsetlocale(LC_CTYPE, _T(""));
	if (argc != 2) {
		_ftprintf(stderr, _T("usage: readtoc drive\n"));
		return 1;
	}
	szDrv[0] = argv[1][0];
	ur = GetDriveType(szDrv);
	if (ur != DRIVE_CDROM) {
		_ftprintf(stderr, _T("CD-ROMドライブではありません。\n"));
		return 1;
	}
	TrackList(szDrv[0]);
	return 0;
}
 
//------------------------------------------------------------------------------
int TrackList(TCHAR cDrv)
{
	int nRet = 0;
 
	// デバイスのオープン
	TCHAR szDev[] = _T("\\\\.\\@:");
	HANDLE hDev;
	BOOL br;
 
	szDev[4] = cDrv;
	hDev = CreateFile(szDev, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ,
		NULL, OPEN_EXISTING, 0, NULL);
	if (hDev == INVALID_HANDLE_VALUE) {
		return -1;
	}
 
	// TOC
	BYTE byBuf[sizeof (READTOC) + 0xf];	// パラグラフ境界
	READTOC *ptoc = (READTOC *)(((UINT_PTR)byBuf + 0xf) & ~0xf);
	UCHAR ucCdb[10];
	DWORD dw;
 
	ZeroMemory(ptoc, sizeof *ptoc);
	ZeroMemory(ucCdb, sizeof ucCdb);
	ucCdb[0] = SCSIOP_READ_TOC;
	ucCdb[6] = 1;
	*(PWORD)(ucCdb + 7) = REVWORD(sizeof *ptoc);
 
	dw = ExecCommand(hDev, ucCdb, sizeof ucCdb, ptoc, sizeof *ptoc);
	if (dw == 0) {
		nRet = -1;
		goto Exit;
	}
 
	// トラック一覧
	BYTE by;
 
	_tprintf(_T("Track\tAttr\tLBA\tLen\n"));
	for (by = 0; by < ptoc->byEndTrack; by++) {
		BYTE byData = ptoc->td[by].data;
		DWORD dwStartAddr = REVDWORD(ptoc->td[by].dwLBA);
		DWORD dwEndAddr = REVDWORD(ptoc->td[by+1].dwLBA) - 1;
		DWORD dwLen = dwEndAddr - dwStartAddr + 1;
		_tprintf(_T("%2u\t%#4x\t%6u\t%6u\n"), by+1, byData, dwStartAddr, dwLen);
	}
Exit:
	br = CloseHandle(hDev);
	return nRet;
}
 
//------------------------------------------------------------------------------
DWORD ExecCommand(
	HANDLE hDev,		// デバイスハンドル
	PUCHAR pucCdb,		// コマンド(SCSI command descriptor block)
	UCHAR ucCdbLen,		// コマンドの長さ
	PVOID pvData,		// バッファ
	ULONG ulDataLen)	// バッファの長さ
{
	SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER swb;
	DWORD dwRet;
	BOOL br;
 
	ZeroMemory(&swb, sizeof swb);
	swb.sptd.Length			= sizeof swb.sptd;
	//
	swb.sptd.CdbLength		= ucCdbLen;
	swb.sptd.SenseInfoLength	= sizeof swb.ucSenseBuf;
	swb.sptd.DataIn			= SCSI_IOCTL_DATA_IN;
	swb.sptd.DataTransferLength	= ulDataLen;
	swb.sptd.TimeOutValue		= 10;	// 秒
	swb.sptd.DataBuffer		= pvData;
	swb.sptd.SenseInfoOffset = offsetof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER, ucSenseBuf);
	memcpy_s(&swb.sptd.Cdb, sizeof swb.sptd.Cdb, pucCdb, ucCdbLen);
 
	br = DeviceIoControl(
		hDev,
		IOCTL_SCSI_PASS_THROUGH_DIRECT,
		&swb, sizeof swb,
		&swb, sizeof swb,
		&dwRet,
		NULL);
	if (br == FALSE) {
		return 0;
	}
	return dwRet;
}
 

出力
Track   Attr    LBA     Len
 1      0x10        37    5375
 2      0x10      5412   29128
 3      0x10     34540   16385
 4      0x10     50925    5242
 5      0x10     56167    5330
 6      0x10     61497   11800
 7      0x10     73297   15910
 8      0x10     89207   16218
 9      0x10    105425    5357
10      0x10    110782    8218
11      0x10    119000   11050
12      0x10    130050   21600
13      0x10    151650   18567
14      0x10    170217    7825
最終更新:2012年10月12日 19:39