開発環境 |
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