// ---------------------------------------------------------------------- // This software is part of the OpenBeOS distribution and is covered // by the OpenBeOS license. // // File Name: VolumeRoster.cpp // // Description: BVolumeRoster class // ---------------------------------------------------------------------- /*! \file VolumeRoster.cpp BVolumeRoster implementation. */ #include #include #include #include #include #include #include #include static const char kBootVolumePath[] = "/boot"; using namespace std; #ifdef USE_OPENBEOS_NAMESPACE namespace OpenBeOS { #endif /*! \class BVolumeRoster \brief A roster of all volumes available in the system Provides an interface for iterating through the volumes available in the system and watching volume mounting/unmounting. The class wraps the next_dev() function for iterating through the volume list and the watch_node()/stop_watching() for the watching features. \author Vincent Dominguez \author Ingo Weinhold \version 0.0.0 */ /*! \var dev_t BVolumeRoster::fCookie \brief The iteration cookie for next_dev(). Initialized with 0. */ /*! \var dev_t BVolumeRoster::fTarget \brief BMessenger referring to the target to which the watching notification messages are sent. The object is allocated and owned by the roster. \c NULL, if not watching. */ // constructor /*! \brief Creates a new BVolumeRoster. The object is ready to be used. */ BVolumeRoster::BVolumeRoster() : fCookie(0), fTarget(NULL) { } // destructor /*! \brief Frees all resources associated with this object. If a watching was activated on (StartWatching()), it is deactived. */ BVolumeRoster::~BVolumeRoster() { StopWatching(); } // GetNextVolume /*! \brief Returns the next volume in the list of available volumes. \param volume A pointer to a pre-allocated BVolume to be initialized to refer to the next volume in the list of available volumes. \return - \c B_OK: Everything went fine. - \c B_BAD_VALUE: The last volume in the list has already been returned. */ status_t BVolumeRoster::GetNextVolume(BVolume *volume) { // check parameter status_t error = (volume ? B_OK : B_BAD_VALUE); // get next device dev_t device; if (error == B_OK) { device = next_dev(&fCookie); if (device < 0) error = device; } // init volume if (error == B_OK) error = volume->SetTo(device); return error; } // Rewind /*! \brief Rewinds the list of available volumes such that the next call to GetNextVolume() will return the first element in the list. */ void BVolumeRoster::Rewind() { fCookie = 0; } // GetBootVolume /*! \brief Returns the boot volume. Currently, this function looks for the volume that is mounted at "/boot". The only way to fool the system into thinking that there is not a boot volume is to rename "/boot" -- but, please refrain from doing so...(:o( \param volume A pointer to a pre-allocated BVolume to be initialized to refer to the boot volume. \return - \c B_OK: Everything went fine. - an error code otherwise */ status_t BVolumeRoster::GetBootVolume(BVolume *volume) { // check parameter status_t error = (volume ? B_OK : B_BAD_VALUE); // get device dev_t device; if (error == B_OK) { device = dev_for_path(kBootVolumePath); if (device < 0) error = device; } // init volume if (error == B_OK) error = volume->SetTo(device); return error; } // StartWatching /*! \brief Starts watching the list of volumes available in the system. Notifications are sent to the specified target whenever a volume is mounted or unmounted. The format of the notification messages is described under watch_node(). Actually BVolumeRoster just provides a more convenient interface for it. If StartWatching() has been called before with another target and no StopWatching() since, StopWatching() is called first, so that the former target won't receive any notifications anymore. When the object is destroyed all watching has an end as well. \param messenger The target to which the notification messages shall be sent. \return - \c B_OK: Everything went fine. - \c B_BAD_VALUE: The supplied BMessenger is invalid. - \c B_NO_MEMORY: Insufficient memory to carry out this operation. */ status_t BVolumeRoster::StartWatching(BMessenger messenger) { StopWatching(); status_t error = (messenger.IsValid() ? B_OK : B_ERROR); // clone messenger if (error == B_OK) { fTarget = new(nothrow) BMessenger(messenger); if (!fTarget) error = B_NO_MEMORY; } // start watching if (error == B_OK) error = watch_node(NULL, B_WATCH_MOUNT, messenger); // cleanup on failure if (error != B_OK && fTarget) { delete fTarget; fTarget = NULL; } return error; } // StopWatching /*! \brief Stops volume watching initiated with StartWatching() before. */ void BVolumeRoster::StopWatching() { if (fTarget) { stop_watching(*fTarget); delete fTarget; fTarget = NULL; } } // Messenger /*! \brief Returns a messenger to the target currently watching the volume list. \return A messenger to the target currently watching the volume list, or an invalid messenger, if noone is currently watching. */ BMessenger BVolumeRoster::Messenger() const { return (fTarget ? *fTarget : BMessenger()); } // FBC void BVolumeRoster::_SeveredVRoster1() {} void BVolumeRoster::_SeveredVRoster2() {} #ifdef USE_OPENBEOS_NAMESPACE } #endif