このページは『[VC] IMAPI v1(その1)』記事のサンプルコードです。
誤っている箇所がありましたら、記事のコメント欄に連絡願います。
//-----------------------------------------------------------------------------
// main.cpp - IMAPAv1サンプル1 情報表示
//
// 2007/02/04 … VC++2005用サンプル
// 2007/02/09 … 冗長的な箇所を修正
//-----------------------------------------------------------------------------
#define WIN32_LEAN_AND_MEAN
#include <atlbase.h>
#include <stdio.h>
#include <tchar.h>
#include <locale.h>       // _tsetlocale()
#include <conio.h>        // _getch()
#include <imapi.h>        // IMAPI support.
#include <imapierror.h>   // IMAPI error.

// プロトタイプ
void DispEnumRecorders(IDiscMaster* &pIdm);
void DispRecorderInfo(CComPtr<IDiscRecorder> & pRecorder);
void DispRecorderProp(CComPtr<IDiscRecorder> & pRecorder);
BOOL DispMediaInfo(CComPtr<IDiscRecorder> & pRecorder);
BOOL FindDriveLetter(LPCTSTR szOSPath, LPTSTR szDrive);

//-----------------------------------------------------------------------------
// エントリーポイント
//-----------------------------------------------------------------------------
int _tmain(int argc, _TCHAR* argv[])
{
    IDiscMaster* pIdm;
    HRESULT hr;

    _tsetlocale( LC_ALL, _T("jpn") );

    // COM初期化
    hr = ::CoInitialize(NULL);
    ATLASSERT(SUCCEEDED(hr));

    // インスタンス作成
    hr = CoCreateInstance(
            CLSID_MSDiscMasterObj,
            NULL,
            CLSCTX_LOCAL_SERVER,
            IID_IDiscMaster,
            (void **) &pIdm );
    ATLASSERT(SUCCEEDED(hr));

    // IMAPIへのアクセス開始
    hr = pIdm->Open();
    ATLASSERT(SUCCEEDED(hr));

    // ドライブの情報を表示する
    DispEnumRecorders( pIdm );

    // IMAPIへのアクセス終了
    pIdm->Close();
    pIdm->Release();

    _tprintf_s(_T("...何かキーを押すと終了します"));
    _gettch();

    ::CoUninitialize();
    return 0;
}

//-----------------------------------------------------------------------------
// レコーダーの列挙
//-----------------------------------------------------------------------------
void DispEnumRecorders(IDiscMaster* &pIdm)
{
    HRESULT    hr;

    CComPtr<IEnumDiscRecorders> pEnum;
    hr = pIdm->EnumDiscRecorders( &pEnum );
    if(!SUCCEEDED(hr)) return;

    while( 1 )
    {
        _tprintf_s(_T("==========================================\n"));

        CComPtr<IDiscRecorder> pRecorder;
        ULONG cFetched;
        hr = pEnum->Next( 1, &pRecorder, &cFetched );
        ATLASSERT(SUCCEEDED(hr));

        if(!pRecorder)
            break;    // 検索終了

        // レコーダー情報
        DispRecorderInfo( pRecorder );

        // メディア情報表示
        DispMediaInfo( pRecorder );

        // レコーダープロパティ
        DispRecorderProp( pRecorder );
    }
}

//-----------------------------------------------------------------------------
// レコーダーの情報表示
//-----------------------------------------------------------------------------
void DispRecorderInfo(
    CComPtr<IDiscRecorder> & pRecorder
    )
{
    HRESULT    hr;

    _tprintf_s(_T("[RecorderInfo]\n"));

    // デバイスGUID
    char dbcc_name[1024];
    ULONG ulReturnSizeRequired;
    hr = pRecorder->GetRecorderGUID( (byte*)dbcc_name, 1024, &ulReturnSizeRequired );
    ATLASSERT(SUCCEEDED(hr));
    _tprintf_s(_T("  GetRecorderGUID():\n  %s\n"), CA2T(dbcc_name));

    // PnPID
    CComBSTR bstrBasePnPID;
    hr = pRecorder->GetBasePnPID( &bstrBasePnPID );
    ATLASSERT(SUCCEEDED(hr));
    _tprintf_s(_T("  GetBasePnPID(): %s\n"), CW2T(bstrBasePnPID.m_str));

    // 表示名
    CComBSTR bstrVendorID, bstrProductID, bstrRevision;
    hr = pRecorder->GetDisplayNames( &bstrVendorID, &bstrProductID, &bstrRevision );
    ATLASSERT(SUCCEEDED(hr));
    _tprintf_s(_T("  VendorID : %s\n"), CW2T(bstrVendorID.m_str));
    _tprintf_s(_T("  ProductID: %s\n"), CW2T(bstrProductID.m_str));
    _tprintf_s(_T("  Revision : %s\n"), CW2T(bstrRevision.m_str));

    // MS-DOS デバイス情報
    CComBSTR bstrPath;
    hr = pRecorder->GetPath( &bstrPath );
    ATLASSERT(SUCCEEDED(hr));
    _tprintf_s(_T("  GetPath(): %s\n"), CW2T(bstrPath.m_str));

    // ドライブレター
    TCHAR szDrvLetter[_MAX_DRIVE];
    if( FindDriveLetter( CW2T(bstrPath.m_str), szDrvLetter ) )
    {
        _tprintf_s(_T("  drive letter: %s\n"), szDrvLetter);
    }

    // レコーダータイプ
    long TypeCode;    // 0x1:RECORDER_CDR, 0x2:RECORDER_CDRW
    hr = pRecorder->GetRecorderType( &TypeCode );
    ATLASSERT(SUCCEEDED(hr));
    if(TypeCode == 0x01){
        _tprintf_s(_T("RecorderType: RECORDER_CDR\n"));
    }else
    if(TypeCode == 0x02){
        _tprintf_s(_T(" RecorderType: RECORDER_CDRW\n"));
    }else{
        _tprintf_s(_T(" RecorderType: \n"));
    }

    // ドライブの状態
    ULONG ulDevStateFlags;
    hr = pRecorder->GetRecorderState( &ulDevStateFlags );
    ATLASSERT(SUCCEEDED(hr));
    if( ulDevStateFlags == RECORDER_DOING_NOTHING ){
        _tprintf_s(_T("DevStateFlags: RECORDER_DOING_NOTHING\n"));
    }else
    if( ulDevStateFlags == RECORDER_OPENED ){
        _tprintf_s(_T(" DevStateFlags: RECORDER_OPENED\n"));
    }else
    if( ulDevStateFlags == RECORDER_BURNING ){
        _tprintf_s(_T(" DevStateFlags: RECORDER_BURNING\n"));
    }
}

//-----------------------------------------------------------------------------
// メディアの情報表示
//-----------------------------------------------------------------------------
BOOL DispMediaInfo(
    CComPtr<IDiscRecorder> & pRecorder
    )
{
    HRESULT    hr;
    BOOL bResult = FALSE;

    // メディア情報を取得する前にドライブに対して排他的ロックをかける
    hr = pRecorder->OpenExclusive();
    if(!SUCCEEDED(hr)) return bResult;

    _tprintf_s(_T("[MediaInfo]\n"));

    byte sessions;
    byte lasttrack;
    ULONG ulstartaddress;
    ULONG ulnextwritable;
    ULONG ulfreeblocks;

    // メディア情報取得
    hr = pRecorder->QueryMediaInfo( &sessions, &lasttrack,
        &ulstartaddress, &ulnextwritable, &ulfreeblocks );
    if(SUCCEEDED(hr))
    {
        _tprintf_s(_T("  Sessions     : %d\n"), sessions      );
        _tprintf_s(_T("  LastTrack    : %d\n"), lasttrack     );
        _tprintf_s(_T("  StartAddress : %d\n"), ulstartaddress);
        _tprintf_s(_T("  NextWritable : %d\n"), ulnextwritable);
        _tprintf_s(_T("  FreeBlocks   : %d\n"), ulfreeblocks  );

        long MediaType;
        long MediaFlags;

        // メディアの種別取得
        hr = pRecorder->QueryMediaType(&MediaType, &MediaFlags);
        if(SUCCEEDED(hr))
        {
            if(MediaType == MEDIA_CD_EXTRA)
                _tprintf_s(_T("MediaType : MEDIA_CD_EXTRA\n")  );
            else if(MediaType == MEDIA_CD_I)
                _tprintf_s(_T(" MediaType : MEDIA_CD_I\n")      );
            else if(MediaType == MEDIA_CD_OTHER)
                _tprintf_s(_T(" MediaType : MEDIA_CD_OTHER\n")  );
            else if(MediaType == MEDIA_CD_ROM_XA)
                _tprintf_s(_T(" MediaType : MEDIA_CD_ROM_XA\n") );
            else if(MediaType == MEDIA_CDDA_CDROM)
                _tprintf_s(_T(" MediaType : MEDIA_CDDA_CDROM\n"));
            else if(MediaType == MEDIA_SPECIAL)
                _tprintf_s(_T(" MediaType : MEDIA_SPECIAL\n")   );

            _tprintf_s(_T("  MediaFlags   : "));
            if(MediaFlags & MEDIA_BLANK)
                _tprintf_s(_T("MEDIA_BLANK, "));
            if(MediaFlags & MEDIA_RW)
                _tprintf_s(_T("MEDIA_RW, "));
            if(MediaFlags & MEDIA_WRITABLE)
                _tprintf_s(_T("MEDIA_WRITABLE, "));
            _tprintf_s(_T("\n"));
        }
        bResult = TRUE;

    }else
    if(hr == IMAPI_E_MEDIUM_NOTPRESENT){
        _tprintf_s(_T(" Nothing...\n"));
    }

    // ロック解除
    hr = pRecorder->Close();
    ATLASSERT(SUCCEEDED(hr));

    return bResult;
}

//-----------------------------------------------------------------------------
// レコーダーのプロパティ表示
//-----------------------------------------------------------------------------
void DispRecorderProp(
    CComPtr<IDiscRecorder> & pRecorder
    )
{
    PROPSPEC    iPropSpec[5];
    PROPVARIANT iPropVariant[5];
    HRESULT    hr;

    // レコーダーのIPropertyStorageインタフェースを取得
    CComPtr<IPropertyStorage> pPropertyStorage;
    hr = pRecorder->GetRecorderProperties(&pPropertyStorage);
    if(!SUCCEEDED(hr)) return ;

    _tprintf_s(_T("[RecorderProp]\n"));

    int cnt = sizeof(iPropSpec) / sizeof(PROPSPEC);
    iPropSpec[0].ulKind = PRSPEC_LPWSTR;
    iPropSpec[0].lpwstr = L"WriteSpeed";
    iPropSpec[1].ulKind = PRSPEC_LPWSTR;
    iPropSpec[1].lpwstr = L"MaxWriteSpeed";
    iPropSpec[2].ulKind = PRSPEC_LPWSTR;
    iPropSpec[2].lpwstr = L"EnableBufferUnderrunFree";
    iPropSpec[3].ulKind = PRSPEC_LPWSTR;
    iPropSpec[3].lpwstr = L"BufferUnderrunFreeCapable";
    iPropSpec[4].ulKind = PRSPEC_LPWSTR;
    iPropSpec[4].lpwstr = L"AudioGapSize";

    // レコーダーのIPropertyStorageインタフェースを取得
    hr = pPropertyStorage->ReadMultiple( cnt, iPropSpec, iPropVariant );
    if(SUCCEEDED(hr))
    {
        // 書き込み速度
        if(iPropVariant[0].vt == VT_I4)
            _tprintf_s(_T("  WriteSpeed     : %d\n"), iPropVariant[0].lVal);

        // 最大書き込み速度
        if(iPropVariant[1].vt == VT_I4)
            _tprintf_s(_T("  MaxWriteSpeed  : %d\n"), iPropVariant[1].lVal);

        // バッファアンダーラン防止機能の状態
        // -1:ドライブがサポートしているなら使用する
        //  0:ドライブがサポートしていない
        //  1:ドライブがサポートしている
        if(iPropVariant[2].vt == VT_I4)
            _tprintf_s(_T("  EnableBufferUnderrunFree  : %d\n"), iPropVariant[2].lVal);

        // バッファアンダーラン防止機能の有無
        if(iPropVariant[3].vt == VT_BOOL)
        {
            if(iPropVariant[3].boolVal == VARIANT_TRUE)
                _tprintf_s(_T(" BufferUnderrunFreeCapable : TRUE\n"));
            else
                _tprintf_s(_T(" BufferUnderrunFreeCapable : FALSE\n"));
        }

        // オーディオギャップサイズ
        if(iPropVariant[4].vt == VT_I4)
            _tprintf_s(_T("  AudioGapSize   : %d\n"), iPropVariant[4].lVal);
    }
}

//-----------------------------------------------------------------------------
// MS-DOS デバイス情報からドライブレターの取得
//-----------------------------------------------------------------------------
BOOL FindDriveLetter(
    LPCTSTR szTargetPath,
    LPTSTR szDrive
    )
{
    TCHAR drive[256];
    TCHAR* pdrv=drive;
    ::GetLogicalDriveStrings(256, drive);
    while(lstrlen(pdrv))
    {
        TCHAR DosDeviceName[_MAX_DRIVE], DevicePath[1024];

        lstrcpyn(DosDeviceName, pdrv, _MAX_DRIVE);
        QueryDosDevice(DosDeviceName, DevicePath, 1024);

        if(lstrcmp(DevicePath, szTargetPath)==0)
        {
            lstrcpyn(szDrive, pdrv, _MAX_DRIVE);
            return TRUE;
        }
        pdrv += (lstrlen(pdrv) + 1);
    }
    return FALSE;
}
今日のジャンク.txt