Beginning of Disk Device API:

* Made all headers parsable. Also some smaller changes.
* Added empty source files for new classes.
* Changed obsolete implementations of existing classes, so that we
  now have basic functionality for BDiskDevice[Roster] and BPartition.
  Iterating through disk devices works and the data we get doesn't look
  too bad for the beginning.


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@3883 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2003-07-06 23:11:10 +00:00
parent c0455c33b8
commit 5c7270efd7
17 changed files with 748 additions and 1295 deletions
+19 -7
View File
@@ -6,8 +6,15 @@
#ifndef _DISK_DEVICE_H
#define _DISK_DEVICE_H
#include <Partition.h>
struct user_disk_device_data;
class BDiskDevice : public BPartition {
public:
BDiskDevice();
virtual ~BDiskDevice();
bool IsRemovable() const;
bool HasMedia() const;
@@ -15,21 +22,26 @@ public:
status_t Update(bool *updated = NULL);
void Unset();
virtual status_t GetPath(BPath *path) const;
virtual BPartition *VisitEachDescendent(BDiskDeviceVisitor *visitor);
bool IsModified() const;
status_t PrepareModifications();
status_t CommitModifications(bool synchronously = true,
BMessenger progressMessenger = BMessenger(),
bool receiveCompleteProgressUpdates = true,
BMessage *template = NULL);
bool receiveCompleteProgressUpdates = true);
status_t CancelModifications();
private:
friend class BDiskDeviceList;
friend class BDiskDeviceRoster;
char fDeviceType[B_FILE_NAME_LENGTH];
char fPath[B_FILE_NAME_LENGTH];
status_t SetTo(partition_id id, size_t neededSize = 0);
status_t SetTo(user_disk_device_data *data);
bool fIsRemovable;
status_t fMediaStatus;
}
user_disk_device_data *fDeviceData;
};
#endif // _DISK_DEVICE_H
+9 -5
View File
@@ -6,6 +6,7 @@
#ifndef _DISK_DEVICE_JOB_H
#define _DISK_DEVICE_JOB_H
#include <DiskDeviceDefs.h>
#include <String.h>
// disk device job types
@@ -42,21 +43,24 @@ enum {
B_DISK_DEVICE_JOB_CAN_CANCEL = 0x01,
B_DISK_DEVICE_JOB_STOP_ON_CANCEL = 0x02,
B_DISK_DEVICE_JOB_REVERSE_ON_CANCEL = 0x04,
B_DISK_DEVICE_JOB_CAN_PAUSE = 0x08,
};
class BDiskDeviceJob {
public:
disk_job_id ID() const;
uint32 Type() const;
partition_id PartitionID() const;
float Progress() const; // [0.0, 1.0]
uint32 Status() const;
const char *Description() const;
status_t GetProgressInfo(disk_devive_progress_info *info) const;
uint32 CancelProperties() const;
// TODO: Add Cancel() and Pause(), SupportsPause().
partition_id PartitionID() const;
status_t GetProgressInfo(disk_device_progress_info *info) const;
uint32 InterruptProperties() const;
status_t Cancel();
status_t Pause();
private:
disk_job_id fJobID;
uint32 fType;
+1 -4
View File
@@ -6,8 +6,8 @@
#ifndef _DISK_DEVICE_PRIVATE_H
#define _DISK_DEVICE_PRIVATE_H
#include <DiskDeviceDefs.h>
#include <DiskDeviceVisitor.h>
#include <SupportDefs.h>
class BMessenger;
@@ -45,13 +45,10 @@ private:
partition_id fID;
};
status_t get_disk_device_messenger(BMessenger *messenger);
} // namespace BPrivate
using BPrivate::PartitionFilter;
using BPrivate::PartitionFilterVisitor;
using BPrivate::IDFinderVisitor;
using BPrivate::get_disk_device_messenger;
#endif // _DISK_DEVICE_PRIVATE_H
+12 -11
View File
@@ -8,17 +8,17 @@
#include <image.h>
#include <DiskDeviceVisitor.h>
#include <DiskDeviceDefs.h>
#include <Messenger.h>
#include <SupportDefs.h>
class BDirectory;
class BDiskDevice;
class BDiskDeviceJob;
class BDiskDeviceVisitor;
class BDiskScannerPartitionAddOn;
class BDiskSystem;
class BPartition;
class BSession;
namespace BPrivate {
class AddOnImage;
@@ -98,10 +98,10 @@ public:
status_t GetNextActiveJob(BDiskDeviceJob *job);
status_t RewindActiveJobs();
partition_id RegisterDeviceFile(const char *filename);
partition_id RegisterFileDevice(const char *filename);
// publishes: /dev/disk/virtual/files/<disk device ID>/raw
status_t UnregisterDeviceFile(const char *filename);
status_t UnregisterDeviceFile(partition_id device);
status_t UnregisterFileDevice(const char *filename);
status_t UnregisterFileDevice(partition_id device);
// TODO: Add the respective syscalls. Also for Get{Device,Partition}ForPath()
bool VisitEachDevice(BDiskDeviceVisitor *visitor,
@@ -138,9 +138,11 @@ public:
uint32 eventMask = B_DEVICE_REQUEST_ALL);
status_t StartWatchingJob(BDiskDeviceJob *job, BMessenger target,
uint32 eventMask = B_DEVICE_REQUEST_JOB_COMPLETE_PROGRESS);
// TODO: Maybe better a BDiskDeviceJob::{Start,Stop}Watching()?
status_t StopWatching(BMessenger target);
private:
#if 0
status_t _GetObjectWithID(const char *fieldName, partition_id id,
BDiskDevice *device) const;
@@ -159,14 +161,13 @@ private:
static status_t _LoadPartitionAddOn(const char *partitioningSystem,
BPrivate::AddOnImage *image,
BDiskScannerPartitionAddOn **addOn);
#endif // 0
private:
BMessenger fManager;
int32 fCookie;
BDirectory *fPartitionAddOnDir;
BDirectory *fFSAddOnDir;
int32 fPartitionAddOnDirIndex;
int32 fFSAddOnDirIndex;
// BDirectory *fPartitionAddOnDir;
// BDirectory *fFSAddOnDir;
// int32 fPartitionAddOnDirIndex;
// int32 fFSAddOnDirIndex;
};
#endif // _DISK_DEVICE_ROSTER_H
+6 -2
View File
@@ -6,6 +6,10 @@
#ifndef _DISK_SYSTEM_H
#define _DISK_SYSTEM_H
#include <DiskDeviceDefs.h>
class BPartition;
class BDiskSystem {
public:
const char *Name() const;
@@ -18,9 +22,9 @@ public:
bool SupportsMoving(BPartition *partition, bool *whileMounted) const;
bool SupportsMovingChild(BPartition *child) const;
bool SupportsCreatingChild(BPartition *partition) const;
bool SupportsParentSystem(KPartition *child, const char *system) const;
bool SupportsParentSystem(BPartition *child, const char *system) const;
// True in most cases. NULL == raw device.
bool SupportsChildSystem(KPartition *child, const char *system) const;
bool SupportsChildSystem(BPartition *child, const char *system) const;
// False for most file systems, true for most partitioning
// systems.
+35 -38
View File
@@ -6,16 +6,25 @@
#ifndef _PARTITION_H
#define _PARTITION_H
#include <ObjectList.h>
#include <DiskDeviceDefs.h>
#include <Messenger.h>
#include <Mime.h>
class BBitmap;
class BDiskDevice;
class BDiskDeviceVisitor;
class BPartitioningInfo;
class BDiskScannerParameterEditor; // TODO: Rename!
class BDiskSystem;
class BVolume;
struct user_partition_data;
// partition statuses
enum {
B_PARTITION_VALID,
B_PARTITION_CORRUPT,
B_PARTITION_UNRECOGNIZED,
}
};
class BPartition {
public:
@@ -33,17 +42,19 @@ public:
bool IsDevice() const;
bool IsReadOnly() const;
bool IsMounted() const;
const char* Name() const;
const char* ContentName() const;
const char* Type() const; // See DiskDeviceTypes.h
const char* ContentType() const; // See DiskDeviceTypes.h
partition_id UniqueID() const;
uint32 Flags() const;
const char *Name() const;
const char *ContentName() const;
const char *Type() const; // See DiskDeviceTypes.h
const char *ContentType() const; // See DiskDeviceTypes.h
partition_id UniqueID() const;
// TODO: just ID() ?
status_t GetDiskSystem(BDiskSystem *diskSystem) const;
status_t GetPath(BPath *path) const;
virtual status_t GetPath(BPath *path) const;
status_t GetVolume(BVolume *volume) const;
status_t GetIcon(BBitmap *icon, icon_size which) const;
@@ -57,17 +68,13 @@ public:
BPartition *ChildAt(int32 index) const;
int32 CountChildren() const;
BPartitioningInfo* GetPartitioningInfo() const;
status_t GetPartitioningInfo(BPartitioningInfo *info) const;
BPartition* VisitEachChild(BDiskDeviceVisitor *visitor);
BPartition* VisitEachDescendent(BDiskDeviceVisitor *visitor);
BPartition *VisitEachChild(BDiskDeviceVisitor *visitor);
virtual BPartition *VisitEachDescendent(BDiskDeviceVisitor *visitor);
// Self Modification
bool IsLocked() const;
status_t Lock(); // to be non-blocking
status_t Unlock();
bool CanDefragment(bool *whileMounted = NULL) const;
status_t Defragment() const;
@@ -108,30 +115,20 @@ public:
bool CanDeleteChild(int32 index) const;
status_t DeleteChild(int32 index);
protected:
off_t fOffset;
off_t fSize;
uint32 fBlockSize;
int32 fIndex;
uint32 fStatus;
private:
BPartition();
BPartition(const Partition &);
virtual ~BPartition();
bool fIsMountable;
bool fIsPartitionable;
status_t SetTo(BDiskDevice *device, BPartition *parent,
user_partition_data *data);
void Unset();
bool fIsDevice;
bool fIsReadOnly;
bool fIsMounted;
char fName[B_FILE_NAME_LENGTH];
char fType[B_FILE_NAME_LENGTH];
char fContentType[B_FILE_NAME_LENGTH];
friend class BDiskDevice;
partition_id fUniqueID;
uint32 fFlags;
BObjectList<BPartition> fChildren;
int32 fChangeCounter;
}
BDiskDevice *fDevice;
BPartition *fParent;
user_partition_data *fPartitionData;
};
#endif // _PARTITION_H
+3 -5
View File
@@ -6,7 +6,7 @@
#ifndef _PARTITIONING_INFO_H
#define _PARTITIONING_INFO_H
class BPartition;
#include <SupportDefs.h>
class BPartitioningInfo {
public:
@@ -14,11 +14,9 @@ public:
off_t *size) const;
int32 CountPartitionableSpaces() const;
BPartition *Parent() const; // needed?
private:
off_t *fOffsetArray;
off_t *fSizeArray;
off_t *fOffsets;
off_t *fSizes;
int32 fCount;
};
+235 -180
View File
@@ -3,6 +3,8 @@
// by the OpenBeOS license.
//---------------------------------------------------------------------
#include <DiskDevice.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
@@ -13,12 +15,12 @@
#include <unistd.h>
#include <DiskDevice.h>
#include <DiskDevicePrivate.h>
#include <DiskDeviceVisitor.h>
#include <Drivers.h>
#include <Message.h>
#include <Partition.h>
#include <RegistrarDefs.h>
#include <Session.h>
#include <Path.h>
#include "ddm_userland_interface.h"
/*! \class BDiskDevice
\brief A BDiskDevice object represents a storage device.
@@ -28,18 +30,8 @@
/*! \brief Creates an uninitialized BDiskDevice object.
*/
BDiskDevice::BDiskDevice()
: fSessions(10, true),
fUniqueID(-1),
fChangeCounter(0),
fMediaStatus(B_ERROR),
fSize(0),
fBlockSize(0),
fType(0),
fReadOnly(false),
fRemovable(false)//,
// fIsFloppy(false)
: fDeviceData(NULL)
{
fPath[0] = '\0';
}
// destructor
@@ -49,78 +41,254 @@ BDiskDevice::~BDiskDevice()
{
}
// IsRemovable
/*! \brief Returns whether the device media are removable.
\return \c true, if the device media are removable, \c false otherwise.
*/
bool
BDiskDevice::IsRemovable() const
{
return (fDeviceData
&& fDeviceData->device_flags & B_DISK_DEVICE_REMOVABLE);
}
// HasMedia
/*! \brief Returns whether the device contains a media.
\return \c true, if the device contains a media, \c false otherwise.
*/
bool
BDiskDevice::HasMedia() const
{
return (fDeviceData
&& fDeviceData->device_flags & B_DISK_DEVICE_HAS_MEDIA);
}
// Eject
/*! \brief Eject the device's media.
The device media must, of course, be removable, and the device must
support ejecting the media.
\param update If \c true, Update() is invoked after successful ejection.
\return
- \c B_OK: Everything went fine.
- \c B_NO_INIT: The device is not properly initialized.
- \c B_BAD_VALUE: The device media is not removable.
- other error codes
*/
status_t
BDiskDevice::Eject(bool update)
{
/* // get path
const char *path = Path();
status_t error = (path ? B_OK : B_NO_INIT);
// check whether the device media is removable
if (error == B_OK && !IsRemovable())
error = B_BAD_VALUE;
// open, eject and close the device
if (error == B_OK) {
int fd = open(path, O_RDONLY);
if (fd < 0 || ioctl(fd, B_EJECT_DEVICE) != 0)
error = errno;
if (fd >= 0)
close(fd);
}
if (error == B_OK && update)
error = Update();
return error;
*/
// not implemented
return B_ERROR;
}
// Update
/*! \brief Updates the object to reflect the latest changes to the device.
Note, that subobjects (BSessions, BPartitions) may be deleted during this
operation. It is also possible, that the device doesn't exist anymore --
e.g. if it is hot-pluggable. Then an error is returned and the object is
uninitialized.
\param updated Pointer to a bool variable which shall be set to \c true,
if the object needed to be updated and to \c false otherwise.
May be \c NULL. Is not touched, if the method fails.
\return \c B_OK, if the update went fine, another error code otherwise.
*/
status_t
BDiskDevice::Update(bool *updated)
{
/*
// get a messenger for the disk device manager
// TODO: Cache the messenger? Maybe add a global variable?
BMessenger manager;
status_t error = get_disk_device_messenger(&manager);
// compose request message
BMessage request(B_REG_UPDATE_DISK_DEVICE);
if (error == B_OK)
error = request.AddInt32("device_id", fUniqueID);
if (error == B_OK)
error = request.AddInt32("change_counter", fChangeCounter);
if (error == B_OK)
error = request.AddInt32("update_policy", B_REG_DEVICE_UPDATE_CHANGED);
// send request
BMessage reply;
if (error == B_OK)
error = manager.SendMessage(&request, &reply);
// analyze reply
bool upToDate = true;
if (error == B_OK) {
// result
status_t result = B_OK;
error = reply.FindInt32("result", &result);
if (error == B_OK)
error = result;
if (error == B_OK)
error = reply.FindBool("up_to_date", &upToDate);
}
// get the archived device, if not up to date
if (error == B_OK && !upToDate) {
BMessage archive;
error = reply.FindMessage("device", &archive);
if (error == B_OK)
error = _Update(&archive);
}
// set result / cleanup on error
if (error == B_OK) {
if (updated)
*updated = !upToDate;
} else
Unset();
return error;
*/
// not implemented
return B_ERROR;
}
// Unset
void
BDiskDevice::Unset()
{
fSessions.MakeEmpty();
fUniqueID = -1;
fChangeCounter = 0;
fMediaStatus = B_ERROR;
fSize = 0;
fBlockSize = 0;
fType = 0;
fReadOnly = false;
fRemovable = false;
// fIsFloppy = false;
fPath[0] = '\0';
free(fDeviceData);
fDeviceData = NULL;
}
// Size
/*! \brief Returns the size of the device.
\return The size of the device in bytes.
*/
off_t
BDiskDevice::Size() const
// GetPath
status_t
BDiskDevice::GetPath(BPath *path) const
{
return fSize;
if (!path || !fDeviceData)
return B_BAD_VALUE;
return path->SetTo(fDeviceData->path);
}
// BlockSize
/*! \brief Returns the block size of the device.
\return The block size of the device in bytes.
*/
int32
BDiskDevice::BlockSize() const
// VisitEachDescendent
BPartition *
BDiskDevice::VisitEachDescendent(BDiskDeviceVisitor *visitor)
{
return fBlockSize;
if (!visitor)
return NULL;
if (visitor->Visit(this))
return this;
return BPartition::VisitEachDescendent(visitor);
}
// CountSessions
/*! \brief Returns the number of sessions on this device.
\return The number of sessions on this device.
*/
int32
BDiskDevice::CountSessions() const
// IsModified
bool
BDiskDevice::IsModified() const
{
return fSessions.CountItems();
// not implemented
return false;
}
// SessionAt
/*! \brief Returns a contained session by index.
\param index The index of the session to be returned.
\return The session with the requested index, or \c NULL, if \a index
is out of range.
*/
BSession *
BDiskDevice::SessionAt(int32 index) const
// PrepareModifications
status_t
BDiskDevice::PrepareModifications()
{
return fSessions.ItemAt(index);
// not implemented
return B_ERROR;
}
// CountPartitions
/*! \brief Returns the number of partitions on this device.
\return The number of partitions on this device.
*/
int32
BDiskDevice::CountPartitions() const
// CommitModifications
status_t
BDiskDevice::CommitModifications(bool synchronously,
BMessenger progressMessenger,
bool receiveCompleteProgressUpdates)
{
int32 count = 0;
for (int32 i = 0; BSession *session = SessionAt(i); i++)
count += session->CountPartitions();
return count;
// not implemented
return B_ERROR;
}
// CancelModifications
status_t
BDiskDevice::CancelModifications()
{
// not implemented
return B_ERROR;
}
// SetTo
status_t
BDiskDevice::SetTo(partition_id id, size_t neededSize)
{
Unset();
// get the device data
void *buffer = NULL;
size_t bufferSize = 0;
if (neededSize > 0) {
// allocate initial buffer
buffer = malloc(neededSize);
if (!buffer)
return B_NO_MEMORY;
bufferSize = neededSize;
}
status_t error = B_OK;
do {
error = _kern_get_disk_device_data(id, false,
(user_disk_device_data*)buffer,
bufferSize, &neededSize);
if (error == B_BUFFER_OVERFLOW) {
// buffer to small re-allocate it
if (buffer)
free(buffer);
buffer = malloc(neededSize);
if (buffer)
bufferSize = neededSize;
else
error = B_NO_MEMORY;
}
} while (error == B_BUFFER_OVERFLOW);
// set the data
if (error == B_OK)
error = SetTo((user_disk_device_data*)buffer);
// cleanup on error
if (error != B_OK)
free(buffer);
return error;
}
// SetTo
status_t
BDiskDevice::SetTo(user_disk_device_data *data)
{
Unset();
if (!data)
return B_BAD_VALUE;
fDeviceData = data;
status_t error = BPartition::SetTo(this, NULL,
&fDeviceData->device_partition_data);
if (error != B_OK) {
// Don't call Unset() here. If SetTo() fails, the caller retains
// ownership of the supplied data.
// TODO: Maybe introduce a _Unset() to avoid potential future
// problems.
fDeviceData = NULL;
}
return error;
}
#if 0
// Path
/*! \brief Returns the path to the device.
\return The path to the device.
@@ -268,26 +436,6 @@ BDiskDevice::IsReadOnly() const
return fReadOnly;
}
// IsRemovable
/*! \brief Returns whether the device media are removable.
\return \c true, if the device media are removable, \c false otherwise.
*/
bool
BDiskDevice::IsRemovable() const
{
return fRemovable;
}
// HasMedia
/*! \brief Returns whether the device contains a media.
\return \c true, if the device contains a media, \c false otherwise.
*/
bool
BDiskDevice::HasMedia() const
{
return (fMediaStatus == B_OK);
}
// IsFloppy
/*! \brief Returns whether the device is a floppy device.
\return \c true, if the device is a floppy device, \c false otherwise.
@@ -337,41 +485,6 @@ BDiskDevice::UniqueID() const
return fUniqueID;
}
// Eject
/*! \brief Eject the device's media.
The device media must, of course, be removable, and the device must
support ejecting the media.
\param update If \c true, Update() is invoked after successful ejection.
\return
- \c B_OK: Everything went fine.
- \c B_NO_INIT: The device is not properly initialized.
- \c B_BAD_VALUE: The device media is not removable.
- other error codes
*/
status_t
BDiskDevice::Eject(bool update)
{
// get path
const char *path = Path();
status_t error = (path ? B_OK : B_NO_INIT);
// check whether the device media is removable
if (error == B_OK && !IsRemovable())
error = B_BAD_VALUE;
// open, eject and close the device
if (error == B_OK) {
int fd = open(path, O_RDONLY);
if (fd < 0 || ioctl(fd, B_EJECT_DEVICE) != 0)
error = errno;
if (fd >= 0)
close(fd);
}
if (error == B_OK && update)
error = Update();
return error;
}
// LowLevelFormat
/*! \brief Low level formats the device.
\return \c B_OK, if everything went fine, another error code otherwise.
@@ -382,65 +495,6 @@ BDiskDevice::LowLevelFormat()
return B_ERROR; // not implemented
}
// Update
/*! \brief Updates the object to reflect the latest changes to the device.
Note, that subobjects (BSessions, BPartitions) may be deleted during this
operation. It is also possible, that the device doesn't exist anymore --
e.g. if it is hot-pluggable. Then an error is returned and the object is
uninitialized.
\param updated Pointer to a bool variable which shall be set to \c true,
if the object needed to be updated and to \c false otherwise.
May be \c NULL. Is not touched, if the method fails.
\return \c B_OK, if the update went fine, another error code otherwise.
*/
status_t
BDiskDevice::Update(bool *updated)
{
// get a messenger for the disk device manager
// TODO: Cache the messenger? Maybe add a global variable?
BMessenger manager;
status_t error = get_disk_device_messenger(&manager);
// compose request message
BMessage request(B_REG_UPDATE_DISK_DEVICE);
if (error == B_OK)
error = request.AddInt32("device_id", fUniqueID);
if (error == B_OK)
error = request.AddInt32("change_counter", fChangeCounter);
if (error == B_OK)
error = request.AddInt32("update_policy", B_REG_DEVICE_UPDATE_CHANGED);
// send request
BMessage reply;
if (error == B_OK)
error = manager.SendMessage(&request, &reply);
// analyze reply
bool upToDate = true;
if (error == B_OK) {
// result
status_t result = B_OK;
error = reply.FindInt32("result", &result);
if (error == B_OK)
error = result;
if (error == B_OK)
error = reply.FindBool("up_to_date", &upToDate);
}
// get the archived device, if not up to date
if (error == B_OK && !upToDate) {
BMessage archive;
error = reply.FindMessage("device", &archive);
if (error == B_OK)
error = _Update(&archive);
}
// set result / cleanup on error
if (error == B_OK) {
if (updated)
*updated = !upToDate;
} else
Unset();
return error;
}
// VisitEachSession
/*! \brief Iterates through the device's sessions.
@@ -746,3 +800,4 @@ BDiskDevice::_AddSession(BSession *session)
return result;
}
#endif //0
+6
View File
@@ -0,0 +1,6 @@
//----------------------------------------------------------------------
// This software is part of the OpenBeOS distribution and is covered
// by the OpenBeOS license.
//---------------------------------------------------------------------
#include <DiskDeviceJob.h>
-36
View File
@@ -5,11 +5,7 @@
#include <DiskDevicePrivate.h>
#include <DiskDevice.h>
#include <RegistrarDefs.h>
#include <RosterPrivate.h>
#include <Messenger.h>
#include <Partition.h>
#include <Session.h>
// PartitionFilterVisitor
@@ -29,13 +25,6 @@ PartitionFilterVisitor::Visit(BDiskDevice *device)
return false;
}
// Visit
bool
PartitionFilterVisitor::Visit(BSession *session)
{
return false;
}
// Visit
bool
PartitionFilterVisitor::Visit(BPartition *partition)
@@ -62,13 +51,6 @@ IDFinderVisitor::Visit(BDiskDevice *device)
return (device->UniqueID() == fID);
}
// Visit
bool
IDFinderVisitor::Visit(BSession *session)
{
return (session->UniqueID() == fID);
}
// Visit
bool
IDFinderVisitor::Visit(BPartition *partition)
@@ -76,21 +58,3 @@ IDFinderVisitor::Visit(BPartition *partition)
return (partition->UniqueID() == fID);
}
// get_disk_device_messenger
status_t
BPrivate::get_disk_device_messenger(BMessenger *messenger)
{
status_t error = (messenger ? B_OK : B_BAD_VALUE);
if (error == B_OK) {
BMessage request(B_REG_GET_DISK_DEVICE_MESSENGER);
BMessage reply;
error = BRoster::Private().SendTo(&request, &reply, false);
if (error == B_OK && reply.what == B_REG_SUCCESS)
error = reply.FindMessenger("messenger", messenger);
else
error = B_ERROR;
}
return error;
}
+161 -188
View File
@@ -3,78 +3,23 @@
// by the OpenBeOS license.
//---------------------------------------------------------------------
#include <new.h>
#include <DiskDeviceRoster.h>
#include <new>
#include <Directory.h>
#include <DiskDevice.h>
#include <DiskDevicePrivate.h>
#include <DiskDeviceRoster.h>
#include <DiskScannerAddOn.h>
//#include <DiskScannerAddOn.h>
#include <Entry.h>
#include <FindDirectory.h>
#include <Message.h>
#include <Partition.h>
#include <Path.h>
#include <RegistrarDefs.h>
#include <RosterPrivate.h>
#include <Session.h>
#include "AddOnImage.h"
//----------------------------------------------------------------------------
// Hack to make BDiskDeviceRoster communicate with our registrar.
BRoster _be_roster;
const BRoster *be_roster = &_be_roster;
// init_roster
struct _InitRoster {
_InitRoster()
{
bool initialized = false;
// find the registrar port
port_id rosterPort = find_port(kRosterPortName);
port_info info;
if (rosterPort >= 0 && get_port_info(rosterPort, &info) == B_OK) {
// construct the roster messenger
struct {
port_id fPort;
int32 fHandlerToken;
team_id fTeam;
int32 extra0;
int32 extra1;
bool fPreferredTarget;
bool extra2;
bool extra3;
bool extra4;
} fakeMessenger;
fakeMessenger.fPort = rosterPort;
fakeMessenger.fHandlerToken = 0;
fakeMessenger.fTeam = info.team;
fakeMessenger.fPreferredTarget = true;
BMessenger mainMessenger = *(BMessenger*)&fakeMessenger;
// ask for the MIME messenger
BMessage reply;
status_t error = mainMessenger.SendMessage(
B_REG_GET_MIME_MESSENGER, &reply);
if (error == B_OK && reply.what == B_REG_SUCCESS) {
BMessenger mimeMessenger;
reply.FindMessenger("messenger", &mimeMessenger);
BRoster::Private(_be_roster).SetTo(mainMessenger,
mimeMessenger);
initialized = true;
} else {
}
}
if (!initialized) {
printf("initializing be_roster failed!\n");
exit(1);
}
}
} _InitRosterObject;
//----------------------------------------------------------------------------
//#include "AddOnImage.h"
#include "ddm_userland_interface.h"
/*! \class BDiskDeviceRoster
\brief An interface for iterating through the disk devices known to the
@@ -99,14 +44,12 @@ static const int32 kAddOnDirCount
The object is ready to be used after construction.
*/
BDiskDeviceRoster::BDiskDeviceRoster()
: fManager(),
fCookie(0),
fPartitionAddOnDir(NULL),
fFSAddOnDir(NULL),
fPartitionAddOnDirIndex(0),
fFSAddOnDirIndex(0)
: fCookie(0)//,
// fPartitionAddOnDir(NULL),
// fFSAddOnDir(NULL),
// fPartitionAddOnDirIndex(0),
// fFSAddOnDirIndex(0)
{
get_disk_device_messenger(&fManager);
}
// destructor
@@ -114,10 +57,10 @@ BDiskDeviceRoster::BDiskDeviceRoster()
*/
BDiskDeviceRoster::~BDiskDeviceRoster()
{
if (fPartitionAddOnDir)
delete fPartitionAddOnDir;
if (fFSAddOnDir)
delete fFSAddOnDir;
// if (fPartitionAddOnDir)
// delete fPartitionAddOnDir;
// if (fFSAddOnDir)
// delete fFSAddOnDir;
}
// GetNextDevice
@@ -133,54 +76,82 @@ BDiskDeviceRoster::~BDiskDeviceRoster()
status_t
BDiskDeviceRoster::GetNextDevice(BDiskDevice *device)
{
//printf("BDiskDeviceRoster::GetNextDevice()\n");
status_t error = (device ? B_OK : B_BAD_VALUE);
// compose request message
BMessage request(B_REG_NEXT_DISK_DEVICE);
if (error == B_OK)
error = request.AddInt32("cookie", fCookie);
// send request
BMessage reply;
if (error == B_OK)
error = fManager.SendMessage(&request, &reply);
// analyze reply
if (error == B_OK) {
//reply.PrintToStream();
// result
status_t result = B_OK;
error = reply.FindInt32("result", &result);
//printf(" check: %s\n", strerror(error));
if (error == B_OK)
error = result;
//printf(" check: %s\n", strerror(error));
// cookie
if (error == B_OK)
error = reply.FindInt32("cookie", &fCookie);
//printf(" check: %s\n", strerror(error));
// device
BMessage archive;
if (error == B_OK)
error = reply.FindMessage("device", &archive);
//printf(" check: %s\n", strerror(error));
if (error == B_OK)
error = device->_Unarchive(&archive);
//printf(" check: %s\n", strerror(error));
}
//printf("BDiskDeviceRoster::GetNextDevice() done: %s\n", strerror(error));
return error;
if (!device)
return B_BAD_VALUE;
size_t neededSize = 0;
partition_id id = _kern_get_next_disk_device_id(&fCookie, &neededSize);
if (id < 0)
return id;
return device->SetTo(id, neededSize);
}
// Rewind
// RewindDevices
/*! \brief Rewinds the device list iterator.
\return \c B_OK, if everything went fine, another error code otherwise.
*/
status_t
BDiskDeviceRoster::Rewind()
BDiskDeviceRoster::RewindDevices()
{
fCookie = 0;
return B_OK;
}
// GetNextDiskSystem
status_t
BDiskDeviceRoster::GetNextDiskSystem(BDiskSystem *system)
{
// not implemented
return B_ERROR;
}
// RewindDiskSystems
status_t
BDiskDeviceRoster::RewindDiskSystems()
{
// not implemented
return B_ERROR;
}
// GetNextActiveJob
status_t
BDiskDeviceRoster::GetNextActiveJob(BDiskDeviceJob *job)
{
// not implemented
return B_ERROR;
}
// RewindActiveJobs
status_t
BDiskDeviceRoster::RewindActiveJobs()
{
// not implemented
return B_ERROR;
}
// RegisterFileDevice
partition_id
BDiskDeviceRoster::RegisterFileDevice(const char *filename)
{
// not implemented
return B_ERROR;
}
// UnregisterFileDevice
status_t
BDiskDeviceRoster::UnregisterFileDevice(const char *filename)
{
// not implemented
return B_ERROR;
}
// UnregisterFileDevice
status_t
BDiskDeviceRoster::UnregisterFileDevice(partition_id device)
{
// not implemented
return B_ERROR;
}
// VisitEachDevice
/*! \brief Iterates through the all devices.
@@ -213,45 +184,6 @@ BDiskDeviceRoster::VisitEachDevice(BDiskDeviceVisitor *visitor,
return terminatedEarly;
}
// VisitEachSession
/*! \brief Iterates through the all devices' sessions.
The supplied visitor's Visit(BSession*) is invoked for each session.
If Visit() returns \c true, the iteration is terminated and this method
returns \c true. If supplied, \a device is set to the concerned device
and in \a session the pointer to the session object is returned.
\param visitor The visitor.
\param device Pointer to a pre-allocated BDiskDevice to be initialized
to the device at which the iteration was terminated.
May be \c NULL.
\param session Pointer to a pre-allocated BSession pointer to be set
to the session at which the iteration was terminated.
May be \c NULL.
\return \c true, if the iteration was terminated, \c false otherwise.
*/
bool
BDiskDeviceRoster::VisitEachSession(BDiskDeviceVisitor *visitor,
BDiskDevice *device, BSession **session)
{
bool terminatedEarly = false;
if (visitor) {
int32 oldCookie = fCookie;
fCookie = 0;
BDiskDevice deviceOnStack;
BDiskDevice *useDevice = (device ? device : &deviceOnStack);
BSession *foundSession = NULL;
while (!foundSession && GetNextDevice(useDevice) == B_OK)
foundSession = useDevice->VisitEachSession(visitor);
fCookie = oldCookie;
if (!terminatedEarly)
useDevice->Unset();
else if (device && session)
*session = foundSession;
}
return terminatedEarly;
}
// VisitEachPartition
/*! \brief Iterates through the all devices' partitions.
@@ -282,7 +214,9 @@ BDiskDeviceRoster::VisitEachPartition(BDiskDeviceVisitor *visitor,
BDiskDevice *useDevice = (device ? device : &deviceOnStack);
BPartition *foundPartition = NULL;
while (!foundPartition && GetNextDevice(useDevice) == B_OK)
foundPartition = useDevice->VisitEachPartition(visitor);
foundPartition = useDevice->VisitEachDescendent(visitor);
// TODO: That probably not correct. VisitEachDescendent()
// should also invoke Visit(BDiskDevice*).
fCookie = oldCookie;
if (!terminatedEarly)
useDevice->Unset();
@@ -292,7 +226,7 @@ BDiskDeviceRoster::VisitEachPartition(BDiskDeviceVisitor *visitor,
return terminatedEarly;
}
// Traverse
// VisitAll
/*! \brief Pre-order traverses the trees of the spanned by the BDiskDevices
and their subobjects.
@@ -305,7 +239,7 @@ BDiskDeviceRoster::VisitEachPartition(BDiskDeviceVisitor *visitor,
\return \c true, if the iteration was terminated, \c false otherwise.
*/
bool
BDiskDeviceRoster::Traverse(BDiskDeviceVisitor *visitor)
BDiskDeviceRoster::VisitAll(BDiskDeviceVisitor *visitor)
{
bool terminatedEarly = false;
if (visitor) {
@@ -313,7 +247,7 @@ BDiskDeviceRoster::Traverse(BDiskDeviceVisitor *visitor)
fCookie = 0;
BDiskDevice device;
while (!terminatedEarly && GetNextDevice(&device) == B_OK)
terminatedEarly = device.Traverse(visitor);
terminatedEarly = device.VisitEachDescendent(visitor);
fCookie = oldCookie;
}
return terminatedEarly;
@@ -382,7 +316,7 @@ BDiskDeviceRoster::VisitEachMountablePartition(BDiskDeviceVisitor *visitor,
if (visitor) {
struct MountablePartitionFilter : public PartitionFilter {
virtual bool Filter(BPartition *partition)
{ return partition->ContainsFileSystem(); }
{ return partition->IsMountable(); }
} filter;
PartitionFilterVisitor filterVisitor(visitor, &filter);
terminatedEarly
@@ -414,11 +348,35 @@ BDiskDeviceRoster::VisitEachInitializablePartition(BDiskDeviceVisitor *visitor,
BDiskDevice *device,
BPartition **partition)
{
bool terminatedEarly = false;
/* bool terminatedEarly = false;
if (visitor) {
struct InitializablePartitionFilter : public PartitionFilter {
virtual bool Filter(BPartition *partition)
{ return !partition->IsHidden(); }
{ return !partition->CanInitialize(NULL); }
// TODO: ???
} filter;
PartitionFilterVisitor filterVisitor(visitor, &filter);
terminatedEarly
= VisitEachPartition(&filterVisitor, device, partition);
}
return terminatedEarly;
*/
// not implemented
return false;
// TODO: Clarify semantics.
}
// VisitEachPartitionablePartition
bool
BDiskDeviceRoster::VisitEachPartitionablePartition(BDiskDeviceVisitor *visitor,
BDiskDevice *device,
BPartition **partition)
{
bool terminatedEarly = false;
if (visitor) {
struct PartitionablePartitionFilter : public PartitionFilter {
virtual bool Filter(BPartition *partition)
{ return partition->IsPartitionable(); }
} filter;
PartitionFilterVisitor filterVisitor(visitor, &filter);
terminatedEarly
@@ -443,36 +401,9 @@ BDiskDeviceRoster::VisitEachInitializablePartition(BDiskDeviceVisitor *visitor,
status_t
BDiskDeviceRoster::GetDeviceWithID(int32 id, BDiskDevice *device) const
{
return _GetObjectWithID("device_id", id, device);
}
// GetSessionWithID
/*! \brief Returns a BSession for a given ID.
The supplied \a device is initialized to the device the session identified
by \a id resides on, and \a session is set to point to the respective
BSession.
\param id The ID of the session to be retrieved.
\param device Pointer to a pre-allocated BDiskDevice to be initialized
to the device the session identified by \a id resides on.
\param session Pointer to a pre-allocated BSession pointer to be set to
the session identified by \a id.
\return
- \c B_OK: Everything went fine.
- \c B_ENTRY_NOT_FOUND: A session with ID \a id could not be found.
- other error codes
*/
status_t
BDiskDeviceRoster::GetSessionWithID(int32 id, BDiskDevice *device,
BSession **session) const
{
status_t error = (device && session ? B_OK : B_BAD_VALUE);
if (error == B_OK)
error = _GetObjectWithID("session_id", id, device);
if (error == B_OK)
*session = device->SessionWithID(id);
return error;
// return _GetObjectWithID("device_id", id, device);
// not implemented
return B_ERROR;
}
// GetPartitionWithID
@@ -496,12 +427,35 @@ status_t
BDiskDeviceRoster::GetPartitionWithID(int32 id, BDiskDevice *device,
BPartition **partition) const
{
status_t error = (device && partition ? B_OK : B_BAD_VALUE);
/* status_t error = (device && partition ? B_OK : B_BAD_VALUE);
if (error == B_OK)
error = _GetObjectWithID("partition_id", id, device);
if (error == B_OK)
*partition = device->PartitionWithID(id);
return error;
*/
// not implemented
return B_ERROR;
}
// GetDeviceForPath
partition_id
BDiskDeviceRoster::GetDeviceForPath(const char *filename, BDiskDevice *device,
bool registerIfFile)
{
// not implemented
return B_ERROR;
}
// GetPartitionForPath
partition_id
BDiskDeviceRoster::GetPartitionForPath(const char *filename,
BDiskDevice *device,
BPartition **partition,
bool registerIfFile)
{
// not implemented
return B_ERROR;
}
// StartWatching
@@ -523,7 +477,7 @@ BDiskDeviceRoster::GetPartitionWithID(int32 id, BDiskDevice *device,
status_t
BDiskDeviceRoster::StartWatching(BMessenger target, uint32 eventMask)
{
status_t error = B_OK;
/* status_t error = B_OK;
// compose request message
BMessage request(B_REG_DEVICE_START_WATCHING);
if (error == B_OK)
@@ -543,6 +497,18 @@ BDiskDeviceRoster::StartWatching(BMessenger target, uint32 eventMask)
error = result;
}
return error;
*/
// not implemented
return B_ERROR;
}
// StartWatchingJob
status_t
BDiskDeviceRoster::StartWatchingJob(BDiskDeviceJob *job, BMessenger target,
uint32 eventMask)
{
// not implemented
return B_ERROR;
}
// StopWatching
@@ -555,7 +521,7 @@ BDiskDeviceRoster::StartWatching(BMessenger target, uint32 eventMask)
status_t
BDiskDeviceRoster::StopWatching(BMessenger target)
{
status_t error = B_OK;
/* status_t error = B_OK;
// compose request message
BMessage request(B_REG_DEVICE_STOP_WATCHING);
if (error == B_OK)
@@ -573,8 +539,14 @@ BDiskDeviceRoster::StopWatching(BMessenger target)
error = result;
}
return error;
*/
// not implemented
return B_ERROR;
}
#if 0
// GetNextPartitioningSystem
/*! \brief Returns the next partitioning system capable of partitioning.
@@ -944,3 +916,4 @@ BDiskDeviceRoster::_LoadPartitionAddOn(const char *partitioningSystem,
return error;
}
#endif // 0
+4 -22
View File
@@ -6,12 +6,12 @@
#include <DiskDeviceVisitor.h>
/*! \class BDiskDeviceVisitor
\brief Base class of visitors used for BDiskDevice, BSession and
\brief Base class of visitors used for BDiskDevice and
BPartition iteration.
BDiskDeviceRoster, BDiskDevice and BSession provide iteration methods,
BDiskDeviceRoster and BDiskDevice provide iteration methods,
that work together with an instance of a derived class of
BDiskDeviceVisitor. For each encountered BDiskDevice, BSession and
BDiskDeviceVisitor. For each encountered BDiskDevice and
BPartition the respective Visit() method is invoked. The return value
of that method specifies whether the iteration shall be terminated at
that point.
@@ -51,24 +51,6 @@ BDiskDeviceVisitor::Visit(BDiskDevice *device)
return false;
}
// Visit
/*! \brief Invoked when a BSession is visited.
If the method returns \c true, the iteration is terminated at this point,
on \c false continued.
Overridden by derived classes.
This class' version does nothing and it returns \c false.
\return \c true, if the iteration shall be terminated at this point,
\c false otherwise.
*/
bool
BDiskDeviceVisitor::Visit(BSession *device)
{
return false;
}
// Visit
/*! \brief Invoked when a BPartition is visited.
@@ -82,7 +64,7 @@ BDiskDeviceVisitor::Visit(BSession *device)
\c false otherwise.
*/
bool
BDiskDeviceVisitor::Visit(BPartition *device)
BDiskDeviceVisitor::Visit(BPartition *partition)
{
return false;
}
+6
View File
@@ -0,0 +1,6 @@
//----------------------------------------------------------------------
// This software is part of the OpenBeOS distribution and is covered
// by the OpenBeOS license.
//---------------------------------------------------------------------
#include <DiskSystem.h>
+18 -25
View File
@@ -1,39 +1,32 @@
SubDir OBOS_TOP src kits storage ;
UsePrivateHeaders $(DOT) ;
UsePrivateHeaders app ;
UsePrivateHeaders [ FDirName kernel disk_device_manager ] ;
UsePrivateHeaders shared ;
UsePrivateHeaders storage ;
SEARCH_SOURCE += [ FDirName $(OBOS_TOP) src kernel libroot os ]
[ FDirName $(OBOS_TOP) src kits app ]
[ FDirName $(OBOS_TOP) src kits storage ] ;
SEARCH_SOURCE += [ FDirName $(OBOS_TOP) src kits storage ] ;
# We need to keep the DiskDevice API out of libopenbeos as long as the
# Interface Kit is not fully functional (at least the part we are using).
# So, we build a separate library.
#
#SharedLibrary diskdevice
# : AddOnImage.cpp
# DiskDevice.cpp
SharedLibrary diskdevice
: #AddOnImage.cpp
DiskDevice.cpp
DiskDeviceJob.cpp
# DiskDeviceList.cpp
# DiskDevicePrivate.cpp
# DiskDeviceRoster.cpp
# DiskDeviceVisitor.cpp
DiskDevicePrivate.cpp
DiskDeviceRoster.cpp
DiskDeviceTypes.cpp
DiskDeviceVisitor.cpp
# DiskScannerAddOn.cpp
# Mime.cpp
# Partition.cpp
DiskSystem.cpp
Partition.cpp
# PartitioningDialog.cpp
# RegistrarDefs.cpp
## Roster.cpp
# RosterPrivate.cpp
# Session.cpp
#
# # from libroot
# #
# disk_scanner.cpp
#
# : <boot!home!config!lib>libkernelland_emu.so be
#;
#AbsSymLink <boot!home!config!lib>libdiskdevice.so : libdiskdevice.so
# : /boot/home/config/lib ;
PartitioningInfo.cpp
: <boot!home!config!lib>libdisk_device_manager.so be
;
AbsSymLink <boot!home!config!lib>libdiskdevice.so : libdiskdevice.so
: /boot/home/config/lib ;
+227 -156
View File
@@ -3,13 +3,17 @@
// by the OpenBeOS license.
//---------------------------------------------------------------------
#include <new>
#include <Partition.h>
#include <DiskDevice.h>
#include <DiskDeviceVisitor.h>
#include <Message.h>
#include <Mime.h>
#include <Session.h>
#include <Volume.h>
#include "ddm_userland_interface.h"
/*! \class BPartition
\brief A BPartition object represent a partition and provides a lot of
methods to retrieve information about it and some to manipulate it.
@@ -20,31 +24,20 @@
(\see IsEmpty()).
*/
// constructor
BPartition::BPartition()
: fDevice(NULL),
fParent(NULL),
fPartitionData(NULL)
{
}
// destructor
/*! \brief Frees all resources associated with this object.
*/
BPartition::~BPartition()
{
}
// Session
/*! \brief Returns the session this partition resides on.
\return The session this partition resides on.
*/
BSession *
BPartition::Session() const
{
return fSession;
}
// Device
/*! \brief Returns the device this partition resides on.
\return The device this partition resides on.
*/
BDiskDevice *
BPartition::Device() const
{
return (fSession ? fSession->Device() : NULL);
Unset();
}
// Offset
@@ -56,7 +49,7 @@ BPartition::Device() const
off_t
BPartition::Offset() const
{
return fInfo.info.offset;
return (fPartitionData ? fPartitionData->offset : 0);
}
// Size
@@ -66,17 +59,17 @@ BPartition::Offset() const
off_t
BPartition::Size() const
{
return fInfo.info.size;
return (fPartitionData ? fPartitionData->size : 0);
}
// BlockSize
/*! \brief Returns the block size of the device.
\return The block size of the device in bytes.
*/
int32
uint32
BPartition::BlockSize() const
{
return (fSession ? fSession->BlockSize() : 0);
return (fPartitionData ? fPartitionData->block_size : 0);
}
// Index
@@ -87,7 +80,59 @@ BPartition::BlockSize() const
int32
BPartition::Index() const
{
return fIndex;
return (fPartitionData ? fPartitionData->index : -1);
}
// Status
uint32
BPartition::Status() const
{
return (fPartitionData ? fPartitionData->status : 0);
}
// IsMountable
bool
BPartition::IsMountable() const
{
return (fPartitionData
&& (fPartitionData->flags & B_PARTITION_MOUNTABLE));
}
// IsPartitionable
bool
BPartition::IsPartitionable() const
{
return (fPartitionData
&& (fPartitionData->flags & B_PARTITION_PARTITIONABLE));
}
// IsDevice
bool
BPartition::IsDevice() const
{
return (fPartitionData
&& (fPartitionData->flags & B_PARTITION_IS_DEVICE));
}
// IsReadOnly
bool
BPartition::IsReadOnly() const
{
return (fPartitionData
&& (fPartitionData->flags & B_PARTITION_READ_ONLY));
}
// IsMounted
/*! \brief Returns whether the volume is mounted.
\return \c true, if the volume is mounted, \c false otherwise.
*/
bool
BPartition::IsMounted() const
{
return (fPartitionData
&& (fPartitionData->flags & B_PARTITION_MOUNTED));
// alternatively:
// return (fPartitionData && fPartitionData->volume >= 0);
}
// Flags
@@ -107,54 +152,7 @@ BPartition::Index() const
uint32
BPartition::Flags() const
{
return fInfo.flags;
}
// IsHidden
/*! \brief Returns whether the partition can contain a file system.
\see Flags().
\return \c true, if the partition can't contain a file system, \c false
otherwise.
*/
bool
BPartition::IsHidden() const
{
return (fInfo.flags & B_HIDDEN_PARTITION);
}
// IsVirtual
/*! \brief Returns whether the object doesn't represents an on-disk partition.
\see Flags().
\return \c true, if the object doesn't represent an on-disk partition,
\c false otherwise.
*/
bool
BPartition::IsVirtual() const
{
return (fInfo.flags & B_VIRTUAL_PARTITION);
}
// IsEmpty
/*! \brief Returns whether the partition is empty.
\see Flags().
\return \c true, if the partition is empty, \c false otherwise.
*/
bool
BPartition::IsEmpty() const
{
return (fInfo.flags & B_EMPTY_PARTITION);
}
// ContainsFileSystem
/*! \brief Returns whether the partition contains a file system recognized by
the system.
\return \c true, if the partition contains a file system recognized by
the system, \c false otherwise.
*/
bool
BPartition::ContainsFileSystem() const
{
return (fInfo.file_system_short_name[0] != '\0');
return (fPartitionData ? fPartitionData->flags : 0);
}
// Name
@@ -169,7 +167,14 @@ BPartition::ContainsFileSystem() const
const char *
BPartition::Name() const
{
return (fInfo.partition_name[0] != '\0' ? fInfo.partition_name : NULL);
return (fPartitionData ? fPartitionData->name : NULL);
}
// ContentName
const char *
BPartition::ContentName() const
{
return (fPartitionData ? fPartitionData->content_name : NULL);
}
// Type
@@ -179,86 +184,14 @@ BPartition::Name() const
const char *
BPartition::Type() const
{
return fInfo.partition_type;
return (fPartitionData ? fPartitionData->type : NULL);
}
// FileSystemShortName
/*! \brief Returns a short string identifying the file system on the partition.
If the partition doesn't contain a recognized file system
(\see ContainsFileSystem()), \c NULL is returned.
\return A short string identifying the file system on the partition,
or \c NULL, if the partition doesn't contain a recognized file
system.
*/
// ContentType
const char *
BPartition::FileSystemShortName() const
BPartition::ContentType() const
{
return (ContainsFileSystem() ? fInfo.file_system_short_name : NULL);
}
// FileSystemLongName
/*! \brief Returns a longer description of the file system on the partition.
If the partition doesn't contain a recognized file system
(\see ContainsFileSystem()), \c NULL is returned.
\return A longer description of the file system on the partition,
or \c NULL, if the partition doesn't contain a recognized file
system.
*/
const char *
BPartition::FileSystemLongName() const
{
return (ContainsFileSystem() ? fInfo.file_system_long_name : NULL);
}
// VolumeName
/*! \brief Returns the name of the volume.
If the partition doesn't contain a recognized file system
(\see ContainsFileSystem()), \c NULL is returned.
\return The name of the volume, or \c NULL, if the partition doesn't
contain a recognized file system.
*/
const char *
BPartition::VolumeName() const
{
return (ContainsFileSystem() ? fInfo.volume_name : NULL);
}
// FileSystemFlags
/*! \brief Returns the file system flags for the volume.
If the partition doesn't contain a recognized file system
(\see ContainsFileSystem()), the return value is undefined.
Note, that, if the volume is mounted, the returned flags are identical
with the ones fs_stat_dev() reports. If not mounted they describe merely
the file system's capabilities. E.g. if the file system supports
writing and the device is not read-only, the B_FS_IS_READONLY is not set,
but it will be set, when the volume is mounted read-only. The same applies
to other capabilities that can be disabled at mount time.
\return The file system flags of the volume, if the partition contains
a recognized file system.
*/
uint32
BPartition::FileSystemFlags() const
{
return fInfo.file_system_flags;
}
// IsMounted
/*! \brief Returns whether the volume is mounted.
\return \c true, if the volume is mounted, \c false otherwise.
*/
bool
BPartition::IsMounted() const
{
return (fVolumeID >= 0);
return (fPartitionData ? fPartitionData->content_type : NULL);
}
// UniqueID
@@ -274,7 +207,23 @@ BPartition::IsMounted() const
int32
BPartition::UniqueID() const
{
return fUniqueID;
return (fPartitionData ? fPartitionData->id : -1);
}
// GetDiskSystem
status_t
BPartition::GetDiskSystem(BDiskSystem *diskSystem) const
{
// not implemented
return B_ERROR;
}
// GetPath
status_t
BPartition::GetPath(BPath *path) const
{
// not implemented
return B_ERROR;
}
// GetVolume
@@ -290,9 +239,9 @@ BPartition::UniqueID() const
status_t
BPartition::GetVolume(BVolume *volume) const
{
status_t error = (volume ? B_OK : B_BAD_VALUE);
status_t error = (fPartitionData && volume ? B_OK : B_BAD_VALUE);
if (error == B_OK)
error = volume->SetTo(fVolumeID);
error = volume->SetTo(fPartitionData->volume);
return error;
}
@@ -312,6 +261,7 @@ BPartition::GetVolume(BVolume *volume) const
status_t
BPartition::GetIcon(BBitmap *icon, icon_size which) const
{
/*
status_t error = (icon ? B_OK : B_BAD_VALUE);
if (error == B_OK) {
if (IsMounted()) {
@@ -331,6 +281,9 @@ BPartition::GetIcon(BBitmap *icon, icon_size which) const
}
}
return error;
*/
// not implemented
return B_ERROR;
}
// Mount
@@ -363,6 +316,124 @@ BPartition::Unmount()
return B_ERROR; // not implemented
}
// Device
/*! \brief Returns the device this partition resides on.
\return The device this partition resides on.
*/
BDiskDevice *
BPartition::Device() const
{
return fDevice;
}
// Parent
BPartition *
BPartition::Parent() const
{
return fParent;
}
// ChildAt
BPartition *
BPartition::ChildAt(int32 index) const
{
if (!fPartitionData || index < 0 || index >= fPartitionData->child_count)
return NULL;
return (BPartition*)fPartitionData->children[index]->user_data;
}
// CountChildren
int32
BPartition::CountChildren() const
{
return (fPartitionData ? fPartitionData->child_count : 0);
}
// GetPartitioningInfo
status_t
BPartition::GetPartitioningInfo(BPartitioningInfo *info) const
{
// not implemented
return B_ERROR;
}
// VisitEachChild
BPartition *
BPartition::VisitEachChild(BDiskDeviceVisitor *visitor)
{
if (visitor) {
for (int32 i = 0; BPartition *child = ChildAt(i); i++) {
if (visitor->Visit(child))
return child;
}
}
return NULL;
}
// VisitEachDescendent
BPartition *
BPartition::VisitEachDescendent(BDiskDeviceVisitor *visitor)
{
if (visitor) {
if (visitor->Visit(this))
return this;
for (int32 i = 0; BPartition *child = ChildAt(i); i++) {
if (BPartition *result = child->VisitEachDescendent(visitor))
return result;
}
}
return NULL;
}
// SetTo
status_t
BPartition::SetTo(BDiskDevice *device, BPartition *parent,
user_partition_data *data)
{
Unset();
if (!device || !data)
return B_BAD_VALUE;
fPartitionData = data;
fDevice = device;
fParent = parent;
fPartitionData->user_data = this;
// create and init children
status_t error = B_OK;
for (int32 i = 0; error == B_OK && i < fPartitionData->child_count; i++) {
BPartition *child = new(nothrow) BPartition;
if (child) {
error = child->SetTo(fDevice, this, fPartitionData->children[i]);
if (error != B_OK)
delete child;
} else
error = B_NO_MEMORY;
}
// cleanup on error
if (error != B_OK)
Unset();
return error;
}
// Unset
void
BPartition::Unset()
{
// delete children
if (fPartitionData) {
for (int32 i = 0; i < fPartitionData->child_count; i++) {
if (BPartition *child = ChildAt(i))
delete child;
}
fPartitionData->user_data = NULL;
}
fDevice = NULL;
fParent = NULL;
fPartitionData = NULL;
}
#if 0
// GetInitializationParameters
/*! \brief Asks the user to set the parameters for initializing this partition.
@@ -454,7 +525,6 @@ BPartition::BPartition()
: fSession(NULL),
fUniqueID(-1),
fChangeCounter(0),
fIndex(-1),
fVolumeID(-1)
{
fInfo.info.offset = 0;
@@ -580,3 +650,4 @@ BPartition::_SetSession(BSession *session)
fSession = session;
}
#endif // 0
+6
View File
@@ -0,0 +1,6 @@
//----------------------------------------------------------------------
// This software is part of the OpenBeOS distribution and is covered
// by the OpenBeOS license.
//---------------------------------------------------------------------
#include <PartitioningInfo.h>
-616
View File
@@ -1,616 +0,0 @@
//----------------------------------------------------------------------
// This software is part of the OpenBeOS distribution and is covered
// by the OpenBeOS license.
//---------------------------------------------------------------------
#include <errno.h>
#include <new.h>
#include <unistd.h>
#include <Session.h>
#include <DiskDevice.h>
#include <DiskDevicePrivate.h>
#include <DiskDeviceRoster.h>
#include <DiskScannerAddOn.h>
#include <Message.h>
#include <Partition.h>
#include "AddOnImage.h"
#include "PartitioningDialog.h"
/*! \class BSession
\brief A BSession object represent a session and provides a lot of
methods to retrieve information about it and some to manipulate it.
Not all BSession represent actual on-disk sessions. Some exist only
to make all devices fit smoothly into the framework (e.g. for hard and
floppy, \see IsVirtual()).
*/
/*! \brief Name of the DOS/Intel partitioning system.
*/
const char *B_INTEL_PARTITIONING = "intel";
// destructor
/*! \brief Frees all resources associated with this object.
*/
BSession::~BSession()
{
}
// Device
/*! \brief Returns the device this session resides on.
\return The device this session resides on.
*/
BDiskDevice *
BSession::Device() const
{
return fDevice;
}
// Offset
/*! \brief Returns the session's offset relative to the beginning of the
device it resides on.
\return The session's offset in bytes relative to the beginning of the
device it resides on.
*/
off_t
BSession::Offset() const
{
return fInfo.offset;
}
// Size
/*! \brief Returns the size of the session.
\return The size of the session in bytes.
*/
off_t
BSession::Size() const
{
return fInfo.size;
}
// BlockSize
/*! \brief Returns the block size of the device.
\return The block size of the device in bytes.
*/
int32
BSession::BlockSize() const
{
return (fDevice ? fDevice->BlockSize() : 0);
}
// CountPartitions
/*! \brief Returns the number of partitions on this session.
\return The number of partitions on this session.
*/
int32
BSession::CountPartitions() const
{
return fPartitions.CountItems();
}
// PartitionAt
/*! \brief Returns a contained partition by index.
\param index The index of the partition to be returned.
\return The partition with the requested index, or \c NULL, if \a index
is out of range.
*/
BPartition *
BSession::PartitionAt(int32 index) const
{
return fPartitions.ItemAt(index);
}
// Index
/*! \brief Returns the index of the session in its device's list of session.
\return The index of the session in its session's list of sessions.
*/
int32
BSession::Index() const
{
return fIndex;
}
// Flags
/*! \brief Returns the flags for this session.
The session flags are a bitwise combination of:
- \c B_DATA_SESSION: The session is a non-audio session.
- \c B_VIRTUAL_SESSION: There exists no on-disk session this object
represents. E.g. for hard disks there will be a BSession object spanning
the whole disk.
\return The flags for this partition.
*/
uint32
BSession::Flags() const
{
return fInfo.flags;
}
// IsAudio
/*! \brief Returns whether the session is an audio session.
\return \c true, if the session is an audio session, \c false otherwise.
*/
bool
BSession::IsAudio() const
{
return !IsData();
}
// IsData
/*! \brief Returns whether the session is a data (i.e. non-audio) session.
\return \c true, if the session is a data session, \c false otherwise.
*/
bool
BSession::IsData() const
{
return (fInfo.flags & B_DATA_SESSION);
}
// IsVirtual
/*! \brief Returns whether the object doesn't represents an on-disk session.
\see Flags().
\return \c true, if the object doesn't represent an on-disk session,
\c false otherwise.
*/
bool
BSession::IsVirtual() const
{
return (fInfo.flags & B_VIRTUAL_SESSION);
}
// PartitioningSystem
/*! \brief Returns the name of the partitioning system used for this session.
If the session is a audio session or virtual (\see Flags()), the method
returns \c NULL, otherwise the name of the partitioning system used.
\return The name of the partitioning system used for this session, if any.
\c NULL otherwise.
*/
const char *
BSession::PartitioningSystem() const
{
return (fPartitioningSystem.Length() > 0
? fPartitioningSystem.String() : NULL);
}
// UniqueID
/*! \brief Returns a unique identifier for this session.
The ID is not persistent, i.e. in general won't be the same after
rebooting.
\see BDiskDeviceRoster::GetSessionWithID().
\return A unique identifier for this session.
*/
int32
BSession::UniqueID() const
{
return fUniqueID;
}
// VisitEachPartition
/*! \brief Iterates through the session's partitions.
The supplied visitor's Visit(BPartition*) is invoked for each partition.
If Visit() returns \c true, the iteration is terminated and the BPartition
object just visited is returned.
\param visitor The visitor.
\return The BPartition object at which the iteration was terminated, or
\c NULL, if the iteration has not been terminated.
*/
BPartition *
BSession::VisitEachPartition(BDiskDeviceVisitor *visitor)
{
if (visitor) {
for (int32 i = 0; BPartition *partition = PartitionAt(i); i++) {
if (visitor->Visit(partition))
return partition;
}
}
return NULL;
}
// PartitionWithID
/*! \brief Returns the partition on the session, that has a certain ID.
\param id The ID of the partition to be returned.
\return The partition with ID \a id, or \c NULL, if a partition with that
ID does not exist on this session.
*/
BPartition *
BSession::PartitionWithID(int32 id)
{
IDFinderVisitor visitor(id);
return VisitEachPartition(&visitor);
}
// GetPartitioningParameters
/*! \brief Asks the user to set the parameters for partitioning this session.
A dialog window will be opened, centered at \a dialogCenter, asking the
user for setting the parameters to be used for partitioning this session
with the partitioning system specified by \a partitioningSystem.
The method does not return until the user has confirmed or cancelled the
dialog. In the latter case \a cancelled is set to \c true, otherwise to
\c false.
\param partitioningSystem The partitioning system the parameters shall be
asked for.
\param parameters Pointer to a pre-allocated BString to be set to the
parameters the user has specified.
\param dialogCenter The rectangle over which to center the dialog. If
omitted, the dialog is displayed centered to the screen.
\param cancelled Pointer to a pre-allocated bool to be set to \c true, if
the dialog has been cancelled by the user, or to \c false
otherwise. May be \c NULL.
\return
- \c B_OK: The parameters have been retrieved successfully.
- \c B_ERROR: Either the dialog has been cancelled -- then \a cancelled
is set accordingly -- or some other error occured.
- another error code
*/
status_t
BSession::GetPartitioningParameters(const char *partitioningSystem,
BString *parameters, BRect dialogCenter,
bool *cancelled)
{
status_t error = (partitioningSystem && parameters ? B_OK : B_BAD_VALUE);
// get the add-on
AddOnImage image;
BDiskScannerPartitionAddOn *addOn = NULL;
if (error == B_OK) {
error = BDiskDeviceRoster::_LoadPartitionAddOn(partitioningSystem,
&image, &addOn);
}
// open the device
int deviceFD = -1;
if (error == B_OK) {
deviceFD = open(Device()->Path(), O_RDONLY);
if (deviceFD < 0)
error = errno;
}
// get the default parameters
char *allocatedBuffer = NULL;
char localBuffer[256];
char *defaultParams = NULL;
if (error == B_OK) {
// try a small buffer on stack
defaultParams = localBuffer;
size_t bufferSize = sizeof(localBuffer);
size_t actualSize = 0;
error = get_partitioning_parameters(deviceFD, Index(),
partitioningSystem, defaultParams,
bufferSize, &actualSize);
if (error == B_OK && actualSize > bufferSize) {
// stack buffer was too small, allocate one on the heap
allocatedBuffer = new(nothrow) char[actualSize];
if (allocatedBuffer) {
defaultParams = allocatedBuffer;
bufferSize = actualSize;
error = get_partitioning_parameters(deviceFD, Index(),
partitioningSystem,
defaultParams, bufferSize,
&actualSize);
if (error == B_OK && actualSize > bufferSize)
error = B_ERROR;
} else
error = B_NO_MEMORY;
}
}
// close the device
if (deviceFD >= 0)
close(deviceFD);
// get an editor
BDiskScannerParameterEditor *editor = NULL;
if (error == B_OK) {
editor = addOn->CreateEditor(this, defaultParams);
if (!editor)
error = B_ERROR;
}
// create and run the editing dialog
PartitioningDialog *dialog = NULL;
if (error == B_OK) {
dialog = new (nothrow) PartitioningDialog(dialogCenter);
if (dialog)
error = dialog->Go(editor, cancelled);
else
error = B_NO_MEMORY;
}
// get the parameters
if (error == B_OK)
error = editor->GetParameters(parameters);
// cleanup
if (allocatedBuffer)
delete allocatedBuffer;
if (editor)
delete editor;
if (addOn)
delete addOn;
return error;
}
// Partition
/*! \brief Partitions the session according to the supplied parameters.
\param partitioningSystem The partitioning system to be used for
partitioning.
\param parameters Partitioning system specific parameters.
\return
- \c B_OK: Everything went fine.
- another error code, if an error occured
*/
status_t
BSession::Partition(const char *partitioningSystem, const char *parameters)
{
return B_ERROR; // not implemented
}
// Partition
/*! \brief Partitions the session after asking the user for the respective
parameters.
A dialog window will be opened, centered at \a dialogCenter, asking the
user for setting the parameters to be used for partitioning this session
with the partitioning system specified by \a partitioningSystem.
The method does not return until the user has either confirmed the dialog
and the partitioning is done, or the dialog has been cancelled. In the
latter case \a cancelled is set to \c true, otherwise to \c false.
\param partitioningSystem The partitioning system to be used for
partitioning.
\param dialogCenter The rectangle over which to center the dialog. If
omitted, the dialog is displayed centered to the screen.
\param cancelled Pointer to a pre-allocated bool to be set to \c true, if
the dialog has been cancelled by the user, or to \c false
otherwise. May be \c NULL.
\return
- \c B_OK: The parameters have been retrieved successfully and the
partitioning went fine, too.
- \c B_ERROR: Either the dialog has been cancelled -- then \a cancelled
is set accordingly -- or some other error occured.
- another error code
*/
status_t
BSession::Partition(const char *partitioningSystem, BRect dialogCenter,
bool *cancelled)
{
status_t error = (partitioningSystem ? B_OK : B_BAD_VALUE);
// get the parameters
BString parameters;
if (error == B_OK) {
error = GetPartitioningParameters(partitioningSystem, &parameters,
dialogCenter, cancelled);
}
// do the partitioning
if (error == B_OK)
error = Partition(partitioningSystem, parameters.String());
return error;
}
// constructor
/*! \brief Creates an uninitialized BSession object.
*/
BSession::BSession()
: fDevice(NULL),
fPartitions(10, true),
fUniqueID(-1),
fChangeCounter(0),
fIndex(-1),
fPartitioningSystem()
{
fInfo.offset = 0;
fInfo.size = 0;
fInfo.flags = 0;
}
// copy constructor
/*! \brief Privatized copy constructor to avoid usage.
*/
BSession::BSession(const BSession &)
{
}
// =
/*! \brief Privatized assignment operator to avoid usage.
*/
BSession &
BSession::operator=(const BSession &)
{
return *this;
}
// _Unset
void
BSession::_Unset()
{
fDevice = NULL;
fPartitions.MakeEmpty();
fUniqueID = -1;
fChangeCounter = 0;
fIndex = -1;
fInfo.offset = 0;
fInfo.size = 0;
fInfo.flags = 0;
fPartitioningSystem.SetTo("");
}
// _Unarchive
status_t
BSession::_Unarchive(BMessage *archive)
{
//printf("BSession::_Unarchive()\n");
_Unset();
status_t error = (archive ? B_OK : B_BAD_VALUE);
if (error == B_OK) {
// ID, change counter and index
if (error == B_OK)
error = archive->FindInt32("id", &fUniqueID);
if (error == B_OK)
error = archive->FindInt32("change_counter", &fChangeCounter);
if (error == B_OK)
error = archive->FindInt32("index", &fIndex);
// fInfo.*
if (error == B_OK)
error = archive->FindInt64("offset", &fInfo.offset);
if (error == B_OK)
error = archive->FindInt64("size", &fInfo.size);
if (error == B_OK)
error = archive->FindInt32("flags", (int32*)&fInfo.flags);
// other data
if (error == B_OK)
error = archive->FindString("partitioning", &fPartitioningSystem);
// partitions
type_code fieldType;
int32 count = 0;
if (error == B_OK) {
if (archive->GetInfo("partitions", &fieldType, &count) != B_OK)
count = 0;
}
for (int32 i = 0; error == B_OK && i < count; i++) {
// get the archived partitions
BMessage partitionArchive;
error = archive->FindMessage("partitions", i, &partitionArchive);
// allocate a partition object
BPartition *partition = NULL;
if (error == B_OK) {
partition = new(nothrow) BPartition;
if (!partition)
error = B_NO_MEMORY;
}
// unarchive the partition
if (error == B_OK)
error = partition->_Unarchive(&partitionArchive);
// add the partition
if (error == B_OK && !_AddPartition(partition))
error = B_NO_MEMORY;
// cleanup on error
if (error != B_OK && partition)
delete partition;
}
}
// cleanup on error
if (error != B_OK)
_Unset();
//printf("BSession::_Unarchive() done: %s\n", strerror(error));
return error;
}
// _Update
status_t
BSession::_Update(BMessage *archive)
{
status_t error = (archive ? B_OK : B_BAD_VALUE);
bool upToDate = false;
if (error == B_OK) {
// ID and change counter
int32 id;
if (error == B_OK)
error = archive->FindInt32("id", &id);
if (error == B_OK && id != fUniqueID)
error = B_ERROR;
int32 changeCounter;
if (error == B_OK)
error = archive->FindInt32("change_counter", &changeCounter);
upToDate = (fChangeCounter == changeCounter);
fChangeCounter = changeCounter;
}
if (error == B_OK && !upToDate) {
if (error == B_OK)
error = archive->FindInt32("index", &fIndex);
// fInfo.*
if (error == B_OK)
error = archive->FindInt64("offset", &fInfo.offset);
if (error == B_OK)
error = archive->FindInt64("size", &fInfo.size);
if (error == B_OK)
error = archive->FindInt32("flags", (int32*)&fInfo.flags);
// other data
if (error == B_OK)
error = archive->FindString("partitioning", &fPartitioningSystem);
// partitions
// copy old partition list and empty it
BObjectList<BPartition> partitions;
for (int32 i = 0; BPartition *partition = fPartitions.ItemAt(i); i++)
partitions.AddItem(partition);
for (int32 i = fPartitions.CountItems() - 1; i >= 0; i--)
fPartitions.RemoveItemAt(i);
// get the partition count
type_code fieldType;
int32 count = 0;
if (error == B_OK) {
if (archive->GetInfo("partitions", &fieldType, &count) != B_OK)
count = 0;
}
for (int32 i = 0; error == B_OK && i < count; i++) {
// get the archived partitions
BMessage partitionArchive;
error = archive->FindMessage("partitions", i, &partitionArchive);
// check, whether we do already know that partition
int32 partitionID;
if (error == B_OK)
error = partitionArchive.FindInt32("id", &partitionID);
BPartition *partition = NULL;
for (int32 k = 0; k < partitions.CountItems(); k++) {
BPartition *oldPartition = partitions.ItemAt(i);
if (oldPartition->UniqueID() == partitionID) {
partition = oldPartition;
break;
}
}
if (error == B_OK) {
if (partition) {
// the partition is known: just update it
error = partition->_Unarchive(&partitionArchive);
} else {
// the partition is unknown
// allocate a partition object
partition = new(nothrow) BPartition;
if (!partition)
error = B_NO_MEMORY;
// unarchive the partition
if (error == B_OK)
error = partition->_Unarchive(&partitionArchive);
}
}
// add the partition
if (error == B_OK && !_AddPartition(partition))
error = B_NO_MEMORY;
// cleanup on error
if (error != B_OK && partition)
delete partition;
}
// delete all obsolete partitions
for (int32 i = partitions.CountItems() - 1; i >= 0; i--)
delete partitions.RemoveItemAt(i);
}
// cleanup on error
if (error != B_OK)
_Unset();
return error;
}
// _SetDevice
void
BSession::_SetDevice(BDiskDevice *device)
{
fDevice = device;
}
// _AddPartition
bool
BSession::_AddPartition(BPartition *partition)
{
bool result = fPartitions.AddItem(partition);
if (result)
partition->_SetSession(this);
return result;
}