diff --git a/src/kits/storage/DiskDevice.cpp b/src/kits/storage/DiskDevice.cpp index 1ca4a12d04..b0a12d9f04 100644 --- a/src/kits/storage/DiskDevice.cpp +++ b/src/kits/storage/DiskDevice.cpp @@ -3,7 +3,12 @@ // by the OpenBeOS license. //--------------------------------------------------------------------- +#include + #include +#include +#include +#include /*! \class BDiskDevice \brief A BDiskDevice object represents a storage device. @@ -13,7 +18,18 @@ /*! \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) { + fPath[0] = '\0'; } // destructor @@ -23,6 +39,23 @@ BDiskDevice::~BDiskDevice() { } +// 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'; +} + // Size /*! \brief Returns the size of the device. \return The size of the device in bytes. @@ -30,7 +63,7 @@ BDiskDevice::~BDiskDevice() off_t BDiskDevice::Size() const { - return 0; // not implemented + return fSize; } // BlockSize @@ -40,7 +73,7 @@ BDiskDevice::Size() const int32 BDiskDevice::BlockSize() const { - return 0; // not implemented + return fBlockSize; } // CountSessions @@ -50,7 +83,7 @@ BDiskDevice::BlockSize() const int32 BDiskDevice::CountSessions() const { - return 0; // not implemented + return fSessions.CountItems(); } // SessionAt @@ -62,7 +95,7 @@ BDiskDevice::CountSessions() const BSession * BDiskDevice::SessionAt(int32 index) const { - return NULL; // not implemented + return fSessions.ItemAt(index); } // CountPartitions @@ -72,17 +105,20 @@ BDiskDevice::SessionAt(int32 index) const int32 BDiskDevice::CountPartitions() const { - return 0; // not implemented + int32 count = 0; + for (int32 i = 0; BSession *session = SessionAt(i); i++) + count += session->CountPartitions(); + return count; } -// DevicePath +// Path /*! \brief Returns the path to the device. \return The path to the device. */ const char * -BDiskDevice::DevicePath() const +BDiskDevice::Path() const { - return NULL; // not implemented + return (fPath[0] != '\0' ? fPath : NULL); } // GetName @@ -102,6 +138,7 @@ BDiskDevice::DevicePath() const void BDiskDevice::GetName(BString *name, bool includeBusID, bool includeLUN) const { + // not implemented } // GetName @@ -121,6 +158,7 @@ BDiskDevice::GetName(BString *name, bool includeBusID, bool includeLUN) const void BDiskDevice::GetName(char *name, bool includeBusID, bool includeLUN) const { + // not implemented } // IsReadOnly @@ -130,7 +168,7 @@ BDiskDevice::GetName(char *name, bool includeBusID, bool includeLUN) const bool BDiskDevice::IsReadOnly() const { - return false; // not implemented + return fReadOnly; } // IsRemovable @@ -140,7 +178,7 @@ BDiskDevice::IsReadOnly() const bool BDiskDevice::IsRemovable() const { - return false; // not implemented + return fRemovable; } // HasMedia @@ -150,7 +188,7 @@ BDiskDevice::IsRemovable() const bool BDiskDevice::HasMedia() const { - return false; // not implemented + return (fMediaStatus == B_OK); } // IsFloppy @@ -160,7 +198,7 @@ BDiskDevice::HasMedia() const bool BDiskDevice::IsFloppy() const { - return false; // not implemented + return !strcmp(fPath, "/dev/disk/floppy/raw"); } // Type @@ -183,7 +221,7 @@ BDiskDevice::IsFloppy() const uint8 BDiskDevice::Type() const { - return 0; // not implemented + return fType; } // UniqueID @@ -199,7 +237,7 @@ BDiskDevice::Type() const int32 BDiskDevice::UniqueID() const { - return -1; // not implemented + return fUniqueID; } // Eject @@ -311,3 +349,88 @@ BDiskDevice::operator=(const BDiskDevice &) return *this; } +// find_string +static +status_t +find_string(BMessage *message, const char *name, char *buffer) +{ + const char *str; + status_t error = message->FindString(name, &str); + if (error != B_OK) + strcpy(buffer, str); + return error; +} + +// _Unarchive +status_t +BDiskDevice::_Unarchive(BMessage *archive) +{ + Unset(); + status_t error = (archive ? B_OK : B_BAD_VALUE); + if (error == B_OK) { + // ID and change counter + if (error == B_OK) + error = archive->FindInt32("id", &fUniqueID); + if (error == B_OK) + error = archive->FindInt32("change_counter", &fChangeCounter); + // geometry + if (error == B_OK) + error = archive->FindInt64("size", &fSize); + if (error == B_OK) + error = archive->FindInt32("block_size", &fBlockSize); + if (error == B_OK) + error = archive->FindInt8("type", (int8*)&fType); + if (error == B_OK) + error = archive->FindBool("removable", &fRemovable); + if (error == B_OK) + error = archive->FindBool("read_only", fReadOnly); +// if (error == B_OK) +// error = archive->FindBool("write_once", fGeometry.write_once); + // other data + if (error == B_OK) + error = find_string(archive, "path", fPath); + if (error == B_OK) + error = archive->FindInt32("media_status", &fMediaStatus); + // sessions + type_code fieldType; + int32 count = 0; + if (error == B_OK) + error = archive->GetInfo("sessions", &fieldType, &count); + for (int32 i = 0; error == B_OK && i < count; i++) { + // get the archived session + BMessage sessionArchive; + error = archive->FindMessage("sessions", i, &sessionArchive); + // allocate a session object + BSession *session = NULL; + if (error == B_OK) { + session = new(nothrow) BSession; + if (!session) + error = B_NO_MEMORY; + } + // unarchive the session + if (error == B_OK) + error = session->_Unarchive(&sessionArchive); + // add the session + if (error == B_OK && !_AddSession(session)) + error = B_NO_MEMORY; + // cleanup on error + if (error != B_OK && session) + delete session; + } + } + // cleanup on error + if (error != B_OK) + Unset(); + return error; +} + +// _AddSession +bool +BDiskDevice::_AddSession(BSession *session) +{ + bool result = fSessions.AddItem(session); + if (result) + session->_SetDevice(this); + return result; +} + diff --git a/src/kits/storage/DiskDeviceRoster.cpp b/src/kits/storage/DiskDeviceRoster.cpp index 57a6ac8d95..348c0d1311 100644 --- a/src/kits/storage/DiskDeviceRoster.cpp +++ b/src/kits/storage/DiskDeviceRoster.cpp @@ -3,7 +3,14 @@ // by the OpenBeOS license. //--------------------------------------------------------------------- +#include + #include +#include +#include +#include +#include +#include /*! \class BDiskDeviceRoster \brief An interface for iterating through the disk devices known to the @@ -17,7 +24,15 @@ The object is ready to be used after construction. */ BDiskDeviceRoster::BDiskDeviceRoster() + : fManager(), + fCookie(0) { + BMessage request(B_REG_GET_DISK_DEVICE_MESSENGER); + BMessage reply; + if (_send_to_roster_(&request, &reply, false) == B_OK + && reply.what == B_REG_SUCCESS) { + reply.FindMessenger("messenger", &fManager); + } } // destructor @@ -40,7 +55,33 @@ BDiskDeviceRoster::~BDiskDeviceRoster() status_t BDiskDeviceRoster::GetNextDevice(BDiskDevice *device) { - return B_ERROR; // not implemented + 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) { + // result + status_t result = B_OK; + error = reply.FindInt32("result", &result); + if (error == B_OK) + error = result; + // cookie + if (error == B_OK) + error = reply.FindInt32("cookie", &fCookie); + // device + BMessage archive; + if (error == B_OK) + error = reply.FindMessage("device", &archive); + if (error == B_OK) + error = device->_Unarchive(&archive); + } + return error; } // Rewind @@ -50,7 +91,8 @@ BDiskDeviceRoster::GetNextDevice(BDiskDevice *device) status_t BDiskDeviceRoster::Rewind() { - return B_ERROR; // not implemented + fCookie = 0; + return B_OK; } // VisitEachDevice diff --git a/src/kits/storage/Partition.cpp b/src/kits/storage/Partition.cpp index 010ea4aec3..13fee7a157 100644 --- a/src/kits/storage/Partition.cpp +++ b/src/kits/storage/Partition.cpp @@ -4,6 +4,11 @@ //--------------------------------------------------------------------- #include +#include +#include +#include +#include +#include /*! \class BPartition \brief A BPartition object represent a partition and provides a lot of @@ -15,6 +20,13 @@ (\see IsEmpty()). */ +// 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. @@ -22,7 +34,7 @@ BSession * BPartition::Session() const { - return NULL; // not implemented + return fSession; } // Device @@ -32,7 +44,7 @@ BPartition::Session() const BDiskDevice * BPartition::Device() const { - return NULL; // not implemented + return (fSession ? fSession->Device() : NULL); } // Offset @@ -44,7 +56,7 @@ BPartition::Device() const off_t BPartition::Offset() const { - return 0; // not implemented + return fInfo.info.offset; } // Size @@ -54,7 +66,7 @@ BPartition::Offset() const off_t BPartition::Size() const { - return 0; // not implemented + return fInfo.info.size; } // BlockSize @@ -64,7 +76,7 @@ BPartition::Size() const int32 BPartition::BlockSize() const { - return 0; // not implemented + return (fSession ? fSession->BlockSize() : 0); } // Index @@ -75,7 +87,7 @@ BPartition::BlockSize() const int32 BPartition::Index() const { - return -1; // not implemented + return fIndex; } // Flags @@ -95,7 +107,7 @@ BPartition::Index() const uint32 BPartition::Flags() const { - return 0; // not implemented + return fInfo.flags; } // IsHidden @@ -107,7 +119,7 @@ BPartition::Flags() const bool BPartition::IsHidden() const { - return false; // not implemented + return (fInfo.flags & B_HIDDEN_PARTITION); } // IsVirtual @@ -119,7 +131,7 @@ BPartition::IsHidden() const bool BPartition::IsVirtual() const { - return false; // not implemented + return (fInfo.flags & B_VIRTUAL_PARTITION); } // IsEmpty @@ -130,7 +142,7 @@ BPartition::IsVirtual() const bool BPartition::IsEmpty() const { - return false; // not implemented + return (fInfo.flags & B_EMPTY_PARTITION); } // ContainsFileSystem @@ -142,7 +154,7 @@ BPartition::IsEmpty() const bool BPartition::ContainsFileSystem() const { - return false; // not implemented + return (fInfo.file_system_short_name[0] != '\0'); } // Name @@ -157,7 +169,7 @@ BPartition::ContainsFileSystem() const const char * BPartition::Name() const { - return NULL; // not implemented + return (fInfo.partition_name[0] != '\0' ? fInfo.partition_name : NULL); } // Type @@ -167,7 +179,7 @@ BPartition::Name() const const char * BPartition::Type() const { - return NULL; // not implemented + return fInfo.partition_type; } // FileSystemShortName @@ -183,7 +195,7 @@ BPartition::Type() const const char * BPartition::FileSystemShortName() const { - return NULL; // not implemented + return (ContainsFileSystem() ? fInfo.file_system_short_name : NULL); } // FileSystemLongName @@ -199,7 +211,7 @@ BPartition::FileSystemShortName() const const char * BPartition::FileSystemLongName() const { - return NULL; // not implemented + return (ContainsFileSystem() ? fInfo.file_system_long_name : NULL); } // VolumeName @@ -214,7 +226,7 @@ BPartition::FileSystemLongName() const const char * BPartition::VolumeName() const { - return NULL; // not implemented + return (ContainsFileSystem() ? fInfo.volume_name : NULL); } // FileSystemFlags @@ -236,7 +248,7 @@ BPartition::VolumeName() const uint32 BPartition::FileSystemFlags() const { - return 0; // not implemented + return fInfo.file_system_flags; } // IsMounted @@ -246,7 +258,7 @@ BPartition::FileSystemFlags() const bool BPartition::IsMounted() const { - return false; // not implemented + return (fVolumeID >= 0); } // UniqueID @@ -262,7 +274,7 @@ BPartition::IsMounted() const int32 BPartition::UniqueID() const { - return 0; // not implemented + return fUniqueID; } // GetVolume @@ -278,7 +290,10 @@ BPartition::UniqueID() const status_t BPartition::GetVolume(BVolume *volume) const { - return B_ERROR; // not implemented + status_t error = (volume ? B_OK : B_BAD_VALUE); + if (error == B_OK) + error = volume->SetTo(fVolumeID); + return error; } // GetIcon @@ -297,7 +312,25 @@ BPartition::GetVolume(BVolume *volume) const status_t BPartition::GetIcon(BBitmap *icon, icon_size which) const { - return B_ERROR; // not implemented + status_t error = (icon ? B_OK : B_BAD_VALUE); + if (error == B_OK) { + if (IsMounted()) { + // mounted: get the icon from the volume + BVolume volume; + error = GetVolume(&volume); + if (error == B_OK) + error = volume.GetIcon(icon, which); + } else { + // not mounted: retrieve the icon ourselves + if (BDiskDevice *device = Device()) { + // get the icon + if (error == B_OK) + error = get_device_icon(device->Path(), icon, which); + } else + error = B_ERROR; + } + } + return error; } // Mount @@ -438,7 +471,21 @@ BPartition::GetFileSystemList(BObjectList *list) /*! \brief Creates an uninitialized BPartition object. */ BPartition::BPartition() + : fSession(NULL), + fUniqueID(-1), + fChangeCounter(0), + fIndex(-1), + fVolumeID(-1) { + fInfo.info.offset = 0; + fInfo.info.size = 0; + fInfo.flags = 0; + fInfo.partition_name[0] = '\0'; + fInfo.partition_type[0] = '\0'; + fInfo.file_system_short_name[0] = '\0'; + fInfo.file_system_long_name[0] = '\0'; + fInfo.volume_name[0] = '\0'; + fInfo.file_system_flags = 0; } // constructor @@ -448,13 +495,6 @@ BPartition::BPartition(const BPartition &) { } -// destructor -/*! \brief Frees all resources associated with this object. -*/ -BPartition::~BPartition() -{ -} - // = /*! \brief Privatized assignment operator to avoid usage. */ @@ -464,3 +504,94 @@ BPartition::operator=(const BPartition &) return *this; } +// _Unset +void +BPartition::_Unset() +{ + fSession = NULL; + fUniqueID = -1; + fChangeCounter = 0; + fIndex = -1; + fInfo.info.offset = 0; + fInfo.info.size = 0; + fInfo.flags = 0; + fInfo.partition_name[0] = '\0'; + fInfo.partition_type[0] = '\0'; + fInfo.file_system_short_name[0] = '\0'; + fInfo.file_system_long_name[0] = '\0'; + fInfo.volume_name[0] = '\0'; + fInfo.file_system_flags = 0; + fVolumeID = -1; +} + +// find_string +static +status_t +find_string(BMessage *message, const char *name, char *buffer) +{ + const char *str; + status_t error = message->FindString(name, &str); + if (error != B_OK) + strcpy(buffer, str); + return error; +} + +// _Unarchive +status_t +BPartition::_Unarchive(BMessage *archive) +{ + _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.info.* + if (error == B_OK) + error = archive->FindInt64("offset", &fInfo.info.offset); + if (error == B_OK) + error = archive->FindInt64("size", &fInfo.info.size); + // fInfo.* + if (error == B_OK) + error = archive->FindInt32("flags", (int32*)&fInfo.flags); + if (error == B_OK) + error = find_string(archive, "name", fInfo.partition_name); + if (error == B_OK) + error = find_string(archive, "type", fInfo.partition_type); + if (error == B_OK) { + error = find_string(archive, "fs_short_name", + fInfo.file_system_short_name); + } + if (error == B_OK) { + error = find_string(archive, "fs_long_name", + fInfo.file_system_long_name); + } + if (error == B_OK) + error = find_string(archive, "volume_name", fInfo.volume_name); + if (error == B_OK) { + error = archive->FindInt32("fs_flags", + (int32*)&fInfo.file_system_flags); + } + // dev_t, if mounted + if (error == B_OK) { + if (archive->FindInt32("volume_id", &fVolumeID) != B_OK) + fVolumeID = -1; + } + } + // cleanup on error + if (error != B_OK) + _Unset(); + return error; +} + +// _SetSession +void +BPartition::_SetSession(BSession *session) +{ + fSession = session; +} + diff --git a/src/kits/storage/Session.cpp b/src/kits/storage/Session.cpp index 88a90569f3..451608b07c 100644 --- a/src/kits/storage/Session.cpp +++ b/src/kits/storage/Session.cpp @@ -3,7 +3,12 @@ // by the OpenBeOS license. //--------------------------------------------------------------------- +#include + #include +#include +#include +#include /*! \class BSession \brief A BSession object represent a session and provides a lot of @@ -19,6 +24,13 @@ */ 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. @@ -26,7 +38,7 @@ const char *B_INTEL_PARTITIONING = "intel"; BDiskDevice * BSession::Device() const { - return NULL; // not implemented + return fDevice; } // Offset @@ -38,7 +50,7 @@ BSession::Device() const off_t BSession::Offset() const { - return 0; // not implemented + return fInfo.offset; } // Size @@ -48,7 +60,17 @@ BSession::Offset() const off_t BSession::Size() const { - return 0; // not implemented + return fInfo.offset; +} + +// 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 @@ -58,7 +80,7 @@ BSession::Size() const int32 BSession::CountPartitions() const { - return 0; // not implemented + return fPartitions.CountItems(); } // PartitionAt @@ -70,7 +92,7 @@ BSession::CountPartitions() const BPartition * BSession::PartitionAt(int32 index) const { - return NULL; // not implemented + return fPartitions.ItemAt(index); } // Index @@ -80,7 +102,7 @@ BSession::PartitionAt(int32 index) const int32 BSession::Index() const { - return -1; // not implemented + return fIndex; } // Flags @@ -97,7 +119,7 @@ BSession::Index() const uint32 BSession::Flags() const { - return 0; // not implemented + return fInfo.flags; } // IsAudio @@ -107,7 +129,7 @@ BSession::Flags() const bool BSession::IsAudio() const { - return false; // not implemented + return !IsData(); } // IsData @@ -117,7 +139,7 @@ BSession::IsAudio() const bool BSession::IsData() const { - return false; // not implemented + return (fInfo.flags & B_DATA_SESSION); } // IsVirtual @@ -129,7 +151,7 @@ BSession::IsData() const bool BSession::IsVirtual() const { - return false; // not implemented + return (fInfo.flags & B_VIRTUAL_SESSION); } // PartitioningSystem @@ -144,7 +166,8 @@ BSession::IsVirtual() const const char * BSession::PartitioningSystem() const { - return NULL; // not implemented + return (fPartitioningSystem.Length() > 0 + ? fPartitioningSystem.String() : NULL); } // UniqueID @@ -160,7 +183,7 @@ BSession::PartitioningSystem() const int32 BSession::UniqueID() const { - return 0; // not implemented + return fUniqueID; } // VisitEachPartition @@ -286,14 +309,16 @@ BSession::GetPartitioningSystemList(BObjectList *list) /*! \brief Creates an uninitialized BSession object. */ BSession::BSession() + : fDevice(NULL), + fPartitions(10, true), + fUniqueID(-1), + fChangeCounter(0), + fIndex(-1), + fPartitioningSystem() { -} - -// destructor -/*! \brief Frees all resources associated with this object. -*/ -BSession::~BSession() -{ + fInfo.offset = 0; + fInfo.size = 0; + fInfo.flags = 0; } // copy constructor @@ -309,6 +334,95 @@ BSession::BSession(const BSession &) BSession & BSession::operator=(const BSession &) { - return *this; // not implemented + 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) +{ + _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) + error = archive->GetInfo("partitions", &fieldType, &count); + 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(); + 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; }