「C言語/C++/readtoc」の編集履歴(バックアップ)一覧に戻る

C言語/C++/readtoc - (2012/10/12 (金) 19:39:14) のソース

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

Windows Driver Kit Version 7.1.0

参考
-[[TOCの取得>http://www2.muroran-it.ac.jp/circle/mpc/front/old1/program/windows/spti_cdda/spti04.html]]

readtoc.cpp
#highlight(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