Detect Media Presence#

Detect whether there is media in a device or not. This is how you do it:

void detect_media_presense(pb::Device* device)
{
    using namespace std;

    // get device description
    auto description = p::ustring(device->description());

    // get media state and unit ready state (aka device status)
    auto media_state = device->mediaState();
    uint32_t unit_ready = device->unitReadyState();

    auto media_state_str = media_state_string(media_state);

    cout << format(" ( {}:) - {}", device->driveLetter(), description.str()) << endl;
    cout << format("  Media State      : {}", media_state_str.str()) << endl;
    cout << format("  Unit Ready State : {:#08x}", unit_ready) << endl;
    
    // get detailed SCSI sense description
    if (unit_ready != 0) {
        ScsiInterface *scsi = device->createScsiInterface();

        // derive SCSI sense from unit ready state    
        ScsiCommandSense sense = {0};
        sense.Key = (unit_ready >> 16) & 0xFF; // second byte
        sense.ASC = (unit_ready >> 8) & 0xFF; // third byte
        sense.ASCQ = unit_ready & 0xFF; // fourth byte

        // get sense message
        auto sense_message = p::ustring(scsi->getSenseMessage(&sense));
        
        cout << format("  SCSI Sense -> Key: {:#04x} ASC: {:#04x} ASCQ: {:#04x} - {}", 
                       sense.Key, sense.ASC, sense.ASCQ, sense_message.str()) << endl;

        scsi->release();
    }
    
    cout << endl;
}

For the media_state_string function definition see C++ Utility Classes and Functions

Complete C++ code#

#include <primo/burner/pb.h>
#include <primo/platform/ustring.h>
#include <primo/platform/reference++.h>

#include <iostream>
#include <format>

namespace p = primo;
namespace pb = primo::burner;

p::ustring media_state_string(pb::MediaReady::Enum media_state)
{
    switch (media_state) {
    case pb::MediaReady::StateUnknown:
        return "Unknown";
    case pb::MediaReady::NotPresent:
        return "Not Present";
    case pb::MediaReady::Present:
        return "Present";
    default:
        return "Unknown";
    }
}

void detect_media_presense(pb::Device* device)
{
    using namespace std;

    // get device description
    auto description = p::ustring(device->description());

    // get media state and unit ready state (aka device status)
    auto media_state = device->mediaState();
    uint32_t unit_ready = device->unitReadyState();

    auto media_state_str = media_state_string(media_state);

    cout << format(" ( {}:) - {}", device->driveLetter(), description.str()) << endl;
    cout << format("  Media State      : {}", media_state_str.str()) << endl;
    cout << format("  Unit Ready State : {:#08x}", unit_ready) << endl;
    
    // get detailed SCSI sense description
    if (unit_ready != 0) {
        ScsiInterface *scsi = device->createScsiInterface();

        // derive SCSI sense from unit ready state    
        ScsiCommandSense sense = {0};
        sense.Key = (unit_ready >> 16) & 0xFF; // second byte
        sense.ASC = (unit_ready >> 8) & 0xFF; // third byte
        sense.ASCQ = unit_ready & 0xFF; // fourth byte

        // get sense message
        auto sense_message = p::ustring(scsi->getSenseMessage(&sense));
        
        cout << format("  SCSI Sense -> Key: {:#04x} ASC: {:#04x} ASCQ: {:#04x} - {}", 
                       sense.Key, sense.ASC, sense.ASCQ, sense_message.str()) << endl;

        scsi->release();
    }
    
    cout << endl;
}

void detect_media_presense(pb::Engine* engine)
{
    // create device enumerator
    auto enumerator = p::make_ref(engine->createDeviceEnumerator());

    for (int i = 0; i < enumerator->count(); i++) {
        // create a device; do not ask for exclusive access
        auto device = p::make_ref(enumerator->createDevice(i, false));
        
        if (device) {
            detect_media_presense(device.get());
        }
    }
}

void detect_media_presense()
{
    // Create engine
    auto engine = p::make_ref(pb::Library::createEngine());

    // Initialize engine
    engine->initialize();

    detect_media_presense(engine.get());

    // terminate engine
    engine->shutdown();
}

int main()
{
    // Set license. To run PrimoBurner in demo mode, comment the next line out
    pb::Library::setLicense("license-xml-string");
    
    pb::Library::enableTraceLog();
    
    detect_media_presense();
    
    pb::Library::disableTraceLog();

    return 0;
}