The beginning of the structures for the registrar side implementation of the DiskDevice API.
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@2623 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -8,12 +8,17 @@
|
|||||||
|
|
||||||
#include <Looper.h>
|
#include <Looper.h>
|
||||||
|
|
||||||
|
#include "RDiskDeviceList.h"
|
||||||
|
|
||||||
class DiskDeviceManager : public BLooper {
|
class DiskDeviceManager : public BLooper {
|
||||||
public:
|
public:
|
||||||
DiskDeviceManager();
|
DiskDeviceManager();
|
||||||
virtual ~DiskDeviceManager();
|
virtual ~DiskDeviceManager();
|
||||||
|
|
||||||
virtual void MessageReceived(BMessage *message);
|
virtual void MessageReceived(BMessage *message);
|
||||||
|
|
||||||
|
private:
|
||||||
|
RDiskDeviceList fDeviceList;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // DISK_DEVICE_MANAGER_H
|
#endif // DISK_DEVICE_MANAGER_H
|
||||||
|
|||||||
@@ -1,9 +1,14 @@
|
|||||||
SubDir OBOS_TOP src servers registrar ;
|
SubDir OBOS_TOP src servers registrar ;
|
||||||
|
|
||||||
UsePublicHeaders app ;
|
UsePublicHeaders app ;
|
||||||
|
UsePrivateHeaders $(DOT) ; # needed for disk_scanner.cpp
|
||||||
UsePrivateHeaders app ;
|
UsePrivateHeaders app ;
|
||||||
|
UsePrivateHeaders shared ;
|
||||||
UsePrivateHeaders storage ;
|
UsePrivateHeaders storage ;
|
||||||
|
|
||||||
|
# needed as long as disk_scanner.cpp is compiled in
|
||||||
|
SEARCH_SOURCE += [ FDirName $(OBOS_TOP) src kernel libroot os ] ;
|
||||||
|
|
||||||
Server obos_registrar :
|
Server obos_registrar :
|
||||||
AppInfoList.cpp
|
AppInfoList.cpp
|
||||||
ClipboardHandler.cpp
|
ClipboardHandler.cpp
|
||||||
@@ -15,17 +20,25 @@ Server obos_registrar :
|
|||||||
MessageEvent.cpp
|
MessageEvent.cpp
|
||||||
MessageRunnerManager.cpp
|
MessageRunnerManager.cpp
|
||||||
MIMEManager.cpp
|
MIMEManager.cpp
|
||||||
|
RDiskDevice.cpp
|
||||||
|
RDiskDeviceList.cpp
|
||||||
RecentApps.cpp
|
RecentApps.cpp
|
||||||
RecentEntries.cpp
|
RecentEntries.cpp
|
||||||
Registrar.cpp
|
Registrar.cpp
|
||||||
RosterAppInfo.cpp
|
RosterAppInfo.cpp
|
||||||
RosterSettingsCharStream.cpp
|
RosterSettingsCharStream.cpp
|
||||||
|
RPartition.cpp
|
||||||
|
RSession.cpp
|
||||||
TRoster.cpp
|
TRoster.cpp
|
||||||
Watcher.cpp
|
Watcher.cpp
|
||||||
WatchingService.cpp
|
WatchingService.cpp
|
||||||
|
|
||||||
|
# from .../libroot/os
|
||||||
|
disk_scanner.cpp
|
||||||
;
|
;
|
||||||
LinkSharedOSLibs obos_registrar :
|
LinkSharedOSLibs obos_registrar :
|
||||||
<boot!home!config!lib>libopenbeos.so
|
<boot!home!config!lib>libopenbeos.so
|
||||||
|
<boot!home!config!lib>libkernelland_emu.so # needed for disk_scanner.cpp
|
||||||
stdc++.r4
|
stdc++.r4
|
||||||
be root
|
be
|
||||||
;
|
;
|
||||||
|
|||||||
@@ -0,0 +1,182 @@
|
|||||||
|
//----------------------------------------------------------------------
|
||||||
|
// This software is part of the OpenBeOS distribution and is covered
|
||||||
|
// by the OpenBeOS license.
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <new.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#include <disk_scanner.h>
|
||||||
|
|
||||||
|
#include "RDiskDevice.h"
|
||||||
|
#include "RDiskDeviceList.h"
|
||||||
|
#include "RPartition.h"
|
||||||
|
#include "RSession.h"
|
||||||
|
|
||||||
|
// constructor
|
||||||
|
RDiskDevice::RDiskDevice()
|
||||||
|
: fSessions(10, true),
|
||||||
|
fDeviceList(NULL),
|
||||||
|
fID(-1),
|
||||||
|
fChangeCounter(0),
|
||||||
|
fTouched(false),
|
||||||
|
fPath(),
|
||||||
|
fFD(-1),
|
||||||
|
fMediaStatus(B_ERROR)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// destructor
|
||||||
|
RDiskDevice::~RDiskDevice()
|
||||||
|
{
|
||||||
|
Unset();
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetTo
|
||||||
|
status_t
|
||||||
|
RDiskDevice::SetTo(const char *path, int fd, const device_geometry *geometry,
|
||||||
|
status_t mediaStatus)
|
||||||
|
{
|
||||||
|
FUNCTION_START();
|
||||||
|
Unset();
|
||||||
|
status_t error = B_OK;
|
||||||
|
fID = _NextID();
|
||||||
|
fChangeCounter = 0;
|
||||||
|
fTouched = true;
|
||||||
|
fPath.SetTo(path);
|
||||||
|
fFD = fd;
|
||||||
|
fGeometry = *geometry;
|
||||||
|
fMediaStatus = mediaStatus;
|
||||||
|
// analyze the media status
|
||||||
|
switch (fMediaStatus) {
|
||||||
|
case B_NO_ERROR:
|
||||||
|
case B_DEV_NO_MEDIA:
|
||||||
|
case B_DEV_NOT_READY:
|
||||||
|
case B_DEV_MEDIA_CHANGE_REQUESTED:
|
||||||
|
case B_DEV_DOOR_OPEN:
|
||||||
|
break;
|
||||||
|
case B_DEV_MEDIA_CHANGED:
|
||||||
|
// the user was fast enough to change the media between opening
|
||||||
|
// and requesting the media status -- media is in, so we are fine
|
||||||
|
fMediaStatus = B_OK;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
error = fMediaStatus;
|
||||||
|
}
|
||||||
|
// scan the device for sessions, if we have a media
|
||||||
|
if (fMediaStatus == B_OK) {
|
||||||
|
session_info sessionInfo;
|
||||||
|
for (int32 i = 0; ; i++) {
|
||||||
|
// get the session info
|
||||||
|
status_t status = get_nth_session_info(fFD, i, &sessionInfo);
|
||||||
|
if (status != B_OK) {
|
||||||
|
if (status != B_ENTRY_NOT_FOUND)
|
||||||
|
error = status;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// create and add a RSession
|
||||||
|
if (RSession *session = new(nothrow) RSession) {
|
||||||
|
error = session->SetTo(fFD, &sessionInfo);
|
||||||
|
if (error == B_OK)
|
||||||
|
AddSession(session);
|
||||||
|
else
|
||||||
|
delete session;
|
||||||
|
} else
|
||||||
|
error = B_NO_MEMORY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// cleanup on error
|
||||||
|
if (error != B_OK)
|
||||||
|
Unset();
|
||||||
|
RETURN_ERROR(error);
|
||||||
|
// return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unset
|
||||||
|
void
|
||||||
|
RDiskDevice::Unset()
|
||||||
|
{
|
||||||
|
for (int32 i = CountSessions() - 1; i >= 0; i--)
|
||||||
|
RemoveSession(i);
|
||||||
|
fID = -1;
|
||||||
|
fPath.SetTo("");
|
||||||
|
if (fFD >= 0) {
|
||||||
|
close(fFD);
|
||||||
|
fFD = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddSession
|
||||||
|
bool
|
||||||
|
RDiskDevice::AddSession(RSession *session)
|
||||||
|
{
|
||||||
|
bool success = false;
|
||||||
|
if (session) {
|
||||||
|
success = fSessions.AddItem(session);
|
||||||
|
if (success) {
|
||||||
|
session->SetDevice(this);
|
||||||
|
if (RDiskDeviceList *deviceList = DeviceList())
|
||||||
|
deviceList->SessionAdded(session);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveSession
|
||||||
|
bool
|
||||||
|
RDiskDevice::RemoveSession(int32 index)
|
||||||
|
{
|
||||||
|
RSession *session = SessionAt(index);
|
||||||
|
if (session) {
|
||||||
|
session->SetDevice(NULL);
|
||||||
|
fSessions.RemoveItemAt(index);
|
||||||
|
if (RDiskDeviceList *deviceList = DeviceList())
|
||||||
|
deviceList->SessionRemoved(session);
|
||||||
|
delete session;
|
||||||
|
}
|
||||||
|
return (session != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveSession
|
||||||
|
bool
|
||||||
|
RDiskDevice::RemoveSession(RSession *session)
|
||||||
|
{
|
||||||
|
bool success = false;
|
||||||
|
if (session) {
|
||||||
|
int32 index = fSessions.IndexOf(session);
|
||||||
|
if (index >= 0)
|
||||||
|
success = RemoveSession(index);
|
||||||
|
}
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update
|
||||||
|
status_t
|
||||||
|
RDiskDevice::Update()
|
||||||
|
{
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dump
|
||||||
|
void
|
||||||
|
RDiskDevice::Dump() const
|
||||||
|
{
|
||||||
|
printf("device `%s'\n", Path());
|
||||||
|
for (int32 i = 0; RSession *session = SessionAt(i); i++)
|
||||||
|
session->Dump();
|
||||||
|
}
|
||||||
|
|
||||||
|
// _NextID
|
||||||
|
int32
|
||||||
|
RDiskDevice::_NextID()
|
||||||
|
{
|
||||||
|
return atomic_add(&fNextID, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// fNextID
|
||||||
|
vint32 RDiskDevice::fNextID = 0;
|
||||||
|
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
//----------------------------------------------------------------------
|
||||||
|
// This software is part of the OpenBeOS distribution and is covered
|
||||||
|
// by the OpenBeOS license.
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifndef DISK_DEVICE_H
|
||||||
|
#define DISK_DEVICE_H
|
||||||
|
|
||||||
|
#include <Drivers.h>
|
||||||
|
#include <ObjectList.h>
|
||||||
|
#include <String.h>
|
||||||
|
|
||||||
|
class RDiskDeviceList;
|
||||||
|
class RPartition;
|
||||||
|
class RSession;
|
||||||
|
|
||||||
|
class RDiskDevice {
|
||||||
|
public:
|
||||||
|
RDiskDevice();
|
||||||
|
~RDiskDevice();
|
||||||
|
|
||||||
|
status_t SetTo(const char *path, int fd, const device_geometry *geometry,
|
||||||
|
status_t mediaStatus);
|
||||||
|
void Unset();
|
||||||
|
|
||||||
|
void SetDeviceList(RDiskDeviceList *deviceList)
|
||||||
|
{ fDeviceList = deviceList ;}
|
||||||
|
RDiskDeviceList *DeviceList() const { return fDeviceList; }
|
||||||
|
|
||||||
|
int32 ID() const { return fID; }
|
||||||
|
int32 ChangeCounter() const { return fChangeCounter; }
|
||||||
|
|
||||||
|
void SetTouched(bool touched) { fTouched = touched; }
|
||||||
|
bool Touched() const { return fTouched; }
|
||||||
|
|
||||||
|
const char *Path() const { return fPath.String(); }
|
||||||
|
|
||||||
|
bool AddSession(RSession *session);
|
||||||
|
bool RemoveSession(int32 index);
|
||||||
|
bool RemoveSession(RSession *session);
|
||||||
|
int32 CountSessions() const { return fSessions.CountItems(); }
|
||||||
|
RSession *SessionAt(int32 index) const { return fSessions.ItemAt(index); }
|
||||||
|
|
||||||
|
status_t Update();
|
||||||
|
|
||||||
|
void Dump() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static int32 _NextID();
|
||||||
|
|
||||||
|
private:
|
||||||
|
BObjectList<RSession> fSessions;
|
||||||
|
RDiskDeviceList *fDeviceList;
|
||||||
|
int32 fID;
|
||||||
|
int32 fChangeCounter;
|
||||||
|
bool fTouched;
|
||||||
|
BString fPath;
|
||||||
|
int fFD;
|
||||||
|
device_geometry fGeometry;
|
||||||
|
status_t fMediaStatus;
|
||||||
|
|
||||||
|
static vint32 fNextID;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // DISK_DEVICE_H
|
||||||
@@ -0,0 +1,325 @@
|
|||||||
|
//----------------------------------------------------------------------
|
||||||
|
// This software is part of the OpenBeOS distribution and is covered
|
||||||
|
// by the OpenBeOS license.
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <new.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#include <Directory.h>
|
||||||
|
#include <Drivers.h>
|
||||||
|
#include <Entry.h>
|
||||||
|
//#include <ObjectLocker.h>
|
||||||
|
#include <Path.h>
|
||||||
|
|
||||||
|
#include "RDiskDeviceList.h"
|
||||||
|
#include "Debug.h"
|
||||||
|
#include "RDiskDevice.h"
|
||||||
|
#include "RPartition.h"
|
||||||
|
#include "RSession.h"
|
||||||
|
|
||||||
|
// compare_ids
|
||||||
|
/*template<typename T>
|
||||||
|
static
|
||||||
|
int
|
||||||
|
compare_ids(const T *object1, const T *object2)
|
||||||
|
{
|
||||||
|
int32 id1 = object1->ID();
|
||||||
|
int32 id2 = object2->ID();
|
||||||
|
if (id1 < id2)
|
||||||
|
return -1;
|
||||||
|
if (id1 > id2)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
// CompareIDPredicate
|
||||||
|
template <typename T>
|
||||||
|
struct CompareIDPredicate : public UnaryPredicate<T> {
|
||||||
|
CompareIDPredicate(int32 id) : fID(id) {}
|
||||||
|
CompareIDPredicate(const T *object) : fID(object->ID()) {}
|
||||||
|
|
||||||
|
virtual int operator()(const T *object) const
|
||||||
|
{
|
||||||
|
int32 id = object->ID();
|
||||||
|
if (fID < id)
|
||||||
|
return -1;
|
||||||
|
if (fID > id)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
int32 fID;
|
||||||
|
};
|
||||||
|
|
||||||
|
// CompareDevicePathPredicate
|
||||||
|
struct CompareDevicePathPredicate : public UnaryPredicate<RDiskDevice> {
|
||||||
|
CompareDevicePathPredicate(const char *path) : fPath(path) {}
|
||||||
|
|
||||||
|
virtual int operator()(const RDiskDevice *device) const
|
||||||
|
{
|
||||||
|
return strcmp(fPath, device->Path());
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const char *fPath;
|
||||||
|
};
|
||||||
|
|
||||||
|
// constructor
|
||||||
|
RDiskDeviceList::RDiskDeviceList()
|
||||||
|
: fLock(),
|
||||||
|
fDevices(20, true),
|
||||||
|
fSessions(40, false),
|
||||||
|
fPartitions(80, false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// destructor
|
||||||
|
RDiskDeviceList::~RDiskDeviceList()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddDevice
|
||||||
|
bool
|
||||||
|
RDiskDeviceList::AddDevice(RDiskDevice *device)
|
||||||
|
{
|
||||||
|
bool success = false;
|
||||||
|
if (device) {
|
||||||
|
fDevices.BinaryInsert(device, CompareIDPredicate<RDiskDevice>(device));
|
||||||
|
device->SetDeviceList(this);
|
||||||
|
DeviceAdded(device);
|
||||||
|
}
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveDevice
|
||||||
|
bool
|
||||||
|
RDiskDeviceList::RemoveDevice(int32 index)
|
||||||
|
{
|
||||||
|
RDiskDevice *device = DeviceAt(index);
|
||||||
|
if (device) {
|
||||||
|
device->SetDeviceList(NULL);
|
||||||
|
fDevices.RemoveItemAt(index);
|
||||||
|
DeviceRemoved(device);
|
||||||
|
delete device;
|
||||||
|
}
|
||||||
|
return (device != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveDevice
|
||||||
|
bool
|
||||||
|
RDiskDeviceList::RemoveDevice(RDiskDevice *device)
|
||||||
|
{
|
||||||
|
bool success = false;
|
||||||
|
if (device) {
|
||||||
|
int32 index = fDevices.FindBinaryInsertionIndex(
|
||||||
|
CompareIDPredicate<RDiskDevice>(device), &success);
|
||||||
|
if (success)
|
||||||
|
success = RemoveDevice(index);
|
||||||
|
}
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeviceWithID
|
||||||
|
RDiskDevice *
|
||||||
|
RDiskDeviceList::DeviceWithID(int32 id) const
|
||||||
|
{
|
||||||
|
bool inList = false;
|
||||||
|
int32 index = fDevices.FindBinaryInsertionIndex(
|
||||||
|
CompareIDPredicate<RDiskDevice>(id), &inList);
|
||||||
|
return (inList ? DeviceAt(index) : NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
// SessionWithID
|
||||||
|
RSession *
|
||||||
|
RDiskDeviceList::SessionWithID(int32 id) const
|
||||||
|
{
|
||||||
|
bool inList = false;
|
||||||
|
int32 index = fSessions.FindBinaryInsertionIndex(
|
||||||
|
CompareIDPredicate<RSession>(id), &inList);
|
||||||
|
return (inList ? SessionAt(index) : NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
// PartitionWithID
|
||||||
|
RPartition *
|
||||||
|
RDiskDeviceList::PartitionWithID(int32 id) const
|
||||||
|
{
|
||||||
|
bool inList = false;
|
||||||
|
int32 index = fPartitions.FindBinaryInsertionIndex(
|
||||||
|
CompareIDPredicate<RPartition>(id), &inList);
|
||||||
|
return (inList ? PartitionAt(index) : NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeviceWithPath
|
||||||
|
RDiskDevice *
|
||||||
|
RDiskDeviceList::DeviceWithPath(const char *path) const
|
||||||
|
{
|
||||||
|
const RDiskDevice *device
|
||||||
|
= fDevices.FindIf(CompareDevicePathPredicate(path));
|
||||||
|
return const_cast<RDiskDevice*>(device);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rescan
|
||||||
|
status_t
|
||||||
|
RDiskDeviceList::Rescan()
|
||||||
|
{
|
||||||
|
FUNCTION_START();
|
||||||
|
status_t error = B_OK;
|
||||||
|
if (Lock()) {
|
||||||
|
// marked all devices untouched
|
||||||
|
for (int32 i = 0; RDiskDevice *device = DeviceAt(i); i++)
|
||||||
|
device->SetTouched(false);
|
||||||
|
// scan the "/dev/disk" directory for devices
|
||||||
|
BDirectory dir;
|
||||||
|
if (dir.SetTo("/dev/disk") == B_OK) {
|
||||||
|
error = _Scan(dir);
|
||||||
|
}
|
||||||
|
// remove all untouched devices
|
||||||
|
for (int32 i = CountDevices() - 1; i >= 0; i--) {
|
||||||
|
if (!DeviceAt(i)->Touched())
|
||||||
|
RemoveDevice(i);
|
||||||
|
}
|
||||||
|
Unlock();
|
||||||
|
} else
|
||||||
|
error = B_ERROR;
|
||||||
|
FUNCTION_END();
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lock
|
||||||
|
bool
|
||||||
|
RDiskDeviceList::Lock()
|
||||||
|
{
|
||||||
|
return fLock.Lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unlock
|
||||||
|
void
|
||||||
|
RDiskDeviceList::Unlock()
|
||||||
|
{
|
||||||
|
fLock.Unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeviceAdded
|
||||||
|
void
|
||||||
|
RDiskDeviceList::DeviceAdded(RDiskDevice *device)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeviceRemoved
|
||||||
|
void
|
||||||
|
RDiskDeviceList::DeviceRemoved(RDiskDevice *device)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// SessionAdded
|
||||||
|
void
|
||||||
|
RDiskDeviceList::SessionAdded(RSession *session)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// SessionRemoved
|
||||||
|
void
|
||||||
|
RDiskDeviceList::SessionRemoved(RSession *session)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// PartitionAdded
|
||||||
|
void
|
||||||
|
RDiskDeviceList::PartitionAdded(RPartition *partition)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// PartitionRemoved
|
||||||
|
void
|
||||||
|
RDiskDeviceList::PartitionRemoved(RPartition *partition)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dump
|
||||||
|
void
|
||||||
|
RDiskDeviceList::Dump() const
|
||||||
|
{
|
||||||
|
for (int32 i = 0; RDiskDevice *device = DeviceAt(i); i++)
|
||||||
|
device->Dump();
|
||||||
|
}
|
||||||
|
|
||||||
|
// _Scan
|
||||||
|
status_t
|
||||||
|
RDiskDeviceList::_Scan(BDirectory &dir)
|
||||||
|
{
|
||||||
|
//BEntry dirEntry;
|
||||||
|
//BPath dirPath;
|
||||||
|
//dir.GetEntry(&dirEntry);
|
||||||
|
//dirEntry.GetPath(&dirPath);
|
||||||
|
//PRINT(("RDiskDeviceList::_Scan(`%s')\n", dirPath.Path()));
|
||||||
|
status_t error = B_OK;
|
||||||
|
BEntry entry;
|
||||||
|
while (dir.GetNextEntry(&entry) == B_OK) {
|
||||||
|
struct stat st;
|
||||||
|
if (entry.GetStat(&st) == B_OK) {
|
||||||
|
//PRINT(("st.st_mode: 0x%x\n", st.st_mode & S_IFMT));
|
||||||
|
if (S_ISDIR(st.st_mode)) {
|
||||||
|
BDirectory subdir;
|
||||||
|
if (subdir.SetTo(&entry) == B_OK)
|
||||||
|
error = _Scan(subdir);
|
||||||
|
} else if (!S_ISLNK(st.st_mode)) {
|
||||||
|
BPath path;
|
||||||
|
if (entry.GetPath(&path) == B_OK) {
|
||||||
|
_ScanDevice(path.Path());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
// _ScanDevice
|
||||||
|
status_t
|
||||||
|
RDiskDeviceList::_ScanDevice(const char *path)
|
||||||
|
{
|
||||||
|
status_t error = B_OK;
|
||||||
|
// search the list for a device with that path
|
||||||
|
if (RDiskDevice *device = DeviceWithPath(path)) {
|
||||||
|
// found: just update it
|
||||||
|
error = device->Update();
|
||||||
|
} else {
|
||||||
|
// not found: check whether it is really a disk device and add it to
|
||||||
|
// the list
|
||||||
|
int fd = open(path, O_RDONLY);
|
||||||
|
if (fd >= 0) {
|
||||||
|
bool closeFile = true;
|
||||||
|
device_geometry geometry;
|
||||||
|
status_t mediaStatus = B_OK;
|
||||||
|
partition_info partitionInfo;
|
||||||
|
if (ioctl(fd, B_GET_MEDIA_STATUS, &mediaStatus) == 0
|
||||||
|
&& ioctl(fd, B_GET_GEOMETRY, &geometry) == 0
|
||||||
|
&& ioctl(fd, B_GET_PARTITION_INFO, &partitionInfo) < 0) {
|
||||||
|
// int32 blockSize = geometry.bytes_per_sector;
|
||||||
|
// off_t deviceSize = (off_t)blockSize
|
||||||
|
// * geometry.sectors_per_track * geometry.cylinder_count
|
||||||
|
// * geometry.head_count;
|
||||||
|
RDiskDevice *device = new(nothrow) RDiskDevice;
|
||||||
|
if (device) {
|
||||||
|
error = device->SetTo(path, fd, &geometry, mediaStatus);
|
||||||
|
if (error == B_OK) {
|
||||||
|
closeFile = false;
|
||||||
|
AddDevice(device);
|
||||||
|
} else
|
||||||
|
delete device;
|
||||||
|
} else
|
||||||
|
error = B_NO_MEMORY;
|
||||||
|
}
|
||||||
|
if (closeFile)
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
//----------------------------------------------------------------------
|
||||||
|
// This software is part of the OpenBeOS distribution and is covered
|
||||||
|
// by the OpenBeOS license.
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifndef DISK_DEVICE_LIST_H
|
||||||
|
#define DISK_DEVICE_LIST_H
|
||||||
|
|
||||||
|
#include <Locker.h>
|
||||||
|
#include <ObjectList.h>
|
||||||
|
|
||||||
|
class BDirectory;
|
||||||
|
class BEntry;
|
||||||
|
|
||||||
|
class RDiskDevice;
|
||||||
|
class RPartition;
|
||||||
|
class RSession;
|
||||||
|
|
||||||
|
class RDiskDeviceList {
|
||||||
|
public:
|
||||||
|
RDiskDeviceList();
|
||||||
|
~RDiskDeviceList();
|
||||||
|
|
||||||
|
bool AddDevice(RDiskDevice *device);
|
||||||
|
bool RemoveDevice(int32 index);
|
||||||
|
bool RemoveDevice(RDiskDevice *device);
|
||||||
|
int32 CountDevices() const { return fDevices.CountItems(); }
|
||||||
|
RDiskDevice *DeviceAt(int32 index) const { return fDevices.ItemAt(index); }
|
||||||
|
|
||||||
|
int32 CountSessions() const { return fSessions.CountItems(); }
|
||||||
|
RSession *SessionAt(int32 index) const { return fSessions.ItemAt(index); }
|
||||||
|
|
||||||
|
int32 CountPartitions() const { return fPartitions.CountItems(); }
|
||||||
|
RPartition *PartitionAt(int32 index) const
|
||||||
|
{ return fPartitions.ItemAt(index); }
|
||||||
|
|
||||||
|
RDiskDevice *DeviceWithID(int32 id) const;
|
||||||
|
RSession *SessionWithID(int32 id) const;
|
||||||
|
RPartition *PartitionWithID(int32 id) const;
|
||||||
|
|
||||||
|
RDiskDevice *DeviceWithPath(const char *path) const;
|
||||||
|
|
||||||
|
status_t Rescan();
|
||||||
|
|
||||||
|
bool Lock();
|
||||||
|
void Unlock();
|
||||||
|
|
||||||
|
void DeviceAdded(RDiskDevice *device);
|
||||||
|
void DeviceRemoved(RDiskDevice *device);
|
||||||
|
void SessionAdded(RSession *session);
|
||||||
|
void SessionRemoved(RSession *session);
|
||||||
|
void PartitionAdded(RPartition *partition);
|
||||||
|
void PartitionRemoved(RPartition *partition);
|
||||||
|
|
||||||
|
void Dump() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
status_t _Scan(BDirectory &dir);
|
||||||
|
status_t _ScanDevice(const char *path);
|
||||||
|
|
||||||
|
private:
|
||||||
|
BLocker fLock;
|
||||||
|
BObjectList<RDiskDevice> fDevices; // sorted by ID
|
||||||
|
BObjectList<RSession> fSessions; //
|
||||||
|
BObjectList<RPartition> fPartitions; //
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // DISK_DEVICE_LIST_H
|
||||||
@@ -0,0 +1,96 @@
|
|||||||
|
//----------------------------------------------------------------------
|
||||||
|
// This software is part of the OpenBeOS distribution and is covered
|
||||||
|
// by the OpenBeOS license.
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include "RPartition.h"
|
||||||
|
#include "RDiskDevice.h"
|
||||||
|
#include "RDiskDeviceList.h"
|
||||||
|
#include "RSession.h"
|
||||||
|
|
||||||
|
// constructor
|
||||||
|
RPartition::RPartition()
|
||||||
|
: fSession(NULL),
|
||||||
|
fID(-1),
|
||||||
|
fChangeCounter(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// destructor
|
||||||
|
RPartition::~RPartition()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetTo
|
||||||
|
status_t
|
||||||
|
RPartition::SetTo(int fd, const extended_partition_info *partitionInfo)
|
||||||
|
{
|
||||||
|
Unset();
|
||||||
|
status_t error = B_OK;
|
||||||
|
fID = _NextID();
|
||||||
|
fChangeCounter = 0;
|
||||||
|
fInfo = *partitionInfo;
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unset
|
||||||
|
void
|
||||||
|
RPartition::Unset()
|
||||||
|
{
|
||||||
|
fID = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeviceList
|
||||||
|
RDiskDeviceList *
|
||||||
|
RPartition::DeviceList() const
|
||||||
|
{
|
||||||
|
return (fSession ? fSession->DeviceList() : NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Device
|
||||||
|
RDiskDevice *
|
||||||
|
RPartition::Device() const
|
||||||
|
{
|
||||||
|
return (fSession ? fSession->Device() : NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
// print_partition_info
|
||||||
|
static
|
||||||
|
void
|
||||||
|
print_partition_info(const char *prefix, const extended_partition_info &info)
|
||||||
|
{
|
||||||
|
printf("%soffset: %lld\n", prefix, info.info.offset);
|
||||||
|
printf("%ssize: %lld\n", prefix, info.info.size);
|
||||||
|
printf("%sblock size: %ld\n", prefix, info.info.logical_block_size);
|
||||||
|
printf("%ssession ID: %ld\n", prefix, info.info.session);
|
||||||
|
printf("%spartition ID: %ld\n", prefix, info.info.partition);
|
||||||
|
printf("%sdevice: `%s'\n", prefix, info.info.device);
|
||||||
|
printf("%sflags: %lx\n", prefix, info.flags);
|
||||||
|
printf("%spartition code: 0x%lx\n", prefix, info.partition_code);
|
||||||
|
printf("%spartition name: `%s'\n", prefix, info.partition_name);
|
||||||
|
printf("%spartition type: `%s'\n", prefix, info.partition_type);
|
||||||
|
printf("%sFS short name: `%s'\n", prefix, info.file_system_short_name);
|
||||||
|
printf("%sFS long name: `%s'\n", prefix, info.file_system_long_name);
|
||||||
|
printf("%svolume name: `%s'\n", prefix, info.volume_name);
|
||||||
|
printf("%smounted at: `%s'\n", prefix, info.mounted_at);
|
||||||
|
printf("%sFS flags: 0x%lx\n", prefix, info.file_system_flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dump
|
||||||
|
void
|
||||||
|
RPartition::Dump() const
|
||||||
|
{
|
||||||
|
printf(" partition %ld:\n", fInfo.info.partition);
|
||||||
|
print_partition_info(" ", fInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
// _NextID
|
||||||
|
int32
|
||||||
|
RPartition::_NextID()
|
||||||
|
{
|
||||||
|
return atomic_add(&fNextID, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// fNextID
|
||||||
|
vint32 RPartition::fNextID = 0;
|
||||||
|
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
//----------------------------------------------------------------------
|
||||||
|
// This software is part of the OpenBeOS distribution and is covered
|
||||||
|
// by the OpenBeOS license.
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifndef PARTITION_H
|
||||||
|
#define PARTITION_H
|
||||||
|
|
||||||
|
#include <disk_scanner.h>
|
||||||
|
#include <SupportDefs.h>
|
||||||
|
|
||||||
|
class RDiskDevice;
|
||||||
|
class RDiskDeviceList;
|
||||||
|
class RSession;
|
||||||
|
|
||||||
|
class RPartition {
|
||||||
|
public:
|
||||||
|
RPartition();
|
||||||
|
~RPartition();
|
||||||
|
|
||||||
|
status_t SetTo(int fd, const extended_partition_info *partitionInfo);
|
||||||
|
void Unset();
|
||||||
|
|
||||||
|
void SetSession(RSession *session) { fSession = session; }
|
||||||
|
RDiskDeviceList *DeviceList() const;
|
||||||
|
RDiskDevice *Device() const;
|
||||||
|
RSession *Session() const { return fSession; }
|
||||||
|
|
||||||
|
int32 ID() const { return fID; }
|
||||||
|
int32 ChangeCounter() const { return fChangeCounter; }
|
||||||
|
|
||||||
|
const extended_partition_info *Info() const { return &fInfo; }
|
||||||
|
|
||||||
|
void Dump() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static int32 _NextID();
|
||||||
|
|
||||||
|
private:
|
||||||
|
RSession *fSession;
|
||||||
|
int32 fID;
|
||||||
|
int32 fChangeCounter;
|
||||||
|
extended_partition_info fInfo;
|
||||||
|
|
||||||
|
static vint32 fNextID;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // PARTITION_H
|
||||||
@@ -0,0 +1,157 @@
|
|||||||
|
//----------------------------------------------------------------------
|
||||||
|
// This software is part of the OpenBeOS distribution and is covered
|
||||||
|
// by the OpenBeOS license.
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <new.h>
|
||||||
|
|
||||||
|
#include <Drivers.h>
|
||||||
|
|
||||||
|
#include "RSession.h"
|
||||||
|
#include "RDiskDevice.h"
|
||||||
|
#include "RDiskDeviceList.h"
|
||||||
|
#include "RPartition.h"
|
||||||
|
|
||||||
|
// constructor
|
||||||
|
RSession::RSession()
|
||||||
|
: fPartitions(10, true),
|
||||||
|
fDevice(NULL),
|
||||||
|
fID(-1),
|
||||||
|
fChangeCounter(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// destructor
|
||||||
|
RSession::~RSession()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetTo
|
||||||
|
status_t
|
||||||
|
RSession::SetTo(int fd, const session_info *sessionInfo)
|
||||||
|
{
|
||||||
|
Unset();
|
||||||
|
status_t error = B_OK;
|
||||||
|
fID = _NextID();
|
||||||
|
fChangeCounter = 0;
|
||||||
|
fInfo = *sessionInfo;
|
||||||
|
// iterate through the partitions
|
||||||
|
for (int32 i = 0; ; i++) {
|
||||||
|
// get the partition info
|
||||||
|
extended_partition_info partitionInfo;
|
||||||
|
status_t status = get_nth_partition_info(fd, sessionInfo->index, i,
|
||||||
|
&partitionInfo, (i == 0 ? fPartitioningSystem : NULL));
|
||||||
|
if (status != B_OK) {
|
||||||
|
if (status != B_ENTRY_NOT_FOUND)
|
||||||
|
error = status;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// create and add a RPartition
|
||||||
|
if (RPartition *partition = new(nothrow) RPartition) {
|
||||||
|
error = partition->SetTo(fd, &partitionInfo);
|
||||||
|
if (error == B_OK)
|
||||||
|
AddPartition(partition);
|
||||||
|
else
|
||||||
|
delete partition;
|
||||||
|
} else
|
||||||
|
error = B_NO_MEMORY;
|
||||||
|
}
|
||||||
|
// cleanup on error
|
||||||
|
if (error != B_OK)
|
||||||
|
Unset();
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unset
|
||||||
|
void
|
||||||
|
RSession::Unset()
|
||||||
|
{
|
||||||
|
for (int32 i = CountPartitions() - 1; i >= 0; i--)
|
||||||
|
RemovePartition(i);
|
||||||
|
fID = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeviceList
|
||||||
|
RDiskDeviceList *
|
||||||
|
RSession::DeviceList() const
|
||||||
|
{
|
||||||
|
return (fDevice ? fDevice->DeviceList() : NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddPartition
|
||||||
|
bool
|
||||||
|
RSession::AddPartition(RPartition *partition)
|
||||||
|
{
|
||||||
|
bool success = false;
|
||||||
|
if (partition) {
|
||||||
|
success = fPartitions.AddItem(partition);
|
||||||
|
if (success) {
|
||||||
|
partition->SetSession(this);
|
||||||
|
if (RDiskDeviceList *deviceList = DeviceList())
|
||||||
|
deviceList->PartitionAdded(partition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemovePartition
|
||||||
|
bool
|
||||||
|
RSession::RemovePartition(int32 index)
|
||||||
|
{
|
||||||
|
RPartition *partition = PartitionAt(index);
|
||||||
|
if (partition) {
|
||||||
|
partition->SetSession(NULL);
|
||||||
|
fPartitions.RemoveItemAt(index);
|
||||||
|
if (RDiskDeviceList *deviceList = DeviceList())
|
||||||
|
deviceList->PartitionRemoved(partition);
|
||||||
|
delete partition;
|
||||||
|
}
|
||||||
|
return (partition != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemovePartition
|
||||||
|
bool
|
||||||
|
RSession::RemovePartition(RPartition *partition)
|
||||||
|
{
|
||||||
|
bool success = false;
|
||||||
|
if (partition) {
|
||||||
|
int32 index = fPartitions.IndexOf(partition);
|
||||||
|
if (index >= 0)
|
||||||
|
success = RemovePartition(index);
|
||||||
|
}
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
// print_session_info
|
||||||
|
static
|
||||||
|
void
|
||||||
|
print_session_info(const char *prefix, const session_info &info)
|
||||||
|
{
|
||||||
|
printf("%soffset: %lld\n", prefix, info.offset);
|
||||||
|
printf("%ssize: %lld\n", prefix, info.size);
|
||||||
|
printf("%sblock size: %ld\n", prefix, info.logical_block_size);
|
||||||
|
printf("%sindex: %ld\n", prefix, info.index);
|
||||||
|
printf("%sflags: %lx\n", prefix, info.flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dump
|
||||||
|
void
|
||||||
|
RSession::Dump() const
|
||||||
|
{
|
||||||
|
printf(" session %ld:\n", fInfo.index);
|
||||||
|
print_session_info(" ", fInfo);
|
||||||
|
printf(" partitioning : `%s'\n", fPartitioningSystem);
|
||||||
|
for (int32 i = 0; RPartition *partition = PartitionAt(i); i++)
|
||||||
|
partition->Dump();
|
||||||
|
}
|
||||||
|
|
||||||
|
// _NextID
|
||||||
|
int32
|
||||||
|
RSession::_NextID()
|
||||||
|
{
|
||||||
|
return atomic_add(&fNextID, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// fNextID
|
||||||
|
vint32 RSession::fNextID = 0;
|
||||||
|
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
//----------------------------------------------------------------------
|
||||||
|
// This software is part of the OpenBeOS distribution and is covered
|
||||||
|
// by the OpenBeOS license.
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifndef SESSION_H
|
||||||
|
#define SESSION_H
|
||||||
|
|
||||||
|
#include <disk_scanner.h>
|
||||||
|
#include <ObjectList.h>
|
||||||
|
|
||||||
|
class RDiskDevice;
|
||||||
|
class RDiskDeviceList;
|
||||||
|
class RPartition;
|
||||||
|
|
||||||
|
class RSession {
|
||||||
|
public:
|
||||||
|
RSession();
|
||||||
|
~RSession();
|
||||||
|
|
||||||
|
status_t SetTo(int fd, const session_info *sessionInfo);
|
||||||
|
void Unset();
|
||||||
|
|
||||||
|
void SetDevice(RDiskDevice *device) { fDevice = device; }
|
||||||
|
RDiskDeviceList *DeviceList() const;
|
||||||
|
RDiskDevice *Device() const { return fDevice; }
|
||||||
|
|
||||||
|
int32 ID() const { return fID; }
|
||||||
|
int32 ChangeCounter() const { return fChangeCounter; }
|
||||||
|
|
||||||
|
bool AddPartition(RPartition *partition);
|
||||||
|
bool RemovePartition(int32 index);
|
||||||
|
bool RemovePartition(RPartition *partition);
|
||||||
|
int32 CountPartitions() const { return fPartitions.CountItems(); }
|
||||||
|
RPartition *PartitionAt(int32 index) const
|
||||||
|
{ return fPartitions.ItemAt(index); }
|
||||||
|
|
||||||
|
const session_info *Info() const { return &fInfo; }
|
||||||
|
|
||||||
|
void Dump() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static int32 _NextID();
|
||||||
|
|
||||||
|
private:
|
||||||
|
BObjectList<RPartition> fPartitions;
|
||||||
|
RDiskDevice *fDevice;
|
||||||
|
int32 fID;
|
||||||
|
int32 fChangeCounter;
|
||||||
|
session_info fInfo;
|
||||||
|
char fPartitioningSystem[B_FILE_NAME_LENGTH];
|
||||||
|
|
||||||
|
static vint32 fNextID;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // SESSION_H
|
||||||
Reference in New Issue
Block a user