Files
haiku-beta6/src/kits/storage/VolumeRoster.cpp
T

222 lines
5.4 KiB
C++
Raw Normal View History

// ----------------------------------------------------------------------
// 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 <errno.h>
#include <new.h>
#include <Bitmap.h>
#include <Directory.h>
#include <fs_info.h>
#include <kernel_interface.h>
#include <Node.h>
#include <NodeMonitor.h>
#include <VolumeRoster.h>
static const char kBootVolumePath[] = "/boot";
#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 <a href='mailto:[email protected]'>Ingo Weinhold</a>
\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