Re[3]: Записать метку CDR/DVDR
От: Patalog Россия  
Дата: 20.09.04 08:22
Оценка: 21 (2)
Здравствуйте, Zvezdopad, Вы писали:

[]

    CComPtr<IDiscMaster> disk_master;
    disk_master.CoCreateInstance(CLSID_MSDiscMasterObj);
    ATLASSERT(disk_master);

    HRESULT res = S_FALSE;

    res = disk_master->Open();
    _ASSERTE(SUCCEEDED(res));

    //enum supported formats (interface IDs) if need. Current only two formats supported - RedBook (IID_IRedbookDiscMaster) & Joilet (IID_IJolietDiscMaster)
    CComPtr<IEnumDiscMasterFormats> format_enumerator;
    res = disk_master->EnumDiscMasterFormats(&format_enumerator);
    _ASSERTE(format_enumerator);

    //enum recorders if needed. Maybe you have multiple recorders?
    CComPtr<IEnumDiscRecorders> recorder_enumerator;
    res = disk_master->EnumDiscRecorders(&recorder_enumerator);
    ATLASSERT(recorder_enumerator);
    IDiscRecorder* recorder = NULL;
    if (recorder_enumerator->Next(1, &recorder, &celt_returned) != S_OK) //use 1st recorder
    _ASSERTE(FALSE); //no recorders
    
    { //print recorder props ... 
        CComBSTR vendor, product, revision;
        res = recorder->GetDisplayNames(&vendor, &product, &revision);
        _ASSERTE(SUCCEEDED(res));

        USES_CONVERSION;
        std::cout << count << ": " << W2A(vendor) << "\t" << W2A(product) << "\t" << W2A(revision) << std::endl;
    }
    
    res = disk_master->SetActiveDiscRecorder(recorder);
    _ASSERTE(SUCCEEDED(res));

    CComPtr<IJolietDiscMaster> joilet_master = NULL;
    res = disk_master->SetActiveDiscMasterFormat(IID_IJolietDiscMaster, reinterpret_cast<void**>(&joilet_master));
    _ASSERTE(joilet_master);

    { //print total number of blocks available for staging a data disc
        LONG total_blocks = 0;
        res = joilet_master->GetTotalDataBlocks(&total_blocks);
        _ASSERTE(SUCCEEDED(res));
        std::cout << "Total blocks: " << total_blocks << std::endl;
    }
    
    { //print total data blocks staged in image
        LONG used_blocks = 0;
        res = joilet_master->GetUsedDataBlocks(&used_blocks);
        _ASSERTE(SUCCEEDED(res));
        std::cout << "Used blocks: " << used_blocks << std::endl;
    }
    
    CComPtr<IPropertyStorage> joilet_properties;
    joilet_master->GetJolietProperties(&joilet_properties);
    _ASSERTE(joilet_properties);

    { //read & print current disk props if need
        const int prop_count = 6;
        PROPSPEC prop_specs[prop_count] = { { PRSPEC_LPWSTR }, 
                                            { PRSPEC_LPWSTR },
                                            { PRSPEC_LPWSTR },
                                            { PRSPEC_LPWSTR },
                                            { PRSPEC_LPWSTR },
                                            { PRSPEC_LPWSTR } };
        prop_specs[0].lpwstr = L"VolumeName";
        prop_specs[1].lpwstr = L"PlaceBootImageOnDisc";
        prop_specs[2].lpwstr = L"BootImageManufacturerIDString";
        prop_specs[3].lpwstr = L"BootImagePlatform";
        prop_specs[4].lpwstr = L"BootImageEmulationType";
        prop_specs[5].lpwstr = L"BootImage";
    
        PROPVARIANT prop_values[prop_count] = { 0 };
        res = joilet_properties->ReadMultiple(prop_count, prop_specs, prop_values);
        _ASSERTE(SUCCEEDED(res));
    
        for (int i = 0; i < prop_count; ++i)
        {
            USES_CONVERSION;
            if (prop_values[i].vt == VT_BSTR)
                std::cout << W2A(prop_specs[i].lpwstr) << ": " << W2A(prop_values[i].bstrVal) << std::endl;
        }
    }
    
    //
    //... change needed prop_values, eg. VolumeName, and use SetJolietProperties, 
    //
    
    CComPtr<IStorage> data_storage;
    res = StgCreateStorageEx(L"work", STGM_READWRITE | STGM_CREATE | STGM_DELETEONRELEASE | STGM_SHARE_EXCLUSIVE, STGFMT_STORAGE , 
                            0, 0, 0, IID_IStorage, reinterpret_cast<void**>(&data_storage));
    _ASSERTE(data_storage);

    //create and add files data to IStorage. You can add as many files & folder to IStorage as you want.
    //Substorages of become folders and streams become files on disk.
    CComPtr<IStream> file_stream;
    res = SHCreateStreamOnFile("my_cool_file.cool", STGM_READWRITE | STGM_SHARE_EXCLUSIVE, &file_stream);
    _ASSERTE(file_stream);
    
    CComPtr<IStream> storage_stream;
    res = data_storage->CreateStream(L"my_cool_file.cool", STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &storage_stream);
    _ASSERTE(storage_stream);

    STATSTG stat_stg = { 0 };
    res = file_stream->Stat(&stat_stg, STATFLAG_NONAME);
    _ASSERTE(SUCCEEDED(res));

    //Copy file data to IStream. You can write your own IStream implementation to use file data "in-place" without copying...
    ULARGE_INTEGER bytes_read = { 0 }, bytes_written = { 0 };
    res = file_stream->CopyTo(storage_stream, stat_stg.cbSize, &bytes_read, &bytes_written);
    _ASSERTE(bytes_written.QuadPart == stat_stg.cbSize.QuadPart);
    file_stream.Release();

    res = storage_stream->Commit(STGC_DEFAULT);
    _ASSERTE(SUCCEEDED(res));
    storage_stream.Release();

    res = data_storage->Commit(STGC_DEFAULT);
    _ASSERTE(SUCCEEDED(res));

    res = joilet_master->AddData(data_storage, 0 /*-don't overwrite existing files with the same name*/);
    _ASSERTE(SUCCEEDED(res));

    //Record disk
    res = disk_master->RecordDisc(false, true);
    _ASSERTE(SUCCEEDED(res));

    res = disk_master->Close();
    _ASSERTE(SUCCEEDED(res));
Почетный кавалер ордена Совка.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.