Записать метку CDR/DVDR
От: Zvezdopad Россия http://vromanv.newmail.ru
Дата: 13.09.04 13:17
Оценка:
Для записи метки на дискету использовали SetVolumeLabel, при попытке использовать эту же функцию для записи метки на перезаписываемые носители типа CDR(W)/DVDR(W) получаю ошибку 1005 "не определённая файлавая система"
Может уважаемый All подскажет, как правильно записать метку на такие носители (CDR/DVDR) ?
Re: Записать метку CDR/DVDR
От: Patalog Россия  
Дата: 14.09.04 06:12
Оценка: 2 (1)
Здравствуйте, Zvezdopad, Вы писали:

[]

Метка диска на CDR(W) согласно ISO 9660 есть Volume Identifier, который находится в Primary Volume Descriptor по смещению 41 to 72, такой же идентификатор (для Joilet) находится в Supplementary Volume Descriptor, по тому же смещению.
Как записать? Подготовить фаловую систему диска, согласно ISO 9660 (level 1, 2, 3) + Joilet по-вкусу, в которую и входит Primary (Supplementary) Volume Descriptor как составная часть, и записать все это дело на диск, используя ASPI либо SPTI. Еще можно использовать IMAPI, тогда вообще не нужено заморачиваться — IJolietDiscMaster вся за тебя сделает. Правда это только для XP.
Почетный кавалер ордена Совка.
Re[2]: Записать метку CDR/DVDR
От: Zvezdopad Россия http://vromanv.newmail.ru
Дата: 20.09.04 05:37
Оценка:
Здравствуйте, Patalog

Подскажите, плз, где можно посмотреть работающий пример на базе IJolietDiscMaster?
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));
Почетный кавалер ордена Совка.
Re[4]: Записать метку CDR/DVDR
От: Аноним  
Дата: 08.06.05 17:05
Оценка:
Хороший пример.
Только у меня временами
1) не проходит SetActiveDiscRecorder(), вываливается с кодом IMAPI_E_STASHINUSE
2) постоянно вызов RecordDisc() вываливается с кодом IMAPI_E_MEDIUM_INVALIDTYPE (проверял, диск вполне пригодный для записи, Неро пишет на него)

Кто пользовался этим компонентом, посдскажите плз в чем могут быть грабли. Может, у кого есть ещё какой примерчик...
Re[5]: Записать метку CDR/DVDR
От: Patalog Россия  
Дата: 09.06.05 06:19
Оценка:
Здравствуйте, <Аноним>, Вы писали:

[]

А>1) не проходит SetActiveDiscRecorder(), вываливается с кодом IMAPI_E_STASHINUSE


Скорее всего кто-нить уже пользует компонент, напр. тот же Nero.

А>2) постоянно вызов RecordDisc() вываливается с кодом IMAPI_E_MEDIUM_INVALIDTYPE (проверял, диск вполне пригодный для записи, Неро пишет на него)


А QueryMediaType & QueryMediaInfo чего говорят?
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Почетный кавалер ордена Совка.
Re[4]: Записать метку CDR/DVDR
От: Juny Россия  
Дата: 09.06.05 09:56
Оценка:
IStorage::CreateStream() в качестве 1-го параметра принимает строчку, как сказано в документации, не более 32 символов длиной. Однако, я столкнулся с тем, что длины имен файлов, которые нужно копировать, бывают значительно больше, и прожигалки умеют их записывать.
Я так понимаю, что IJolietDiscMaster записывает имена файлов такие, какие прописаны в том IStorage, который подается в ф-ю AddData().
А как можно записать файл с длиной названия более 32 символов?
Спасибо.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.